79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
type BarOption = {
|
|
optionId: string;
|
|
text: string;
|
|
count: number;
|
|
percent: number;
|
|
isCorrect?: boolean;
|
|
};
|
|
|
|
export function PresentStatsBars({
|
|
kind,
|
|
options,
|
|
answeredCount,
|
|
percentAnswered,
|
|
totalResponses,
|
|
revealCorrect,
|
|
}: {
|
|
kind: string;
|
|
options: BarOption[];
|
|
answeredCount?: number;
|
|
percentAnswered?: number;
|
|
totalResponses: number;
|
|
revealCorrect?: boolean;
|
|
}) {
|
|
if (kind === "text") {
|
|
return (
|
|
<div className="rounded-xl border border-[#e5e5ea] bg-[#f9f9fb] p-6 text-center">
|
|
<p className="text-4xl font-bold tabular-nums text-[#24282f]">{answeredCount ?? 0}</p>
|
|
<p className="mt-2 text-sm text-[rgba(36,40,47,0.65)]">
|
|
of {totalResponses} responded ({percentAnswered ?? 0}%)
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (options.length === 0) {
|
|
return <p className="text-center text-sm text-[rgba(36,40,47,0.55)]">No options for this question.</p>;
|
|
}
|
|
|
|
return (
|
|
<div className="flex flex-col gap-3">
|
|
{options.map((opt) => {
|
|
const highlighted = revealCorrect && opt.isCorrect === true;
|
|
const barColor = highlighted ? "bg-emerald-500" : "bg-[#1e72ef]";
|
|
const borderColor = highlighted ? "border-emerald-400 ring-2 ring-emerald-200" : "border-[#e5e5ea]";
|
|
|
|
return (
|
|
<div key={opt.optionId} className={`rounded-lg border bg-white p-4 shadow-sm ${borderColor}`}>
|
|
<div className="mb-2 flex flex-wrap items-center justify-between gap-2">
|
|
<span className="min-w-0 flex-1 text-base font-medium leading-snug text-[#24282f]">
|
|
{opt.text || "—"}
|
|
{highlighted ? (
|
|
<span className="ml-2 inline-flex rounded-full bg-emerald-100 px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-emerald-800">
|
|
Correct answer
|
|
</span>
|
|
) : null}
|
|
</span>
|
|
<div className="flex shrink-0 items-center gap-2">
|
|
<span className="text-sm font-semibold tabular-nums text-[#1e72ef]">{opt.percent}%</span>
|
|
<div className="flex items-center gap-1.5 rounded-full bg-[#f2f2f7] px-2.5 py-0.5">
|
|
<span className="text-base font-bold tabular-nums leading-none text-[#24282f]">{opt.count}</span>
|
|
<span className="text-[10px] font-semibold uppercase tracking-wide text-[rgba(36,40,47,0.55)]">
|
|
{opt.count === 1 ? "response" : "responses"}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="h-3 overflow-hidden rounded-full bg-[#e5e5ea]">
|
|
<div
|
|
className={`h-full rounded-full transition-[width] duration-500 ease-out ${barColor}`}
|
|
style={{ width: `${Math.min(100, Math.max(opt.count > 0 ? 2 : 0, opt.percent))}%` }}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
}
|