import React, { useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { X, Trash2, Play, BrainCircuit, PenTool, Loader2, Calendar, FileDown, FileUp, Check, ListChecks } from 'lucide-react'; import { QuizListItem } from '../types'; import { useBodyScrollLock } from '../hooks/useBodyScrollLock'; interface QuizLibraryProps { isOpen: boolean; onClose: () => void; quizzes: QuizListItem[]; loading: boolean; loadingQuizId: string | null; deletingQuizId: string | null; exporting: boolean; error: string | null; onLoadQuiz: (id: string) => void; onDeleteQuiz: (id: string) => void; onExportQuizzes: (ids: string[]) => Promise; onImportClick: () => void; onRetry: () => void; } export const QuizLibrary: React.FC = ({ isOpen, onClose, quizzes, loading, loadingQuizId, deletingQuizId, exporting, error, onLoadQuiz, onDeleteQuiz, onExportQuizzes, onImportClick, onRetry, }) => { const [confirmDeleteId, setConfirmDeleteId] = useState(null); const [selectMode, setSelectMode] = useState(false); const [selectedIds, setSelectedIds] = useState>(new Set()); const isAnyOperationInProgress = loading || !!loadingQuizId || !!deletingQuizId || exporting; useBodyScrollLock(isOpen); const toggleSelectMode = () => { if (selectMode) { setSelectedIds(new Set()); } setSelectMode(!selectMode); }; const toggleQuizSelection = (e: React.MouseEvent, id: string) => { e.stopPropagation(); const newSelected = new Set(selectedIds); if (newSelected.has(id)) { newSelected.delete(id); } else { newSelected.add(id); } setSelectedIds(newSelected); }; const toggleSelectAll = () => { if (selectedIds.size === quizzes.length) { setSelectedIds(new Set()); } else { setSelectedIds(new Set(quizzes.map(q => q.id))); } }; const handleExport = async () => { await onExportQuizzes(Array.from(selectedIds)); setSelectMode(false); setSelectedIds(new Set()); }; const handleDeleteClick = (e: React.MouseEvent, id: string) => { e.stopPropagation(); setConfirmDeleteId(id); }; const confirmDelete = async (e: React.MouseEvent) => { e.stopPropagation(); if (confirmDeleteId) { try { await onDeleteQuiz(confirmDeleteId); setConfirmDeleteId(null); } catch { setConfirmDeleteId(null); } } }; const cancelDelete = (e: React.MouseEvent) => { e.stopPropagation(); setConfirmDeleteId(null); }; const formatDate = (dateString: string) => { try { return new Date(dateString).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric', }); } catch (e) { return dateString; } }; return ( {isOpen && ( <> e.stopPropagation()} className="bg-white w-full max-w-2xl max-h-[80vh] flex flex-col rounded-[2rem] shadow-[0_10px_0_rgba(0,0,0,0.1)] border-4 border-white/50 relative overflow-hidden" >

My Library

{selectMode ? `${selectedIds.size} of ${quizzes.length} selected` : 'Select a quiz to play' }

{!loading && quizzes.length > 0 && ( <> )}
{loading && (

Loading your quizzes...

)} {!loading && error && (

{error}

)} {!loading && !error && quizzes.length === 0 && (

No saved quizzes yet

Create or generate a quiz to save it here!

)} {selectMode && quizzes.length > 0 && (
)} {!loading && !error && quizzes.map((quiz) => ( { if (isAnyOperationInProgress) return; if (selectMode) { toggleQuizSelection(e, quiz.id); } else { onLoadQuiz(quiz.id); } }} >
{selectMode && (
{selectedIds.has(quiz.id) && ( )}
)}
{quiz.source === 'ai_generated' ? ( AI ) : ( Manual )} {formatDate(quiz.createdAt)}

{quiz.title}

{quiz.questionCount} question{quiz.questionCount !== 1 ? 's' : ''} {quiz.aiTopic && • Topic: {quiz.aiTopic}}

{!selectMode && (
{loadingQuizId === quiz.id ? (
) : deletingQuizId === quiz.id ? (
) : confirmDeleteId === quiz.id ? (
e.stopPropagation()}>
) : ( <>
)}
)}
))}
{selectMode && (
)}
)}
); };