184 lines
9.4 KiB
TypeScript
184 lines
9.4 KiB
TypeScript
"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>
|
||
)
|
||
}
|