Files
pragativeer-v2/src/components/AI/AdaptiveStudyPlan.tsx

106 lines
5.5 KiB
TypeScript

"use client"
import { useState } from "react"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { CheckCircle2, Clock, SkipForward, BrainCircuit } from "lucide-react"
type PlanState = 'PENDING' | 'DONE' | 'SKIPPED';
interface PlanItem {
id: string;
title: string;
duration: string;
type: string;
status: PlanState;
}
const INITIAL_PLAN: PlanItem[] = [
{ id: '1', title: 'Revise Thermodynamics Concepts', duration: '45 min', type: 'Theory', status: 'PENDING' },
{ id: '2', title: 'Solve 15 Rotational Dynamics DPPs', duration: '30 min', type: 'Practice', status: 'PENDING' },
{ id: '3', title: 'Review Mistakes in Optics (T-3)', duration: '20 min', type: 'Review', status: 'PENDING' },
];
export function AdaptiveStudyPlan() {
const [items, setItems] = useState<PlanItem[]>(INITIAL_PLAN);
const updateStatus = (id: string, newStatus: PlanState) => {
setItems(items.map(item => item.id === id ? { ...item, status: newStatus } : item));
};
const totalTime = items.reduce((acc, curr) => {
if (curr.status === 'DONE' || curr.status === 'PENDING') {
return acc + parseInt(curr.duration);
}
return acc;
}, 0);
return (
<Card className="border-border bg-background shadow-sm h-full flex flex-col">
<CardHeader className="pb-4 border-b border-border">
<div className="flex items-center justify-between">
<CardTitle className="text-xl flex items-center gap-2">
<BrainCircuit className="text-primary" /> Adaptive Study Plan
<Badge variant="outline" className="border-[#00F0FF]/30 text-[#00F0FF] bg-[#00F0FF]/5 rounded-md text-[10px] uppercase font-bold ml-2 hidden sm:flex">AI Coach</Badge>
</CardTitle>
<div className="flex items-center gap-2 bg-secondary/50 px-3 py-1 rounded-full text-xs font-bold text-foreground">
<Clock size={14} className="text-primary" /> Today: {totalTime} min
</div>
</div>
<p className="text-sm text-muted-foreground">Dynamically generated based on your weak areas.</p>
</CardHeader>
<CardContent className="flex-1 p-6">
<div className="relative space-y-6 before:absolute before:inset-0 before:ml-5 before:-translate-x-px md:before:mx-auto md:before:translate-x-0 before:h-full before:w-0.5 before:bg-gradient-to-b before:from-transparent before:via-border before:to-transparent">
{items.map((item, index) => {
const isDone = item.status === 'DONE';
const isSkipped = item.status === 'SKIPPED';
return (
<div key={item.id} className="relative flex items-center justify-between md:justify-normal md:odd:flex-row-reverse group is-active">
{/* Timeline Icon */}
<div className={`flex items-center justify-center w-10 h-10 rounded-full border-4 border-background shrink-0 md:order-1 md:group-odd:-translate-x-1/2 md:group-even:translate-x-1/2 shadow-sm z-10 transition-colors
${isDone ? 'bg-green-500 text-white' : isSkipped ? 'bg-muted border-muted text-muted-foreground' : 'bg-primary/20 text-primary border-primary/30'}
`}>
{isDone ? <CheckCircle2 size={18} /> : isSkipped ? <SkipForward size={18} /> : <div className="size-2.5 rounded-full bg-primary animate-pulse" />}
</div>
{/* Card */}
<div className="w-[calc(100%-4rem)] md:w-[calc(50%-2.5rem)] p-4 rounded-xl border border-border bg-background shadow-sm transition-all hover:shadow-md">
<div className={`flex items-center justify-between mb-1 ${isSkipped ? 'opacity-50' : ''}`}>
<span className="text-[10px] uppercase font-bold tracking-wider text-muted-foreground bg-secondary/50 px-2 py-0.5 rounded-md">
{item.type}
</span>
<span className="text-xs font-semibold text-primary">{item.duration}</span>
</div>
<h4 className={`font-bold text-sm md:text-base leading-tight mb-3 transition-colors ${isDone ? 'line-through text-muted-foreground' : isSkipped ? 'text-muted-foreground' : 'text-foreground'}`}>
{item.title}
</h4>
{/* Actions */}
<div className="flex gap-2">
{item.status === 'PENDING' ? (
<>
<Button size="sm" onClick={() => updateStatus(item.id, 'DONE')} className="h-8 text-xs font-bold flex-1 bg-green-500/10 text-green-500 hover:bg-green-500 hover:text-white border border-green-500/20">
Mark Done
</Button>
<Button variant="outline" size="sm" onClick={() => updateStatus(item.id, 'SKIPPED')} className="h-8 text-xs font-bold px-3 hover:bg-destructive/10 hover:text-destructive">
Skip
</Button>
</>
) : (
<div className="w-full flex items-center justify-center py-1 bg-secondary/50 rounded-lg text-xs font-bold text-muted-foreground">
{isDone ? 'Completed' : 'Rescheduled'}
</div>
)}
</div>
</div>
</div>
)
})}
</div>
</CardContent>
</Card>
)
}