Files
NextEdu/src/app/(dashboard)/layout.tsx
SpecialX 21142f9b99 feat(app): add error/loading boundaries across all dashboard routes and new routes
- Add error.tsx and loading.tsx boundaries for admin, parent, student, teacher routes

- Add admin announcements edit, audit-logs overview, curriculum-map, invitation-codes, permissions, questions, roles routes

- Add admin elective detail and components, files, course-plans, users, scheduling boundaries

- Add messages group-compose route

- Add parent course-plans, elective, grades report-card, practice routes

- Add student course-plans, elective detail, error-book dialogs, grades report-card, learning study-path, leave, schedule boundaries

- Add teacher attendance report, classes boundaries, course-plans boundaries, elective, exams analytics/edit-rich/all/create/new, grades report-card, homework boundaries, leave, lesson-plans calendar

- Add auth loading, onboarding loading, api cron
2026-07-03 10:26:25 +08:00

34 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { AppSidebar } from "@/modules/layout/components/app-sidebar"
import { SidebarProvider } from "@/modules/layout/components/sidebar-provider"
import { SiteHeader } from "@/modules/layout/components/site-header"
import {
AiClientProvider,
} from "@/modules/ai/context/ai-client-provider"
import { AiAssistantWidget } from "@/modules/ai/components/ai-assistant-widget"
import { createFullAiClientService } from "@/modules/ai/context/create-ai-client-service"
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}): React.ReactNode {
// 在 Server Component 函数体内创建 service避免模块级单例在未来扩展请求级状态时泄露上下文。
// service 对象本身仅是 Server Action 引用集合无共享可变状态Action 内部通过 requirePermission() 动态解析当前用户。
const aiClientService = createFullAiClientService()
return (
<AiClientProvider service={aiClientService}>
<SidebarProvider sidebar={<AppSidebar />}>
<a href="#main-content" className="sr-only focus:not-sr-only focus:absolute focus:z-50 focus:p-4 focus:bg-background focus:text-foreground focus:border focus:border-border focus:rounded-md focus:m-2">
Skip to main content
</a>
<SiteHeader />
<main id="main-content" className="flex-1 overflow-auto p-6">
{children}
</main>
<AiAssistantWidget />
</SidebarProvider>
</AiClientProvider>
)
}