import { MaterialIcon } from "@/components/ui/MaterialIcon";
import { MCQ_FORMATS } from "@/lib/question-formats";
interface McqOptionItem {
key: string;
text: string;
}
interface MatchingOptionItem {
left: string;
right?: string;
}
interface OptionDisplayProps {
format: string;
options: unknown;
correctAnswer: string;
userAnswer: string;
}
export function OptionDisplay({ format, options, correctAnswer, userAnswer }: OptionDisplayProps) {
if (!Array.isArray(options) || options.length === 0) return null;
if (format === "matching_pairs") {
return ;
}
if (format === "true_false_not_given") {
return ;
}
if (format === "author_view") {
return ;
}
if ((MCQ_FORMATS as readonly string[]).includes(format)) {
return ;
}
return null;
}
function McqOptions({ options, correctAnswer, userAnswer }: { options: { key: string; text: string }[]; correctAnswer: string; userAnswer: string }) {
const normUser = userAnswer?.trim().toUpperCase() || "";
const normCorrect = correctAnswer?.trim().toUpperCase() || "";
const hasAnswer = !!userAnswer && userAnswer !== "Tidak dijawab";
return (
{options.map((opt) => {
const key = opt.key.trim().toUpperCase();
const isCorrectOption = key === normCorrect;
const isChosen = key === normUser && hasAnswer;
const isWrongChoice = isChosen && !isCorrectOption;
let bg = "bg-[var(--oat-light)]";
let keyBg = "bg-[var(--oat-light)] text-[var(--clay-black)]";
let border = "border-[var(--oat-border)]";
let icon = null;
if (isWrongChoice) {
bg = "bg-[var(--pomegranate-100)]";
keyBg = "bg-[var(--pomegranate-400)] text-[var(--pure-white)]";
border = "border-[var(--pomegranate-400)]";
icon =
;
} else if (isCorrectOption) {
bg = "bg-[var(--matcha-300)]/20";
keyBg = "bg-[var(--matcha-600)] text-[var(--pure-white)]";
border = "border-[var(--matcha-400)]";
icon =
;
}
return (
{key || "?"}
{opt.text}
{icon}
);
})}
);
}
function TriStateOptions({ choices, labels, correctAnswer, userAnswer }: { choices: string[]; labels: Record; correctAnswer: string; userAnswer: string }) {
const normUser = userAnswer?.trim().toUpperCase().replace(/\s+/g, "_") || "";
const normCorrect = correctAnswer?.trim().toUpperCase() || "";
const hasAnswer = !!userAnswer && userAnswer !== "Tidak dijawab";
return (
{choices.map((c) => {
const isCorrectOption = c === normCorrect;
const isChosen = c === normUser && hasAnswer;
const isWrongChoice = isChosen && !isCorrectOption;
let bg = "bg-[var(--oat-light)]";
let dot = "border-[var(--oat-border)]";
let textColor = "text-[var(--warm-charcoal)]";
if (isWrongChoice) {
bg = "bg-[var(--pomegranate-100)]";
dot = "border-[var(--pomegranate-400)] bg-[var(--pomegranate-400)]";
textColor = "text-[var(--pomegranate-600)]";
} else if (isCorrectOption) {
bg = "bg-[var(--matcha-300)]/20";
dot = "border-[var(--matcha-600)] bg-[var(--matcha-600)]";
textColor = "text-[var(--matcha-800)]";
}
return (
{isChosen || isCorrectOption ? : null}
{labels[c]}
);
})}
);
}
function MatchingPairsOptions({ options, correctAnswer, userAnswer }: { options: MatchingOptionItem[]; correctAnswer: string; userAnswer: string }) {
const parseMapping = (s: string): Map => {
const map = new Map();
if (!s) return map;
s.split(",").forEach((pair) => {
const [k, v] = pair.split(":").map((x) => x.trim());
if (k && v) map.set(k, v);
});
return map;
};
const correctMap = parseMapping(correctAnswer);
const userMap = parseMapping(userAnswer);
return (
{options.map((opt) => {
const matchedCorrect = correctMap.get(opt.left) || "";
const matchedUser = userMap.get(opt.left) || "";
const isMatchCorrect = matchedUser === matchedCorrect;
const hasUserAnswer = !!matchedUser;
return (
{opt.left.charAt(0).toUpperCase()}
{opt.left}
→
{hasUserAnswer && (
{matchedUser}
)}
{!isMatchCorrect && matchedCorrect && (
{matchedCorrect}
)}
);
})}
);
}