feat(portal-shell): implement portal-shell with apollo-router integration

M8: portal-shell unified frontend shell (Modular Monolith + micro-kernel).

- Apollo Client -> apollo-router (port 4010, RSC prefetch)

- 5 layouts: classic/focus/split/triple/canvas

- Registry + PluginLoader (dynamic import ssr:false)

- 3-layer props merge, Zustand PluginStore

- 4 widgets: grades/notification-bell/user-menu/class-selector

- config-service: new pluginConfig GraphQL resolver

- apollo-router: CORS + header propagation for portal-shell

- docker-compose.yml: portal-shell service block
This commit is contained in:
SpecialX
2026-07-15 08:06:09 +08:00
parent 47e950c664
commit 514e26ebb4
49 changed files with 2802 additions and 6 deletions

View File

@@ -0,0 +1,55 @@
import "./globals.css";
import type { Metadata } from "next";
import { Inter, Fraunces, JetBrains_Mono } from "next/font/google";
import type { ReactNode } from "react";
/**
* 字体加载next/font/google self-host
*
* 通过 CSS 变量暴露字体族(--font-inter / --font-fraunces / --font-jetbrains-mono
* ui-tokens 的 semantic 层将它们映射为 --font-family-sans/serif/mono。
* 禁止字体名字面量project_rules §3.10)。
*/
const inter = Inter({
subsets: ["latin"],
variable: "--font-inter",
display: "swap",
});
const fraunces = Fraunces({
subsets: ["latin"],
variable: "--font-fraunces",
display: "swap",
});
const mono = JetBrains_Mono({
subsets: ["latin"],
variable: "--font-jetbrains-mono",
display: "swap",
});
export const metadata: Metadata = {
title: "Edu Portal Shell",
description: "K12 智慧教务平台 - 插件化仪表盘",
};
/**
* RootLayout
*
* 仅负责 <html>/<body> 与字体变量。需要 RSC 数据的 Providers
* Apollo/Auth/ThemeI18n在 ClientShell 中挂载spec §5.5)。
*/
export default function RootLayout({
children,
}: {
children: ReactNode;
}): ReactNode {
return (
<html
lang="zh-CN"
className={`${inter.variable} ${fraunces.variable} ${mono.variable}`}
>
<body>{children}</body>
</html>
);
}