refactor(modules): update existing module implementations across attendance, audit, auth, classes, course-plans, exams, files, homework, layout, proctoring, questions, scheduling, textbooks, users

- Update attendance components and data-access for record management

- Update audit log views, filters, and data-access

- Update auth login and register forms

- Update classes actions, components, and data-access (admin, schedule, stats)

- Update course-plans actions, form, list, progress, and schema

- Update exams actions, AI pipeline, preview components, and hooks

- Update files components (icon, list, preview, upload) and data-access

- Update homework assignment form, review view, auto-save hook, and stats-service

- Update layout sidebar, header, and navigation config

- Update proctoring actions, anti-cheat monitor, and data-access

- Update questions actions, components (dialog, actions, columns, filters), and data-access

- Update scheduling actions, auto-scheduler, components, and schema

- Update textbooks constants and text-selection hook

- Update users class-registration, import-dialog, data-access, and user-service
This commit is contained in:
SpecialX
2026-06-23 17:38:56 +08:00
parent 1a9377222c
commit 4f0ef217a0
56 changed files with 1251 additions and 850 deletions

View File

@@ -17,6 +17,12 @@ export const CourseSelectionStatusEnum = z.enum([
"rejected",
])
const isValidDateString = (v: string | null | undefined): boolean => {
if (v === null || v === undefined || v === "") return true
const d = new Date(v)
return !Number.isNaN(d.getTime())
}
const emptyToNull = (v: string | undefined | null): string | null =>
v && v.length > 0 ? v : null
@@ -33,10 +39,30 @@ export const CreateElectiveCourseSchema = z
capacity: z.coerce.number().int().min(1).max(500).optional(),
classroom: z.string().trim().optional().nullable(),
schedule: z.string().trim().optional().nullable(),
startDate: z.string().trim().optional().nullable(),
endDate: z.string().trim().optional().nullable(),
selectionStartAt: z.string().trim().optional().nullable(),
selectionEndAt: z.string().trim().optional().nullable(),
startDate: z
.string()
.trim()
.optional()
.nullable()
.refine(isValidDateString, "开始日期格式无效"),
endDate: z
.string()
.trim()
.optional()
.nullable()
.refine(isValidDateString, "结束日期格式无效"),
selectionStartAt: z
.string()
.trim()
.optional()
.nullable()
.refine(isValidDateString, "选课开始时间格式无效"),
selectionEndAt: z
.string()
.trim()
.optional()
.nullable()
.refine(isValidDateString, "选课结束时间格式无效"),
selectionMode: ElectiveSelectionModeEnum.optional(),
credit: z.string().trim().optional().nullable(),
})
@@ -69,10 +95,30 @@ export const UpdateElectiveCourseSchema = z
capacity: z.coerce.number().int().min(1).max(500).optional(),
classroom: z.string().trim().optional().nullable(),
schedule: z.string().trim().optional().nullable(),
startDate: z.string().trim().optional().nullable(),
endDate: z.string().trim().optional().nullable(),
selectionStartAt: z.string().trim().optional().nullable(),
selectionEndAt: z.string().trim().optional().nullable(),
startDate: z
.string()
.trim()
.optional()
.nullable()
.refine(isValidDateString, "开始日期格式无效"),
endDate: z
.string()
.trim()
.optional()
.nullable()
.refine(isValidDateString, "结束日期格式无效"),
selectionStartAt: z
.string()
.trim()
.optional()
.nullable()
.refine(isValidDateString, "选课开始时间格式无效"),
selectionEndAt: z
.string()
.trim()
.optional()
.nullable()
.refine(isValidDateString, "选课结束时间格式无效"),
status: ElectiveCourseStatusEnum.optional(),
selectionMode: ElectiveSelectionModeEnum.optional(),
credit: z.string().trim().optional().nullable(),