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

218 lines
12 KiB
TypeScript

"use client"
import { useRef } from "react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { BrainCircuit, Play, ChevronRight, Activity, Target, CheckCircle2, AlertTriangle, TrendingUp, Calendar, Zap, LayoutDashboard, Share2, Trophy, Lock, ArrowRight, Clock } from "lucide-react"
import * as htmlToImage from 'html-to-image'
import { MistakeHeatmap } from "@/components/AI/MistakeHeatmap"
import { AdaptiveStudyPlan } from "@/components/AI/AdaptiveStudyPlan"
import { useActiveUser } from "@/hooks/useActiveUser"
export default function DashboardPage() {
const { user, hasAccessTo, loading } = useActiveUser()
const progressRef = useRef<HTMLDivElement>(null)
const handleExport = async () => {
if (progressRef.current) {
try {
const dataUrl = await htmlToImage.toPng(progressRef.current, { backgroundColor: '#09090b' })
const link = document.createElement('a')
link.download = 'pragativeer-progress.png'
link.href = dataUrl
link.click()
} catch (err) {
console.error("Failed to export image", err)
}
}
}
if (loading) {
return (
<div className="h-[70vh] flex flex-col items-center justify-center p-8">
<div className="h-8 w-8 border-4 border-[#00F0FF] border-t-transparent rounded-full animate-spin mb-4"></div>
<p className="text-muted-foreground font-medium animate-pulse">Loading dashboard...</p>
</div>
)
}
return (
<div className="p-8 max-w-7xl mx-auto space-y-10 animate-in fade-in duration-500 slide-in-from-bottom-4">
{/* Basic Performance Dashboard (F-05) */}
<section>
<div className="flex flex-col md:flex-row md:items-end justify-between gap-4 mb-8">
<div>
<h1 className="text-3xl md:text-4xl font-black tracking-tight flex items-center gap-3 mb-1">
<span className="p-2.5 rounded-xl bg-yellow-50 dark:bg-[#00F0FF]/10 border border-yellow-300/60 dark:border-[#00F0FF]/20">
<LayoutDashboard className="text-yellow-600 dark:text-[#00F0FF]" size={28} />
</span>
Performance Overview
</h1>
<p className="text-muted-foreground text-base font-medium max-w-2xl pl-1">
Your overall progress, scores, and active study plan at a glance.
</p>
</div>
<Button onClick={handleExport} variant="outline" size="sm" className="gap-2 font-medium shrink-0">
<Share2 size={16} /> Share Card
</Button>
</div>
<div ref={progressRef} className="grid grid-cols-2 md:grid-cols-4 gap-4 p-4 -mx-4 bg-background rounded-2xl">
<Card>
<CardContent className="p-5 flex flex-col items-center text-center">
<div className="p-3 bg-secondary rounded-full mb-3 text-primary"><Target size={24} /></div>
<p className="text-sm font-bold text-muted-foreground uppercase tracking-wider mb-1">Today's Score</p>
<h3 className="text-2xl font-bold">42 / 60</h3>
<p className="text-xs text-green-500 font-bold mt-2 flex items-center gap-1"><TrendingUp size={12}/> +5 from yesterday</p>
</CardContent>
</Card>
<Card>
<CardContent className="p-5 flex flex-col items-center text-center">
<div className="p-3 bg-secondary rounded-full mb-3 text-amber-500"><Activity size={24} /></div>
<p className="text-sm font-bold text-muted-foreground uppercase tracking-wider mb-1">Overall Accuracy</p>
<h3 className="text-2xl font-bold">68%</h3>
<p className="text-xs text-amber-500 font-bold mt-2">Needs Improvement</p>
</CardContent>
</Card>
<Card>
<CardContent className="p-5 flex flex-col items-center text-center">
<div className="p-3 bg-secondary rounded-full mb-3 text-[#00F0FF]"><CheckCircle2 size={24} /></div>
<p className="text-sm font-bold text-muted-foreground uppercase tracking-wider mb-1">Qs Attempted</p>
<h3 className="text-2xl font-bold">1,245</h3>
<p className="text-xs text-muted-foreground font-medium mt-2">Lifetime total</p>
</CardContent>
</Card>
<Card className="relative overflow-hidden group">
<div className="absolute inset-0 bg-gradient-to-br from-background to-secondary/50 z-0"></div>
<CardContent className="p-5 flex flex-col items-center text-center relative z-10">
<div className="p-3 bg-background border border-border shadow-sm rounded-full mb-3 text-foreground group-hover:scale-110 transition-transform"><Trophy size={24} /></div>
<div className="flex items-center gap-2 mb-1">
<p className="text-sm font-bold text-muted-foreground uppercase tracking-wider">City Rank</p>
</div>
<h3 className="text-2xl font-bold">#42 <span className="text-base text-muted-foreground font-medium">/ 1,200</span></h3>
<p className="text-xs text-muted-foreground font-medium mt-2 text-[#00F0FF]">Top 5% in Jaipur</p>
</CardContent>
</Card>
</div>
</section>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-8">
<section>
<AdaptiveStudyPlan />
</section>
<section>
<MistakeHeatmap />
</section>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
{/* Dynamic DPP Modules */}
<section>
<div className="flex items-center justify-between mb-5">
<h2 className="text-xl font-semibold tracking-tight flex items-center gap-2">
Today's DPPs
</h2>
<Button variant="ghost" size="sm" className="text-muted-foreground font-medium">View All</Button>
</div>
<div className="space-y-4">
<Card className="hover:border-primary/30 hover:shadow-md cursor-pointer transition-all duration-300 group">
<CardContent className="p-5 flex items-center justify-between">
<div className="flex gap-4 items-center">
<div className="p-3 bg-secondary rounded-xl text-foreground">
<BrainCircuit size={20} />
</div>
<div>
<h3 className="font-medium text-base group-hover:text-primary transition-colors">Physics: Rotational Dynamics</h3>
<p className="text-sm text-muted-foreground mt-0.5">20 Questions • High Priority</p>
</div>
</div>
<Button variant="outline" size="sm" className="gap-2 rounded-xl group-hover:bg-primary group-hover:text-primary-foreground group-hover:border-primary transition-all">
Start <ArrowRight size={14} />
</Button>
</CardContent>
</Card>
{hasAccessTo("topic-wise-microtests-unlimited") ? (
<Card className="hover:border-primary/30 hover:shadow-md cursor-pointer transition-all duration-300 group">
<CardContent className="p-5 flex items-center justify-between">
<div className="flex gap-4 items-center">
<div className="p-3 bg-secondary rounded-xl text-foreground">
<BrainCircuit size={20} />
</div>
<div>
<h3 className="font-medium text-base group-hover:text-primary transition-colors">Biology: Human Physiology</h3>
<p className="text-sm text-muted-foreground mt-0.5">30 Questions • Medium Priority</p>
</div>
</div>
<Button variant="outline" size="sm" className="gap-2 rounded-xl group-hover:bg-primary group-hover:text-primary-foreground group-hover:border-primary transition-all">
Start <ArrowRight size={14} />
</Button>
</CardContent>
</Card>
) : (
<Card className="relative opacity-60 cursor-not-allowed border-dashed">
<CardContent className="p-5 flex items-center justify-between">
<div className="flex gap-4 items-center">
<div className="p-3 bg-secondary rounded-xl text-muted-foreground">
<Lock size={20} />
</div>
<div>
<h3 className="font-medium text-base text-muted-foreground">Biology: Human Physiology</h3>
<p className="text-sm text-muted-foreground mt-0.5 flex items-center gap-1"><Lock size={12}/> Pro Feature</p>
</div>
</div>
<Button variant="outline" size="sm" disabled className="gap-2 rounded-xl">
Locked
</Button>
</CardContent>
</Card>
)}
</div>
</section>
{/* Upcoming CBTs */}
<section>
<div className="flex items-center justify-between mb-5">
<h2 className="text-xl font-semibold tracking-tight flex items-center gap-2">
Upcoming CBTs
</h2>
</div>
<Card className="overflow-hidden">
<div className="p-6 border-b border-border flex items-center justify-between bg-background">
<div>
<div className="flex items-center gap-3 mb-2">
<Badge variant="outline" className="border-primary/20 bg-primary/5 text-primary">Mock Test</Badge>
<span className="text-xs text-muted-foreground font-semibold uppercase tracking-wider">Tomorrow, 10:00 AM</span>
</div>
<h3 className="font-semibold text-lg tracking-tight">AITS Full Syllabus Test 4</h3>
<p className="text-sm text-muted-foreground flex items-center gap-1.5 mt-1.5">
<Clock size={14} /> 180 Minutes • 720 Marks
</p>
</div>
<Button variant="secondary" className="rounded-xl font-medium">Remind Me</Button>
</div>
{hasAccessTo("weekly-test-series") ? (
<div className="p-5 bg-secondary/50 flex items-center justify-between transition-colors hover:bg-secondary/70 cursor-pointer group">
<div>
<h3 className="font-medium text-sm text-foreground flex items-center gap-2"><Activity size={14} className="text-primary group-hover:animate-pulse"/> Part Test 3: Mechanics</h3>
<p className="text-xs text-muted-foreground mt-0.5 font-medium ml-6">Oct 24, 2026</p>
</div>
<Button variant="outline" size="sm" className="h-7 text-xs rounded-lg group-hover:bg-primary group-hover:text-primary-foreground group-hover:border-primary">Start <ArrowRight size={12} className="ml-1" /></Button>
</div>
) : (
<div className="p-5 bg-secondary/50 flex items-center justify-between transition-colors hover:bg-secondary/70 opacity-75">
<div>
<h3 className="font-medium text-sm text-foreground flex items-center gap-2"><Lock size={14} className="text-muted-foreground"/> Part Test 3: Mechanics</h3>
<p className="text-xs text-muted-foreground mt-0.5 font-medium ml-6">Oct 24, 2026</p>
</div>
<Badge variant="secondary" className="text-xs">Pro Only</Badge>
</div>
)}
</Card>
</section>
</div>
</div>
)
}