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

180 lines
9.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { MistakeHeatmap } from "@/components/AI/MistakeHeatmap"
import { Flame, AlertTriangle, TrendingDown, BookOpen, ArrowRight, BarChart2, Target, CheckCircle2 } from "lucide-react"
import { Card, CardContent } from "@/components/ui/card"
import Link from "next/link"
import { useActiveUser, isDemoUser } from "@/hooks/useActiveUser"
const DEMO_CRITICAL_TOPICS = [
{ name: "Rotational Dynamics", rate: "80%", rateNum: 80, subject: "Physics" },
{ name: "Optics", rate: "60%", rateNum: 60, subject: "Physics" },
{ name: "Electromagnetism", rate: "30%", rateNum: 30, subject: "Physics" },
{ name: "GOC — Reaction Mechanisms", rate: "55%", rateNum: 55, subject: "Chemistry" },
{ name: "Thermodynamics", rate: "25%", rateNum: 25, subject: "Physics" },
]
const DEMO_SUMMARY_STATS = [
{ label: "Total Errors (Last 5 Tests)", value: "87", icon: <AlertTriangle size={18} className="text-red-400" />, color: "border-red-400/20 bg-red-400/5" },
{ label: "Critical Topics", value: "4", icon: <Flame size={18} className="text-orange-400" />, color: "border-orange-400/20 bg-orange-400/5" },
{ label: "Improving Topics", value: "3", icon: <TrendingDown size={18} className="text-green-400" />, color: "border-green-400/20 bg-green-400/5" },
{ label: "Avg Error Rate", value: "38%", icon: <Target size={18} className="text-amber-400" />, color: "border-amber-400/20 bg-amber-400/5" },
]
const ZERO_SUMMARY_STATS = [
{ label: "Total Errors (Last 5 Tests)", value: "0", icon: <AlertTriangle size={18} className="text-muted-foreground" />, color: "border-white/10 bg-white/5" },
{ label: "Critical Topics", value: "0", icon: <Flame size={18} className="text-muted-foreground" />, color: "border-white/10 bg-white/5" },
{ label: "Improving Topics", value: "0", icon: <TrendingDown size={18} className="text-muted-foreground" />, color: "border-white/10 bg-white/5" },
{ label: "Avg Error Rate", value: "0%", icon: <Target size={18} className="text-green-400" />, color: "border-green-400/20 bg-green-400/5" },
]
export default function HeatmapPage() {
const { userId } = useActiveUser()
const isDemo = isDemoUser(userId)
const summaryStats = isDemo ? DEMO_SUMMARY_STATS : ZERO_SUMMARY_STATS
const criticalTopics = isDemo ? DEMO_CRITICAL_TOPICS : []
return (
<div className="p-6 md:p-8 max-w-7xl mx-auto space-y-8 min-h-screen">
{/* Page Header */}
<div className="border-b border-border/50 pb-6">
<div className="flex items-start justify-between gap-4 flex-wrap">
<div>
<h1 className="text-3xl md:text-4xl font-black tracking-tight flex items-center gap-3 mb-2">
<span className="p-2.5 rounded-xl bg-cyan-50 dark:bg-[var(--cyan-ai-10)] border border-cyan-300/60 dark:border-[var(--cyan-ai-20)]">
<Flame className="text-cyan-700 dark:text-[var(--cyan-ai)]" size={28} />
</span>
Mastery Map Vault
</h1>
<p className="text-muted-foreground text-base font-medium max-w-2xl pl-1">
Visual density map of your errors across subjects and topics — pinpoint your weakest areas instantly.
</p>
</div>
<span className="text-xs font-bold uppercase tracking-wider text-amber-500 bg-cyan-50 dark:bg-[var(--cyan-ai-10)] border border-cyan-300/60 dark:border-[var(--cyan-ai-20)] px-3 py-1.5 rounded-full flex items-center gap-1.5 shrink-0 self-start">
<AlertTriangle size={12} /> Error Density Analysis
</span>
</div>
</div>
{/* KPI Strip */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{summaryStats.map((kpi) => (
<Card key={kpi.label} className={`rounded-2xl border ${kpi.color} hover:scale-[1.02] transition-transform`}>
<CardContent className="p-5 flex flex-col gap-2">
{kpi.icon}
<div className="text-2xl font-black">{kpi.value}</div>
<div className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">{kpi.label}</div>
</CardContent>
</Card>
))}
</div>
{/* Legend / Guidance Row */}
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
{[
{ label: "Critical (> 50%)", color: "bg-red-500/20 border-red-500/30 text-red-400", dot: "bg-red-500", desc: "Immediate revision needed" },
{ label: "Warning (30–50%)", color: "bg-amber-500/20 border-amber-500/30 text-amber-400", dot: "bg-amber-500", desc: "Focus on these next" },
{ label: "Moderate (10–30%)", color: "bg-yellow-500/20 border-yellow-500/30 text-yellow-400", dot: "bg-yellow-500", desc: "Review periodically" },
{ label: "Good (< 10%)", color: "bg-green-500/20 border-green-500/30 text-green-400", dot: "bg-green-500", desc: "Mostly understood" },
].map((item) => (
<Card key={item.label} className={`rounded-2xl border ${item.color.split(" ").slice(0, 2).join(" ")}`}>
<CardContent className="p-4">
<div className={`inline-flex items-center gap-1.5 text-xs font-black uppercase tracking-wider mb-1 ${item.color.split(" ")[2]}`}>
<span className={`w-2.5 h-2.5 rounded-sm ${item.dot}`} />
{item.label}
</div>
<p className="text-xs text-muted-foreground font-medium">{item.desc}</p>
</CardContent>
</Card>
))}
</div>
{/* Main 2-col layout */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Heatmap — takes 2/3 */}
<div className="lg:col-span-2 space-y-3">
<div className="flex items-center gap-2 text-sm font-black uppercase tracking-wider text-muted-foreground">
<TrendingDown size={16} className="text-red-400" />
Topic Error Rate — Last 5 Tests
</div>
<MistakeHeatmap />
</div>
{/* Side panel */}
<div className="space-y-6">
{/* Error frequency chart */}
<Card className="bg-secondary/10 border-border/60 rounded-2xl">
<CardContent className="p-5 space-y-4">
<h3 className="text-sm font-black uppercase tracking-wider text-foreground flex items-center gap-2">
<BarChart2 size={15} className="text-red-400" /> Priority Topics by Error Rate
</h3>
<div className="space-y-3">
{criticalTopics.length === 0 ? (
<div className="p-5 rounded-xl bg-white/5 border border-border/40 text-center space-y-1.5">
<CheckCircle2 size={24} className="mx-auto text-green-400 opacity-80" />
<p className="text-xs font-bold text-foreground">Clean Error Log</p>
<p className="text-[11px] text-muted-foreground">
No mistake hotspots detected yet. Practice questions to see priority areas here.
</p>
</div>
) : (
criticalTopics.map((t) => (
<div key={t.name}>
<div className="flex items-center justify-between mb-1">
<div>
<p className="text-xs font-bold leading-tight">{t.name}</p>
<p className="text-[11px] text-muted-foreground">{t.subject}</p>
</div>
<span className={`text-xs font-black px-2 py-0.5 rounded-md ${t.rateNum >= 50 ? "text-red-400 bg-red-400/10" : t.rateNum >= 30 ? "text-amber-400 bg-amber-400/10" : "text-yellow-400 bg-yellow-400/10"}`}>
{t.rate}
</span>
</div>
<div className="h-1.5 w-full bg-secondary rounded-full overflow-hidden">
<div
className={`h-full rounded-full ${t.rateNum >= 50 ? "bg-red-500" : t.rateNum >= 30 ? "bg-amber-500" : "bg-yellow-500"}`}
style={{ width: `${t.rateNum}%` }}
/>
</div>
</div>
))
)}
</div>
</CardContent>
</Card>
{/* Action card */}
<Card className="bg-gradient-to-br from-[var(--cyan-ai-10)] via-secondary/20 to-background border border-[var(--cyan-ai-20)] rounded-2xl">
<CardContent className="p-5 space-y-3">
<h3 className="text-sm font-black uppercase tracking-wider text-[var(--cyan-ai)]">What To Do Next</h3>
<div className="space-y-2">
{[
{ label: "Take a Physics DPP", href: "/dashboard/ai-coach/cbt-dpp" },
{ label: "Check Exam Readiness Score", href: "/dashboard/ai-coach/readiness" },
].map((link) => (
<Link key={link.href} href={link.href}
className="flex items-center justify-between text-sm font-bold text-muted-foreground hover:text-foreground py-2 border-b border-border/30 last:border-0 transition-colors group">
{link.label}
<ArrowRight size={14} className="group-hover:translate-x-1 transition-transform" />
</Link>
))}
</div>
</CardContent>
</Card>
{/* Tip */}
<Card className="bg-secondary/20 border-border/40 rounded-2xl">
<CardContent className="p-4">
<div className="flex items-start gap-2.5">
<BookOpen size={16} className="text-[var(--cyan-ai)] shrink-0 mt-0.5" />
<p className="text-xs text-muted-foreground font-medium">
<span className="font-black text-foreground">Pro Tip:</span> Focus the next 3 days entirely on Rotational Dynamics — it alone is worth 8–12 marks in JEE and shows an 80% error rate across your last 5 tests.
</p>
</div>
</CardContent>
</Card>
</div>
</div>
</div>
)
}