'use client' import { useState, useEffect } from 'react' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { Label } from '@/components/ui/label' import { Badge } from '@/components/ui/badge' import { Progress } from '@/components/ui/progress' import { useNotebooks } from '@/lib/hooks/use-notebooks' import { useFlashcards, useFlashcardStats, useGenerateFlashcards, useReviewFlashcard } from '@/lib/hooks/use-quiz' import { Flashcard, FLASHCARD_RATINGS } from '@/lib/types/quiz' import { LoadingSpinner } from '@/components/common/LoadingSpinner' import { cn } from '@/lib/utils' import { Plus, Sparkles, Play, RotateCcw, ChevronLeft, ChevronRight, Eye, EyeOff, Layers } from 'lucide-react' export function FlashcardSection() { const [selectedNotebook, setSelectedNotebook] = useState('') const [numCards, setNumCards] = useState(20) const [reviewMode, setReviewMode] = useState(false) const { data: notebooks } = useNotebooks() const { data: flashcards, isLoading: cardsLoading } = useFlashcards(selectedNotebook || undefined, reviewMode) const { data: stats } = useFlashcardStats(selectedNotebook || undefined) const generateFlashcards = useGenerateFlashcards() const handleGenerateFlashcards = async () => { if (!selectedNotebook) return await generateFlashcards.mutateAsync({ notebook_id: selectedNotebook, num_cards: numCards, }) } const handleStartReview = () => { setReviewMode(true) } // If in review mode and we have cards, show the review interface if (reviewMode && flashcards && flashcards.length > 0) { return ( setReviewMode(false)} /> ) } return (
{/* Generate Flashcards Card */} Generate Flashcards Create AI-generated flashcards from your content
{/* Flashcard Stats & Review Card */} Your Flashcards Review due cards using spaced repetition {stats ? ( <> {/* Stats Grid */}
{stats.total}
Total Cards
{stats.due}
Due Today
{stats.new}
New
{stats.review}
In Review
{/* Review Button */} ) : cardsLoading ? (
) : (

No flashcards yet

Generate some flashcards to get started!

)}
) } interface FlashcardReviewProps { flashcards: Flashcard[] onExit: () => void } function FlashcardReview({ flashcards, onExit }: FlashcardReviewProps) { const [currentIndex, setCurrentIndex] = useState(0) const [showBack, setShowBack] = useState(false) const [reviewedCount, setReviewedCount] = useState(0) const reviewFlashcard = useReviewFlashcard() const currentCard = flashcards[currentIndex] const progress = (reviewedCount / flashcards.length) * 100 // Keyboard navigation useEffect(() => { const handleKeyPress = (e: KeyboardEvent) => { // Space or Enter to flip card if ((e.key === ' ' || e.key === 'Enter') && !showBack) { e.preventDefault() setShowBack(true) } // Number keys 1-4 for ratings (only when back is shown) if (showBack && ['1', '2', '3', '4'].includes(e.key)) { const rating = parseInt(e.key) as 1 | 2 | 3 | 4 handleRating(rating) } } window.addEventListener('keydown', handleKeyPress) return () => window.removeEventListener('keydown', handleKeyPress) }, [showBack, currentCard]) if (!currentCard || reviewedCount >= flashcards.length) { // Review complete return (
Review Complete! 🎉 You reviewed {reviewedCount} cards
) } const handleRating = async (rating: 1 | 2 | 3 | 4) => { try { console.log('Rating flashcard:', currentCard.id, 'with rating:', rating) await reviewFlashcard.mutateAsync({ flashcardId: currentCard.id, data: { rating } }) console.log('Review successful') // Move to next card first, then increment reviewed count if (currentIndex < flashcards.length - 1) { setCurrentIndex(prev => prev + 1) setShowBack(false) setReviewedCount(prev => prev + 1) } else { // This was the last card, increment reviewed count to trigger completion setReviewedCount(prev => prev + 1) } } catch (error: any) { console.error('Error reviewing flashcard:', error) console.error('Error response:', error?.response?.data) console.error('Error message:', error?.message) alert(`Failed to review flashcard: ${error?.response?.data?.detail || error?.message || 'Unknown error'}`) } } return (
{/* Header */}
Card {currentIndex + 1} of {flashcards.length}
{reviewedCount} reviewed
{/* Progress */} {/* Flashcard */} setShowBack(!showBack)} > {!showBack ? ( <>
Question

{currentCard.front}

Click to reveal answer

) : ( <>
Answer

{currentCard.back}

)}
{/* Rating Buttons (shown after revealing) */} {showBack && (

How well did you know this? (Press 1-4)

{([1, 2, 3, 4] as const).map((rating) => { const ratingInfo = FLASHCARD_RATINGS[rating] return ( ) })}
)} {/* Navigation hint */} {!showBack && (
Press Space to flip
)}
) }