Skip to content

Feat(ui): add pre-generation quiz review and confirmation flow#518

Open
piyush06singhal wants to merge 8 commits intoAOSSIE-Org:mainfrom
piyush06singhal:feature/quiz-review-confirmation
Open

Feat(ui): add pre-generation quiz review and confirmation flow#518
piyush06singhal wants to merge 8 commits intoAOSSIE-Org:mainfrom
piyush06singhal:feature/quiz-review-confirmation

Conversation

@piyush06singhal
Copy link

@piyush06singhal piyush06singhal commented Mar 3, 2026

Addressed Issues:

Fixes #515


Summary

This PR introduces a Review & Confirmation step before triggering quiz generation.

Users can now verify all configuration settings before the API call is made, improving UX clarity and preventing accidental submissions.


What’s Added

  • New /review route between Input and Output
  • New Review.jsx component
  • Confirmation step before API call
  • Duplicate submission prevention (disabled button + loading state)
  • State persistence using localStorage
  • Content preview (first 200 characters)

Flow Change

Before:
Home → Question Type → Input → [API Call] → Output

After:
Home → Question Type → Input → Review → [API Call] → Output
                                          ↓
                                     Back to Edit


Key Improvements

  • Prevents accidental quiz generation
  • Reduces duplicate API calls
  • Improves user confidence before expensive operations
  • Maintains consistent UI (gradients, spacing, typography)
  • Fully mobile responsive

Files Changed

  • src/App.js
  • src/pages/Text_Input.jsx
  • src/pages/Review.jsx (new)

No backend changes.
No new dependencies added.


Screenshots/Recordings

Review Page – Desktop View
Screenshot (2048)


Testing Performed

  • Full navigation flow verified
  • Back navigation preserves state
  • Duplicate submission prevention confirmed
  • API integration tested
  • Mobile responsiveness verified
  • Edge cases (refresh, missing data, double-click) handled
  • No console warnings or errors

Additional Notes

  • Minimal and focused implementation
  • Reused existing API logic (moved from Input to Review)
  • No refactoring of unrelated components
  • Matches existing design system

Checklist

  • My PR addresses a single issue, fixes a single bug or makes a single improvement.
  • My code follows the project's code style and conventions
  • If applicable, I have made corresponding changes or additions to the documentation
  • If applicable, I have made corresponding changes or additions to tests
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contribution Guidelines
  • Once I submit my PR, CodeRabbit AI will automatically review it and I will address CodeRabbit's comments.

AI Usage Disclosure

  • This PR does not contain AI-generated code at all.
  • This PR contains AI-generated code. I have tested the code locally and I am responsible for it.

I have used the following AI models and tools:

  • Kiro AI Assistant (implementation guidance)
  • Manual testing and validation performed

⚠️ AI Notice - Important!

We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact.

Summary by CodeRabbit

  • New Features

    • Added a Review/confirmation page to preview input source, question type, difficulty, question count, and Wikipedia option before generating questions; includes Back to Edit and Confirm & Generate with loading state.
    • Text input now tracks input source, hydrates/saves fields to localStorage, validates file uploads and Google Doc URLs, and routes users to the review step.
  • Chores

    • Reinstated ignoring of .DS_Store and added a large archive pattern to .gitignore.

@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abe6b69 and 838f968.

📒 Files selected for processing (1)
  • eduaid_web/src/pages/Text_Input.jsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • eduaid_web/src/pages/Text_Input.jsx

📝 Walkthrough

Walkthrough

Adds a Review & Confirm step: Text_Input persists configuration (including inputSource) to localStorage and navigates to a new Review page, which hydrates the config, displays a summary, and on confirm POSTs to the backend to generate qaPairs and then navigates to the output page.

Changes

