feat: complete comprehensive zero-state metrics across all dashboard pages for new accounts

This commit is contained in:
2026-09-13 22:17:40 +05:30
parent d9bd142e6a
commit afab06d33c
22 changed files with 771 additions and 299 deletions

View File

@@ -16,7 +16,7 @@ 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 } from "@/hooks/useActiveUser"
import { useActiveUser, isDemoUser } from "@/hooks/useActiveUser"
import Link from "next/link"
@@ -36,8 +36,10 @@ export default function AICoachDashboard() {
const [mistakes, setMistakes] = useState<MistakePayload[]>([])
const [currentIndex, setCurrentIndex] = useState(0)
const [loading, setLoading] = useState(true)
const [stats, setStats] = useState<any>(null)
const { userId, user, hasAccessTo, loading: userLoading } = useActiveUser();
const isDemo = isDemoUser(userId);
const fetchMistakes = async () => {
if (!userId) return
@@ -58,6 +60,10 @@ export default function AICoachDashboard() {
useEffect(() => {
if (!userLoading && userId) {
fetchMistakes()
fetch(`/api/users/${userId}/stats`)
.then(res => res.ok ? res.json() : null)
.then(data => setStats(data))
.catch(() => setStats(null))
}
}, [userId, userLoading])
@@ -114,9 +120,11 @@ export default function AICoachDashboard() {
}
const daysLeft = getDaysToExam(user?.target_exam || "NEET")
const physicsErrors = mistakes.filter(m => m.question.subject === "Physics").length
const chemErrors = mistakes.filter(m => m.question.subject === "Chemistry").length
const mathErrors = mistakes.filter(m => m.question.subject === "Maths" || m.question.subject === "Mathematics").length
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 animate-in fade-in duration-500">
@@ -125,7 +133,7 @@ export default function AICoachDashboard() {
<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 || 0}-Day Streak
{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} />
@@ -143,11 +151,11 @@ export default function AICoachDashboard() {
{/* ── QUICK STATS ── */}
<section className="grid grid-cols-2 md:grid-cols-5 gap-4">
{[
{ label: "Questions Solved", value: "1,247", color: "text-[#00F0FF]", bg: "bg-[#00F0FF]/5", border: "border-[#00F0FF]/20", icon: <FileText size={32} /> },
{ label: "Overall Accuracy", value: "74%", color: "text-amber-500", bg: "bg-amber-500/5", border: "border-amber-500/20", icon: <Target size={32} /> },
{ label: "Current Streak", value: `${user?.streak_count || 0} d`, 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: 38, color: "text-green-400", bg: "bg-green-400/5", border: "border-green-400/20", icon: <CheckCircle2 size={32} /> },
{ label: "AI Sessions", value: 124, color: "text-purple-400", bg: "bg-purple-400/5", border: "border-purple-400/20", icon: <Bot size={32} /> },
{ label: "Questions Solved", value: questionsSolved, color: "text-[#00F0FF]", bg: "bg-[#00F0FF]/5", border: "border-[#00F0FF]/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 transition-all duration-300 transform hover:-translate-y-1 rounded-2xl`}>
<CardContent className="p-6 flex flex-col items-center justify-center text-center">