124 lines
5.9 KiB
TypeScript
124 lines
5.9 KiB
TypeScript
"use client"
|
||
import { Card, CardContent } from "@/components/ui/card"
|
||
import { Flame, Star, Clock, TrendingUp } from "lucide-react"
|
||
import { useState } from "react"
|
||
|
||
const SLOTS = [
|
||
{ label: "6 AM", h: 30, score: 52, peak: false },
|
||
{ label: "9 AM", h: 55, score: 68, peak: false },
|
||
{ label: "12 PM", h: 65, score: 74, peak: false },
|
||
{ label: "2 PM", h: 90, score: 91, peak: false },
|
||
{ label: "3 PM", h: 100, score: 95, peak: true },
|
||
{ label: "5 PM", h: 82, score: 85, peak: false },
|
||
{ label: "7 PM", h: 70, score: 78, peak: false },
|
||
{ label: "9 PM", h: 55, score: 67, peak: false },
|
||
{ label: "11 PM", h: 32, score: 48, peak: false },
|
||
]
|
||
|
||
export function StudyTimeOptimizationCard() {
|
||
const [hovered, setHovered] = useState<number | null>(null)
|
||
const maxH = Math.max(...SLOTS.map(s => s.h))
|
||
|
||
return (
|
||
<div>
|
||
<Card className="border-border bg-card shadow-[0_4px_24px_rgba(0,0,0,0.3)] min-h-[440px] flex flex-col justify-between group hover:border-[#00F0FF]/30 transition-colors">
|
||
<CardContent className="p-5 flex-1 flex flex-col gap-4">
|
||
{/* Header stats */}
|
||
<div className="flex items-center gap-3 flex-wrap">
|
||
<div className="flex items-center gap-2">
|
||
<Star size={15} className="fill-yellow-500 text-yellow-500" />
|
||
<span className="text-sm font-bold text-yellow-500">Peak Window:</span>
|
||
<span className="text-sm font-bold bg-yellow-500/10 border border-yellow-500/20 px-2.5 py-0.5 rounded-full">
|
||
2 PM – 5 PM
|
||
</span>
|
||
</div>
|
||
<div className="ml-auto flex items-center gap-1.5 text-xs font-bold text-green-400 bg-green-400/10 border border-green-400/20 px-2.5 py-1 rounded-full">
|
||
<TrendingUp size={11} /> 95% efficiency at peak
|
||
</div>
|
||
</div>
|
||
|
||
{/* Bar chart with Y-axis */}
|
||
<div className="flex gap-2 flex-1">
|
||
{/* Y-axis labels */}
|
||
<div className="flex flex-col justify-between pb-6 text-right pr-1.5">
|
||
{[100, 75, 50, 25].map(v => (
|
||
<span key={v} className="text-[10px] text-muted-foreground font-semibold leading-none">{v}%</span>
|
||
))}
|
||
</div>
|
||
|
||
{/* Bars */}
|
||
<div className="flex-1 flex flex-col gap-1">
|
||
{/* Grid lines */}
|
||
<div className="relative flex-1 min-h-[120px]">
|
||
{[0, 25, 50, 75].map(pct => (
|
||
<div
|
||
key={pct}
|
||
className="absolute w-full border-t border-border/20"
|
||
style={{ bottom: `${pct}%` }}
|
||
/>
|
||
))}
|
||
<div className="flex items-end gap-1 h-full absolute inset-0">
|
||
{SLOTS.map((slot, i) => (
|
||
<div
|
||
key={slot.label}
|
||
className="flex-1 flex flex-col items-center justify-end h-full cursor-pointer relative group/bar"
|
||
onMouseEnter={() => setHovered(i)}
|
||
onMouseLeave={() => setHovered(null)}
|
||
>
|
||
{/* Tooltip */}
|
||
{hovered === i && (
|
||
<div className="absolute bottom-full mb-1.5 left-1/2 -translate-x-1/2 bg-background border border-border rounded-lg px-2.5 py-1.5 text-xs font-bold whitespace-nowrap shadow-lg z-10 pointer-events-none">
|
||
<div className="text-foreground">{slot.label}</div>
|
||
<div className={slot.peak ? "text-yellow-400" : "text-[#00F0FF]"}>Score: {slot.score}%</div>
|
||
</div>
|
||
)}
|
||
<div
|
||
className={`w-full rounded-t-md transition-all duration-300 ${
|
||
slot.peak
|
||
? "bg-gradient-to-t from-yellow-600/80 to-yellow-400 shadow-[0_0_14px_rgba(234,179,8,0.5)]"
|
||
: hovered === i
|
||
? "bg-gradient-to-t from-[#00F0FF]/70 to-[#00F0FF]"
|
||
: "bg-gradient-to-t from-[#00F0FF]/20 to-[#00F0FF]/50"
|
||
}`}
|
||
style={{ height: `${(slot.h / maxH) * 100}%` }}
|
||
/>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
{/* X-axis labels */}
|
||
<div className="flex gap-1 pt-1">
|
||
{SLOTS.map((slot) => (
|
||
<div key={slot.label} className="flex-1 text-center">
|
||
<span className="text-[10px] text-muted-foreground font-bold whitespace-nowrap">{slot.label}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Efficiency breakdown */}
|
||
<div className="grid grid-cols-3 gap-2 text-center">
|
||
{[
|
||
{ label: "Morning", time: "6–9 AM", eff: 60, color: "text-muted-foreground" },
|
||
{ label: "Peak", time: "2–5 PM", eff: 95, color: "text-yellow-400" },
|
||
{ label: "Evening", time: "7–9 PM", eff: 73, color: "text-[#00F0FF]" },
|
||
].map(slot => (
|
||
<div key={slot.label} className="p-2.5 rounded-xl bg-white/5 border border-border/30">
|
||
<div className={`text-base font-black ${slot.color}`}>{slot.eff}%</div>
|
||
<div className="text-[11px] font-bold text-muted-foreground">{slot.label}</div>
|
||
<div className="text-[10px] text-muted-foreground/60">{slot.time}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
<div className="px-3.5 py-3 bg-yellow-500/10 border border-yellow-500/20 rounded-xl text-xs md:text-sm text-yellow-500 font-bold flex items-center gap-2">
|
||
<Flame size={18} className="fill-yellow-500 shrink-0" />
|
||
You perform best 2–5 PM. Schedule your hardest mock tests and DPPs in this window.
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
)
|
||
}
|