"use client"; import Link from "next/link"; import { motion } from "framer-motion"; import type { Activity, Deck } from "@/lib/schemas"; import { downloadDeck } from "@/lib/storage"; import { cn } from "@/lib/utils"; import { BoltIcon, DownloadIcon, FlameIcon, HomeIcon, RefreshIcon, SnowflakeIcon } from "@/components/icons"; import { Button, Chip } from "@/components/ui"; import type { AttemptResult } from "./StudyFeed"; export function answerFor(activity: Activity): string { switch (activity.type) { case "flashcard": return activity.back; case "multiple_choice": return activity.options[activity.correctIndex]; case "true_false": return activity.answer ? "True" : "False"; case "fill_blank": return activity.answer; case "matching": return activity.pairs.map((pair) => `${pair.term} → ${pair.definition}`).join("; "); case "ordering": return activity.items.map((item, index) => `${index + 1}. ${item}`).join(" "); case "short_answer": return activity.referenceAnswer; } } export function promptFor(activity: Activity): string { switch (activity.type) { case "flashcard": return activity.front; case "multiple_choice": return activity.question; case "true_false": return activity.statement; case "fill_blank": return activity.sentence.replace(/_{2,}/, "____"); case "matching": return activity.instruction; case "ordering": return activity.instruction; case "short_answer": return activity.question; } } export function ResultsScreen({ deck, xp, bestStreak, total, correct, missed, results, retryMode, onRetryMissed, onRestart, }: { deck: Deck; xp: number; bestStreak: number; total: number; correct: number; missed: Activity[]; results: Record; retryMode: boolean; onRetryMissed: () => void; onRestart: () => void; }) { const percent = total > 0 ? Math.round((correct / total) * 100) : 0; const perfect = missed.length === 0 && total > 0; const tone = percent >= 80 ? "emerald" : percent >= 50 ? "frost" : "amber"; return (

{perfect ? "Perfect freeze! 🧊" : percent >= 60 ? "Nicely done!" : "Good start — keep going!"}

{perfect ? `You aced all ${total} activities in “${deck.title}”.` : `You got ${correct} of ${total} right${retryMode ? " on the retry run" : ""}.`}

{xp} XP earned Best streak {bestStreak} {[deck.difficulty].map((value) => value[0].toUpperCase() + value.slice(1))[0]} difficulty {deck.bestScore !== undefined && !retryMode ? ( 🏆 Best {deck.bestScore}% ) : null}
{missed.length > 0 ? (

Missed items ({missed.length})

    {missed.map((activity) => (
  • {promptFor(activity)}

    {results[activity.id]?.userAnswer ? (

    Your answer: {results[activity.id]?.userAnswer}

    ) : null}

    Answer: {answerFor(activity)}

  • ))}
) : null}
{missed.length > 0 ? ( ) : ( )} {missed.length > 0 ? ( ) : null}
Library
); } function ScoreRing({ percent, tone }: { percent: number; tone: "emerald" | "frost" | "amber" }) { const radius = 52; const circumference = 2 * Math.PI * radius; const offset = circumference * (1 - Math.min(100, Math.max(0, percent)) / 100); const colors: Record = { emerald: "stroke-emerald-500", frost: "stroke-accent-500", amber: "stroke-amber-500", }; return (
{percent}% score
); }