Skip to content

E2619 - Student Quiz Frontend (solved diff)#181

Open
atmai0829 wants to merge 1 commit into
expertiza:mainfrom
maibin2004:main
Open

E2619 - Student Quiz Frontend (solved diff)#181
atmai0829 wants to merge 1 commit into
expertiza:mainfrom
maibin2004:main

Conversation

@atmai0829
Copy link
Copy Markdown

@atmai0829 atmai0829 commented Apr 30, 2026

Implements the student quiz workflow in the Expertiza React/TypeScript frontend. Students on assignments that require a quiz must now complete the quiz before they can start their peer review. Instructors and submitting teams can author quiz questions with correct answers directly in the questionnaire editor.

Summary by CodeRabbit

  • New Features

    • Added "Reviews" tab to student assignments page for viewing assigned peer and teammate reviews.
    • Added quiz questionnaire authoring with correct answer tracking for quiz items.
    • Enhanced teammate review questionnaire support with separate questionnaire configuration.
    • Added ability to create/edit quiz questionnaires from the reviewer assignment page.
  • Bug Fixes

    • Fixed form select component controlled-input behavior.
    • Fixed questionnaire instructor display when data is missing.
    • Fixed questionnaire edit navigation routing.
  • Improvements

    • Updated assignment form rubric questionnaire selection with dedicated teammate review options.
    • Enhanced reviewer-to-team mapping with backend persistence and deletion support.
    • Improved review interface with full questionnaire rendering and response management.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

📝 Walkthrough

Walkthrough

This PR introduces quiz questionnaire support throughout the application and adds a new "AssignedReviews" student page for managing peer and quiz reviews. Changes span routing, form components, questionnaire editing and authoring, teammate review submission, and assignment configuration, enabling quiz creation, quiz taking, and reviewer-to-team mapping persistence.

Changes

Cohort / File(s) Summary
Routing & Core Setup
src/App.tsx
Adds loader for questionnaire data on edit-questionnaire path; introduces protected routes for AssignedReviews at both global (student_tasks/reviews) and assignment-scoped (student_tasks/:assignmentId/reviews) levels.
Form Components
src/components/Form/FormSelect.tsx
Forces controlled input behavior by explicitly setting value={field.value ?? ""}, preventing React warnings when Formik provides null or undefined.
Hooks
src/hooks/useSignupSheet.ts
Changes signup-sheet data source endpoint from /sign_up_topics to /project_topics while preserving query parameters and authorization.
Assignment Configuration
src/pages/Assignments/AssignReviewer.tsx
Adds backend persistence for reviewer-to-team mappings: creates and POSTs to /response_maps, handles deletion via DELETE, and introduces quiz creation action with navigation to questionnaire editor.
Assignment Configuration
src/pages/Assignments/AssignmentEditor.tsx, src/pages/Assignments/AssignmentUtil.ts
Removes is_role_based from form defaults; adds teammate-review-specific questionnaire options filtering; dynamically builds assignment_questionnaires_attributes from questionnaire-round keys and appends quiz rows; replaces allow_topic_suggestion_from_students with allow_suggestions flag; deserializes persisted questionnaires back into dynamic form fields.
Assignment Configuration
src/pages/Assignments/tabs/GeneralTab.tsx
Whitespace and line-ending normalization only; no functional changes to component behavior.
Questionnaire System
src/pages/Questionnaires/Questionnaire.tsx, src/pages/Questionnaires/QuestionnaireColumns.tsx
Navigation route changed to absolute path; instructor column accessors updated to safely handle missing data via optional chaining.
Questionnaire Editor
src/pages/Questionnaires/QuestionnaireEditor.tsx
Conditionally sets instructor_id when team_id absent; PATCHes /teams/{teamId}/quiz_questionnaire on create for quiz mode; navigates to return_to when provided; adds correct_answer to item mappings.
Questionnaire Authoring
src/pages/Questionnaires/QuestionnaireForm.tsx, src/pages/Questionnaires/QuestionnaireItemsFieldArray.tsx, src/pages/Questionnaires/QuestionnaireUtils.tsx
Passes questionnaireType prop through form layers; renders correct_answer controls for quiz item types (checkboxes, scales, dropdowns, text fields); filters out multiple-choice option for non-quizzes; extends IItem interface with quiz-related fields (correct_answer, textarea/textbox dimensions, grid metadata).
Student Review Pages
src/pages/Student Teams/TeammateReview.tsx
Fully refactored to handle questionnaire-driven reviews and quizzes: parses routing params, fetches questionnaire items, supports draft state via localStorage/response maps, renders multiple item types, builds scores_attributes payloads, implements response submission with scoring, and handles quiz success UI.
Student Task Management
src/pages/StudentTasks/StudentTasks.tsx, src/pages/StudentTasks/AssignedReviews.tsx
StudentTasks adds "Reviews" tab alongside sign-up; new AssignedReviews page fetches assignment details, student task quiz requirements, response maps, and questionnaires; computes review rows with status tracking; manages localStorage hydration; provides openReview and handleTakeQuiz handlers for navigation and quiz creation.

