// 仪表盘页面 // 依据:02-architecture-design.md §3.1 路由结构、§15 仪表盘设计 // 路由:/parent/dashboard // - 多子女并列展示 ChildSummaryCard // - 顶部关注横幅(逾期作业 / 出勤率低预警) // - 当前选中子女的考勤日历 "use client"; import { useState, useCallback, useEffect } from "react"; import { useChildSwitcher } from "@/hooks/useChildSwitcher"; import { useChildSummary } from "@/hooks/useChildSummary"; import { useChildAttendance } from "@/hooks/useChildAttendance"; import { ChildSummaryCard } from "@/components/ChildSummaryCard"; import { AttendanceCalendar } from "@/components/AttendanceCalendar"; import { ParentAttentionBanner } from "@/components/ParentAttentionBanner"; import type { ChildInfo, ChildSummary } from "@/types"; export default function DashboardPage() { const { children, currentChild, loading } = useChildSwitcher(); const { attendance, loading: attLoading } = useChildAttendance(); const [summaries, setSummaries] = useState>({}); const handleSummaryLoaded = useCallback( (childId: string, summary: ChildSummary) => { setSummaries((prev) => { if (prev[childId]?.avgScore === summary.avgScore) return prev; return { ...prev, [childId]: summary }; }); }, [], ); if (loading) { return (
); } if (children.length === 0) { return (

暂无绑定子女

); } const attentionItems = children.map((c) => ({ childId: c.id, childName: c.name, pendingHomeworkCount: summaries[c.id]?.pendingHomeworkCount ?? 0, attendanceRate: summaries[c.id]?.attendanceRate ?? 1, })); return (

学习概览

{/* 多子女并列卡片 */}
{children.map((child) => ( ))}
{/* 当前选中子女的考勤日历 */} {currentChild && (

{currentChild.name}的考勤

{attLoading ? ( ) : ( )}
)}
); } // 子女仪表盘卡片:独立获取每个子女的 summary function ChildDashboardCard({ child, onSummaryLoaded, }: { child: ChildInfo; onSummaryLoaded: (childId: string, summary: ChildSummary) => void; }) { const { summary, loading, error } = useChildSummary(child.id); useEffect(() => { if (summary) { onSummaryLoaded(child.id, summary); } }, [summary, child.id, onSummaryLoaded]); if (loading) { return (

{child.name}

); } if (error) { return (

{child.name}

加载失败:{error.message}
); } if (!summary) { return (

{child.name}

暂无数据

); } return (

{child.name}

); }