Cohort / File(s) Summary
Ignore patterns
\.gitignore
Re-added .DS_Store and added backend/s2v_reddit_2015_md.tar.gz to ignored patterns.
Routing
eduaid_web/src/App.js
Imported Review and registered a /review route in the HashRouter.
New Review page
eduaid_web/src/pages/Review.jsx
New React component that hydrates config from localStorage, validates fields, selects backend endpoint by difficulty/question type, POSTs payload to generate qaPairs, stores results and updates a capped last5Quizzes in localStorage, shows loading state, and navigates to /output.
Text input refactor
eduaid_web/src/pages/Text_Input.jsx
Hydrates state from localStorage, introduces inputSource and error state, updates textarea and upload/url handlers to set inputSource, validates and fetches Google Doc content, persists config to localStorage, and navigates to /review (removes prior direct backend call paths).
Manifest
package.json
Large manifest changes added (+232 lines).

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant TextInput as Text_Input
    participant LocalStorage as localStorage
    participant Review as Review
    participant Backend as Backend\ API
    participant Output as Output\ Page

    User->>TextInput: Fill config & click Next
    TextInput->>LocalStorage: Save text, difficulty, numQuestions, useWikipedia, inputSource
    TextInput->>Review: Navigate to /review
    Review->>LocalStorage: Load configuration on mount
    Review->>Review: Derive inputSource & validate fields
    Review->>User: Display review summary
    User->>Review: Click Confirm & Generate
    Review->>Backend: POST {input_text, max_questions, use_mediawiki}
    Backend-->>Review: Return qaPairs
    Review->>LocalStorage: Store qaPairs & update last5Quizzes
    Review->>Output: Navigate to /output
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I nibble settings, tuck them neat and small,
I hop to review before the questions call.
A confident thump — confirm, then away,
I watch quiz seeds sprout where choices lay.
Hooray, the questions bloom today!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: adding a pre-generation quiz review and confirmation flow, which is the primary objective of the PR.
Linked Issues check ✅ Passed All coding requirements from issue #515 are met: new Review component added [#515], summary card with all required fields displayed [#515], Back and Confirm buttons implemented [#515], backend request moved to Review step [#515], frontend-only changes maintained [#515].
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the review and confirmation flow. Modifications to .gitignore (backend tar file) are minimal and not code-related.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • 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

Comment @coderabbitai help to get the list of available commands and usage tips.

@piyush06singhal piyush06singhal changed the title Feature/quiz review confirmation Feat(ui): add pre-generation quiz review and confirmation flow Mar 3, 2026
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)

61-80: ⚠️ Potential issue | 🟠 Major

Google Doc path currently requires two clicks to reach review.

When docUrl is present, the first click only fetches content (Lines 62–73) and does not persist configuration or navigate; users must click Next again.

