cpns / apps /web /src /components /analytics /WeaknessPanel.tsx
pramudya-yb
Rename project from Labas to Pram
2b62b0c
Raw
History Blame Contribute Delete
4.28 kB
import { Card, CardContent, CardHeader, CardTitle } from "@pram/ui/components/card";
import { MaterialIcon } from "@/components/ui/MaterialIcon";
import { formatLabel } from "@/lib/format";
interface Weakness {
type: "format" | "section" | "skill";
name: string;
totalQuestions: number;
accuracyPct: number;
}
interface WeaknessPanelProps {
weaknesses: Weakness[] | undefined;
recommendations: string[] | undefined;
}
function getTypeIcon(type: Weakness["type"]) {
switch (type) {
case "format":
return "quiz";
case "section":
return "folder";
case "skill":
return "psychology";
}
}
function getTypeLabel(type: Weakness["type"]) {
switch (type) {
case "format":
return "Format";
case "section":
return "Section";
case "skill":
return "Skill";
}
}
function getSeverityColor(pct: number) {
if (pct < 40) return "text-[var(--pomegranate-600)]";
if (pct < 60) return "text-[var(--lemon-700)]";
return "text-[var(--matcha-600)]";
}
export function WeaknessPanel({ weaknesses, recommendations }: WeaknessPanelProps) {
const hasData = weaknesses && weaknesses.length > 0;
return (
<Card className="clay-shadow bg-[var(--pure-white)] border-2 border-[var(--oat-border)] rounded-[var(--radius-xl)]">
<CardHeader>
<CardTitle className="text-lg font-headline font-bold text-[var(--clay-black)] flex items-center gap-2">
<MaterialIcon name="analytics" className="text-[var(--pomegranate-600)]" />
Area untuk Ditingkatkan
</CardTitle>
</CardHeader>
<CardContent className="space-y-6">
{hasData ? (
<>
<div className="space-y-3">
{weaknesses.map((w, _i) => (
<div
key={`${w.type}-${w.name}`}
className="flex items-center gap-4 p-3 rounded-[var(--radius-md)] bg-[var(--warm-cream)] border-2 border-[var(--oat-border)]"
>
<div className="flex items-center justify-center w-10 h-10 rounded-[var(--radius-lg)] bg-[var(--oat-light)] shrink-0">
<MaterialIcon name={getTypeIcon(w.type)} className="text-[var(--warm-charcoal)]" />
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
<span className="text-xs font-medium text-[var(--warm-silver)] uppercase tracking-wide">
{getTypeLabel(w.type)}
</span>
</div>
<div className="text-sm font-semibold text-[var(--clay-black)] truncate">
{formatLabel(w.name)}
</div>
</div>
<div className="text-right shrink-0">
<div className={`text-xl font-headline font-extrabold ${getSeverityColor(w.accuracyPct)}`}>
{w.accuracyPct}%
</div>
<div className="text-xs text-[var(--warm-silver)]">{w.totalQuestions} soal</div>
</div>
</div>
))}
</div>
{recommendations && recommendations.length > 0 && (
<div className="space-y-2">
<h4 className="text-sm font-semibold text-[var(--clay-black)]">Rekomendasi</h4>
<ul className="space-y-2">
{recommendations.map((rec, i) => (
<li key={i} className="flex items-start gap-2 text-sm text-[var(--warm-charcoal)]">
<MaterialIcon name="lightbulb" className="text-[var(--lemon-700)] shrink-0 mt-0.5" />
<span>{rec}</span>
</li>
))}
</ul>
</div>
)}
</>
) : (
<div className="text-center py-8 text-[var(--warm-charcoal)]">
<MaterialIcon name="insights" className="text-5xl text-[var(--warm-silver)] mx-auto mb-3" />
<p className="font-semibold">Belum cukup data</p>
<p className="text-sm mt-1">Selesaikan lebih banyak latihan untuk melihat analisis kelemahan.</p>
</div>
)}
</CardContent>
</Card>
);
}