issue #215/added: toast messages#232
Conversation
|
@manjeetsinghmeena is attempting to deploy a commit to the mrimmortal09's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds a client-side toast system and Provider, replaces component-local inline alert banners in sign-in, notes upload, and papers upload with toast-based feedback, wraps the app subtree with Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Client as App UI
participant Auth as Auth/API
participant Upload as Upload/API
participant Toast as ToastProvider
User->>Client: submit credentials / click Google sign-in / submit file
alt sign-in
Client->>Auth: signIn(credentials) or signIn('google')
Auth-->>Client: success or error
Client->>Toast: addToast(title, description?, type)
opt success
Client->>User: navigate / refresh
end
else upload
Client->>Upload: POST /api/notes or /api/papers
Upload-->>Client: success or error
Client->>Toast: addToast(title, description?, type)
end
Note right of Toast: Toasts render in viewport, auto-dismiss after 3000ms or dismissed manually
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
app/upload-notes/page.tsx (1)
21-21:⚠️ Potential issue | 🟡 MinorRemove unused
AlertCircleimport.
AlertCircleis imported but never used in the component. Remove it from the lucide-react import statement at line 21.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/upload-notes/page.tsx` at line 21, Remove the unused AlertCircle import from the lucide-react import statement in the upload-notes page component: locate the import line that includes AlertCircle and delete only the AlertCircle identifier so the import only includes icons actually used in the component (e.g., keep other symbols but remove AlertCircle).app/upload-papers/page.tsx (1)
44-45:⚠️ Potential issue | 🟡 Minor
successstate is completely unused and should be removed.The
successstate is set on line 196 but never read anywhere in the component. Since feedback is provided entirely through toast notifications, this variable serves no purpose and can be safely removed.The
errorstate, however, is read in the file change handler (line 111) to clear errors when a new file is selected. While it's not rendered in the JSX, keeping it allows users to start fresh when selecting a new file. You may keep this if that behavior is intentional, or remove it if you want to simplify further.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/upload-papers/page.tsx` around lines 44 - 45, Remove the unused success state and its updater: delete the useState declaration for success and all references to setSuccess (e.g., the call that sets success on submission). Keep the error state/useState("error" and setError) if you want to preserve the behavior in the file change handler that clears prior errors; otherwise remove error and its usages as well. Ensure any toast-based success feedback remains unchanged and run a quick search for "success" to remove leftover references (e.g., calls to setSuccess or checks against success) and update imports/types if needed.
🧹 Nitpick comments (6)
app/upload-notes/page.tsx (1)
46-47: Consider removing unusederrorandsuccessstate.Same as in
upload-papers/page.tsx— these state variables are set but no longer rendered after switching to toast notifications.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/upload-notes/page.tsx` around lines 46 - 47, The file declares unused React state variables error, setError, success, and setSuccess via useState in upload-notes/page.tsx; remove those declarations and any calls to setError or setSuccess and any references to error/success, and also remove any now-unused imports (e.g., useState) if they become unused, mirroring the cleanup already done in upload-papers/page.tsx so the component relies solely on toast notifications.context/toast-provider.tsx (2)
31-33: Usesubstringinstead of deprecatedsubstr.
String.prototype.substris deprecated. Usesubstringinstead for future compatibility.🔧 Proposed fix
- const id = Math.random().toString(36).substr(2, 9) + const id = Math.random().toString(36).substring(2, 11)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@context/toast-provider.tsx` around lines 31 - 33, Replace the deprecated String.prototype.substr call used when generating the toast id with substring to ensure future compatibility: in the id generation line (where id is assigned via Math.random().toString(36).substr(2, 9)) change to use Math.random().toString(36).substring(2, 11) (or equivalent slice) so the resulting id length remains the same; keep the surrounding logic that calls setToasts([...]) and the setTimeout that calls removeToast(id) unchanged.
123-128: Consider adding accessibility attributes to the dismiss button.The dismiss button lacks an accessible label for screen readers.
♿ Proposed fix
<button onClick={() => onRemove(id)} - className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 flex-shrink-0" + className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 flex-shrink-0" + aria-label="Dismiss notification" > <X className="w-4 h-4" /> </button>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@context/toast-provider.tsx` around lines 123 - 128, The dismiss button in toast-provider.tsx (the <button> that calls onRemove(id) and renders the X icon) lacks an accessible label; add an explicit accessible name and proper button semantics by setting type="button" and an aria-label (e.g. "Dismiss notification" or a dynamic label using the toast title/description if available) and optionally a title attribute for tooltip support so screen readers and keyboard users can identify the control.app/globals.css (1)
81-90: Rename keyframes to kebab-case for consistency with Stylelint rules.The keyframes name
slideInshould follow kebab-case naming convention (slide-in) as flagged by Stylelint. This will require updating the animation reference incontext/toast-provider.tsxline 102 as well.🔧 Proposed fix
In
app/globals.css:-@keyframes slideIn { +@keyframes slide-in { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }In
context/toast-provider.tsx(line 102):style={{ - animation: 'slideIn 0.3s ease-in-out', + animation: 'slide-in 0.3s ease-in-out', }}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/globals.css` around lines 81 - 90, Rename the keyframes identifier slideIn to kebab-case slide-in in the CSS `@keyframes` declaration in globals.css and update every usage to match; specifically update the animation reference in context/toast-provider.tsx (where animation: slideIn is used around the toast rendering at the cited location) to use slide-in so Stylelint passes and the animation still applies.app/auth/signin/page.tsx (1)
121-128: Redundant error feedback: both inline alert and toast are shown.Unlike the upload pages where inline alerts were removed, this page still renders the inline error alert while also showing toast notifications for errors. This results in duplicate error feedback to users.
Consider either:
- Removing the inline error alert (consistent with upload pages), or
- Removing the error toasts and keeping only the inline alert
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/auth/signin/page.tsx` around lines 121 - 128, The page currently shows duplicate error feedback by rendering the inline alert block conditional on the error variable (the {error && (...)} JSX that uses AlertCircle) while also emitting toast notifications (e.g., calls to toast.error elsewhere); remove the inline alert to match the upload pages—delete the {error && (...)} block (the div containing AlertCircle and <span>{error}</span>) so errors are only reported via toasts, or if you prefer inline alerts instead, remove the toast.error calls and keep the {error && ...} block; pick one approach and apply it consistently.app/upload-papers/page.tsx (1)
23-24: Remove unused importsCheckCircleandAlertCircle.These icons are no longer used after removing the inline alert UI from the component.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/upload-papers/page.tsx` around lines 23 - 24, Remove the now-unused icon imports from the component: delete CheckCircle and AlertCircle from the import list where they are imported (symbols CheckCircle, AlertCircle) in the upload-papers page component, and run the linter or TypeScript check to ensure no other references remain; this cleans up unused imports and resolves related warnings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@app/upload-notes/page.tsx`:
- Line 21: Remove the unused AlertCircle import from the lucide-react import
statement in the upload-notes page component: locate the import line that
includes AlertCircle and delete only the AlertCircle identifier so the import
only includes icons actually used in the component (e.g., keep other symbols but
remove AlertCircle).
In `@app/upload-papers/page.tsx`:
- Around line 44-45: Remove the unused success state and its updater: delete the
useState declaration for success and all references to setSuccess (e.g., the
call that sets success on submission). Keep the error state/useState("error" and
setError) if you want to preserve the behavior in the file change handler that
clears prior errors; otherwise remove error and its usages as well. Ensure any
toast-based success feedback remains unchanged and run a quick search for
"success" to remove leftover references (e.g., calls to setSuccess or checks
against success) and update imports/types if needed.
---
Nitpick comments:
In `@app/auth/signin/page.tsx`:
- Around line 121-128: The page currently shows duplicate error feedback by
rendering the inline alert block conditional on the error variable (the {error
&& (...)} JSX that uses AlertCircle) while also emitting toast notifications
(e.g., calls to toast.error elsewhere); remove the inline alert to match the
upload pages—delete the {error && (...)} block (the div containing AlertCircle
and <span>{error}</span>) so errors are only reported via toasts, or if you
prefer inline alerts instead, remove the toast.error calls and keep the {error
&& ...} block; pick one approach and apply it consistently.
In `@app/globals.css`:
- Around line 81-90: Rename the keyframes identifier slideIn to kebab-case
slide-in in the CSS `@keyframes` declaration in globals.css and update every usage
to match; specifically update the animation reference in
context/toast-provider.tsx (where animation: slideIn is used around the toast
rendering at the cited location) to use slide-in so Stylelint passes and the
animation still applies.
In `@app/upload-notes/page.tsx`:
- Around line 46-47: The file declares unused React state variables error,
setError, success, and setSuccess via useState in upload-notes/page.tsx; remove
those declarations and any calls to setError or setSuccess and any references to
error/success, and also remove any now-unused imports (e.g., useState) if they
become unused, mirroring the cleanup already done in upload-papers/page.tsx so
the component relies solely on toast notifications.
In `@app/upload-papers/page.tsx`:
- Around line 23-24: Remove the now-unused icon imports from the component:
delete CheckCircle and AlertCircle from the import list where they are imported
(symbols CheckCircle, AlertCircle) in the upload-papers page component, and run
the linter or TypeScript check to ensure no other references remain; this cleans
up unused imports and resolves related warnings.
In `@context/toast-provider.tsx`:
- Around line 31-33: Replace the deprecated String.prototype.substr call used
when generating the toast id with substring to ensure future compatibility: in
the id generation line (where id is assigned via
Math.random().toString(36).substr(2, 9)) change to use
Math.random().toString(36).substring(2, 11) (or equivalent slice) so the
resulting id length remains the same; keep the surrounding logic that calls
setToasts([...]) and the setTimeout that calls removeToast(id) unchanged.
- Around line 123-128: The dismiss button in toast-provider.tsx (the <button>
that calls onRemove(id) and renders the X icon) lacks an accessible label; add
an explicit accessible name and proper button semantics by setting type="button"
and an aria-label (e.g. "Dismiss notification" or a dynamic label using the
toast title/description if available) and optionally a title attribute for
tooltip support so screen readers and keyboard users can identify the control.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 08372caa-1a96-43d3-8b82-db95ea943f80
📒 Files selected for processing (6)
app/auth/signin/page.tsxapp/globals.cssapp/layout.jsxapp/upload-notes/page.tsxapp/upload-papers/page.tsxcontext/toast-provider.tsx
There was a problem hiding this comment.
Pull request overview
Implements a lightweight toast notification system and integrates it into key user flows to provide consistent feedback (validation, upload results, auth outcomes) across the app.
Changes:
- Added a
ToastProvider+useToasthook to manage and render toast notifications globally. - Wrapped the application layout with
ToastProviderso toasts can be triggered from any client page. - Replaced several inline success/error alert UIs in upload flows with toast notifications, and added toast feedback to sign-in.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
context/toast-provider.tsx |
Introduces toast context/provider and UI rendering for notifications. |
app/layout.jsx |
Wraps the app shell in ToastProvider to enable global toasts. |
app/globals.css |
Adds slideIn keyframe animation used by toast items. |
app/auth/signin/page.tsx |
Adds toast notifications for validation/auth outcomes and Google sign-in redirect. |
app/upload-notes/page.tsx |
Adds toasts for validation/upload outcomes and removes inline alert rendering. |
app/upload-papers/page.tsx |
Adds toasts for validation/upload outcomes and removes inline alert rendering. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const addToast = ( | ||
| title: string, | ||
| description?: string, | ||
| type: ToastType = 'info' | ||
| ) => { | ||
| const id = Math.random().toString(36).substr(2, 9) | ||
| setToasts((prev) => [...prev, { id, title, description, type }]) | ||
| setTimeout(() => removeToast(id), 3000) | ||
| } |
There was a problem hiding this comment.
addToast generates IDs via Math.random().toString(36).substr(...), which can collide and uses deprecated substr. Prefer a stronger unique id (e.g., crypto.randomUUID() with a fallback) or an incrementing counter stored in a ref.
| export const ToastProvider = ({ children }: { children: ReactNode }) => { | ||
| const [toasts, setToasts] = useState<ToastMessage[]>([]) | ||
|
|
||
| const addToast = ( | ||
| title: string, | ||
| description?: string, | ||
| type: ToastType = 'info' | ||
| ) => { | ||
| const id = Math.random().toString(36).substr(2, 9) | ||
| setToasts((prev) => [...prev, { id, title, description, type }]) | ||
| setTimeout(() => removeToast(id), 3000) | ||
| } | ||
|
|
||
| const removeToast = (id: string) => { | ||
| setToasts((prev) => prev.filter((toast) => toast.id !== id)) | ||
| } |
There was a problem hiding this comment.
addToast schedules a setTimeout that isn't cleared on unmount. If the provider ever unmounts (or during fast refresh), this can trigger state updates on an unmounted component. Track timeout handles and clear them in an effect cleanup (or use a ref-based timer map per toast).
| <button | ||
| onClick={() => onRemove(id)} | ||
| className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 flex-shrink-0" | ||
| > | ||
| <X className="w-4 h-4" /> | ||
| </button> |
There was a problem hiding this comment.
Toast UI is missing basic a11y hooks: the close icon button has no accessible name, and the viewport/items don't expose an aria-live region/appropriate role (e.g., status for info/success, alert for error). Add aria-label to the close button and an aria-live container (or per-toast roles) so screen readers announce notifications.
| if ( | ||
| !finalSubject || | ||
| !formData.facultyName || | ||
| !formData.year || | ||
| !formData.semester || | ||
| !formData.term || | ||
| !formData.uploaded_file | ||
| ) { | ||
| const msg = 'Please fill in all required fields' | ||
| setError(msg) | ||
| addToast('Validation Error', msg, 'error') | ||
| setIsLoading(false) | ||
| return | ||
| } | ||
|
|
||
| const allowedTypes = [ | ||
| 'application/pdf', | ||
| 'image/png', | ||
| 'image/jpeg', | ||
| 'image/webp', | ||
| ] | ||
| if (!allowedTypes.includes(formData.uploaded_file.type)) { | ||
| setError('Only PDF, PNG, JPG, JPEG, and WEBP files are allowed') | ||
| setIsLoading(false) | ||
| return | ||
| } | ||
| const maxSize = 25 * 1024 * 1024 | ||
| if (formData.uploaded_file.size > maxSize) { | ||
| const msg = 'File size must be less than 25MB' | ||
| setError(msg) | ||
| addToast('File Too Large', msg, 'error') | ||
| setIsLoading(false) | ||
| return | ||
| } |
There was a problem hiding this comment.
The validation early-returns inside the try block call setIsLoading(false) before returning, but the finally also always calls setIsLoading(false). This causes redundant state updates/renders; remove the pre-return setIsLoading(false) calls (or move validation before the try).
| return ( | ||
| <div className="w-full flex flex-col items-center justify-center"> | ||
| <div className="w-full max-w-2xl px-5 mt-6 mb-10 space-y-6"> | ||
| {/* Header */} | ||
| <div className="flex flex-col sm:flex-row sm:relative sm:justify-center items-center gap-3"> | ||
| <h1 className="text-3xl font-semibold text-center">Upload a Note</h1> | ||
| </div> | ||
|
|
||
| {/* Alerts */} | ||
| {error && ( | ||
| <div className="flex items-start gap-3 px-4 py-3 rounded-md border border-destructive/40 bg-destructive/10 text-destructive text-sm"> | ||
| <AlertCircle className="w-4 h-4 mt-0.5 flex-shrink-0" /> | ||
| <div> | ||
| <p className="font-medium">Upload failed</p> | ||
| <p className="text-xs mt-0.5 opacity-80">{error}</p> | ||
| </div> | ||
| <button | ||
| onClick={() => setError(null)} | ||
| className="ml-auto flex-shrink-0 opacity-70 hover:opacity-100" | ||
| > | ||
| ✕ | ||
| </button> | ||
| </div> | ||
| )} | ||
| {success && ( | ||
| <div className="flex items-start gap-3 px-4 py-3 rounded-md border border-green-500/40 bg-green-500/10 text-green-600 dark:text-green-400 text-sm"> | ||
| <CheckCircle className="w-4 h-4 mt-0.5 flex-shrink-0" /> | ||
| <p className="font-medium">{success}</p> | ||
| <button | ||
| onClick={() => setSuccess(null)} | ||
| className="ml-auto flex-shrink-0 opacity-70 hover:opacity-100" | ||
| > | ||
| ✕ | ||
| </button> | ||
| </div> | ||
| )} | ||
|
|
||
| {/* Form */} | ||
| <form onSubmit={handleSubmit} className="space-y-5"> |
There was a problem hiding this comment.
After removing the inline alert UI, AlertCircle imported from lucide-react is no longer used in this file. Please remove the unused import to satisfy the repo's ESLint rules.
| if ( | ||
| !finalSubject || | ||
| !formData.year || | ||
| !formData.semester || | ||
| !formData.term || | ||
| !formData.uploaded_file | ||
| ) { | ||
| const msg = 'Please fill in all required fields' | ||
| setError(msg) | ||
| addToast('Validation Error', msg, 'error') | ||
| setIsLoading(false) | ||
| return | ||
| } | ||
|
|
||
| // Validate file size (25MB max) | ||
| const maxSize = 25 * 1024 * 1024 // 25MB in bytes | ||
| if (formData.uploaded_file.size > maxSize) { | ||
| setError('File size must be less than 25MB') | ||
| setIsLoading(false) | ||
| return | ||
| } | ||
| // Validate file size (25MB max) | ||
| const maxSize = 25 * 1024 * 1024 // 25MB in bytes | ||
| if (formData.uploaded_file.size > maxSize) { | ||
| const msg = 'File size must be less than 25MB' | ||
| setError(msg) | ||
| addToast('File Too Large', msg, 'error') | ||
| setIsLoading(false) | ||
| return | ||
| } |
There was a problem hiding this comment.
Similar to upload-notes: inside handleSubmit, validation early-returns call setIsLoading(false) but the finally also calls setIsLoading(false) even when returning from try. Drop the redundant pre-return updates to avoid extra renders.
| <Card className="shadow-lg"> | ||
| <CardContent> | ||
| {/* Error Message */} | ||
| {error && ( | ||
| <div className="mb-6 p-4 bg-destructive/10 border border-destructive rounded-lg flex items-start gap-3"> | ||
| <AlertCircle className="h-5 w-5 text-destructive mt-0.5" /> | ||
| <div> | ||
| <h4 className="font-medium text-destructive">Error</h4> | ||
| <p className="text-sm text-destructive/90">{error}</p> | ||
| </div> | ||
| </div> | ||
| )} | ||
|
|
||
| {/* Success Message */} | ||
| {success && ( | ||
| <div className="mb-6 p-4 bg-green-500/10 border border-green-500 rounded-lg flex items-start gap-3"> | ||
| <CheckCircle className="h-5 w-5 text-green-500 mt-0.5" /> | ||
| <div> | ||
| <h4 className="font-medium text-green-500">Success</h4> | ||
| <p className="text-sm text-green-500/90">{success}</p> | ||
| </div> | ||
| </div> | ||
| )} | ||
|
|
||
| <form onSubmit={handleSubmit} className="space-y-6"> | ||
| {/* Subject Field */} |
There was a problem hiding this comment.
The inline error/success alert blocks were removed, but the CheckCircle/AlertCircle icon imports used by those blocks are now unused in this file (the remaining file-selected indicator uses a literal ✓). Remove the unused icon imports to satisfy ESLint.
| @@ -13,6 +13,7 @@ export default function SignIn() { | |||
| const [error, setError] = useState('') | |||
| const [loading, setLoading] = useState(false) | |||
| const router = useRouter() | |||
| const { addToast } = useToast() | |||
|
|
|||
There was a problem hiding this comment.
PR description says inline alerts were replaced with toasts, but this page still renders an inline error banner ({error && ...}) in addition to showing toast errors. This can lead to duplicated messaging; either remove the inline banner or avoid triggering toasts for the same errors on this page.
| if (!response.ok) throw new Error(data.message || 'Failed to upload note') | ||
|
|
||
| const successMsg = 'Note uploaded successfully!' | ||
| setSuccess(successMsg) | ||
| addToast('Upload Successful', successMsg, 'success') | ||
| setFormData({ | ||
| facultyName: '', | ||
| content: '', | ||
| subject: '', | ||
| year: '', | ||
| semester: '', | ||
| term: '', | ||
| category: 'academic', | ||
| uploaded_file: null, | ||
| }) | ||
| setCustomSubject('') | ||
| setIsNewSubject(false) | ||
| if (fileInputRef.current) fileInputRef.current.value = '' | ||
| } catch (err) { |
There was a problem hiding this comment.
setSuccess(successMsg) is called, but the success state is never read/rendered anywhere after the inline success alert was removed. This is dead state and will trigger no-unused-vars for the success variable; remove the success state/setter usage or reintroduce UI that consumes it.
| // Success | ||
| const successMsg = 'Paper uploaded successfully!' | ||
| setSuccess(successMsg) | ||
| addToast('Upload Successful', successMsg, 'success') | ||
|
|
||
| // Reset form | ||
| setFormData({ | ||
| facultyName: '', | ||
| content: '', | ||
| subject: '', | ||
| year: '', | ||
| semester: '', | ||
| term: '', | ||
| uploaded_file: null, | ||
| }) | ||
| setCustomSubject('') | ||
| setIsNewSubject(false) |
There was a problem hiding this comment.
setSuccess(successMsg) is called, but the success state value is never read/rendered anywhere (the success banner was removed). This leaves dead state and will trigger no-unused-vars for the success variable; remove the success state/setter usage (and consider removing error state too if it's no longer shown).
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/globals.css`:
- Around line 81-90: The keyframes name slideIn violates Stylelint's
keyframes-name-pattern; rename the keyframe to kebab-case (e.g., slide-in) in
app/globals.css and update the corresponding animation reference in
context/toast-provider.tsx (the animation usage around the toast component,
previously referencing "slideIn" at ~Line 102) to match the new name; also
search the repo for any other occurrences of "slideIn" and replace them to avoid
lint/ runtime mismatches.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 11b64d4f-8a63-44eb-801e-5fbee142da65
📒 Files selected for processing (6)
app/auth/signin/page.tsxapp/globals.cssapp/layout.jsxapp/upload-notes/page.tsxapp/upload-papers/page.tsxcontext/toast-provider.tsx
✅ Files skipped from review due to trivial changes (2)
- app/layout.jsx
- app/auth/signin/page.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
- app/upload-papers/page.tsx
- app/upload-notes/page.tsx
- context/toast-provider.tsx
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
app/upload-notes/page.tsx (1)
121-122: Remove redundant loading resets in early returns.Line 121/130/144 calls
setIsLoading(false)beforereturn, but Line 199 already handles this infinally. Keeping onlyfinallyavoids repeated state updates.Also applies to: 130-131, 144-145, 198-200
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/upload-notes/page.tsx` around lines 121 - 122, Remove the redundant setIsLoading(false) calls that appear immediately before early returns inside the upload handler function (the places that call setIsLoading(false) at lines matching the early-return branches) and rely on the existing finally block to reset loading; specifically, delete the pre-return invocations of setIsLoading(false) in the upload handling function so only the finally block performs the state reset, leaving other logic and returns unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/auth/signin/page.tsx`:
- Around line 29-32: Multiple error paths in sign-in emit duplicate toasts by
calling addToast twice (e.g., the 'Only IIITL email addresses are allowed'
block); replace the two calls with a single addToast invocation using the
intended signature (title, message, type) and remove the redundant addToast(msg)
call. Update the same pattern in the other error handlers referenced (the blocks
around the calls at the other indicated ranges) so each failure path emits one
clear toast, and ensure setLoading(false) remains after the single toast call.
- Around line 75-85: Move the setLoading(true) call out of the try block in
handleGoogleSignIn so it always runs before the async signIn('google', {
callbackUrl: '/' }) call, and add a finally block to the try/catch/finally that
calls setLoading(false) to guarantee loading resets regardless of success,
redirect, or unexpected error; keep the existing catch to show toasts on errors
and reference handleGoogleSignIn, setLoading, and signIn when making the
changes.
In `@app/upload-notes/page.tsx`:
- Around line 118-120: The code is triggering duplicate toasts by calling
addToast twice (e.g., addToast(msg) followed by addToast('Validation Error',
msg, 'error')); update each branch in page.tsx (the blocks around msg and
addToast calls at the shown diffs and the other affected ranges) to call
addToast only once, using the preferred signature (title, message, level) and
removing the redundant simple addToast(msg) invocation so each outcome emits a
single, full toast notification.
---
Nitpick comments:
In `@app/upload-notes/page.tsx`:
- Around line 121-122: Remove the redundant setIsLoading(false) calls that
appear immediately before early returns inside the upload handler function (the
places that call setIsLoading(false) at lines matching the early-return
branches) and rely on the existing finally block to reset loading; specifically,
delete the pre-return invocations of setIsLoading(false) in the upload handling
function so only the finally block performs the state reset, leaving other logic
and returns unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5075f203-1b73-451f-82f7-dc7b0ff917fe
📒 Files selected for processing (3)
app/auth/signin/page.tsxapp/upload-notes/page.tsxcontext/toast-provider.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- context/toast-provider.tsx
|
@manjeetsinghmeena resolve the merge conflicts. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/auth/signin/page.tsx`:
- Around line 29-30: Replace bare addToast(...) calls in the failure branches
with the same structured call pattern used for success/info so failures get an
explicit error variant; specifically change uses like addToast(msg) (the one
that sets const msg = 'Only IIITL email addresses are allowed' and the other
occurrences around the sign-in handler) to the structured form that includes
variant: 'error' (e.g., addToast({ title: msg, variant: 'error' })) so all auth
failure paths consistently render as error toasts.
In `@app/upload-papers/page.tsx`:
- Around line 129-130: The toasts use addToast(...) without specifying
type/severity so users don't get consistent cues; update all calls to addToast
in upload-papers/page.tsx (including the validation case where msg = 'Please
fill in all required fields', the other occurrences around the indicated ranges)
to pass an explicit type/level (e.g., { type: 'warning' } for validation, {
type: 'success' } for successful actions, and { type: 'error' } for upload
failures) so the UI shows correct severity; locate and update the addToast calls
and any helper wrapper around addToast to accept and forward a type field.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 10cd57a6-3e90-4651-a18b-763fbc7f8176
📒 Files selected for processing (3)
app/auth/signin/page.tsxapp/upload-notes/page.tsxapp/upload-papers/page.tsx
✅ Files skipped from review due to trivial changes (1)
- app/upload-notes/page.tsx
|
@MrImmortal09 fixed all the issues you insisted to consider |
|
@coderabbitai full-review |
🧩 Analysis chainThe PR description image shows the StudentHub login page with a toast notification in the top-right corner displaying "Redirecting - Signing in with Google..." with a close (×) button, confirming the toast system is functional. Let me examine the actual code changes to conduct a thorough review. 🏁 Script executed: Length of output: 48471
Review: Toast Notification System (PR
|
| Severity | Issue | File |
|---|---|---|
| 🔴 Bug | File size limit mismatch (10MB code vs 25MB message) | upload-papers/page.tsx |
| 🔴 Bug | All error/success toasts display as blue 'info' |
signin/page.tsx, upload-notes/page.tsx, upload-papers/page.tsx |
| 🟡 Code Quality | Dead error, success, session state |
upload-papers/page.tsx |
| 🟡 Code Quality | Deprecated substr |
toast-provider.tsx |
| 🟡 Accessibility | No aria-live on toast viewport |
toast-provider.tsx |
| 🟡 Missing Feature | Sign-up page toast notifications not implemented | — |
✅ Actions performed
Full review triggered.
|
@manjeetsinghmeena fix from above coderabbit comments. |
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (3)
app/globals.css (1)
81-90:⚠️ Potential issue | 🟡 MinorRename this keyframe to kebab-case to satisfy Stylelint.
Line 81 still uses
slideIn, which violates the configuredkeyframes-name-patternrule and can fail CI.Proposed fix
-@keyframes slideIn { +@keyframes slide-in { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }- animation: 'slideIn 0.3s ease-in-out', + animation: 'slide-in 0.3s ease-in-out',🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/globals.css` around lines 81 - 90, The `@keyframes` name slideIn violates the keyframes-name-pattern; rename the keyframe to kebab-case (e.g., slide-in) and update all references (animation, animation-name, or shorthand usages) that currently reference slideIn so they point to slide-in; ensure the `@keyframes` declaration and any CSS/JS that uses the animation name (e.g., animation: slideIn ...) are updated consistently.app/auth/signin/page.tsx (1)
29-30:⚠️ Potential issue | 🟠 MajorUse explicit error variants for all sign-in failure toasts.
These failure branches still call bare
addToast(...), so they default to info styling instead of error severity.Proposed fix
- addToast(msg) + addToast('Validation Error', msg, 'warning') @@ - addToast(errorMsg) + addToast('Sign-in Failed', errorMsg, 'error') } else { - addToast(result.error) + addToast('Sign-in Failed', result.error, 'error') } @@ - addToast(errorMessage) + addToast('Sign-in Failed', errorMessage, 'error') @@ - addToast(msg) + addToast('Google Sign-in Failed', msg, 'error')Also applies to: 49-53, 65-65, 77-78
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/auth/signin/page.tsx` around lines 29 - 30, The toast calls on sign-in failure currently call addToast(msg) which yields default/info styling; update each failure branch in app/auth/signin/page.tsx (the addToast usages around the 'msg' variable and the other branches at the later occurrences) to supply an explicit error variant, e.g. call addToast(msg, { variant: 'error' }) or addToast({ message: msg, variant: 'error' }) depending on the addToast API your codebase uses so these toasts render as error severity; change all occurrences that currently call addToast(...) without an error variant.app/upload-papers/page.tsx (1)
129-130:⚠️ Potential issue | 🟠 MajorSet explicit toast severity for validation, success, and failure outcomes.
These
addToast(...)calls are still untyped, so they render as default info toasts and lose severity cues.Proposed fix
- addToast(msg) + addToast('Validation Error', msg, 'warning') @@ - addToast(msg) + addToast('File Too Large', msg, 'error') @@ - addToast(msg) + addToast('Invalid File Type', msg, 'error') @@ - addToast(successMsg) + addToast('Upload Successful', successMsg, 'success') @@ - addToast(errorMsg) + addToast('Upload Failed', errorMsg, 'error')Also applies to: 138-139, 152-153, 190-191, 212-216
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/upload-papers/page.tsx` around lines 129 - 130, The addToast calls in page.tsx are untyped and default to info; update every addToast invocation (e.g., the validation msg 'Please fill in all required fields' and the other toasts used for submit success/failure) to pass an explicit severity option so the UI shows proper levels—use severity: 'error' for validation/failure toasts and severity: 'success' for successful outcomes when calling addToast, and ensure the same pattern is applied to all occurrences referenced in the review (validation, success, and error branches).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/upload-notes/page.tsx`:
- Around line 118-119: Update all addToast calls in upload-notes/page.tsx to
pass an explicit toast type instead of relying on the default 'info': for
validation failures (e.g., where const msg = 'Please fill in all required
fields' and similar messages at the mentioned ranges) call addToast(msg, { type:
'error' }); for upload failures and exceptions use addToast(errorMessage, {
type: 'error' }); and for successful uploads (the success branch around lines
~171-172) call addToast(successMsg, { type: 'success' }); locate these calls by
searching for addToast(...) in the handlers (e.g., the validate/submit
functions) and update the second argument to include the appropriate type.
In `@app/upload-papers/page.tsx`:
- Around line 136-139: The validation enforces maxSize = 10 * 1024 * 1024 but
the toast text says "25MB"; update the message shown by addToast to match the
enforced limit (e.g., change the string to "File size must be less than 10MB")
so that formData.uploaded_file.size, maxSize and the user-facing message are
consistent.
In `@context/toast-provider.tsx`:
- Around line 100-105: The toast container divs in context/toast-provider.tsx
(the JSX elements using className={`${styles.bg} border ${styles.border}
rounded-lg shadow-lg p-4 pointer-events-auto`} and the other similar divs at the
referenced ranges) lack ARIA live-region attributes; add accessible live-region
semantics by adding role="status", aria-live="polite" and aria-atomic="true" to
these toast wrapper elements so screen readers will announce success/error
messages (for high-priority errors you can use aria-live="assertive" instead);
update the JSX for the divs in the ToastProvider component accordingly.
- Around line 31-33: The id generation uses the non-standard substr call; update
the id creation in the toast creation logic (where id is set before calling
setToasts in the toast provider) to use the standard String.prototype.slice
instead of substr (i.e., change Math.random().toString(36).substr(2, 9) to use
slice to produce the same 9-character substring), keeping the surrounding logic
that calls setToasts(...) and setTimeout(() => removeToast(id), 3000) unchanged.
---
Duplicate comments:
In `@app/auth/signin/page.tsx`:
- Around line 29-30: The toast calls on sign-in failure currently call
addToast(msg) which yields default/info styling; update each failure branch in
app/auth/signin/page.tsx (the addToast usages around the 'msg' variable and the
other branches at the later occurrences) to supply an explicit error variant,
e.g. call addToast(msg, { variant: 'error' }) or addToast({ message: msg,
variant: 'error' }) depending on the addToast API your codebase uses so these
toasts render as error severity; change all occurrences that currently call
addToast(...) without an error variant.
In `@app/globals.css`:
- Around line 81-90: The `@keyframes` name slideIn violates the
keyframes-name-pattern; rename the keyframe to kebab-case (e.g., slide-in) and
update all references (animation, animation-name, or shorthand usages) that
currently reference slideIn so they point to slide-in; ensure the `@keyframes`
declaration and any CSS/JS that uses the animation name (e.g., animation:
slideIn ...) are updated consistently.
In `@app/upload-papers/page.tsx`:
- Around line 129-130: The addToast calls in page.tsx are untyped and default to
info; update every addToast invocation (e.g., the validation msg 'Please fill in
all required fields' and the other toasts used for submit success/failure) to
pass an explicit severity option so the UI shows proper levels—use severity:
'error' for validation/failure toasts and severity: 'success' for successful
outcomes when calling addToast, and ensure the same pattern is applied to all
occurrences referenced in the review (validation, success, and error branches).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e5e42a5b-5fb9-4fe5-9016-3af9243d5041
📒 Files selected for processing (6)
app/auth/signin/page.tsxapp/globals.cssapp/layout.jsxapp/upload-notes/page.tsxapp/upload-papers/page.tsxcontext/toast-provider.tsx
|
@coderabbitai full-review |
🧩 Analysis chainThe PR description image shows the StudentHub login page with a toast notification in the top-right corner displaying "Redirecting - Signing in with Google..." with a close button, confirming the toast system is visually functional. Let me examine the current state of the code to conduct a thorough review. 🏁 Script executed: Length of output: 47401 🏁 Script executed: Length of output: 16645
Review: Toast Notification System — Updated (PR
|
| Issue | Status |
|---|---|
File size mismatch (10MB vs 25MB) in upload-papers |
✅ Resolved — code, toast, and UI all say 10MB now |
Dead error/success state in upload-papers |
✅ Removed |
Success/info toasts in signin/page.tsx |
✅ Correctly typed ('success', 'info') |
🔴 New Critical Bug: Duplicate useSession() in app/upload-notes/page.tsx
useSession() is called twice, declaring status twice in the same scope — this is a TypeScript compile error:
// Line ~9 — first call
const { status } = useSession()
const { addToast } = useToast()
// Line ~11 — second call, re-declares `status` ← COMPILE ERROR
const { data: session, status } = useSession()Fix by merging into a single call:
const { data: session, status } = useSession()
const { addToast } = useToast()🔴 Bug: Toast Type Argument Still Wrong in upload-notes and upload-papers
The addToast signature is:
addToast(title: string, description?: string, type?: ToastType)But the calls in both upload pages pass the type string as the second argument (description), not the third:
// WRONG — 'error' is the description, type defaults to 'info'
addToast('Please fill in all required fields', 'error')
addToast('File size must be less than 10MB', 'error')
addToast('Note uploaded successfully!', 'success')
// CORRECT — pass undefined for description, then the type
addToast('Please fill in all required fields', undefined, 'error')
addToast('File size must be less than 10MB', undefined, 'error')
addToast('Note uploaded successfully!', undefined, 'success')This affects all addToast calls in both app/upload-notes/page.tsx and app/upload-papers/page.tsx — they all still render as blue info toasts.
🔴 Bug: Error Toasts in app/auth/signin/page.tsx Still Default to 'info'
These five calls still have no explicit type and show as blue:
// All should be: addToast(msg, undefined, 'error')
addToast(msg) // IIITL email validation
addToast(errorMsg) // 'Invalid email or password'
addToast(result.error) // other credential errors
addToast(errorMessage) // catch block
addToast(msg) // Google sign-in failure🟡 Remaining from Previous Review (Unchanged)
Deprecated substr — context/toast-provider.tsx:
// Before (deprecated)
const id = Math.random().toString(36).substr(2, 9)
// After
const id = Math.random().toString(36).substring(2, 11)Missing aria-live — context/toast-provider.tsx:
// ToastViewport div should be:
<div
role="region"
aria-live="polite"
aria-label="Notifications"
className="fixed top-0 right-0 z-50 flex flex-col gap-2 p-4 pointer-events-none max-w-md"
>Sign-up page (app/auth/signup/page.tsx) — Not Updated:
The sign-up page still uses setError() and renders an inline <AlertCircle> banner. Issue #215 requires sign-up feedback via toasts too. All setError(...) calls and the error JSX block should be replaced with addToast(..., undefined, 'error').
Updated Summary
| Severity | Issue | File | Status |
|---|---|---|---|
| 🔴 New | Duplicate useSession() — compile error |
upload-notes/page.tsx |
❌ Not fixed |
| 🔴 Bug | 'error'/'success' passed as description, not type |
upload-notes/page.tsx, upload-papers/page.tsx |
❌ Not fixed |
| 🔴 Bug | Error toasts in signin show as blue 'info' |
signin/page.tsx |
❌ Not fixed |
| ✅ Fixed | File size mismatch (10MB) | upload-papers/page.tsx |
✅ Fixed |
| ✅ Fixed | Dead error/success state |
upload-papers/page.tsx |
✅ Fixed |
| 🟡 | Deprecated substr |
toast-provider.tsx |
❌ Not fixed |
| 🟡 | No aria-live on toast viewport |
toast-provider.tsx |
❌ Not fixed |
| 🟡 | Sign-up page not updated with toasts | signup/page.tsx |
❌ Not fixed |
✅ Actions performed
Full review triggered.
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (3)
context/toast-provider.tsx (2)
31-31:⚠️ Potential issue | 🟡 MinorReplace deprecated
substrhere.
String.prototype.substris legacy/deprecated.slice(2, 11)gives the same 9-character suffix without relying on Annex B behavior.Suggested fix
- const id = Math.random().toString(36).substr(2, 9) + const id = Math.random().toString(36).slice(2, 11)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@context/toast-provider.tsx` at line 31, The id generation uses the deprecated String.prototype.substr; update the expression that assigns id (const id = Math.random().toString(36).substr(2, 9)) to use String.prototype.slice instead so it returns the same 9-character suffix (i.e., replace the substr call with slice(2, 11)); ensure the variable name id and surrounding logic in the toast-provider component (where id is generated) remains unchanged.
100-127:⚠️ Potential issue | 🟠 MajorExpose the toast viewport as a live region.
These toasts now carry login and upload feedback, but the rendered markup still has no live-region semantics. Screen-reader users will not reliably hear new notifications, and the close button still lacks an accessible name.
Suggested fix
<div style={{ animation: 'slideIn 0.3s ease-in-out', }} + role={type === 'error' ? 'alert' : 'status'} + aria-live={type === 'error' ? 'assertive' : 'polite'} + aria-atomic="true" className={`${styles.bg} border ${styles.border} rounded-lg shadow-lg p-4 pointer-events-auto`} > @@ <button onClick={() => onRemove(id)} className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 flex-shrink-0" title="Close notification" + aria-label="Close notification" > @@ - <div className="fixed top-0 right-0 z-50 flex flex-col gap-2 p-4 pointer-events-none max-w-md"> + <div + className="fixed top-0 right-0 z-50 flex flex-col gap-2 p-4 pointer-events-none max-w-md" + aria-label="Notifications" + aria-relevant="additions text" + >Also applies to: 143-154
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@context/toast-provider.tsx` around lines 100 - 127, The toast markup needs live-region semantics and an accessible name for the close button: update the toast viewport/container (the element rendering the list of toasts in toast-provider.tsx) to include aria-live="polite" (or "assertive" if immediate), role="status" (or "log" depending on verbosity), and aria-atomic="true" so screen readers announce new notifications (apply same change to the other viewport instance around lines 143-154), and give the close button (the button with onClick={() => onRemove(id)}) a programmatic accessible name via aria-label (e.g., aria-label={`Close notification: ${title}`} or a localized equivalent) so assistive tech can identify it; ensure these attributes are added alongside existing className/props (refer to the container element that uses styles.bg and the close button using onRemove and id).app/globals.css (1)
81-90:⚠️ Potential issue | 🟡 MinorRename this keyframe to kebab-case.
slideInstill violates the configuredkeyframes-name-pattern, so lint will keep failing until both this declaration and theanimation: 'slideIn ...'reference incontext/toast-provider.tsxare renamed consistently.Suggested fix
-@keyframes slideIn { +@keyframes slide-in { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/globals.css` around lines 81 - 90, The keyframe declaration named slideIn violates the keyframes-name-pattern; rename the keyframe to kebab-case (e.g., slide-in) in the `@keyframes` block and update the corresponding animation usage in context/toast-provider.tsx where animation: 'slideIn ...' is referenced so both declaration (slideIn) and reference are changed consistently to the kebab-case name (slide-in).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/layout.jsx`:
- Around line 29-34: The layout removed the shared ChatWidget from the component
tree when wrapping with ToastProvider; restore the ChatWidget JSX so it is
mounted on every page by adding the <ChatWidget /> element back into the
ToastProvider wrapper (alongside Header, {children}, Footer, Analytics) in
app/layout.jsx; keep the existing import of ChatWidget and place the element in
the same shared layout location so the widget is rendered on every page.
In `@app/quick-reads/page.tsx`:
- Around line 880-883: The icon-only close button that calls
setIsStagingOpen(false) needs an explicit accessible name—add an aria-label (for
example aria-label="Close staged changes panel") to the <button> alongside the
existing title so screen readers can identify its purpose; locate the button
using the setIsStagingOpen handler in page.tsx and add the aria-label attribute.
In `@app/upload-notes/page.tsx`:
- Around line 31-33: There's a duplicate destructuring of useSession(): remove
the first "const { status } = useSession()" and rely on the combined
destructuring "const { data: session, status } = useSession()"; ensure any code
referencing status or session uses those variables from the combined declaration
(update references if they were pointed at the removed binding), and keep the
existing "const { addToast } = useToast()" untouched.
In `@context/toast-provider.tsx`:
- Around line 17-18: The addToast signature is positional (addToast(title:
string, description?: string, type?: ToastType)) causing calls like
addToast(msg, 'error') to bind 'error' to description; change addToast to accept
a single options object (e.g., addToast({ title: string, description?: string,
type?: ToastType })) and keep removeToast unchanged; update the ToastProvider
implementation and its consumers (references to addToast in
app/upload-notes/page.tsx, app/upload-papers/page.tsx, app/auth/signin/page.tsx)
to call addToast({ title: ..., description: ..., type: 'error' | 'info' | ... })
so types are explicit and positional mistakes are eliminated.
---
Duplicate comments:
In `@app/globals.css`:
- Around line 81-90: The keyframe declaration named slideIn violates the
keyframes-name-pattern; rename the keyframe to kebab-case (e.g., slide-in) in
the `@keyframes` block and update the corresponding animation usage in
context/toast-provider.tsx where animation: 'slideIn ...' is referenced so both
declaration (slideIn) and reference are changed consistently to the kebab-case
name (slide-in).
In `@context/toast-provider.tsx`:
- Line 31: The id generation uses the deprecated String.prototype.substr; update
the expression that assigns id (const id = Math.random().toString(36).substr(2,
9)) to use String.prototype.slice instead so it returns the same 9-character
suffix (i.e., replace the substr call with slice(2, 11)); ensure the variable
name id and surrounding logic in the toast-provider component (where id is
generated) remains unchanged.
- Around line 100-127: The toast markup needs live-region semantics and an
accessible name for the close button: update the toast viewport/container (the
element rendering the list of toasts in toast-provider.tsx) to include
aria-live="polite" (or "assertive" if immediate), role="status" (or "log"
depending on verbosity), and aria-atomic="true" so screen readers announce new
notifications (apply same change to the other viewport instance around lines
143-154), and give the close button (the button with onClick={() =>
onRemove(id)}) a programmatic accessible name via aria-label (e.g.,
aria-label={`Close notification: ${title}`} or a localized equivalent) so
assistive tech can identify it; ensure these attributes are added alongside
existing className/props (refer to the container element that uses styles.bg and
the close button using onRemove and id).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6c2c360e-3109-483a-8656-eb92de43ecda
📒 Files selected for processing (7)
app/auth/signin/page.tsxapp/globals.cssapp/layout.jsxapp/quick-reads/page.tsxapp/upload-notes/page.tsxapp/upload-papers/page.tsxcontext/toast-provider.tsx
| addToast: (title: string, description?: string, type?: ToastType) => void | ||
| removeToast: (id: string) => void |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify current misuses of the positional addToast API in the changed callers.
rg -nP "addToast\(\s*[^,]+,\s*'(?:success|error|info|warning)'\s*\)" \
app/upload-notes/page.tsx app/upload-papers/page.tsx
rg -nP "addToast\(\s*[^,()]+\s*\)" app/auth/signin/page.tsxRepository: iiitl/student-hub
Length of output: 798
🏁 Script executed:
cat -n context/toast-provider.tsx | head -50Repository: iiitl/student-hub
Length of output: 1805
The addToast API parameter order causes incorrect toast types at its call sites.
With the signature (title: string, description?: string, type?: ToastType), calls like addToast(msg, 'error') compile but produce an info toast with the description literally set to "error". This misuse is already present in app/upload-notes/page.tsx and app/upload-papers/page.tsx, while bare calls in app/auth/signin/page.tsx silently default to 'info'. Switch to an options object pattern to prevent this positional binding error and update all call sites accordingly.
Suggested API shape
+interface AddToastOptions {
+ title: string
+ description?: string
+ type?: ToastType
+}
+
interface ToastContextType {
toasts: ToastMessage[]
- addToast: (title: string, description?: string, type?: ToastType) => void
+ addToast: (options: AddToastOptions) => void
removeToast: (id: string) => void
}
@@
- const addToast = (
- title: string,
- description?: string,
- type: ToastType = 'info'
- ) => {
+ const addToast = ({
+ title,
+ description,
+ type = 'info',
+ }: AddToastOptions) => {
const id = Math.random().toString(36).substr(2, 9)
setToasts((prev) => [...prev, { id, title, description, type }])
setTimeout(() => removeToast(id), 3000)
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@context/toast-provider.tsx` around lines 17 - 18, The addToast signature is
positional (addToast(title: string, description?: string, type?: ToastType))
causing calls like addToast(msg, 'error') to bind 'error' to description; change
addToast to accept a single options object (e.g., addToast({ title: string,
description?: string, type?: ToastType })) and keep removeToast unchanged;
update the ToastProvider implementation and its consumers (references to
addToast in app/upload-notes/page.tsx, app/upload-papers/page.tsx,
app/auth/signin/page.tsx) to call addToast({ title: ..., description: ..., type:
'error' | 'info' | ... }) so types are explicit and positional mistakes are
eliminated.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
@manjeetsinghmeena fix the lint issue.
run pnpm run lint
then
pnpm run build
make sure both commands don't throw any error
Resolves #215
Description
Implement toast notification system in the project to show user feedback for actions like success, error, info, and warning messages. This resolves #215.
Toast notifications now display feedback for:
Changes Made
context/toast-provider.tsx- Toast context provider with useToast hookslideIntoapp/globals.cssapp/layout.jsxto wrap app with<ToastProvider>app/auth/signin/page.tsxapp/upload-notes/page.tsxapp/upload-papers/page.tsxLive Demo
Checkout
Summary by CodeRabbit
New Features
Bug Fixes / UX
Accessibility