File size: 4,690 Bytes
65d68f5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | "use client";
import { ClipboardCheck } from "lucide-react";
import type { BrainAnswerCorrectionOutput } from "@/lib/api/types";
import type { StudyCardMeta } from "./types";
export function AnswerCorrectionCard({
data,
topic,
meta,
}: {
data: BrainAnswerCorrectionOutput;
topic: string;
meta?: StudyCardMeta;
}) {
const isSourceMismatch = data.source_truth.toLowerCase().includes("not found");
return (
<article className="animate-msg-assistant w-full rounded-xl border border-white/[0.06] bg-[#080809] p-5">
<div className="mb-3 flex items-center gap-2.5">
<ClipboardCheck className="size-4 shrink-0 text-emerald-400/70" />
<div>
<span className="text-[10px] font-medium uppercase tracking-[0.08em] text-white/22">Answer Correction</span>
<p className="text-[15px] font-semibold tracking-[-0.01em] text-white/95">{topic}</p>
</div>
</div>
{/* Score + rubric */}
<div className="mb-4 rounded-lg border border-white/[0.06] bg-white/[0.02] px-3 py-2.5">
<p className="text-[13px] font-semibold text-white/80">{data.score}</p>
<p className="mt-0.5 text-[11px] text-white/35">{data.mark_scheme_assumption}</p>
</div>
{/* What you wrote correctly */}
{data.what_correct.length > 0 && (
<Section title="What you wrote correctly" items={data.what_correct} variant="default" />
)}
{/* Marks lost */}
<Section
title="Marks lost"
items={data.marks_lost}
variant={isSourceMismatch ? "caution" : "default"}
/>
{/* Missing keywords */}
{data.missing_keywords.length > 0 && (
<Section title="Missing keywords" items={data.missing_keywords} variant="keywords" />
)}
{/* Corrected board-answer version */}
<div className="mt-3">
<p className="mb-1.5 text-[10px] font-medium uppercase tracking-[0.08em] text-white/22">Corrected board-answer version</p>
<div className="rounded-lg border border-emerald-500/10 bg-emerald-500/[0.03] px-3 py-2.5">
<p className="text-[13px] leading-[1.7] text-white/75 whitespace-pre-wrap">{data.corrected_board_answer}</p>
</div>
</div>
{/* How to improve */}
{data.how_to_improve.length > 0 && (
<Section title="How to improve next time" items={data.how_to_improve} variant="action" />
)}
{/* Quick retry task */}
{data.quick_retry_task && (
<div className="mt-3 rounded-lg border border-white/[0.1] bg-white/[0.04] px-3 py-2.5">
<p className="mb-1 text-[10px] font-medium uppercase tracking-[0.08em] text-white/45">Quick retry task</p>
<p className="text-[13px] leading-[1.6] text-white/70">{data.quick_retry_task}</p>
</div>
)}
{/* Source truth */}
<p className="mt-3 text-[11px] text-white/30">{data.source_truth}</p>
{/* Source evidence */}
{data.source_evidence.length > 0 && (
<div className="mt-2 rounded-lg border border-white/[0.04] bg-white/[0.01] px-3 py-2">
<p className="mb-1 text-[10px] font-medium uppercase tracking-[0.08em] text-white/20">Source evidence</p>
{data.source_evidence.map((evidence, i) => (
<p key={i} className="text-[11px] leading-[1.5] text-white/35">{evidence}</p>
))}
</div>
)}
{meta?.evidenceLabel ? (
<p className="mt-2 text-[10px] text-white/25">{meta.evidenceLabel}</p>
) : null}
</article>
);
}
function Section({
title,
items,
variant = "default",
}: {
title: string;
items: string[];
variant?: "default" | "caution" | "action" | "keywords";
}) {
const variantStyles = {
default: "border-white/[0.06] bg-white/[0.02]",
caution: "border-amber-500/10 bg-amber-500/[0.03]",
action: "border-white/[0.1] bg-white/[0.04]",
keywords: "border-blue-500/10 bg-blue-500/[0.03]",
};
const dotStyles = {
default: "bg-white/30",
caution: "bg-amber-400/50",
action: "bg-white/45",
keywords: "bg-blue-400/50",
};
return (
<div className="mt-3">
<p className="mb-1.5 text-[10px] font-medium uppercase tracking-[0.08em] text-white/22">{title}</p>
<div className={`rounded-lg border px-3 py-2.5 ${variantStyles[variant]}`}>
<ul className="space-y-1.5">
{items.map((item, i) => (
<li key={i} className="flex items-start gap-2">
<span className={`mt-1.5 size-1.5 shrink-0 rounded-full ${dotStyles[variant]}`} />
<span className="text-[13px] leading-[1.6] text-white/70">{item}</span>
</li>
))}
</ul>
</div>
</div>
);
}
|