feat(dashboard,diagnostic,elective): add widgets, layout, parent dashboard, role-config, services, elective components

dashboard:

- Add comparison-badge, dashboard-notification-widget, dashboard-responsive-layout, dashboard-time-range-filter

- Add parent-dashboard components directory

- Add config, hooks, and services directories

diagnostic:

- Add role-config and services directory

elective:

- Add elective-course-detail, elective-stats-cards, parent-selection-view components

- Add data-access-settings and data-access-stats
This commit is contained in:
SpecialX
2026-07-03 10:25:46 +08:00
parent dfffb61e94
commit 138b6f1b00
58 changed files with 3313 additions and 695 deletions

View File

@@ -9,40 +9,18 @@ import { EmptyState } from "@/shared/components/ui/empty-state"
import { StatusBadge } from "@/shared/components/ui/status-badge"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/shared/components/ui/table"
import { formatDate, cn } from "@/shared/lib/utils"
import { getActionLabelKey, getActionVariant, getDueUrgency } from "@/modules/dashboard/lib/dashboard-utils"
import type { StudentHomeworkAssignmentListItem } from "@/modules/homework/types"
import {
STUDENT_HOMEWORK_PROGRESS_VARIANT,
STUDENT_HOMEWORK_PROGRESS_LABEL,
} from "@/modules/homework/types"
const getActionLabelKey = (status: string): "action.review" | "action.view" | "action.continue" | "action.start" => {
if (status === "graded") return "action.review"
if (status === "submitted") return "action.view"
if (status === "in_progress") return "action.continue"
return "action.start"
}
const getActionVariant = (status: string): "default" | "secondary" | "outline" => {
if (status === "graded" || status === "submitted") return "outline"
return "default"
}
const getDueUrgency = (dueAt: string | null): "overdue" | "urgent" | "warning" | "normal" | null => {
if (!dueAt) return null
const now = new Date()
const due = new Date(dueAt)
const diffHours = (due.getTime() - now.getTime()) / (1000 * 60 * 60)
if (diffHours < 0) return "overdue"
if (diffHours < 48) return "urgent"
if (diffHours < 120) return "warning"
return "normal"
}
export async function StudentUpcomingAssignmentsCard({ upcomingAssignments }: { upcomingAssignments: StudentHomeworkAssignmentListItem[] }) {
const t = await getTranslations("dashboard")
const locale = await getLocale()
const hasAssignments = upcomingAssignments.length > 0
const now = new Date()
return (
<Card>
@@ -78,7 +56,7 @@ export async function StudentUpcomingAssignmentsCard({ upcomingAssignments }: {
</TableHeader>
<TableBody>
{upcomingAssignments.map((a) => {
const urgency = getDueUrgency(a.dueAt)
const urgency = getDueUrgency(a.dueAt, now)
const isGraded = a.progressStatus === "graded"
return (