Files
CICD/src/modules/homework/components/homework-assignment-question-error-overview-card.tsx

92 lines
3.6 KiB
TypeScript

"use client"
import type { HomeworkAssignmentQuestionAnalytics } from "@/modules/homework/types"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { Bar, BarChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts"
export function HomeworkAssignmentQuestionErrorOverviewCard({
questions,
gradedSampleCount,
}: {
questions: HomeworkAssignmentQuestionAnalytics[]
gradedSampleCount: number
}) {
const data = questions.map((q, index) => ({
name: `Q${index + 1}`,
errorRate: q.errorRate * 100,
errorCount: q.errorCount,
total: gradedSampleCount,
}))
return (
<Card className="md:col-span-1">
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium text-muted-foreground">Error Rate Overview</CardTitle>
</CardHeader>
<CardContent className="h-72">
{questions.length === 0 || gradedSampleCount === 0 ? (
<div className="flex h-full items-center justify-center text-sm text-muted-foreground">
No graded submissions yet.
</div>
) : (
<ResponsiveContainer width="100%" height="100%">
<BarChart data={data} margin={{ top: 10, right: 10, left: -20, bottom: 0 }}>
<CartesianGrid strokeDasharray="3 3" vertical={false} />
<XAxis
dataKey="name"
tickLine={false}
axisLine={false}
tick={{ fontSize: 12, fill: "hsl(var(--muted-foreground))" }}
interval={0}
/>
<YAxis
tickLine={false}
axisLine={false}
tick={{ fontSize: 12, fill: "hsl(var(--muted-foreground))" }}
tickFormatter={(value) => `${value}%`}
domain={[0, 100]}
/>
<Tooltip
cursor={{ fill: "hsl(var(--muted)/0.2)" }}
content={({ active, payload }) => {
if (active && payload && payload.length) {
const d = payload[0].payload
return (
<div className="rounded-lg border bg-background p-2 shadow-sm">
<div className="grid grid-cols-2 gap-2">
<div className="flex flex-col">
<span className="text-[0.70rem] uppercase text-muted-foreground">Question</span>
<span className="font-bold text-muted-foreground">{d.name}</span>
</div>
<div className="flex flex-col">
<span className="text-[0.70rem] uppercase text-muted-foreground">Error Rate</span>
<span className="font-bold">{d.errorRate.toFixed(1)}%</span>
</div>
<div className="flex flex-col">
<span className="text-[0.70rem] uppercase text-muted-foreground">Errors</span>
<span className="font-bold">
{d.errorCount} / {d.total}
</span>
</div>
</div>
</div>
)
}
return null
}}
/>
<Bar
dataKey="errorRate"
fill="hsl(var(--primary))"
radius={[4, 4, 0, 0]}
maxBarSize={40}
/>
</BarChart>
</ResponsiveContainer>
)}
</CardContent>
</Card>
)
}