Sequence Diagrams

sequenceDiagram
    actor User
    participant Client as Browser/React
    participant Server as Backend API
    
    User->>Client: Navigate to AssignedReviews
    Client->>Server: GET /assignments/{id}
    Server-->>Client: Assignment details
    Client->>Server: GET /student_tasks/list
    Server-->>Client: Student task quiz requirements
    Client->>Server: GET /response_maps (filtered by reviewer_user_id)
    Server-->>Client: Response maps and responses
    Client->>Client: Build review rows from questionnaires<br/>and response states
    Client->>User: Render reviews table with status
    User->>Client: Click "Take Quiz" button
    Client->>Server: POST /quiz_response_maps
    Server-->>Client: New quiz response map
    Client->>Client: Navigate to /response/new with<br/>quiz map/questionnaire params
    User->>Client: Submit quiz responses
    Client->>Server: PATCH /responses/{id}/submit
    Server-->>Client: Confirmation + total_score
    Client->>User: Show quiz success UI
Loading
sequenceDiagram
    actor Instructor
    participant Client as Browser/React
    participant Server as Backend API
    
    Instructor->>Client: Access Questionnaire Editor
    Client->>Client: Initialize form with questionnaire_type=Quiz
    Instructor->>Client: Fill quiz questions + correct answers
    Client->>Client: Render correct_answer controls<br/>(checkboxes, scales, dropdowns, etc.)
    Instructor->>Client: Save questionnaire
    Client->>Server: POST /questionnaires (with items including correct_answer)
    Server-->>Client: Created questionnaire {id}
    
    alt If team_id present (creating quiz for team)
        Client->>Server: PATCH /teams/{teamId}/quiz_questionnaire
        Server-->>Client: Team quiz_questionnaire_id updated
    end
    
    Client->>Client: Navigate back (return_to or /questionnaires)
    
    par Student takes quiz
        Instructor->>Client: Create response map for student quiz
        Client->>Client: Render TeammateReview in quiz mode
        Client->>Client: Display items with correct answer indicators
        Instructor->>Client: Select answers for each item
        Client->>Server: PATCH /responses/{id}/submit
        Server-->>Client: Scoring result (total_score)
        Client->>Client: Display score + success message
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 Quizzes bloom where questionnaires grow,
Reviews assigned now steal the show,
From drafts to scores, a student's way,
Backend maps keep answers in play, 🎓
One hop, two hops—all paths align!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.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 title 'E2619 - Student Quiz Frontend (solved diff)' clearly identifies the main feature being implemented (student quiz frontend) and is directly supported by the substantial changes across questionnaire, assignment, and student task components.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Review rate limit: 8/10 reviews remaining, refill in 11 minutes and 6 seconds.

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

Copy link
Copy Markdown

@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: 5

Caution

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

⚠️ Outside diff range comments (1)
src/pages/Assignments/AssignmentEditor.tsx (1)

56-102: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore the is_role_based default in initialValues.

The form still binds name="is_role_based" later, and transformAssignmentRequest still serializes this field. Removing it from the defaults leaves new assignments with an undefined checkbox state instead of a predictable false.

🔧 Suggested fix
   review_rubric_varies_by_role: false,
