75 lines
1.9 KiB
TypeScript
75 lines
1.9 KiB
TypeScript
import type { QuizSections } from "@/lib/quiz-groups";
|
|
import { QuizGrid } from "./quiz-grid";
|
|
|
|
/**
|
|
* The "All" tab: Books → book, Lectures & Conversations → year, then the
|
|
* stand-alone quizzes. groupQuizzes only returns non-empty groups, and each
|
|
* section here renders only when it has groups, so nothing empty shows.
|
|
*/
|
|
export function GroupedQuizzes({ sections }: { sections: QuizSections }) {
|
|
return (
|
|
<div className="space-y-10">
|
|
{sections.books.length > 0 && (
|
|
<Section title="Books">
|
|
{sections.books.map((g) => (
|
|
<Group key={g.key} label={g.label} count={g.quizzes.length}>
|
|
<QuizGrid quizzes={g.quizzes} />
|
|
</Group>
|
|
))}
|
|
</Section>
|
|
)}
|
|
{sections.lectures.length > 0 && (
|
|
<Section title="Lectures & Conversations">
|
|
{sections.lectures.map((g) => (
|
|
<Group key={g.key} label={g.label} count={g.quizzes.length}>
|
|
<QuizGrid quizzes={g.quizzes} />
|
|
</Group>
|
|
))}
|
|
</Section>
|
|
)}
|
|
{sections.other.length > 0 && (
|
|
<Section title="Other quizzes">
|
|
<QuizGrid quizzes={sections.other} />
|
|
</Section>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Section({
|
|
title,
|
|
children,
|
|
}: {
|
|
title: string;
|
|
children: React.ReactNode;
|
|
}) {
|
|
return (
|
|
<section className="space-y-5">
|
|
<h2 className="font-[family-name:var(--font-title)] text-lg font-semibold text-foreground sm:text-xl">
|
|
{title}
|
|
</h2>
|
|
{children}
|
|
</section>
|
|
);
|
|
}
|
|
|
|
function Group({
|
|
label,
|
|
count,
|
|
children,
|
|
}: {
|
|
label: string;
|
|
count: number;
|
|
children: React.ReactNode;
|
|
}) {
|
|
return (
|
|
<div className="space-y-2.5">
|
|
<h3 className="flex min-w-0 items-baseline gap-2 text-sm font-medium text-muted-foreground">
|
|
<span className="min-w-0 truncate">{label}</span>
|
|
<span className="shrink-0 text-xs tabular-nums">{count}</span>
|
|
</h3>
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|