Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | 3x 7x 7x | import React from "react";
import { Box, Grid, Stack, Typography } from "@mui/material";
import SubmissionQuestionCard from "./SubmissionQuestionCard";
import CommentCard from "./CommentCard";
import { SubmissionGraphProvider } from "./SubmissionGraphContext";
/**
* Per-question rows of [question card | comment card] for a submitted
* assignment. Shared by the teacher's "Individual Answers" tab (viewing an
* arbitrary student, editable comments) and the student's own submission
* page (`readOnly` — comments display-only, no save/delete handlers needed).
*
* `canMark` (teacher only) turns on the hand-marking control under each WRITTEN
* answer; `onMarkSave(questionId, points, feedback)` persists one student's mark.
*
* `editablePoints` (teacher only) additionally lets the points Chip on each
* question card be edited inline; `onPointsSave(questionId, points)` and
* `pointsActionState` (questionId -> "saving") mirror the comment save flow.
*/
const SubmissionAnswersList = ({
questions,
answers,
comments,
settings,
commentActionState,
onCommentSave,
onCommentDelete,
readOnly = false,
editablePoints = false,
canMark = false,
markActionState,
onMarkSave,
pointsActionState,
onPointsSave,
}) => {
Eif (!questions?.length) {
return (
<Box sx={{ textAlign: "center", py: 6 }}>
<Typography variant="body1" color="text.secondary">
No questions found for this assignment.
</Typography>
</Box>
);
}
return (
<SubmissionGraphProvider>
<Stack spacing={3}>
{questions.map((question, index) => {
const action = commentActionState?.[question._id];
return (
<Grid container spacing={3} key={question._id || index} alignItems="stretch">
<Grid size={{ xs: 12, md: 8 }}>
<SubmissionQuestionCard
question={question}
answerEntry={(answers || []).find((a) => a.questionId === question._id)}
itemNumber={index + 1}
settings={settings}
editablePoints={editablePoints}
isSavingPoints={pointsActionState?.[question._id] === "saving"}
onPointsSave={(points) => onPointsSave?.(question._id, points)}
// Only written answers are marked by hand. A wrong
// multiple-choice answer is wrong, and offering to mark
// it would promise something the API refuses.
canMark={canMark && question?.questionType === "free-response"}
isSavingMark={markActionState?.[question._id] === "saving"}
onMarkSave={(points, feedback) => onMarkSave?.(question._id, points, feedback)}
/>
</Grid>
<Grid size={{ xs: 12, md: 4 }}>
<CommentCard
comment={comments?.[question._id]}
isSaving={action === "saving"}
isDeleting={action === "deleting"}
onSave={(text) => onCommentSave?.(question._id, text)}
onDelete={() => onCommentDelete?.(question._id)}
readOnly={readOnly}
/>
</Grid>
</Grid>
);
})}
</Stack>
</SubmissionGraphProvider>
);
};
export default SubmissionAnswersList;
|