+  is_role_based: false,
   has_max_review_limit: false,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/Assignments/AssignmentEditor.tsx` around lines 56 - 102, The
initialValues object is missing the is_role_based default which causes the
checkbox bound via name="is_role_based" to be undefined; update the
initialValues (type IAssignmentFormValues) to include is_role_based: false so
new assignments have a predictable false state and remain consistent with
transformAssignmentRequest serialization.
🧹 Nitpick comments (1)
src/pages/StudentTasks/StudentTasks.tsx (1)

304-435: ⚡ Quick win

Remove unused assigned-reviews fetching logic from this page.

These states/effects/callbacks are not consumed by the rendered Sign Up UI, but still trigger localStorage parsing and /response_maps requests.

Also applies to: 437-458

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

In `@src/pages/StudentTasks/StudentTasks.tsx` around lines 304 - 435, The
assigned-reviews logic is unused in the Sign Up UI; remove the unused state and
its side-effect to stop localStorage parsing and /response_maps calls: delete
the const [assignedReviews, setAssignedReviews] =
useState<AssignedReviewRow[]>([]) declaration plus the entire useEffect that
builds rows (including buildRows, isTeammateQuestionnaire,
teammateQuestionnaire/normalReviewQuestionnaire logic and the localStorage +
axiosClient.get('/response_maps') flow) and any direct references to
setAssignedReviews or assignedReviews in this file; if other code relies on
buildRows, isolate or move it, and ensure you also remove any now-unused imports
(e.g. axiosClient) to keep the file clean.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/pages/Assignments/AssignReviewer.tsx`:
- Around line 491-495: The onCreateQuiz function always routes to the create
flow (/questionnaires/new) even when editing an existing team quiz; update the
logic so when a questionnaireId for an existing quiz is present it navigates to
the edit route instead (e.g.
navigate(`/questionnaires/${questionnaireId}/edit?team_id=${teamId}&assignment_id=${assignmentId}&return_to=${returnTo}`)),
and keep the current /questionnaires/new path only for true create actions;
modify the relevant handlers (onCreateQuiz and the analogous block referenced
around lines 601-608) to check for an existing questionnaireId or “isEdit” flag
and choose the correct route accordingly.

In `@src/pages/Questionnaires/QuestionnaireEditor.tsx`:
- Around line 77-88: The create-flow currently always navigates away even if the
team-linking PATCH (axiosClient.patch in the mode === "create" block) fails;
change the flow so navigation only happens after a successful link: move the
navigate(returnTo ? decodeURIComponent(returnTo) : "/questionnaires") and the
subsequent return into the try block after the axiosClient.patch completes, and
in the catch (linkErr) for the patch do not navigate—log or surface the error
and let the function continue without redirecting so the user stays on the page
to fix the issue.

In `@src/pages/Questionnaires/QuestionnaireItemsFieldArray.tsx`:
- Around line 516-536: The Add action allows pushing items with an empty
question_type when numQuestions is provided but questionType is unset; update
the onClick handlers (the one with push, questionType, numQuestions,
setNumQuestions, setQuestionType and the similar block at the later location) to
guard early: check that questionType is a non-empty string (and numQuestions is
a positive number) before calling push in the loop, and if invalid simply return
(or disable the button upstream); ensure you do the same guard in both
occurrences so no item is created with question_type === "".

In `@src/pages/Questionnaires/QuestionnaireUtils.tsx`:
- Line 121: Remove the two console.log calls that print full questionnaire
payloads (the calls printing "Original Form Values:" and the other at line 138)
so sensitive quiz/answer data is not emitted in normal runtime; instead either
delete them entirely or replace with a non-production-guarded debug logger
(e.g., wrap in if (process.env.NODE_ENV === 'development') or use a secure
logger.debug after redacting answers) and update the code paths in
QuestionnaireUtils.tsx where these console.log calls occur (search for the exact
string "Original Form Values:" to locate one of them).