💡 Proposed fix
   const handleSaveToLocalStorage = async () => {
+    const persistAndNavigate = (finalText) => {
+      localStorage.setItem("textContent", finalText);
+      localStorage.setItem("difficulty", difficulty);
+      localStorage.setItem("numQuestions", numQuestions);
+      localStorage.setItem("useWikipedia", isToggleOn.toString());
+      localStorage.setItem("inputSource", docUrl ? "Google Doc URL" : "Text");
+      navigate("/review");
+    };
+
     if (docUrl) {
       setLoading(true);
       try {
         const data = await apiClient.post("/get_content", { document_url: docUrl });
-        setDocUrl("");
-        setText(data || "Error in retrieving");
+        const finalText = data || "Error in retrieving";
+        setDocUrl("");
+        setText(finalText);
+        persistAndNavigate(finalText);
       } catch (error) {
         console.error("Error:", error);
         setText("Error retrieving Google Doc content");
       } finally {
         setLoading(false);
       }
     } else if (text) {
-      localStorage.setItem("textContent", text);
-      localStorage.setItem("difficulty", difficulty);
-      localStorage.setItem("numQuestions", numQuestions);
-      localStorage.setItem("useWikipedia", isToggleOn.toString());
-      navigate("/review");
+      persistAndNavigate(text);
     }
   };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eduaid_web/src/pages/Text_Input.jsx` around lines 61 - 80, The
handleSaveToLocalStorage flow for Google Docs only fetches content and doesn't
persist settings or navigate, requiring a second click; inside the async branch
where docUrl is truthy (in function handleSaveToLocalStorage), after
successfully receiving data and setting setText(...) (and before clearing
setDocUrl("") if you prefer), also write the same localStorage keys used in the
text branch (textContent, difficulty, numQuestions, useWikipedia) and then call
navigate("/review") so the user is taken to the review page in one click; ensure
this happens only on successful fetch (inside the try block) and keep the
existing loading/error handling intact.
🧹 Nitpick comments (1)
eduaid_web/src/pages/Review.jsx (1)

89-94: Harden last5Quizzes parsing to avoid breaking post-success navigation.

If last5Quizzes contains malformed JSON, JSON.parse throws and prevents redirect even after a successful generation response.

💡 Proposed fix
-            let last5Quizzes = JSON.parse(localStorage.getItem("last5Quizzes")) || [];
+            let last5Quizzes = [];
+            try {
+                const parsed = JSON.parse(localStorage.getItem("last5Quizzes"));
+                if (Array.isArray(parsed)) last5Quizzes = parsed;
+            } catch (_) {
+                last5Quizzes = [];
+            }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eduaid_web/src/pages/Review.jsx` around lines 89 - 94, Parsing
localStorage.getItem("last5Quizzes") with JSON.parse can throw on malformed JSON
and block post-success navigation; wrap the parse in a try/catch (or use a safe
parse helper) to fall back to an empty array when parse fails, ensure the result
is an array before pushing quizDetails (e.g., if not Array, set to []), then
push quizDetails, trim to 5, and call localStorage.setItem as before; update the
code around the last5Quizzes variable/logic so a bad stored value never prevents
redirect.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@eduaid_web/src/pages/Review.jsx`:
- Around line 57-66: getEndpoint currently maps difficulty and questionType to a
string used as the route, but that string comes from localStorage-backed state
and may be malformed; before calling apiClient.post with the computed endpoint
(where apiClient.post is invoked elsewhere in this file), validate the computed
endpoint against an allowlist of permitted endpoints (e.g., "get_shortq",
"get_mcq", "get_shortq_hard", "get_mcq_hard") and refuse or fallback if it is
not in the list. Update the code paths that call apiClient.post to run this
check (use the getEndpoint(resultingDifficulty, questionType) return value) and
handle invalid endpoints by logging an error and returning early or using a safe
default endpoint.
- Line 22: The code in Review.jsx sets numQuestions with
parseInt(localStorage.getItem("numQuestions")) || 10 which treats a saved "0" as
falsy and overwrites it; change the logic to default only when the stored value
is missing by using a null-coalescing approach (e.g., check if
localStorage.getItem("numQuestions") is null and only then use 10, or use
parseInt(localStorage.getItem("numQuestions") ?? "10", 10)) and ensure parseInt
is called with radix 10 so that a saved "0" is preserved.
- Around line 26-31: The current heuristic in Review.jsx using the local
variable inputSource and inspecting text (lines with text.includes(...)) is
brittle; change the component to read an explicit persisted inputSource field
(e.g., review.inputSource or props.inputSource) and use that value to set
inputSource, falling back to the existing text-based heuristic only if the
explicit field is undefined. Update any code paths that construct the review
object to persist inputSource on submit/upload so Review.jsx can reliably read
it, and remove or demote the brittle detection logic (keep it as a fallback in
the inputSource assignment).

---

Outside diff comments:
In `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 61-80: The handleSaveToLocalStorage flow for Google Docs only
fetches content and doesn't persist settings or navigate, requiring a second
click; inside the async branch where docUrl is truthy (in function
handleSaveToLocalStorage), after successfully receiving data and setting
setText(...) (and before clearing setDocUrl("") if you prefer), also write the
same localStorage keys used in the text branch (textContent, difficulty,
numQuestions, useWikipedia) and then call navigate("/review") so the user is
taken to the review page in one click; ensure this happens only on successful
fetch (inside the try block) and keep the existing loading/error handling
intact.

---

