feat(dashboard): optimize teacher dashboard ui and layout
- Refactor layout: move Needs Grading to main column, Homework to sidebar - Enhance TeacherStats: replace static counts with actionable metrics (Needs Grading, Active Assignments, Avg Score, Submission Rate) - Update RecentSubmissions: table view with quick grade actions and late status - Update TeacherSchedule: vertical timeline view with scroll hints - Update TeacherHomeworkCard: compact list view - Integrate Recharts: add TeacherGradeTrends chart and shared chart component - Update documentation
This commit is contained in:
@@ -1,20 +1,22 @@
|
||||
import Link from "next/link";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card";
|
||||
import { Users, BookOpen, FileCheck, Calendar } from "lucide-react";
|
||||
import { FileCheck, PenTool, TrendingUp, BarChart } from "lucide-react";
|
||||
import { Skeleton } from "@/shared/components/ui/skeleton";
|
||||
import { cn } from "@/shared/lib/utils";
|
||||
|
||||
interface TeacherStatsProps {
|
||||
totalStudents: number;
|
||||
classCount: number;
|
||||
toGradeCount: number;
|
||||
todayScheduleCount: number;
|
||||
activeAssignmentsCount: number;
|
||||
averageScore: number;
|
||||
submissionRate: number;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
export function TeacherStats({
|
||||
totalStudents,
|
||||
classCount,
|
||||
toGradeCount,
|
||||
todayScheduleCount,
|
||||
activeAssignmentsCount,
|
||||
averageScore,
|
||||
submissionRate,
|
||||
isLoading = false,
|
||||
}: TeacherStatsProps) {
|
||||
if (isLoading) {
|
||||
@@ -38,48 +40,59 @@ export function TeacherStats({
|
||||
|
||||
const stats = [
|
||||
{
|
||||
title: "Total Students",
|
||||
value: String(totalStudents),
|
||||
description: "Across all your classes",
|
||||
icon: Users,
|
||||
},
|
||||
{
|
||||
title: "My Classes",
|
||||
value: String(classCount),
|
||||
description: "Active classes you manage",
|
||||
icon: BookOpen,
|
||||
},
|
||||
{
|
||||
title: "To Grade",
|
||||
title: "Needs Grading",
|
||||
value: String(toGradeCount),
|
||||
description: "Submitted homework waiting for grading",
|
||||
description: "Submissions pending review",
|
||||
icon: FileCheck,
|
||||
href: "/teacher/homework/submissions?status=submitted",
|
||||
highlight: toGradeCount > 0,
|
||||
color: "text-amber-500",
|
||||
},
|
||||
{
|
||||
title: "Today",
|
||||
value: String(todayScheduleCount),
|
||||
description: "Scheduled items today",
|
||||
icon: Calendar,
|
||||
title: "Active Assignments",
|
||||
value: String(activeAssignmentsCount),
|
||||
description: "Published and ongoing",
|
||||
icon: PenTool,
|
||||
href: "/teacher/homework/assignments?status=published",
|
||||
color: "text-blue-500",
|
||||
},
|
||||
{
|
||||
title: "Average Score",
|
||||
value: `${Math.round(averageScore)}%`,
|
||||
description: "Across recent assignments",
|
||||
icon: TrendingUp,
|
||||
href: "#grade-trends",
|
||||
color: "text-emerald-500",
|
||||
},
|
||||
{
|
||||
title: "Submission Rate",
|
||||
value: `${Math.round(submissionRate)}%`,
|
||||
description: "Overall completion rate",
|
||||
icon: BarChart,
|
||||
href: "#grade-trends",
|
||||
color: "text-purple-500",
|
||||
},
|
||||
] as const;
|
||||
|
||||
return (
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||
{stats.map((stat, i) => (
|
||||
<Card key={i}>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">
|
||||
{stat.title}
|
||||
</CardTitle>
|
||||
<stat.icon className="h-4 w-4 text-muted-foreground" />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{stat.value}</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{stat.description}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Link key={i} href={stat.href} className="block transition-transform hover:-translate-y-1">
|
||||
<Card className={cn(stat.highlight && "border-amber-200 bg-amber-50/50 dark:border-amber-900 dark:bg-amber-950/20")}>
|
||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<CardTitle className="text-sm font-medium">
|
||||
{stat.title}
|
||||
</CardTitle>
|
||||
<stat.icon className={cn("h-4 w-4", stat.color)} />
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{stat.value}</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{stat.description}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user