feat(portal-shell): grades 模块 5 页迁移(教师域 §9.1 B2)

§9.1 B2 grades 行:/grades、/entry、/analytics、/stats、/report-card
契约:grade(id)  真实查询;列表/分析/统计/成绩单 → MSW 兜底

新增文件:
- src/lib/api/grades.ts (6 hooks)
- src/lib/api/operations/grades.graphql.ts (6 documents)
- src/features/teacher/grades/ (7 files: transformations + tests + 5 clients)
- src/app/shell/teacher/grades/ (5 page.tsx + loading.tsx + error.tsx)

修改文件:
- src/mocks/graphql-data.ts (5 mock 常量 + 6 handler cases)
- src/messages/{zh-CN,en}.json (grades i18n)
- src/lib/api/{index,operations/index}.ts (导出 grades)
- scripts/check-page-count.ts (baseline 26 → 31)

DoD 验收(§11.3 11 项):
- typecheck 0 errors
- lint 0 errors
- vitest 357 tests passed
- lint:tokens 0 errors
- check:pages 31 PASS

关联:ARCHITECTURE.md §5.3 / §5.4 / §9.1 / §10 P2 / §11.3 / §11.4
This commit is contained in:
SpecialX
2026-07-22 18:41:55 +08:00
parent 081cb5fbc3
commit 2f8f3f3855
22 changed files with 3144 additions and 34 deletions

View File

@@ -513,7 +513,125 @@
}
},
"grades": {
"title": "Grades"
"title": "Grades",
"list": {
"title": "Grades",
"description": "View and manage all student grades",
"entry": "Record Grade",
"searchPlaceholder": "Search by student name/no...",
"statusFilter": "Filter by status",
"statusAll": "All statuses",
"statusGraded": "Graded",
"statusPending": "Pending",
"statusExempt": "Exempt",
"statusAbsent": "Absent",
"total": "{count} total",
"colStudent": "Student",
"colClass": "Class",
"colSource": "Source",
"colScore": "Score",
"colStatus": "Status",
"colGradedAt": "Graded At",
"mswNotice": "List query contract is pending, please ensure NEXT_PUBLIC_MSW=1 is enabled."
},
"entry": {
"title": "Record Grade",
"description": "Fill in student grade information",
"submit": "Submit",
"success": "Grade recorded successfully",
"error": "Submission failed",
"classId": "Class ID",
"studentId": "Student ID",
"examId": "Exam ID (optional)",
"examIdPlaceholder": "e.g. exam-001",
"homeworkId": "Homework ID (optional)",
"homeworkIdPlaceholder": "e.g. hw-001",
"score": "Score",
"totalScore": "Total Score",
"feedbackLabel": "Feedback",
"feedbackPlaceholder": "Write feedback to the student...",
"errorClassRequired": "Please fill in Class ID",
"errorStudentRequired": "Please fill in Student ID",
"errorScoreInvalid": "Score is invalid, please enter a non-negative number",
"errorTotalInvalid": "Total score is invalid, please enter a positive number",
"errorSourceRequired": "At least one of Exam ID or Homework ID is required",
"contractPending": "Grade submission contract is @contract-pending, currently backed by MSW. Will switch to real submission once backend mutation is ready."
},
"analytics": {
"title": "Grade Analytics",
"subtitle": "Scope: {scope}",
"notFound": "No analytics data found, grading may not be complete",
"sectionSummary": "Summary",
"sectionDistribution": "Score Distribution",
"sectionRankings": "Student Rankings",
"summaryTotal": "Expected",
"summaryGraded": "Graded",
"summaryAvg": "Average",
"summaryMax": "Max",
"summaryMin": "Min",
"summaryPassRate": "Pass Rate",
"summaryPassScore": "Pass Score",
"emptyDistribution": "No score distribution data",
"emptyRankings": "No ranking data",
"colRank": "Rank",
"colStudentNo": "Student No.",
"colStudentName": "Name",
"colScore": "Score",
"colLevel": "Level"
},
"stats": {
"title": "Grade Statistics",
"subtitle": "Class: {classId} · Period: {period}",
"notFound": "No statistics data found",
"empty": "No subject statistics data",
"sectionSummary": "Subject Summary Cards",
"sectionTable": "Subject Statistics Table",
"studentCount": "{count} students",
"avgScore": "Average",
"maxScore": "Max",
"minScore": "Min",
"passRate": "Pass Rate",
"passCount": "Pass Count",
"failCount": "Fail Count",
"colSubject": "Subject",
"colClass": "Class",
"colStudentCount": "Students",
"colAvgScore": "Average",
"colMaxScore": "Max",
"colMinScore": "Min",
"colPassRate": "Pass Rate",
"colPassCount": "Pass Count",
"colFailCount": "Fail Count"
},
"reportCard": {
"title": "Report Card",
"titleWithName": "{name}'s Report Card",
"subtitle": "No.: {no} · Class: {className} · Period: {period}",
"notFound": "No report card data found",
"sectionBasic": "Student Info",
"sectionEntries": "Subject Grades",
"sectionSummary": "Summary",
"fieldStudentName": "Name",
"fieldStudentNo": "Student No.",
"fieldClass": "Class",
"fieldPeriod": "Period",
"colSubject": "Subject",
"colSource": "Source",
"colScore": "Score",
"colLevel": "Level",
"colFeedback": "Feedback",
"colGradedAt": "Graded At",
"emptyEntries": "No subject grades",
"totalAvgScore": "Total Average",
"totalRank": "Total Rank",
"totalStudents": "Total Students",
"rankValue": "Rank {rank} / {total}"
},
"error": {
"title": "Grades page error",
"unknown": "Unknown error",
"retry": "Retry"
}
},
"analytics": {
"title": "Analytics"