Nitpick comments:
In `@eduaid_web/src/pages/Review.jsx`:
- Around line 89-94: Parsing localStorage.getItem("last5Quizzes") with
JSON.parse can throw on malformed JSON and block post-success navigation; wrap
the parse in a try/catch (or use a safe parse helper) to fall back to an empty
array when parse fails, ensure the result is an array before pushing quizDetails
(e.g., if not Array, set to []), then push quizDetails, trim to 5, and call
localStorage.setItem as before; update the code around the last5Quizzes
variable/logic so a bad stored value never prevents redirect.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc3bf1a and 0e68957.

📒 Files selected for processing (4)
  • .gitignore
  • eduaid_web/src/App.js
  • eduaid_web/src/pages/Review.jsx
  • eduaid_web/src/pages/Text_Input.jsx

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: 4

🧹 Nitpick comments (1)
eduaid_web/src/pages/Review.jsx (1)

100-107: Avoid duplicating full quiz payload in history storage.

Line 100 stores full responseData in qaPairs, and Line 106 stores it again per history entry. This can exhaust localStorage quota faster and make history writes brittle.

💡 Proposed refactor
 const quizDetails = {
     difficulty: reviewData.difficulty,
     numQuestions: reviewData.numQuestions,
     date: new Date().toLocaleDateString(),
-    qaPair: responseData,
+    qaPairCount: Array.isArray(responseData) ? responseData.length : undefined,
 };

Also applies to: 122-127

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eduaid_web/src/pages/Review.jsx` around lines 100 - 107, The code currently
writes the full responseData twice — once into localStorage "qaPairs" and again
embedded into each quizDetails history entry (qaPair field), which duplicates
data and risks filling localStorage; change quizDetails to store a lightweight
reference instead (e.g., an id, timestamp, or index) rather than the entire
responseData, keep the full responseData only under the single "qaPairs" key,
and update any retrieval logic that reads quizDetails.qaPair to resolve the
reference back to the full QA payload from the "qaPairs" store; look for usages
of localStorage.setItem("qaPairs"), the quizDetails object (qaPair, date,
difficulty, numQuestions), and any history write paths around lines handling
quizDetails (including the other block at 122-127) to implement this
reference-based approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@eduaid_web/src/pages/Review.jsx`:
- Around line 82-97: The code currently builds requestData from reviewData
without validating inputs; before constructing requestData in the function where
setLoading(true) and getEndpoint(...) are used, add guards that trim
reviewData.text and ensure it's non-empty, and validate reviewData.numQuestions
is a positive integer (e.g., Number.isInteger(...) && >0); if either check
fails, call setLoading(false), surface an appropriate error (console.error or
set a UI error state) and return early; keep existing useWikipedia conversion
for use_mediawiki and reuse symbols endpoint, allowedEndpoints, requestData,
setLoading to locate and implement the checks.

