| 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> |
| ); |
| } |
|
|