chore: remove parent dashboard UI and update PRD tags

This commit is contained in:
2026-08-13 11:41:52 +05:30
parent ba583836e3
commit b152f73c3d
2 changed files with 18 additions and 246 deletions

View File

@@ -1,222 +0,0 @@
"use client"
import { useState, useEffect } from "react"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Switch } from "@/components/ui/switch"
import { Label } from "@/components/ui/label"
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts"
import { Activity, Clock, Flame, AlertTriangle, RefreshCw } from "lucide-react"
import { useActiveUser } from "@/hooks/useActiveUser"
// Hardcoded mock UUIDs for this sprint
const PARENT_ID = "parent-123"
const DICTIONARY = {
en: {
title: "Parent Monitoring Portal",
subtitle: "Real-time analytics for your child's learning journey.",
lang_toggle: "हिंदी",
time_spent: "Weekly Time Spent",
minutes: "Minutes",
streak: "Active Streak",
days: "Days",
tests_attempted: "Tests Attempted",
tests: "This week",
accuracy_trend: "7-Day Accuracy Trend",
areas_of_concern: "Areas of Concern",
attention_needed: "Attention Needed",
pending_errors: "pending errors",
loading: "Loading child data...",
no_concerns: "No current areas of concern. Great job!"
},
hi: {
title: "अभिभावक निगरानी पोर्टल",
subtitle: "आपके बच्चे की सीखने की यात्रा के लिए वास्तविक समय विश्लेषिकी।",
lang_toggle: "English",
time_spent: "साप्ताहिक समय व्यतीत",
minutes: "मिनट",
streak: "सक्रिय लकीर",
days: "दिन",
tests_attempted: "परीक्षण का प्रयास",
tests: "इस सप्ताह",
accuracy_trend: "7-दिवसीय सटीकता प्रवृत्ति",
areas_of_concern: "चिंता के विषय",
attention_needed: "ध्यान देने की आवश्यकता है",
pending_errors: "लंबित त्रुटियां",
loading: "बच्चे का डेटा लोड हो रहा है...",
no_concerns: "चिंता का कोई विषय नहीं है। बहुत बढ़िया!"
}
}
export default function ParentDashboard() {
const { userId, loading: userLoading } = useActiveUser()
const [lang, setLang] = useState<'en' | 'hi'>('en')
const [data, setData] = useState<any>(null)
const [loading, setLoading] = useState(true)
const t = DICTIONARY[lang]
useEffect(() => {
if (userLoading || !userId) return;
async function fetchDashboard() {
try {
const res = await fetch(`/api/parent/${PARENT_ID}/dashboard/${userId}`)
if (!res.ok) throw new Error("Failed to fetch")
const payload = await res.json()
setData(payload)
} catch (err) {
console.error(err)
// Fallback mock data if server fails
setData({
student_name: "Rahul",
streak_count: 5,
weekly_minutes_spent: 124.5,
total_tests_attempted_this_week: 3,
accuracy_trend: [
{ date: "Jul 01", accuracy: 40 },
{ date: "Jul 02", accuracy: 55 },
{ date: "Jul 03", accuracy: 50 },
{ date: "Jul 04", accuracy: 70 },
{ date: "Jul 05", accuracy: 65 },
{ date: "Jul 06", accuracy: 80 },
{ date: "Jul 07", accuracy: 85 }
],
areas_of_concern: [
{ topic: "Thermodynamics", pending_errors: 4 },
{ topic: "Integration", pending_errors: 2 }
]
})
} finally {
setLoading(false)
}
}
fetchDashboard()
}, [userId, userLoading])
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center">
<RefreshCw className="animate-spin text-muted-foreground mr-3" /> {t.loading}
</div>
)
}
return (
<div className="p-8 max-w-6xl mx-auto space-y-10 animate-in fade-in duration-500">
{/* Header & Language Toggle */}
<header className="flex flex-col md:flex-row md:items-center justify-between gap-4 border-b border-border pb-6">
<div>
<h1 className="text-3xl font-bold tracking-tight text-primary">
{t.title}
</h1>
<p className="text-muted-foreground mt-1 font-medium">{t.subtitle} — {data?.student_name}</p>
</div>
{/*
<div className="flex items-center space-x-3">
<Label htmlFor="lang-switch" className="font-bold text-muted-foreground">{lang === 'hi' ? 'English' : 'हिंदी'}</Label>
<Switch
id="lang-switch"
checked={lang === 'hi'}
onCheckedChange={(c) => setLang(c ? 'hi' : 'en')}
/>
</div>
*/}
</header>
{/* Metric Blocks */}
<section className="grid grid-cols-1 md:grid-cols-3 gap-6">
<Card className="border-border shadow-sm bg-secondary/10">
<CardContent className="p-6 flex items-center gap-5">
<div className="p-4 bg-primary/10 rounded-2xl text-primary"><Clock size={28}/></div>
<div>
<p className="text-sm font-bold text-muted-foreground uppercase tracking-wider">{t.time_spent}</p>
<h3 className="text-3xl font-black mt-1">{data?.weekly_minutes_spent} <span className="text-sm font-semibold text-muted-foreground lowercase">{t.minutes}</span></h3>
</div>
</CardContent>
</Card>
<Card className="border-border shadow-sm bg-secondary/10">
<CardContent className="p-6 flex items-center gap-5">
<div className="p-4 bg-amber-500/10 rounded-2xl text-amber-500"><Flame size={28}/></div>
<div>
<p className="text-sm font-bold text-muted-foreground uppercase tracking-wider">{t.streak}</p>
<h3 className="text-3xl font-black mt-1">{data?.streak_count} <span className="text-sm font-semibold text-muted-foreground lowercase">{t.days}</span></h3>
</div>
</CardContent>
</Card>
<Card className="border-border shadow-sm bg-secondary/10">
<CardContent className="p-6 flex items-center gap-5">
<div className="p-4 bg-emerald-500/10 rounded-2xl text-emerald-500"><Activity size={28}/></div>
<div>
<p className="text-sm font-bold text-muted-foreground uppercase tracking-wider">{t.tests_attempted}</p>
<h3 className="text-3xl font-black mt-1">{data?.total_tests_attempted_this_week} <span className="text-sm font-semibold text-muted-foreground lowercase">{t.tests}</span></h3>
</div>
</CardContent>
</Card>
</section>
{/* Main Grid */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Chart */}
<Card className="lg:col-span-2 border-border shadow-sm">
<CardHeader>
<CardTitle className="text-lg">{t.accuracy_trend}</CardTitle>
</CardHeader>
<CardContent>
<div className="h-[300px] w-full">
<ResponsiveContainer width="100%" height="100%">
<LineChart data={data?.accuracy_trend}>
<CartesianGrid strokeDasharray="3 3" stroke="#333" opacity={0.2} />
<XAxis dataKey="date" stroke="#888" fontSize={12} tickLine={false} axisLine={false} />
<YAxis stroke="#888" fontSize={12} tickLine={false} axisLine={false} domain={[0, 100]} tickFormatter={(val) => `${val}%`} />
<Tooltip
contentStyle={{ backgroundColor: 'hsl(var(--background))', borderColor: 'hsl(var(--border))', borderRadius: '8px' }}
itemStyle={{ color: 'hsl(var(--primary))' }}
/>
<Line
type="monotone"
dataKey="accuracy"
stroke="hsl(var(--primary))"
strokeWidth={4}
dot={{ r: 4, fill: 'hsl(var(--primary))' }}
activeDot={{ r: 8 }}
/>
</LineChart>
</ResponsiveContainer>
</div>
</CardContent>
</Card>
{/* Areas of Concern */}
<Card className="border-border shadow-sm">
<CardHeader>
<CardTitle className="text-lg flex items-center gap-2">
<AlertTriangle className="text-red-500" size={20} />
{t.areas_of_concern}
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
{!data?.areas_of_concern || data.areas_of_concern.length === 0 ? (
<div className="text-center p-6 bg-secondary/20 rounded-xl">
<p className="text-muted-foreground font-medium">{t.no_concerns}</p>
</div>
) : (
data.areas_of_concern.map((concern: any, idx: number) => (
<div key={idx} className="p-4 rounded-xl border border-red-500/20 bg-red-500/5 relative overflow-hidden group">
<div className="absolute left-0 top-0 bottom-0 w-1 bg-red-500 rounded-l-xl"></div>
<h4 className="font-bold text-foreground mb-1">{concern.topic}</h4>
<p className="text-xs font-semibold text-red-500 uppercase tracking-wider">
{t.attention_needed} • {concern.pending_errors} {t.pending_errors}
</p>
</div>
))
)}
</CardContent>
</Card>
</div>
</div>
)
}