In `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 50-56: The current handlers setText(data.content || data.error)
and setText("Error uploading file") allow transport/error messages to become the
quiz content and later be persisted via textContent; change these handlers in
the upload/fetch logic (the upload handler and the fetch response handling in
Text_Input.jsx) to not place error strings into the text state—use an empty
string or keep previous valid state and set a separate error flag/state (e.g.,
uploadError) instead, still call setInputSource("file") as needed, and ensure
the code that writes/persists textContent checks that text is non-empty and not
an error before saving.
- Around line 69-73: Trim the user-provided inputs before performing truthy
checks to avoid whitespace-only values triggering backend calls or navigation;
specifically, trim docUrl before the if check that calls setLoading and
apiClient.post("/get_content", { document_url: docUrl }) (use a trimmedDocUrl
variable) and likewise trim the text/value used in the save/review flow (the
variable checked around lines 91-97) and use the trimmed versions for
routing/POST decisions so only non-empty, non-whitespace strings proceed.
- Around line 96-97: When the textarea is edited, ensure the inputSource state
and persisted value are updated to "text" so summaries reflect manual edits: in
the textarea's onChange handler (the function handling user text edits around
the current textarea block) call setInputSource("text") and
localStorage.setItem("inputSource","text") before any save/submit logic, so the
existing localStorage.setItem("inputSource", inputSource) / navigate("/review")
flow picks up the updated source.

---

Nitpick comments:
In `@eduaid_web/src/pages/Review.jsx`:
- Around line 100-107: The code currently writes the full responseData twice —
once into localStorage "qaPairs" and again embedded into each quizDetails
history entry (qaPair field), which duplicates data and risks filling
localStorage; change quizDetails to store a lightweight reference instead (e.g.,
an id, timestamp, or index) rather than the entire responseData, keep the full
responseData only under the single "qaPairs" key, and update any retrieval logic
that reads quizDetails.qaPair to resolve the reference back to the full QA
payload from the "qaPairs" store; look for usages of
localStorage.setItem("qaPairs"), the quizDetails object (qaPair, date,
difficulty, numQuestions), and any history write paths around lines handling
quizDetails (including the other block at 122-127) to implement this
reference-based approach.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e68957 and 5effadd.

📒 Files selected for processing (2)
  • eduaid_web/src/pages/Review.jsx
  • eduaid_web/src/pages/Text_Input.jsx

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: 2

♻️ Duplicate comments (1)
eduaid_web/src/pages/Text_Input.jsx (1)

49-51: ⚠️ Potential issue | 🟠 Major

Do not write upload error text into text state.

Line 50 still allows non-content error payloads to become quiz content (data.content || data.error). This can propagate invalid content into review/generation.

💡 Proposed fix
-        const data = await apiClient.postFormData("/upload", formData);
-        setText(data.content || data.error);
-        setInputSource("file");
+        const data = await apiClient.postFormData("/upload", formData);
+        const uploadedText =
+          typeof data?.content === "string" ? data.content.trim() : "";
+        if (!uploadedText) {
+          console.error("Uploaded file content is empty or invalid");
+          return;
+        }
+        setText(uploadedText);
+        setInputSource("file");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eduaid_web/src/pages/Text_Input.jsx` around lines 49 - 51, The code is
assigning error payloads into the quiz text by doing setText(data.content ||
data.error); change this so setText is only called when data.content exists
(e.g., if (data.content) setText(data.content)); handle error cases separately
(e.g., setError state, show a toast, or console.error with data.error) and only
call setInputSource("file") on successful content upload; update the upload
handling around apiClient.postFormData, setText, and setInputSource to reflect
this separation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@eduaid_web/src/pages/Review.jsx`:
- Around line 22-24: The hydration of numQuestions from localStorage can produce
NaN or non-positive values; update the logic around
savedNumQuestions/numQuestions to parse the stored value and validate it is a
positive integer (e.g., use parseInt then Number.isInteger and > 0) and
otherwise fall back to 10; ensure this validation is performed where
numQuestions is defined so downstream code (including the generation logic that
expects a positive count) always receives a valid positive integer.

In `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 66-70: In handleSaveToLocalStorage, add a guard that validates
numQuestions is a positive integer (>0) before persisting and navigating to
'/review' — if numQuestions is invalid, do not write to localStorage or call
navigate and instead surface an error (e.g., set an error state or return
early). Apply the same validation for the other save/submit path around lines
96-103 (the alternative save handler) so both code paths check the numQuestions
variable prior to storing docUrl/text/numQuestions and calling
navigate('/review').

---

