refactor(attendance,elective): 审计第二轮 — 全量完成 P0/P1 改进项

P0 修复:
- 页面层 i18n 全量补齐(admin/teacher/parent/student × attendance/elective)
- types.ts 状态标签常量迁移至 constants.ts(i18n key + Badge variant)
- 修复 getTranslations 导入路径(next-intl → next-intl/server)

P1 改进:
- 解耦 parent 模块对 attendance 类型的直接依赖(本地 view-model 类型)
- 导出纯函数(computeStats/buildWarnings/buildLotteryRankCase 等)
- 统一空状态为 EmptyState 组件
- 清理死代码读 Action(attendance 5 个 + elective 3 个)
- 预留监控埋点接口(trackEvent 13 个新事件名)
- 补齐骨架屏 loading.tsx(8 个页面)
- AlertDialog 替换 window.confirm(student-selection-view)
- a11y 改进(aria-label/role/键盘导航)

修复:
- AttendanceStatus 从 constants.ts 重导出,消除 types/constants 双源混乱
- buildWarnings 的 Translator 类型改用 ReturnType<typeof useTranslations>
This commit is contained in:
SpecialX
2026-06-22 17:33:29 +08:00
parent 76966581b8
commit f62b8c0f86
46 changed files with 1748 additions and 545 deletions

View File

@@ -31,7 +31,12 @@
"excused": "Excused",
"attendanceRate": "Attendance Rate",
"lateRate": "Late Rate",
"recentRecords": "Recent Records"
"recentRecords": "Recent Records",
"studentRecords": "Student Records",
"noClasses": "No classes",
"noClassesDescription": "You don't have any classes yet.",
"noData": "No data",
"noDataDescription": "No attendance data available for this class."
},
"filters": {
"class": "Class",
@@ -66,7 +71,10 @@
"selectClass": "Select Class",
"selectDate": "Select Date",
"noStudents": "No students in this class",
"description": "Select a class and date, then mark attendance for each student.",
"confirmDelete": "Are you sure you want to delete this attendance record?",
"confirmClassSwitch": "Switching class will discard unsaved changes. Continue?",
"confirmClassSwitchAction": "Switch Class",
"saved": "Attendance saved",
"updated": "Attendance updated",
"deleted": "Attendance record deleted"
@@ -86,10 +94,34 @@
"parent": {
"warningTitle": "Attendance Warnings",
"rateCardTitle": "Attendance Rate Summary",
"calendarTitle": "Attendance Calendar",
"calendarTitle": "Attendance calendar for {name}",
"calendarFor": "{name}'s Calendar",
"prevMonth": "Previous month",
"nextMonth": "Next month",
"noWarnings": "No attendance warnings",
"absentWarning": "{count} absence(s)",
"absentHighSeverity": "{count} absences recorded. Consider contacting the homeroom teacher.",
"lateWarning": "{count} late arrival(s)",
"lowRateWarning": "Attendance rate {rate}% below threshold"
"lowRateWarning": "Attendance rate {rate}% below threshold",
"contactHomeroom": "Consider contacting the homeroom teacher for details.",
"rateExcellent": "Excellent",
"rateNeedsAttention": "Needs attention",
"rateBelowStandard": "Below standard",
"children": "Children",
"linked": "linked",
"thisPeriod": "this period",
"noChildrenTitle": "No children linked",
"noChildrenDescription": "Your account is not linked to any student accounts yet. Please contact the school administrator.",
"compareDescription": "Compare attendance across all your children. For single-child details, open the child's detail page.",
"noRecordsDescription": "Your children don't have any attendance records yet.",
"weekday": {
"sun": "Sun",
"mon": "Mon",
"tue": "Tue",
"wed": "Wed",
"thu": "Thu",
"fri": "Fri",
"sat": "Sat"
}
}
}

View File

@@ -8,6 +8,8 @@
},
"description": {
"adminList": "Manage elective courses, open/close selection and lottery.",
"create": "Create a new elective course.",
"edit": "Update elective course details.",
"teacher": "View and manage the elective courses you teach.",
"student": "Browse available courses and make selections."
},
@@ -21,6 +23,9 @@
"fcfs": "First Come First Served",
"lottery": "Lottery"
},
"filters": {
"allStatuses": "All Modes"
},
"selectionStatus": {
"selected": "Selected",
"enrolled": "Enrolled",

View File

@@ -31,7 +31,12 @@
"excused": "请假",
"attendanceRate": "出勤率",
"lateRate": "迟到率",
"recentRecords": "最近记录"
"recentRecords": "最近记录",
"studentRecords": "学生记录",
"noClasses": "暂无班级",
"noClassesDescription": "您目前没有任何班级。",
"noData": "暂无数据",
"noDataDescription": "该班级暂无考勤数据。"
},
"filters": {
"class": "班级",
@@ -66,7 +71,10 @@
"selectClass": "选择班级",
"selectDate": "选择日期",
"noStudents": "该班级暂无学生",
"description": "选择班级和日期,然后为每位学生标记考勤。",
"confirmDelete": "确定删除此条考勤记录吗?",
"confirmClassSwitch": "切换班级将丢弃未保存的修改,是否继续?",
"confirmClassSwitchAction": "切换班级",
"saved": "考勤已保存",
"updated": "考勤已更新",
"deleted": "考勤记录已删除"
@@ -86,10 +94,34 @@
"parent": {
"warningTitle": "考勤异常预警",
"rateCardTitle": "出勤率汇总",
"calendarTitle": "考勤月历",
"calendarTitle": "{name} 的考勤月历",
"calendarFor": "{name} 的月历",
"prevMonth": "上个月",
"nextMonth": "下个月",
"noWarnings": "暂无考勤异常",
"absentWarning": "{count} 次缺勤",
"absentHighSeverity": "已记录 {count} 次缺勤,建议联系班主任了解情况。",
"lateWarning": "{count} 次迟到",
"lowRateWarning": "出勤率 {rate}% 低于阈值"
"lowRateWarning": "出勤率 {rate}% 低于阈值",
"contactHomeroom": "如需了解详情,请联系班主任。",
"rateExcellent": "优秀",
"rateNeedsAttention": "需要关注",
"rateBelowStandard": "未达标",
"children": "子女",
"linked": "已关联",
"thisPeriod": "本周期",
"noChildrenTitle": "尚未关联子女",
"noChildrenDescription": "您的账号尚未关联任何学生账号,请联系学校管理员。",
"compareDescription": "对比所有子女的考勤情况。如需查看单个子女详情,请进入子女详情页。",
"noRecordsDescription": "您的子女暂无任何考勤记录。",
"weekday": {
"sun": "周日",
"mon": "周一",
"tue": "周二",
"wed": "周三",
"thu": "周四",
"fri": "周五",
"sat": "周六"
}
}
}

View File

@@ -8,6 +8,8 @@
},
"description": {
"adminList": "管理选修课程、开放/关闭选课与抽签。",
"create": "创建新的选修课程。",
"edit": "更新选修课程详情。",
"teacher": "查看和管理您教授的选修课程。",
"student": "浏览可选课程并进行选课。"
},
@@ -21,6 +23,9 @@
"fcfs": "先到先得",
"lottery": "抽签"
},
"filters": {
"allStatuses": "全部模式"
},
"selectionStatus": {
"selected": "已选",
"enrolled": "已录取",