File size: 5,100 Bytes
5eefa6a | 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 131 132 | import { useState } from "react";
import { CheckCircle2, ChevronDown, ChevronRight } from "lucide-react";
import type { InterviewResult, QAPair } from "../../../services/interviewApi";
interface Props {
result: InterviewResult;
}
export default function InterviewResultView({ result }: Props) {
const [openSections, setOpenSections] = useState<Set<number>>(new Set([0]));
const toggleSection = (i: number) => {
setOpenSections((prev) => {
const next = new Set(prev);
if (next.has(i)) next.delete(i);
else next.add(i);
return next;
});
};
return (
<div className="mx-4 my-4 rounded-2xl border border-emerald-200 bg-emerald-50/60 overflow-hidden text-sm">
{/* Header */}
<div className="flex items-center gap-2 px-4 py-3 bg-emerald-100/80 border-b border-emerald-200">
<CheckCircle2 className="w-4 h-4 text-emerald-600 flex-shrink-0" />
<span className="font-semibold text-emerald-800">Hasil Interview</span>
</div>
<div className="px-4 py-4 space-y-5">
{/* Summary */}
{result.summary && (
<div>
<p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">Ringkasan</p>
<p className="text-slate-700 leading-relaxed">{result.summary}</p>
</div>
)}
{/* Goals */}
{result.goals?.length > 0 && (
<div>
<p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">Tujuan</p>
<ul className="space-y-1">
{result.goals.map((g, i) => (
<li key={i} className="flex gap-2 text-slate-700">
<span className="text-emerald-500 flex-shrink-0 mt-0.5">•</span>
<span>{g}</span>
</li>
))}
</ul>
</div>
)}
{/* Section Results */}
{result.section_results?.length > 0 && (
<div>
<p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2">Sesi Pertanyaan</p>
<div className="space-y-2">
{result.section_results.map((section, i) => (
<div key={i} className="rounded-xl border border-slate-200 bg-white overflow-hidden">
<button
onClick={() => toggleSection(i)}
className="w-full flex items-center justify-between px-3 py-2.5 text-left hover:bg-slate-50 transition"
>
<span className="font-medium text-slate-700">{section.section_title}</span>
{openSections.has(i) ? (
<ChevronDown className="w-3.5 h-3.5 text-slate-400 flex-shrink-0" />
) : (
<ChevronRight className="w-3.5 h-3.5 text-slate-400 flex-shrink-0" />
)}
</button>
{openSections.has(i) && (
<div className="px-3 pb-3 space-y-3 border-t border-slate-100 pt-2">
{section.section_summary && (
<p className="text-xs text-slate-500 italic">{section.section_summary}</p>
)}
{section.qa_pairs?.map((qa, j) => (
<QAItem key={j} qa={qa} depth={0} />
))}
</div>
)}
</div>
))}
</div>
</div>
)}
{/* Key Insights */}
{result.key_insights?.length > 0 && (
<div>
<p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">Key Insights</p>
<ul className="space-y-1">
{result.key_insights.map((insight, i) => (
<li key={i} className="flex gap-2 text-slate-700">
<span className="text-blue-400 flex-shrink-0 mt-0.5">•</span>
<span>{insight}</span>
</li>
))}
</ul>
</div>
)}
{/* Unresolved Items */}
{result.unresolved_items?.length > 0 && (
<div>
<p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">Belum Terjawab</p>
<ul className="space-y-1">
{result.unresolved_items.map((item, i) => (
<li key={i} className="flex gap-2 text-amber-700">
<span className="text-amber-400 flex-shrink-0 mt-0.5">•</span>
<span>{item}</span>
</li>
))}
</ul>
</div>
)}
</div>
</div>
);
}
function QAItem({ qa, depth }: { qa: QAPair; depth: number }) {
return (
<div className={depth > 0 ? "ml-4 pl-3 border-l-2 border-slate-100" : ""}>
<p className="text-xs text-slate-500 mb-0.5">T: {qa.question_text}</p>
<p className="text-slate-700">J: {qa.answer_cleaned}</p>
{qa.follow_ups?.map((f, i) => (
<QAItem key={i} qa={f} depth={depth + 1} />
))}
</div>
);
}
|