Duplicate comments:
In `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 49-51: The code is assigning error payloads into the quiz text by
doing setText(data.content || data.error); change this so setText is only called
when data.content exists (e.g., if (data.content) setText(data.content)); handle
error cases separately (e.g., setError state, show a toast, or console.error
with data.error) and only call setInputSource("file") on successful content
upload; update the upload handling around apiClient.postFormData, setText, and
setInputSource to reflect this separation.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5effadd and a79067f.

📒 Files selected for processing (2)
  • eduaid_web/src/pages/Review.jsx
  • eduaid_web/src/pages/Text_Input.jsx

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: 1

♻️ Duplicate comments (1)
eduaid_web/src/pages/Text_Input.jsx (1)

49-51: ⚠️ Potential issue | 🟠 Major

Do not persist backend error text as quiz content.

data.content || data.error can still write error strings into text, and that can flow into review/generation as valid content.

💡 Proposed fix
-        const data = await apiClient.postFormData("/upload", formData);
-        setText(data.content || data.error);
-        setInputSource("file");
+        const data = await apiClient.postFormData("/upload", formData);
+        if (typeof data?.content === "string" && data.content.trim()) {
+          setText(data.content.trim());
+          setInputSource("file");
+        } else {
+          console.error("Invalid uploaded file content");
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eduaid_web/src/pages/Text_Input.jsx` around lines 49 - 51, The code is
writing backend error text into the quiz content by using setText(data.content
|| data.error); change the flow so only a valid payload populates text: call
setText(...) and setInputSource("file") only when apiClient.postFormData returns
a genuine content (e.g., data.content is non-empty/valid); otherwise do not call
setText with data.error — instead surface the error via an error
state/notification (e.g., setUploadError or showToast) and keep input source
unchanged. Target the post-upload logic around apiClient.postFormData, setText,
and setInputSource to implement this check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 31-33: When hydrating numQuestions from localStorage (the
savedNumQuestions -> setNumQuestions path in Text_Input.jsx), validate the
parsed value before calling setNumQuestions: parse with
parseInt(savedNumQuestions, 10), ensure the result is a finite integer and
within your allowed range (e.g., >= 1), and fall back to the existing default
(or omit state update) if validation fails; update the branch that currently
calls setNumQuestions(parseInt(savedNumQuestions, 10)) to perform this check and
only set state when the value is valid.

---

Duplicate comments:
In `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 49-51: The code is writing backend error text into the quiz
content by using setText(data.content || data.error); change the flow so only a
valid payload populates text: call setText(...) and setInputSource("file") only
when apiClient.postFormData returns a genuine content (e.g., data.content is
non-empty/valid); otherwise do not call setText with data.error — instead
surface the error via an error state/notification (e.g., setUploadError or
showToast) and keep input source unchanged. Target the post-upload logic around
apiClient.postFormData, setText, and setInputSource to implement this check.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a79067f and 106a3fb.

📒 Files selected for processing (2)
  • eduaid_web/src/pages/Review.jsx
  • eduaid_web/src/pages/Text_Input.jsx

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: 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 `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 89-93: The fetch failure and invalid `/get_content` responses are
only logged to console; update the Text_Input.jsx logic to surface these errors
to the UI by introducing and using a state setter (e.g., add error state like
setFetchError or setErrorMessage via useState) and call it wherever you
currently call console.error (the block checking if (!data || typeof data !==
"string" || !data.trim()) and the similar block at lines ~106-108), still call
setLoading(false) and return, and then render that error state in the component
(display a user-friendly message and optional retry) so users see actionable
feedback instead of only console messages.
- Line 40: The hydration for useWikipedia can set isToggleOn to NaN because
parseInt(savedWikipedia, 10) may return NaN for legacy/non-numeric values;
change the logic around savedWikipedia (from Text_Input.jsx) to parse and
validate before calling setIsToggleOn — e.g., compute const parsed =
parseInt(savedWikipedia, 10), check Number.isNaN(parsed) (or use a
numeric/default fallback like 0/1) and only call setIsToggleOn(parsed) with a
validated number (or convert to Boolean/0/1) so toggle updates remain stable;
update the usage sites that reference savedWikipedia, parseInt, and
setIsToggleOn accordingly.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 106a3fb and a37949f.

📒 Files selected for processing (1)
  • eduaid_web/src/pages/Text_Input.jsx

@piyush06singhal
Copy link
Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 2

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)

138-140: ⚠️ Potential issue | 🟡 Minor

Prevent decrementing below 1 to match save validation.

The decrement function allows numQuestions to reach 0, but handleSaveToLocalStorage requires a positive count. This inconsistency can confuse users when "Next" silently fails at 0.

