import type { JSX } from "react" import Link from "next/link" import { EmptyState } from "@/shared/components/ui/empty-state" import { Badge } from "@/shared/components/ui/badge" import { Button } from "@/shared/components/ui/button" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/shared/components/ui/table" import { Progress } from "@/shared/components/ui/progress" import { ListPagination, computePagination, paginate } from "@/shared/components/ui/list-pagination" import { formatDate, formatNumber } from "@/shared/lib/utils" import { getParam, type SearchParams } from "@/shared/lib/search-params" import { getHomeworkAssignments } from "@/modules/homework/data-access" import { getTeacherClasses } from "@/modules/classes/data-access" import { PenTool, PlusCircle, AlertCircle } from "lucide-react" import { getTeacherIdForMutations } from "@/modules/classes/data-access" import { getTranslations } from "next-intl/server" export const dynamic = "force-dynamic" const PAGE_SIZE = 10 export default async function AssignmentsPage({ searchParams }: { searchParams: Promise }): Promise { const t = await getTranslations("examHomework") const sp = await searchParams const rawClassId = getParam(sp, "classId") const creatorId = await getTeacherIdForMutations() // Only fetch classes list when a class filter is active — needed to resolve // the class name for display. When no filter is applied, skip the query to // avoid an unnecessary DB round-trip. const filteredClassId = rawClassId && rawClassId !== "all" ? rawClassId : null const [assignments, classes] = await Promise.all([ getHomeworkAssignments({ creatorId, classId: filteredClassId ?? undefined }), filteredClassId ? getTeacherClasses() : Promise.resolve([]), ]) const hasAssignments = assignments.length > 0 const className = filteredClassId ? classes.find((c) => c.id === filteredClassId)?.name : undefined // 分页计算 const { page } = computePagination(sp, PAGE_SIZE) const total = assignments.length const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE)) const currentPage = Math.min(page, totalPages) const pagedAssignments = paginate(assignments, currentPage, PAGE_SIZE) return (

{t("homework.list.title")}

{filteredClassId ? t("homework.list.filterByClass", { className: className ?? filteredClassId }) : t("homework.list.description")}

{filteredClassId ? ( ) : null}
{!hasAssignments ? ( ) : (
{t("homework.list.columns.title")} {t("homework.list.columns.status")} {t("homework.list.columns.dueAt")} {t("homework.list.columns.submissionRate")} {t("homework.list.columns.averageScore")} {t("homework.list.columns.overdue")} {t("homework.list.columns.sourceExam")} {t("homework.list.columns.createdAt")} {pagedAssignments.map((a) => { const submissionRate = a.targetCount > 0 ? (a.submittedCount / a.targetCount) * 100 : 0 const hasOverdue = a.overdueCount > 0 return ( {a.title} {t(`homework.status.${a.status}`)} {a.dueAt ? formatDate(a.dueAt) : "-"}
{a.submittedCount}/{a.targetCount}
{a.averageScore !== null ? formatNumber(a.averageScore, 1) : "-"} {hasOverdue ? ( ) : ( 0 )} {a.sourceExamTitle} {formatDate(a.createdAt)}
) })}
)}
) }