Files
pragativeer-v2/src/app/dashboard/ai-coach/page.tsx

213 lines
10 KiB
TypeScript

"use client";
import { fetchWithAuth } from "@/lib/apiClient";
import { useEffect, useState } from "react"
import { MistakeHeatmap } from "@/components/AI/MistakeHeatmap"
import { StudyPlanCard } from "@/components/AI/StudyPlanCard"
import { ReadinessGauge } from "@/components/AI/ReadinessGauge"
import { CollegePredictorCard } from "@/components/AI/CollegePredictorCard"
import { ExamStrategyCard } from "@/components/AI/ExamStrategyCard"
import { StudyTimeOptimizationCard } from "@/components/AI/StudyTimeOptimizationCard"
import { TutorChat } from "@/components/AI/TutorChat"
import { ReferralCard } from "@/components/AI/ReferralCard"
import { ProgressShare } from "@/components/AI/ProgressShare"
import { DailyChallengeBanner } from "@/components/AI/DailyChallengeBanner"
import { WeeklyProgressReport } from "@/components/AI/WeeklyProgressReport"
import { Card, CardContent } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { BrainCircuit, RefreshCw, CheckCircle2, Flame, Trophy, Target, Zap, BookOpen, Bot, FileText } from "lucide-react"
import { useActiveUser, isDemoUser } from "@/hooks/useActiveUser"
import Link from "next/link"
// Days until NEET 2026 (May 3, 2026)
function getDaysToExam(exam: string) {
const targets: Record<string, Date> = {
"NEET": new Date("2026-05-03"),
"JEE_Main": new Date("2026-01-22"),
"JEE_Advanced": new Date("2026-05-24"),
}
const t = targets[exam] || targets["NEET"]
const diff = Math.ceil((t.getTime() - Date.now()) / 86400000)
return diff > 0 ? diff : 0
}
export default function AICoachDashboard() {
const [stats, setStats] = useState<any>(null)
const { userId, user, hasAccessTo, loading: userLoading } = useActiveUser();
const isDemo = isDemoUser(userId);
useEffect(() => {
if (!userLoading && userId) {
fetchWithAuth(`/api/users/${userId}/stats`)
.then(res => res.ok ? res.json() : null)
.then(data => setStats(data))
.catch(() => setStats(null))
}
}, [userId, userLoading])
if (userLoading) {
return (
<div className="h-screen flex items-center justify-center">
<div className="flex flex-col items-center gap-3 text-muted-foreground">
<BrainCircuit size={32} className="animate-pulse text-[var(--cyan-ai)]" />
<span className="text-sm font-medium">Loading AI Coach...</span>
</div>
</div>
)
}
if (!hasAccessTo("ai-mistake-tracking")) {
return (
<div className="max-w-3xl mx-auto text-center py-20 px-8 space-y-8">
<div className="size-20 rounded-full bg-[var(--cyan-ai-10)] flex items-center justify-center mx-auto text-[var(--cyan-ai)] border border-[var(--cyan-ai-20)] shadow-[0_0_20px_rgba(12,96,96,0.1)]">
<BrainCircuit size={40} />
</div>
<div className="space-y-4">
<h1 className="text-4xl font-extrabold tracking-tight">AI Coach Workspace</h1>
<p className="text-muted-foreground text-lg max-w-xl mx-auto leading-relaxed">
Mistake tracking, Spaced Repetition (SM-2), AI Tutor Chats, and Readiness scores are premium features reserved for <strong>AI Coach</strong> subscribers.
</p>
</div>
<div className="pt-4">
<Link href="/upgrade">
<Button size="lg" className="rounded-xl px-8 font-bold bg-[var(--cyan-ai)] text-background hover:bg-[var(--cyan-ai-80)] shadow-[0_0_25px_-5px_var(--cyan-ai)]">
Upgrade to AI Coach Plan
</Button>
</Link>
</div>
</div>
)
}
const daysLeft = getDaysToExam(user?.target_exam || "NEET")
const questionsSolved = isDemo ? "1,247" : (stats?.total_questions_attempted ?? 0).toLocaleString()
const overallAccuracy = isDemo ? "74%" : `${stats?.overall_accuracy ?? 0}%`
const mistakesMastered = isDemo ? 38 : 0
const aiSessions = isDemo ? 124 : 0
const currentStreakDays = `${user?.streak_count || (isDemo ? 12 : 1)} d`
return (
<div className="p-6 max-w-6xl mx-auto space-y-8">
{/* ── METRICS BAR ── */}
<div className="flex flex-wrap items-center justify-end gap-2 pt-2">
<div className="inline-flex items-center gap-1.5 bg-yellow-500/10 text-yellow-500 px-3 py-1.5 rounded-xl text-xs font-bold border border-yellow-500/20">
<Flame size={14} className="fill-yellow-500" />
{user?.streak_count || 1}-Day Streak
</div>
<div className="inline-flex items-center gap-1.5 bg-red-500/10 text-red-400 px-3 py-1.5 rounded-xl text-xs font-bold border border-red-500/20">
<Target size={13} />
{daysLeft} days to {user?.target_exam?.replace("_", " ") || "Exam"}
</div>
<div className="inline-flex items-center gap-1.5 bg-purple-500/10 text-purple-400 px-3 py-1.5 rounded-xl text-xs font-bold border border-purple-500/20">
<Trophy size={13} />
AI Coach
</div>
</div>
{/* ── DAILY CHALLENGE BANNER ── */}
<div className=""><DailyChallengeBanner /></div>
{/* ── QUICK STATS ── */}
<section className="grid grid-cols-2 md:grid-cols-5 gap-4">
{[
{ label: "Questions Solved", value: questionsSolved, color: "text-[var(--cyan-ai)]", bg: "bg-[var(--cyan-ai-10)]", border: "border-[var(--cyan-ai-20)]", icon: <FileText size={32} /> },
{ label: "Overall Accuracy", value: overallAccuracy, color: "text-amber-500", bg: "bg-amber-500/5", border: "border-amber-500/20", icon: <Target size={32} /> },
{ label: "Current Streak", value: currentStreakDays, color: "text-yellow-400", bg: "bg-yellow-400/5", border: "border-yellow-400/20", icon: <Flame size={32} className="fill-yellow-400" /> },
{ label: "Mistakes Mastered", value: mistakesMastered, color: "text-green-400", bg: "bg-green-400/5", border: "border-green-400/20", icon: <CheckCircle2 size={32} /> },
{ label: "AI Sessions", value: aiSessions, color: "text-purple-400", bg: "bg-purple-400/5", border: "border-purple-400/20", icon: <Bot size={32} /> },
].map((stat) => (
<Card key={stat.label} className={`border ${stat.border} ${stat.bg} backdrop-blur-sm rounded-2xl`}>
<CardContent className="p-6 flex flex-col items-center justify-center text-center">
<div className="text-3xl mb-2 filter drop-shadow-md">{stat.icon}</div>
<div className={`text-4xl font-black ${stat.color} leading-none tracking-tight mb-2 filter drop-shadow-sm`}>{stat.value}</div>
<div className="text-xs font-extrabold text-muted-foreground uppercase tracking-wider">{stat.label}</div>
</CardContent>
</Card>
))}
</section>
{/* ── PREDICTIVE INTELLIGENCE ROW ── */}
<section className="mt-10">
<div className="flex items-center justify-between gap-3 mb-6">
<div className="flex items-center gap-2 text-base md:text-lg font-black uppercase tracking-widest text-[var(--cyan-ai)]">
<Zap size={20} />
Predictive Intelligence & Strategy
</div>
<div className="flex items-center gap-3">
<Link href="/dashboard/ai-coach/readiness" className="text-xs font-bold text-[var(--cyan-ai)] hover:underline flex items-center gap-1">
Full Analytics →
</Link>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<ReadinessGauge />
<CollegePredictorCard />
<ExamStrategyCard />
<StudyTimeOptimizationCard />
</div>
</section>
{/* ── HEATMAP / STUDY PLAN / WEEKLY REPORT ── */}
<section className="grid grid-cols-1 lg:grid-cols-2 gap-8 pt-10 border-t border-border">
<div>
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-2 text-base font-extrabold">
<BookOpen size={18} className="text-[var(--cyan-ai)]" /> Study Plan
</div>
<Link href="/dashboard/ai-coach/study-plan" className="text-xs font-bold text-[var(--cyan-ai)] hover:underline">
Full Schedule →
</Link>
</div>
<StudyPlanCard />
</div>
<div>
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-2 text-base font-extrabold">
<Flame size={18} className="text-yellow-500" /> Mastery Map
</div>
<Link href="/dashboard/ai-coach/heatmap" className="text-xs font-bold text-[var(--cyan-ai)] hover:underline">
Mastery Map Vault →
</Link>
</div>
<MistakeHeatmap />
</div>
</section>
<section className="pt-8 border-t border-border">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-2 text-base font-extrabold">
<Target size={18} className="text-[var(--cyan-ai)]" /> Weekly Progress Overview
</div>
<Link href="/dashboard/ai-coach/study-plan" className="text-xs font-bold text-[var(--cyan-ai)] hover:underline">
View Details →
</Link>
</div>
<WeeklyProgressReport />
</section>
{/* ── TUTOR CHAT ── */}
<section className="pt-8 border-t border-border">
<div className="flex items-center justify-between mb-4">
<h2 className="text-2xl font-extrabold tracking-tight">24/7 AI Tutor Chat Assistant</h2>
<Link href="/dashboard/ai-coach/tutor" className="text-xs font-extrabold text-[var(--cyan-ai)] bg-[var(--cyan-ai-10)] px-3.5 py-1.5 rounded-xl border border-[var(--cyan-ai-30)] hover:bg-[var(--cyan-ai)] hover:text-black transition-all">
Full Desk Mode →
</Link>
</div>
<TutorChat />
</section>
{/* ── GROWTH HUB ── */}
<section className="grid grid-cols-1 lg:grid-cols-2 gap-6 pt-6 border-t border-border">
<ReferralCard />
<ProgressShare />
</section>
</div>
)
}