"use client"; import { useState, useEffect } from "react"; import { CardResponse } from "@/lib/types/cards"; import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { Progress } from "@/components/ui/progress"; import { processReview, gradeCard } from "@/actions/srs"; import "./cards.css"; interface StudyCardProps { card: CardResponse; userId: number; onComplete: (newCard: CardResponse) => void; onSkip?: () => void; } export default function StudyCard({ card, userId, onComplete, onSkip }: StudyCardProps) { const [isFlipped, setIsFlipped] = useState(false); const [startTime, setStartTime] = useState(0); const [isSubmitting, setIsSubmitting] = useState(false); // Reset the timer when a new card is shown useEffect(() => { setIsFlipped(false); setStartTime(Date.now()); }, [card.id]); // Toggle card flip const flipCard = () => { if (!isFlipped) { setIsFlipped(true); } }; // Calculate time spent on card in milliseconds const getReviewTime = () => { return Date.now() - startTime; }; // Handle card grading (Good/Again) const handleGrade = async (isCorrect: boolean) => { if (isSubmitting) return; setIsSubmitting(true); try { const result = await gradeCard(userId, card.id, isCorrect); if ('error' in result) { console.error("Error grading card:", result.error); } else { onComplete(result as CardResponse); } } catch (error) { console.error("Error processing review:", error); } finally { setIsSubmitting(false); } }; // Handle detailed grading with accuracy level const handleDetailedGrade = async (accuracy: number) => { if (isSubmitting) return; setIsSubmitting(true); try { const reviewTime = getReviewTime(); const result = await processReview(userId, card.id, accuracy, reviewTime); if ('error' in result) { console.error("Error processing review:", result.error); } else { onComplete(result as CardResponse); } } catch (error) { console.error("Error processing review:", error); } finally { setIsSubmitting(false); } }; // Calculate progress percentage for the card const getProgressPercentage = () => { const { interval, easeFactor } = card.progress; // Assuming max interval is 365 days and max ease factor is 4.0 const intervalProgress = Math.min(interval / 365, 1) * 70; // 70% weight to interval const easeProgress = Math.min((easeFactor - 1) / 3, 1) * 30; // 30% weight to ease factor return intervalProgress + easeProgress; }; // Format content based on card type const formatCardContent = (content: string, isBack: boolean = false) => { // You can add more sophisticated formatting here based on card type return content; }; // Render IPA pronunciation if available const renderIPA = () => { if (card.expression.ipa && card.expression.ipa.length > 0) { return (