💡 Proposed fix
   const decrementQuestions = () => {
-    setNumQuestions((prev) => (prev > 0 ? prev - 1 : 0));
+    setNumQuestions((prev) => (prev > 1 ? prev - 1 : 1));
   };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eduaid_web/src/pages/Text_Input.jsx` around lines 138 - 140,
decrementQuestions currently allows numQuestions to go to 0 while
handleSaveToLocalStorage expects a positive count; update decrementQuestions so
it enforces a minimum of 1 (e.g., change the conditional in decrementQuestions
that uses setNumQuestions to ensure prev > 1 before decrementing), and
double-check any UI/state initialization around numQuestions and the
handleSaveToLocalStorage validation to keep behavior consistent.
🧹 Nitpick comments (1)
eduaid_web/src/pages/Text_Input.jsx (1)

120-127: Handle the case when no input is provided.

If both URL and text are empty/whitespace-only, clicking "Next" silently does nothing. Consider adding an else branch to inform the user.

💡 Proposed fix
     } else if (trimmedText) {
       localStorage.setItem("textContent", trimmedText);
       localStorage.setItem("difficulty", difficulty);
       localStorage.setItem("numQuestions", numQuestions.toString());
       localStorage.setItem("useWikipedia", isToggleOn.toString());
       localStorage.setItem("inputSource", inputSource);
       navigate("/review");
+    } else {
+      setError("Please enter text or provide a Google Doc URL.");
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eduaid_web/src/pages/Text_Input.jsx` around lines 120 - 127, The current
Next-button flow saves inputs and calls navigate("/review") only when
trimmedText (or URL) exists, but if both are empty the click silently does
nothing; add an else branch after the existing if/else-if that handles the case
when neither inputSource URL nor trimmedText has content and surface a
user-visible error (e.g., set a component state like errorMessage or call an
existing showToast/alert) so the user is informed and prevented from proceeding;
update the Text_Input.jsx handler that uses trimmedText, inputSource, and
navigate to perform this validation and display.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 88-91: The handler that checks validQuestionCount (where
numQuestions and validQuestionCount are validated in Text_Input.jsx) currently
just console.error and returns, so the user gets no feedback; update the
validation branch in that function to set a visible UI error instead of only
logging — e.g., set a state like questionCountError or validationError (create
useState if missing) and populate it with a user-friendly message when
validQuestionCount is false, ensure the JSX near the numQuestions input renders
that state (styled and accessible) and prevents advancing until cleared; keep
the console.error for devs but add the user-facing error message and clear it on
successful validation or on input change.
- Around line 64-72: The file upload branch currently only logs failures to
console; update the invalid-response branch and the catch block in the file
upload handler to call the component error state setter (setError) with a
user-facing message (e.g., "File upload failed" or the caught error message) and
clear or reset input-related state as appropriate; specifically, replace or
augment the console.error in the invalid data branch and the catch block that
surround setText and setInputSource so they call setError(...) and optionally
setInputSource(null) or setText("") to ensure the UI shows the error like the
URL fetch flow does.

---

Outside diff comments:
In `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 138-140: decrementQuestions currently allows numQuestions to go to
0 while handleSaveToLocalStorage expects a positive count; update
decrementQuestions so it enforces a minimum of 1 (e.g., change the conditional
in decrementQuestions that uses setNumQuestions to ensure prev > 1 before
decrementing), and double-check any UI/state initialization around numQuestions
and the handleSaveToLocalStorage validation to keep behavior consistent.

---

Nitpick comments:
In `@eduaid_web/src/pages/Text_Input.jsx`:
- Around line 120-127: The current Next-button flow saves inputs and calls
navigate("/review") only when trimmedText (or URL) exists, but if both are empty
the click silently does nothing; add an else branch after the existing
if/else-if that handles the case when neither inputSource URL nor trimmedText
has content and surface a user-visible error (e.g., set a component state like
errorMessage or call an existing showToast/alert) so the user is informed and
prevented from proceeding; update the Text_Input.jsx handler that uses
trimmedText, inputSource, and navigate to perform this validation and display.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a37949f and abe6b69.

📒 Files selected for processing (1)
  • eduaid_web/src/pages/Text_Input.jsx

@piyush06singhal
Copy link
Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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]: Add Quiz Review & Confirmation Step Before Generation

1 participant