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

184 lines
9.4 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 { StudyTimeOptimizationCard } from "@/components/AI/StudyTimeOptimizationCard"
import { Clock, Zap, Moon, Sun, AlertCircle, ArrowRight, BarChart2 } from "lucide-react"
import { Card, CardContent } from "@/components/ui/card"
import Link from "next/link"
import { useActiveUser, isDemoUser } from "@/hooks/useActiveUser"
const DEMO_INSIGHTS = [
{
icon: <Sun size={16} className="text-yellow-400" />,
title: "Peak Cognitive Window",
desc: "2 PM – 5 PM is your highest-efficiency block. Reserve this for new concepts, hard problems, and mock tests.",
color: "border-yellow-400/20 bg-yellow-400/5",
},
{
icon: <Moon size={16} className="text-indigo-400" />,
title: "Evening Consolidation",
desc: "9–10 PM is ideal for light revision and flashcard review — this window solidifies short-term to long-term memory.",
color: "border-indigo-400/20 bg-indigo-400/5",
},
{
icon: <AlertCircle size={16} className="text-red-400" />,
title: "Avoid After 11 PM",
desc: "Cognitive fatigue significantly increases error rate. Solving new concepts late at night is counterproductive.",
color: "border-red-400/20 bg-red-400/5",
},
]
const DEMO_HOURLY_EFFICIENCY = [
{ slot: "6–9 AM", pct: 60, label: "Morning" },
{ slot: "9–12 PM", pct: 72, label: "Mid-Morning" },
{ slot: "12–2 PM", pct: 55, label: "Post-Lunch dip" },
{ slot: "2–5 PM", pct: 95, label: "Peak ★", highlight: true },
{ slot: "5–7 PM", pct: 82, label: "Afternoon" },
{ slot: "7–9 PM", pct: 74, label: "Evening" },
{ slot: "9–11 PM", pct: 60, label: "Night Revision" },
{ slot: "11 PM+", pct: 32, label: "Avoid" },
]
const ZERO_HOURLY_EFFICIENCY = [
{ slot: "6–9 AM", pct: 0, label: "Pending" },
{ slot: "9–12 PM", pct: 0, label: "Pending" },
{ slot: "12–2 PM", pct: 0, label: "Pending" },
{ slot: "2–5 PM", pct: 0, label: "Calibrating", highlight: false },
{ slot: "5–7 PM", pct: 0, label: "Pending" },
{ slot: "7–9 PM", pct: 0, label: "Pending" },
{ slot: "9–11 PM", pct: 0, label: "Pending" },
{ slot: "11 PM+", pct: 0, label: "Pending" },
]
export default function TimeOptimizationPage() {
const { userId } = useActiveUser()
const isDemo = isDemoUser(userId)
const hourlySlots = isDemo ? DEMO_HOURLY_EFFICIENCY : ZERO_HOURLY_EFFICIENCY
const insights = isDemo ? DEMO_INSIGHTS : [
{
icon: <Sun size={16} className="text-yellow-400" />,
title: "Peak Window Calibrating",
desc: "Complete 3 test sessions at different times of day to establish your circadian peak focus hours.",
color: "border-yellow-400/20 bg-yellow-400/5",
},
{
icon: <Moon size={16} className="text-indigo-400" />,
title: "Consistency Booster",
desc: "Start with a 30-minute daily review routine to jumpstart your spaced repetition learning schedule.",
color: "border-indigo-400/20 bg-indigo-400/5",
},
]
return (
<div className="p-6 md:p-8 max-w-7xl mx-auto space-y-8 min-h-screen animate-in fade-in zoom-in-95 slide-in-from-bottom-4 duration-500">
{/* 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)]">
<Clock className="text-cyan-700 dark:text-[var(--cyan-ai)]" size={28} />
</span>
Study Time Optimization
</h1>
<p className="text-muted-foreground text-base font-medium max-w-2xl pl-1">
Understand your peak productive hours and schedule your hardest topics in your highest-efficiency windows.
</p>
</div>
<span className="text-xs font-bold uppercase tracking-wider text-[var(--cyan-ai)] 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">
<Zap size={12} /> Chronobiology Analytics
</span>
</div>
</div>
{/* KPI Strip */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{[
{ label: "Peak Efficiency", value: isDemo ? "95%" : "--", sub: isDemo ? "2–5 PM window" : "Calibrating", color: "border-yellow-400/20 bg-yellow-400/5", icon: <Sun size={18} className="text-yellow-400" /> },
{ label: "Study Hrs Today", value: isDemo ? "3.8 h" : "0.0 h", sub: "Target: 6 h", color: "border-[var(--cyan-ai-20)] bg-[var(--cyan-ai-10)]", icon: <Clock size={18} className="text-[var(--cyan-ai)]" /> },
{ label: "Morning Block", value: isDemo ? "60%" : "0%", sub: "6–9 AM", color: "border-indigo-400/20 bg-indigo-400/5", icon: <Moon size={18} className="text-indigo-400" /> },
{ label: "Evening Block", value: isDemo ? "74%" : "0%", sub: "7–9 PM", color: "border-green-400/20 bg-green-400/5", icon: <BarChart2 size={18} className="text-green-400" /> },
].map(kpi => (
<Card key={kpi.label} className={`rounded-2xl border ${kpi.color}`}>
<CardContent className="p-4 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>
<div className="text-[11px] font-bold text-muted-foreground/60">{kpi.sub}</div>
</CardContent>
</Card>
))}
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Chart — 2/3 */}
<div className="lg:col-span-2 space-y-4">
<div className="flex items-center gap-2 text-sm font-black uppercase tracking-wider text-muted-foreground">
<BarChart2 size={16} className="text-[var(--cyan-ai)]" />
Hourly Efficiency Profile
</div>
<StudyTimeOptimizationCard />
</div>
{/* Right Panel */}
<div className="space-y-5">
{/* Slot breakdown table */}
<Card className="bg-secondary/10 border-border/60 rounded-2xl">
<CardContent className="p-5 space-y-3">
<h3 className="text-sm font-black uppercase tracking-wider text-muted-foreground">Time Slot Breakdown</h3>
<div className="space-y-2">
{hourlySlots.map(slot => (
<div key={slot.slot} className={`flex items-center gap-3 p-2 rounded-lg ${slot.highlight ? "bg-yellow-400/10 border border-yellow-400/20" : "bg-white/5"}`}>
<div className="w-16 text-xs font-bold text-muted-foreground shrink-0">{slot.slot}</div>
<div className="flex-1 h-1.5 bg-secondary rounded-full overflow-hidden">
<div
className={`h-full rounded-full ${slot.pct >= 80 ? (slot.highlight ? "bg-yellow-400" : "bg-green-400") : slot.pct >= 60 ? "bg-[var(--cyan-ai)]" : isDemo ? "bg-red-400" : "bg-white/10"}`}
style={{ width: `${slot.pct}%` }}
/>
</div>
<div className={`text-xs font-black w-8 text-right shrink-0 ${slot.highlight ? "text-yellow-400" : "text-muted-foreground"}`}>{slot.pct}%</div>
{slot.highlight && <span className="text-[10px] font-black text-yellow-400 shrink-0">PEAK</span>}
</div>
))}
</div>
</CardContent>
</Card>
{/* AI Insights */}
<div className="space-y-3">
{insights.map(insight => (
<Card key={insight.title} className={`rounded-2xl border ${insight.color}`}>
<CardContent className="p-4 flex items-start gap-3">
<div className="mt-0.5 shrink-0">{insight.icon}</div>
<div>
<p className="text-sm font-black">{insight.title}</p>
<p className="text-xs text-muted-foreground font-medium mt-0.5">{insight.desc}</p>
</div>
</CardContent>
</Card>
))}
</div>
<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)]">Apply Insights</h3>
<div className="space-y-2">
{[
{ label: "Schedule Today's Study Plan", href: "/dashboard/ai-coach/study-plan" },
{ label: "Check Exam Readiness", href: "/dashboard/ai-coach/readiness" },
{ label: "Launch a Practice Test Now", href: "/dashboard/ai-coach/cbt-dpp" },
].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>
</div>
</div>
</div>
)
}