import { getContextData } from "waku/middleware/context"; import { Link } from "waku"; import { getUserLessons, getUserStudyStats } from "@/actions/srs"; import { BookOpen, GraduationCap, Clock, Star, ChevronRight, BrainCircuit, Flame, Layers, CalendarDays } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import { Progress } from "@/components/ui/progress"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Badge } from "@/components/ui/badge"; import Navbar from "@/components/Navbar"; // This is a server component that gets the initial data export default async function StudyPage() { const { user } = getContextData() as any; // Redirect to login if not authenticated if (!user) { return (

Login Required

You need to be logged in to access your study dashboard.

); } // Fetch user study data let userStats; let userLessons; try { // Get user stats and lessons in parallel [userStats, userLessons] = await Promise.all([ getUserStudyStats(user.id), getUserLessons(user.id) ]); } catch (error) { console.error("Error fetching study data:", error); userStats = { totalCards: 0, masteredCards: 0, dueCards: 0, averageEaseFactor: 2.5, successRate: 0, streakDays: 0 }; userLessons = []; } // Calculate overall progress const overallProgress = userStats.totalCards > 0 ? Math.round((userStats.masteredCards / userStats.totalCards) * 100) : 0; // Sort lessons by different criteria const dueLessons = [...userLessons].sort((a, b) => b.dueCards - a.dueCards).filter(l => l.dueCards > 0); const inProgressLessons = userLessons.filter(lesson => lesson.progress > 0 && lesson.progress < 100); const recentLessons = [...userLessons].sort((a, b) => b.id - a.id).slice(0, 4); return (
{/* Dashboard Header */}

Study Dashboard

Track your progress, review due cards, and continue your language learning journey

{/* Stats Overview */}
Total

{userStats.totalCards}

Total Cards

{Math.round(userStats.masteredCards / Math.max(userStats.totalCards, 1) * 100)}%

{userStats.masteredCards}

Mastered Cards

0 ? "bg-red-100 text-red-800" : "bg-gray-100"}> {userStats.dueCards > 0 ? "Due Today" : "All Caught Up"}

{userStats.dueCards}

Cards Due for Review

Streak

{userStats.streakDays}

Days in a Row

{/* Main Content Tabs */} All Lessons Due for Review {dueLessons.length > 0 && `(${dueLessons.length})`} In Progress Study Stats {/* All Lessons Tab */}
{userLessons.length > 0 ? ( userLessons.map((lesson) => ( )) ) : (

No lessons available yet

Start your language learning journey by adding lessons

)}
{/* Due for Review Tab */} {dueLessons.length > 0 ? (
{dueLessons.map((lesson) => ( ))}
) : (

All caught up!

You don't have any cards due for review right now. Check back later or start a new lesson.

)}
{/* In Progress Tab */} {inProgressLessons.length > 0 ? (
{inProgressLessons.map((lesson) => ( ))}
) : (

No lessons in progress

Start learning by selecting a lesson from the All Lessons tab.

)}
{/* Stats Tab */}
Overall Progress Your language learning journey progress
Progress {overallProgress}%
Success Rate {Math.round(userStats.successRate * 100)}%
Average Ease {userStats.averageEaseFactor.toFixed(1)}
Total Cards {userStats.totalCards}
Mastered {userStats.masteredCards}
Study Streak Keep the momentum going!
{userStats.streakDays}
Days in a row
Recent Activity Your latest learning progress
{recentLessons.map(lesson => (
{lesson.name}
{lesson.description || `Lesson ${lesson.id}`}
{Math.round(lesson.progress)}%
{lesson.masteredCards} / {lesson.totalCards} cards
))}
{/* Quick Access Section */}

Quick Access

Start New Lesson

Add text to study

Review Due Cards

{userStats.dueCards} cards waiting

Track Progress

View detailed statistics

); } // Lesson Card Component function LessonCard({ lesson, showDueCardsBadge = false, showProgress = false }: { lesson: any; showDueCardsBadge?: boolean; showProgress?: boolean; }) { return (
{lesson.name} {lesson.description || `Lesson ${lesson.id}`}
{showDueCardsBadge && lesson.dueCards > 0 && ( {lesson.dueCards} due )}
{lesson.masteredCards} of {lesson.totalCards} mastered {Math.round(lesson.progress)}% complete
{showProgress && (
Due Cards {lesson.dueCards}
Mastered {lesson.masteredCards}
)}
); } export const getConfig = async () => { return { render: "dynamic", } as const; };