Skip to content

Conversation

@Vaibhaviitian
Copy link

@Vaibhaviitian Vaibhaviitian commented Aug 31, 2025

This Pr solved the issue of toast/notification during wrong file submission in input page
Fix #276
image

image

Summary by CodeRabbit

  • New Features
    • Added client-side validation for file uploads (supports MP3 and PDF).
    • Introduced on-screen toast notifications for missing/invalid files, upload success, and errors.
    • Displays immediate feedback before and after upload, improving clarity and responsiveness.
  • Style
    • Minor UI text and layout tweaks for headings and gradients; no functional impact.

@coderabbitai
Copy link

coderabbitai bot commented Aug 31, 2025

Walkthrough

Adds client-side file upload validation to Text_Input.jsx and replaces inline error text with react-toastify toasts. Validation covers presence, extension (mp3/pdf), and MIME type (audio/mpeg, application/pdf). On success, shows a toast, uploads to /upload, and sets returned text. Adds a ToastContainer. Minor JSX formatting changes.

Changes

Cohort / File(s) Summary
Client-side validation and toast notifications
eduaid_web/src/pages/Text_Input.jsx
Added react-toastify imports and global ToastContainer; implemented file presence/extension/MIME validation; replaced inline error handling with toast messages; show success/error toasts around /upload flow; retain setting text from server response; minor JSX formatting and payload line-wrapping.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor U as User
    participant TI as Text_Input.jsx
    participant T as Toast (react-toastify)
    participant S as Server (/upload)

    U->>TI: Select file / Click Upload
    TI->>TI: Validate presence, extension, MIME
    alt Invalid input
        TI-->>T: show error toast
    else Valid input
        TI-->>T: show "uploading" toast
        TI->>S: POST /upload (file)
        S-->>TI: 200 OK / Error
        alt Success
            TI-->>T: show success toast
            TI->>TI: setText(response.text)
        else Failure
            TI-->>T: show error toast
        end
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
Use a toast/modal/alert for errors instead of injecting into input area [#276]
Ensure input area remains untouched by error messages [#276]
Errors should be easily dismissible [#276]

Possibly related issues

Poem

A nibble of bytes, a hop through the UI,
Toasts pop up—ping!—as uploads fly.
No more scribbles in the text box bed,
Errors drift past in bubbles instead.
With a twitch of whiskers, success we boast—
Hare today, gone tomorrow—raise a toast! 🥂🐇

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
eduaid_web/src/pages/Text_Input.jsx (1)

70-80: Don’t write Google Doc errors into the textarea; use toasts instead and handle response shape consistently.

Keeps input untouched on errors (issue #276) and aligns with file-upload handling.

-        const data = await apiClient.post("/get_content", {
-          document_url: docUrl,
-        });
-        setDocUrl("");
-        setText(data || "Error in retrieving");
+        const data = await apiClient.post("/get_content", {
+          document_url: docUrl,
+        });
+        setDocUrl("");
+        if (data?.content) {
+          setText(data.content);
+          toast.success("Content retrieved successfully.");
+        } else {
+          toast.error(data?.error || "Failed to retrieve Google Doc content.");
+        }
       } catch (error) {
         console.error("Error:", error);
-        setText("Error retrieving Google Doc content");
+        toast.error("Failed to retrieve Google Doc content.");
       } finally {
         setLoading(false);
       }
🧹 Nitpick comments (4)
eduaid_web/src/pages/Text_Input.jsx (4)

223-228: Restrict file chooser to supported types via accept=.

Improves UX and reduces invalid selections before validation.

-          <input
+          <input
             type="file"
             ref={fileInputRef}
             onChange={handleFileUpload}
+            accept=".pdf,.mp3,application/pdf,audio/mpeg"
             style={{ display: "none" }}
           />

138-144: Harden localStorage parsing against corrupted data.

Prevents runtime errors if stored JSON is invalid.

-      let last5Quizzes = JSON.parse(localStorage.getItem("last5Quizzes")) || [];
+      let last5Quizzes;
+      try {
+        last5Quizzes = JSON.parse(localStorage.getItem("last5Quizzes")) || [];
+      } catch {
+        last5Quizzes = [];
+      }
       last5Quizzes.push(quizDetails);
       if (last5Quizzes.length > 5) {
         last5Quizzes.shift(); // Keep only the last 5 quizzes
       }

303-307: Disable “Next” while loading to prevent duplicate submissions.

-          <button
-            onClick={handleSaveToLocalStorage}
-            className="bg-black text-white text-lg sm:text-xl px-4 py-2 border-gradient flex justify-center items-center rounded-xl w-full sm:w-auto"
+          <button
+            onClick={handleSaveToLocalStorage}
+            disabled={loading}
+            className={`bg-black text-white text-lg sm:text-xl px-4 py-2 border-gradient flex justify-center items-center rounded-xl w-full sm:w-auto ${loading ? "opacity-50 cursor-not-allowed" : ""}`}
           >

310-321: Optional: render a single ToastContainer at the app root.

Prevents multiple containers across pages if this component mounts alongside others.

If other pages also mount ToastContainer, consider centralizing it (e.g., in App.jsx) and removing duplicates here.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5d6e4ad and 8733288.

📒 Files selected for processing (1)
  • eduaid_web/src/pages/Text_Input.jsx (11 hunks)
🔇 Additional comments (2)
eduaid_web/src/pages/Text_Input.jsx (2)

28-31: LGTM: clear, user-friendly empty-file check.


161-165: LGTM: pointer-events gating during loading prevents accidental interactions.

Comment on lines +32 to +43
const allowedExtensions = ["mp3", "pdf"];
const allowedMimeTypes = ["audio/mpeg", "application/pdf"];
const fileName = file.name;
const fileType = file.type;
const fileExtension = fileName.split(".").pop().toLowerCase();
const isValidExtension = allowedExtensions.includes(fileExtension);
const isValidMimeType = allowedMimeTypes.includes(fileType);
if (!(isValidExtension || isValidMimeType)) {
toast.error("Only MP3 and PDF files are allowed!");
event.target.value = "";
return;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Tighten validation: require a supported extension and, when present, a matching MIME type.

Current OR check allows renamed files (e.g., .pdf with wrong MIME). Prefer strict extension check plus MIME check when available.

-    const isValidExtension = allowedExtensions.includes(fileExtension);
-    const isValidMimeType = allowedMimeTypes.includes(fileType);
-    if (!(isValidExtension || isValidMimeType)) {
-      toast.error("Only MP3 and PDF files are allowed!");
-      event.target.value = "";
-      return;
-    }
+    const isValidExtension = allowedExtensions.includes(fileExtension);
+    const isValidMimeType = allowedMimeTypes.includes(fileType);
+    if (!isValidExtension) {
+      toast.error("Only MP3 and PDF files are allowed!");
+      event.target.value = "";
+      return;
+    }
+    if (fileType && !isValidMimeType) {
+      toast.error("Invalid file type. Only audio/mpeg and application/pdf are allowed.");
+      event.target.value = "";
+      return;
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const allowedExtensions = ["mp3", "pdf"];
const allowedMimeTypes = ["audio/mpeg", "application/pdf"];
const fileName = file.name;
const fileType = file.type;
const fileExtension = fileName.split(".").pop().toLowerCase();
const isValidExtension = allowedExtensions.includes(fileExtension);
const isValidMimeType = allowedMimeTypes.includes(fileType);
if (!(isValidExtension || isValidMimeType)) {
toast.error("Only MP3 and PDF files are allowed!");
event.target.value = "";
return;
}
const allowedExtensions = ["mp3", "pdf"];
const allowedMimeTypes = ["audio/mpeg", "application/pdf"];
const fileName = file.name;
const fileType = file.type;
const fileExtension = fileName.split(".").pop().toLowerCase();
const isValidExtension = allowedExtensions.includes(fileExtension);
const isValidMimeType = allowedMimeTypes.includes(fileType);
if (!isValidExtension) {
toast.error("Only MP3 and PDF files are allowed!");
event.target.value = "";
return;
}
if (fileType && !isValidMimeType) {
toast.error("Invalid file type. Only audio/mpeg and application/pdf are allowed.");
event.target.value = "";
return;
}
🤖 Prompt for AI Agents
In eduaid_web/src/pages/Text_Input.jsx around lines 32 to 43, the current
validation uses an OR which permits mismatched extension/MIME; change it to
require a supported extension AND, if a MIME type is present, require that it
matches the expected MIME for that extension. Keep allowedExtensions and
allowedMimeTypes (or better, use a mapping like {mp3: 'audio/mpeg', pdf:
'application/pdf'}), compute fileExtension, first reject if extension not in
allowed list, then if file.type is non-empty verify it equals the mapped MIME
for that extension; on failure call toast.error("Only MP3 and PDF files are
allowed!"), clear event.target.value and return.

Comment on lines +47 to 53
toast.success("File uploaded successfully!");
const data = await apiClient.postFormData("/upload", formData);
setText(data.content || data.error);
} catch (error) {
console.error("Error uploading file:", error);
toast.error("Error uploding file to server ");
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Avoid premature success toast and stop injecting server errors into the textarea; also fix typo.

Success is shown before the upload finishes, and on failure the server error may end up in the input (violates issue #276: input must remain untouched on errors). Also "uploding" typo.

-      toast.success("File uploaded successfully!");
-      const data = await apiClient.postFormData("/upload", formData);
-      setText(data.content || data.error);
+      const data = await apiClient.postFormData("/upload", formData);
+      if (data && data.content) {
+        setText(data.content);
+        toast.success("File uploaded successfully.");
+      } else {
+        toast.error(data?.error || "Upload failed.");
+      }
+      event.target.value = "";
     } catch (error) {
       console.error("Error uploading file:", error);
-      toast.error("Error uploding file to server ");
+      toast.error("Error uploading file to server.");
+      event.target.value = "";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
toast.success("File uploaded successfully!");
const data = await apiClient.postFormData("/upload", formData);
setText(data.content || data.error);
} catch (error) {
console.error("Error uploading file:", error);
toast.error("Error uploding file to server ");
}
try {
const data = await apiClient.postFormData("/upload", formData);
if (data && data.content) {
setText(data.content);
toast.success("File uploaded successfully.");
} else {
toast.error(data?.error || "Upload failed.");
}
event.target.value = "";
} catch (error) {
console.error("Error uploading file:", error);
toast.error("Error uploading file to server.");
event.target.value = "";
}
🤖 Prompt for AI Agents
In eduaid_web/src/pages/Text_Input.jsx around lines 47 to 53, the code shows a
success toast before the async upload completes and writes server errors into
the textarea, plus a typo in the error toast; change the flow so the await
apiClient.postFormData completes before calling toast.success, only call setText
when the response contains a valid content field (do not setText to data.error),
and in the catch handler leave the textarea unchanged while logging the error
and showing a corrected toast.error("Error uploading file to server"). Ensure
you check response shape (e.g., data.content) before updating state and remove
any assignment that injects server error text into the input.

Comment on lines +186 to +188
<span className="bg-gradient-to-r from-[#7600F2] to-[#00CBE7] text-transparent bg-clip-text">
Questionaries
</span>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix user-facing typo: “Questionnaires”.

Visible copy matters.

-              Questionaries
+              Questionnaires
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<span className="bg-gradient-to-r from-[#7600F2] to-[#00CBE7] text-transparent bg-clip-text">
Questionaries
</span>
<span className="bg-gradient-to-r from-[#7600F2] to-[#00CBE7] text-transparent bg-clip-text">
Questionnaires
</span>
🤖 Prompt for AI Agents
In eduaid_web/src/pages/Text_Input.jsx around lines 186 to 188, the displayed
label text contains a typo ("Questionaries"); update the visible copy to the
correct spelling "Questionnaires" by replacing the string inside the span while
preserving the existing styling and structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: User-Friendly Error Handling for Input Page

1 participant