feat(dashboard): 新增分区 Error Boundary + Suspense 骨架屏(P2)

新增 components/dashboard-section.tsx,包含:

- DashboardSectionErrorBoundary:分区级 Error Boundary,单区块崩溃仅替换该区块不波及整页

- DashboardSectionSkeleton:5 种骨架变体(stats/card/chart/table/list),匹配不同数据区块布局

- DashboardSection:组合 Error Boundary + Suspense + 骨架屏的包装器

将 admin/teacher/student 三个仪表盘视图的每个独立数据区块用 DashboardSection 包裹,i18n 补充 sectionLoadFailed/sectionLoadFailedDesc 翻译键,同步更新架构图 004/005 文档
This commit is contained in:
SpecialX
2026-06-22 15:58:49 +08:00
parent 868ac5f9cf
commit 21c1e7a286
8 changed files with 454 additions and 167 deletions

View File

@@ -1,5 +1,6 @@
import type { StudentDashboardProps } from "@/modules/dashboard/types"
import { DashboardSection } from "../dashboard-section"
import { StudentDashboardHeader } from "./student-dashboard-header"
import { StudentGradesCard } from "./student-grades-card"
import { StudentStatsGrid } from "./student-stats-grid"
@@ -20,21 +21,29 @@ export async function StudentDashboard({
<div className="space-y-6">
<StudentDashboardHeader studentName={studentName} />
<StudentStatsGrid
enrolledClassCount={enrolledClassCount}
dueSoonCount={dueSoonCount}
overdueCount={overdueCount}
gradedCount={gradedCount}
ranking={grades.ranking}
/>
<DashboardSection variant="stats">
<StudentStatsGrid
enrolledClassCount={enrolledClassCount}
dueSoonCount={dueSoonCount}
overdueCount={overdueCount}
gradedCount={gradedCount}
ranking={grades.ranking}
/>
</DashboardSection>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div className="lg:col-span-2 space-y-6">
<StudentUpcomingAssignmentsCard upcomingAssignments={upcomingAssignments} />
<StudentGradesCard grades={grades} />
<DashboardSection variant="list">
<StudentUpcomingAssignmentsCard upcomingAssignments={upcomingAssignments} />
</DashboardSection>
<DashboardSection variant="card">
<StudentGradesCard grades={grades} />
</DashboardSection>
</div>
<div className="space-y-6">
<StudentTodayScheduleCard items={todayScheduleItems} />
<DashboardSection variant="card">
<StudentTodayScheduleCard items={todayScheduleItems} />
</DashboardSection>
</div>
</div>
</div>