"use client"; /** * /quizzes — every published quiz, with where you are in each. * * Reached from the Quizzes card on the search page. Quizzes are deliberately * not in search results: they're something to do, not something to look up. * Signed in only: visitors get the sign-in modal, and home if they dismiss it. */ import { useEffect, useMemo, useState } from "react"; import Link from "next/link"; import { ClipboardCheck } from "lucide-react"; import { useSignedInPage } from "@/components/auth/use-signed-in-page"; import { quiz, quizActionLabel, type QuizCard } from "@/lib/quiz"; import { cn } from "@/lib/utils"; const KIND: Record = { chapter: "Book chapter", lecture: "Lecture", conversation: "Conversation", standalone: "Quiz", }; type Filter = "all" | "todo" | "done"; export function QuizzesList() { const { user } = useSignedInPage(); const userId = user?.id; const [list, setList] = useState(null); const [filter, setFilter] = useState("all"); useEffect(() => { if (!userId) return; let cancelled = false; quiz .list() .then((l) => !cancelled && setList(l)) .catch(() => !cancelled && setList([])); return () => { cancelled = true; }; }, [userId]); const shown = useMemo( () => (list ?? []).filter((q) => filter === "all" ? true : filter === "done" ? q.my.state === "completed" : q.my.state !== "completed", ), [list, filter], ); return (

Quizzes

Test what you've read and heard. Each quiz can be taken once, and only you can see your results.

{user && ( // Phones: three equal, thumb-sized tabs across the width. From sm up // they shrink back to compact pills.
{( [ ["all", "All"], ["todo", "To do"], ["done", "Finished"], ] as const ).map(([k, label]) => ( ))}
)} {!user ? null : list === null ? (

Loading…

) : shown.length === 0 ? (

{list.length === 0 ? "No quizzes yet — check back soon." : "Nothing here."}

) : ( // minmax(0,1fr) + min-w-0: grid items otherwise refuse to shrink // below their content, so one long word pushes a card off-screen.
    {shown.map((q) => { const done = q.my.state === "completed"; return (
  • {KIND[q.target_kind]}

    {q.title}

    {q.target_title && (

    {q.target_title}

    )}
    {q.question_count}{" "} {q.question_count === 1 ? "question" : "questions"} {quizActionLabel(q.my.state)} {done && q.my.score !== undefined && ` · ${q.my.score}/${q.my.total}`}
  • ); })}
)}
); }