import { useEffect, useRef, useState } from "react"; import { api, type Structure, type QuizCard } from "../lib/api.js"; import { useSystemStructures } from "../hooks/useSystemStructures.js"; import { Scene } from "../components/viewer/Scene.js"; import { LayerToggle } from "../components/LayerToggle.js"; import { useAtlasStore } from "../store/useAtlasStore.js"; type Deck = (Structure & { quizCard: QuizCard | null })[]; export default function QuizPage() { const visibleSystems = useAtlasStore((s) => s.visibleSystems); const { bySlug } = useSystemStructures(visibleSystems); const [deck, setDeck] = useState([]); const [index, setIndex] = useState(0); const [feedback, setFeedback] = useState<"correct" | "wrong" | null>(null); const [score, setScore] = useState({ correct: 0, total: 0 }); const [layersOpen, setLayersOpen] = useState(false); const selectedStructureId = useAtlasStore((s) => s.selectedStructureId); const selectStructure = useAtlasStore((s) => s.selectStructure); const setVisibleSystems = useAtlasStore((s) => s.setVisibleSystems); const focusOnStructure = useAtlasStore((s) => s.focusOnStructure); async function loadDeck() { const next = await api.quizNext({ limit: 10 }); setDeck(next); setIndex(0); setScore({ correct: 0, total: 0 }); selectStructure(null); if (next.length > 0) { setVisibleSystems([...new Set(next.map((s) => s.system.slug))]); } } useEffect(() => { loadDeck(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const current = deck[index]; const ignoreNextSelectRef = useRef(false); useEffect(() => { if (!current || !selectedStructureId || feedback) return; if (ignoreNextSelectRef.current) { ignoreNextSelectRef.current = false; return; } const isCorrect = selectedStructureId === current.id; setFeedback(isCorrect ? "correct" : "wrong"); setScore((s) => ({ correct: s.correct + (isCorrect ? 1 : 0), total: s.total + 1 })); api.quizReview(current.id, isCorrect ? 5 : 2).catch(console.error); // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedStructureId]); function next() { selectStructure(null); setFeedback(null); if (index + 1 < deck.length) setIndex(index + 1); else loadDeck(); } function giveUp() { if (!current) return; setFeedback("wrong"); setScore((s) => ({ ...s, total: s.total + 1 })); api.quizReview(current.id, 2).catch(console.error); ignoreNextSelectRef.current = true; focusOnStructure(current.slug); selectStructure(current.id); } return (
{layersOpen && (
setLayersOpen(false)} /> )}
{!current ? (

Nenhuma estrutura pendente de revisão agora. 🎉

) : ( <>

Onde fica esta estrutura?

{current.namePt}

{current.system.namePt}

{feedback === "correct" && (

Correto! ✅

)} {feedback === "wrong" && (

Não foi essa estrutura.

)}
{feedback ? ( ) : ( )}

{index + 1} / {deck.length} · acertos: {score.correct}/{score.total}

)}
); }