In `@src/pages/StudentTasks/AssignedReviews.tsx`:
- Around line 272-278: buildRows is called without currentUserTeamId so
backendRows' AssignedReviewRow.isTeammateReview is incorrectly false and then
overwrites local rows during setAssignedReviews merge by mapId; fix by ensuring
buildRows receives currentUserTeamId (e.g., change call to buildRows(maps,
currentUserTeamId) and propagate that param into buildRows) or, when merging in
setAssignedReviews, preserve the existing prev row's isTeammateReview for the
same mapId (use prev's row fields where present, especially isTeammateReview) so
teammate classification isn't lost.

---

Outside diff comments:
In `@src/pages/Assignments/AssignmentEditor.tsx`:
- Around line 56-102: The initialValues object is missing the is_role_based
default which causes the checkbox bound via name="is_role_based" to be
undefined; update the initialValues (type IAssignmentFormValues) to include
is_role_based: false so new assignments have a predictable false state and
remain consistent with transformAssignmentRequest serialization.

---

Nitpick comments:
In `@src/pages/StudentTasks/StudentTasks.tsx`:
- Around line 304-435: The assigned-reviews logic is unused in the Sign Up UI;
remove the unused state and its side-effect to stop localStorage parsing and
/response_maps calls: delete the const [assignedReviews, setAssignedReviews] =
useState<AssignedReviewRow[]>([]) declaration plus the entire useEffect that
builds rows (including buildRows, isTeammateQuestionnaire,
teammateQuestionnaire/normalReviewQuestionnaire logic and the localStorage +
axiosClient.get('/response_maps') flow) and any direct references to
setAssignedReviews or assignedReviews in this file; if other code relies on
buildRows, isolate or move it, and ensure you also remove any now-unused imports
(e.g. axiosClient) to keep the file clean.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c6a590f7-fcfe-46a3-9718-fd2fdc16100b

📥 Commits

Reviewing files that changed from the base of the PR and between 474e9f7 and ae09b34.

📒 Files selected for processing (16)
  • src/App.tsx
  • src/components/Form/FormSelect.tsx
  • src/hooks/useSignupSheet.ts
  • src/pages/Assignments/AssignReviewer.tsx
  • src/pages/Assignments/AssignmentEditor.tsx
  • src/pages/Assignments/AssignmentUtil.ts
  • src/pages/Assignments/tabs/GeneralTab.tsx
  • src/pages/Questionnaires/Questionnaire.tsx
  • src/pages/Questionnaires/QuestionnaireColumns.tsx
  • src/pages/Questionnaires/QuestionnaireEditor.tsx
  • src/pages/Questionnaires/QuestionnaireForm.tsx
  • src/pages/Questionnaires/QuestionnaireItemsFieldArray.tsx
  • src/pages/Questionnaires/QuestionnaireUtils.tsx
  • src/pages/Student Teams/TeammateReview.tsx
  • src/pages/StudentTasks/AssignedReviews.tsx
  • src/pages/StudentTasks/StudentTasks.tsx

Comment on lines +491 to +495
function onCreateQuiz(teamId: Id) {
if (!hasValidId) return;
const returnTo = encodeURIComponent(`/assignments/edit/${assignmentId}/assignreviewer`);
navigate(`/questionnaires/new?type=Quiz&team_id=${teamId}&assignment_id=${assignmentId}&return_to=${returnTo}`);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

edit quiz currently routes to create flow.

Line 607 advertises edit behavior, but Line 494 always sends users to /questionnaires/new. Existing team quizzes should route to edit mode.

Suggested fix
-  function onCreateQuiz(teamId: Id) {
+  function onCreateQuiz(teamId: Id, quizQuestionnaireId?: Id | null) {
     if (!hasValidId) return;
     const returnTo = encodeURIComponent(`/assignments/edit/${assignmentId}/assignreviewer`);
-    navigate(`/questionnaires/new?type=Quiz&team_id=${teamId}&assignment_id=${assignmentId}&return_to=${returnTo}`);
+    if (quizQuestionnaireId) {
+      navigate(`/questionnaires/${quizQuestionnaireId}/edit?type=Quiz&team_id=${teamId}&assignment_id=${assignmentId}&return_to=${returnTo}`);
+      return;
+    }
+    navigate(`/questionnaires/new?type=Quiz&team_id=${teamId}&assignment_id=${assignmentId}&return_to=${returnTo}`);
   }
- onClick={() => hasValidId && onCreateQuiz(team.id)}
+ onClick={() => hasValidId && onCreateQuiz(team.id, team.quiz_questionnaire_id)}

Also applies to: 601-608

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

In `@src/pages/Assignments/AssignReviewer.tsx` around lines 491 - 495, The
onCreateQuiz function always routes to the create flow (/questionnaires/new)
even when editing an existing team quiz; update the logic so when a
questionnaireId for an existing quiz is present it navigates to the edit route
instead (e.g.
navigate(`/questionnaires/${questionnaireId}/edit?team_id=${teamId}&assignment_id=${assignmentId}&return_to=${returnTo}`)),
and keep the current /questionnaires/new path only for true create actions;
modify the relevant handlers (onCreateQuiz and the analogous block referenced
around lines 601-608) to check for an existing questionnaireId or “isEdit” flag
and choose the correct route accordingly.

Comment on lines +77 to +88
if (mode === "create" && teamId && response.data?.id) {
try {
await axiosClient.patch(
`/teams/${teamId}/quiz_questionnaire`,
{ questionnaire_id: response.data.id },
{ headers: { Authorization: `Bearer ${token}` } }
);
} catch (linkErr) {
console.error("Failed to link quiz questionnaire to team:", linkErr);
}
navigate(returnTo ? decodeURIComponent(returnTo) : "/questionnaires");
return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Do not redirect when team-quiz linking fails.

Line 84 catches link errors, but Line 87 still navigates away. That can leave the new quiz unassigned to the team while showing a success flow.

Suggested fix
-    if (mode === "create" && teamId && response.data?.id) {
-      try {
-        await axiosClient.patch(
-          `/teams/${teamId}/quiz_questionnaire`,
-          { questionnaire_id: response.data.id },
-          { headers: { Authorization: `Bearer ${token}` } }
-        );
-      } catch (linkErr) {
-        console.error("Failed to link quiz questionnaire to team:", linkErr);
-      }
-      navigate(returnTo ? decodeURIComponent(returnTo) : "/questionnaires");
-      return;
-    }
+    if (mode === "create" && teamId && response.data?.id) {
+      await axiosClient.patch(
+        `/teams/${teamId}/quiz_questionnaire`,
+        { questionnaire_id: response.data.id },
+        { headers: { Authorization: `Bearer ${token}` } }
+      );
+      navigate(returnTo ? decodeURIComponent(returnTo) : "/questionnaires");
+      return;
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/Questionnaires/QuestionnaireEditor.tsx` around lines 77 - 88, The
create-flow currently always navigates away even if the team-linking PATCH
(axiosClient.patch in the mode === "create" block) fails; change the flow so
navigation only happens after a successful link: move the navigate(returnTo ?
decodeURIComponent(returnTo) : "/questionnaires") and the subsequent return into
the try block after the axiosClient.patch completes, and in the catch (linkErr)
for the patch do not navigate—log or surface the error and let the function
continue without redirecting so the user stays on the page to fix the issue.

Comment on lines +516 to +536
onClick={() => {
const questionCount =
typeof numQuestions === "number" ? numQuestions : 0;

for (let i = 0; i < questionCount; i++) {
push({
id: undefined,
txt: "",
weight: "",
question_type: questionType,
break_before: 1,
alternatives: "",
min_label: "",
max_label: "",
seq: values.items.length + 1,
correct_answer: "",
});
}
setNumQuestions("");
setQuestionType("");
}}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Guard the Add action when no item type is selected.

Line 525 can persist an empty question_type if the user enters a count but leaves the type dropdown unset.

Suggested fix
 onClick={() => {
   const questionCount =
     typeof numQuestions === "number" ? numQuestions : 0;
+  if (!questionType || questionCount <= 0) return;
 
   for (let i = 0; i < questionCount; i++) {
     push({

Also applies to: 554-560

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

In `@src/pages/Questionnaires/QuestionnaireItemsFieldArray.tsx` around lines 516 -
536, The Add action allows pushing items with an empty question_type when
numQuestions is provided but questionType is unset; update the onClick handlers
(the one with push, questionType, numQuestions, setNumQuestions, setQuestionType
and the similar block at the later location) to guard early: check that
questionType is a non-empty string (and numQuestions is a positive number)
before calling push in the loop, and if invalid simply return (or disable the
button upstream); ensure you do the same guard in both occurrences so no item is
created with question_type === "".

* passed as the request body.
*/
export const transformQuestionnaireRequest = (values: QuestionnaireFormValues) => {
console.log("Original Form Values:", values);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove console logging of questionnaire payloads.

Line 121 and Line 138 log full form/request objects, including quiz answer data. This should not be emitted in normal runtime paths.

Also applies to: 138-138

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

In `@src/pages/Questionnaires/QuestionnaireUtils.tsx` at line 121, Remove the two
console.log calls that print full questionnaire payloads (the calls printing
"Original Form Values:" and the other at line 138) so sensitive quiz/answer data
is not emitted in normal runtime; instead either delete them entirely or replace
with a non-production-guarded debug logger (e.g., wrap in if
(process.env.NODE_ENV === 'development') or use a secure logger.debug after
redacting answers) and update the code paths in QuestionnaireUtils.tsx where
these console.log calls occur (search for the exact string "Original Form
Values:" to locate one of them).

Comment on lines +272 to +278
const backendRows = buildRows(maps);
setAssignedReviews((prev) => {
// Backend rows take priority; keep any localStorage-only rows
const byMapId = new Map<number, AssignedReviewRow>();
prev.forEach((r) => byMapId.set(r.mapId, r));
backendRows.forEach((r) => byMapId.set(r.mapId, r));
return Array.from(byMapId.values());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Backend rows can misclassify teammate reviews as normal reviews.

Line 272 builds backend rows without currentUserTeamId, so isTeammateReview falls back to false. Then Line 277 overwrites any prior local row classification by mapId.

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

In `@src/pages/StudentTasks/AssignedReviews.tsx` around lines 272 - 278, buildRows
is called without currentUserTeamId so backendRows'
AssignedReviewRow.isTeammateReview is incorrectly false and then overwrites
local rows during setAssignedReviews merge by mapId; fix by ensuring buildRows
receives currentUserTeamId (e.g., change call to buildRows(maps,
currentUserTeamId) and propagate that param into buildRows) or, when merging in
setAssignedReviews, preserve the existing prev row's isTeammateReview for the
same mapId (use prev's row fields where present, especially isTeammateReview) so
teammate classification isn't lost.

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.

1 participant