完整性更新

现在已经实现了大部分基础功能
This commit is contained in:
SpecialX
2026-01-08 11:14:03 +08:00
parent 0da2eac0b4
commit 57807def37
155 changed files with 26421 additions and 1036 deletions

View File

@@ -0,0 +1,83 @@
import Link from "next/link"
import { PenTool } from "lucide-react"
import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/shared/components/ui/table"
import { formatDate } from "@/shared/lib/utils"
import type { StudentHomeworkAssignmentListItem } from "@/modules/homework/types"
const getStatusVariant = (status: string): "default" | "secondary" | "outline" => {
if (status === "graded") return "default"
if (status === "submitted") return "secondary"
if (status === "in_progress") return "secondary"
return "outline"
}
const getStatusLabel = (status: string) => {
if (status === "graded") return "Graded"
if (status === "submitted") return "Submitted"
if (status === "in_progress") return "In progress"
return "Not started"
}
export function StudentUpcomingAssignmentsCard({ upcomingAssignments }: { upcomingAssignments: StudentHomeworkAssignmentListItem[] }) {
const hasAssignments = upcomingAssignments.length > 0
return (
<Card className="lg:col-span-4">
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle className="text-base flex items-center gap-2">
<PenTool className="h-4 w-4 text-muted-foreground" />
Upcoming Assignments
</CardTitle>
<Button asChild variant="outline" size="sm">
<Link href="/student/learning/assignments">View all</Link>
</Button>
</CardHeader>
<CardContent>
{!hasAssignments ? (
<EmptyState
icon={PenTool}
title="No assignments"
description="You have no assigned homework right now."
className="border-none h-72"
/>
) : (
<div className="rounded-md border bg-card">
<Table>
<TableHeader>
<TableRow className="bg-muted/50">
<TableHead className="text-xs font-medium uppercase text-muted-foreground">Title</TableHead>
<TableHead className="text-xs font-medium uppercase text-muted-foreground">Status</TableHead>
<TableHead className="text-xs font-medium uppercase text-muted-foreground">Due</TableHead>
<TableHead className="text-xs font-medium uppercase text-muted-foreground">Score</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{upcomingAssignments.map((a) => (
<TableRow key={a.id} className="h-12">
<TableCell className="font-medium">
<Link href={`/student/learning/assignments/${a.id}`} className="truncate hover:underline">
{a.title}
</Link>
</TableCell>
<TableCell>
<Badge variant={getStatusVariant(a.progressStatus)} className="capitalize">
{getStatusLabel(a.progressStatus)}
</Badge>
</TableCell>
<TableCell className="text-muted-foreground">{a.dueAt ? formatDate(a.dueAt) : "-"}</TableCell>
<TableCell className="tabular-nums">{a.latestScore ?? "-"}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
)}
</CardContent>
</Card>
)
}