feat(admin): 独立后台壳、站点分析与聊天监管,公开站拆出主题切换与访问埋点
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
import type { Metadata } from "next";
|
||||
import { cookies } from "next/headers";
|
||||
import { cookies, headers } from "next/headers";
|
||||
import { Plus_Jakarta_Sans, Noto_Sans_SC, JetBrains_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import SiteChrome from "@/components/SiteChrome";
|
||||
import Toaster from "@/components/Toaster";
|
||||
import TipHost from "@/components/TipHost";
|
||||
import AccountGuard from "@/components/AccountGuard";
|
||||
import ThemeSync from "@/components/ThemeSync";
|
||||
import RealtimeProvider from "@/components/RealtimeProvider";
|
||||
import VisitBeacon from "@/components/VisitBeacon";
|
||||
import PostLinkProvider from "@/components/PostLinkProvider";
|
||||
import CodeFoldProvider from "@/components/markdown/CodeFoldProvider";
|
||||
import MotionProvider from "@/components/MotionProvider";
|
||||
import CommentsPolicyProvider from "@/components/CommentsPolicyProvider";
|
||||
@@ -65,6 +66,11 @@ export default async function RootLayout({
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const cookieStore = await cookies();
|
||||
const headerStore = await headers();
|
||||
// middleware 写入 x-pathname;供 SiteChrome SSR 初值(软导航靠客户端 pathname)
|
||||
const pathname = headerStore.get("x-pathname") || "";
|
||||
const isAdmin = pathname === "/admin" || pathname.startsWith("/admin/");
|
||||
|
||||
// 浅色优先的设计系统,仅在显式选择暗色时挂 .dark
|
||||
const theme = cookieStore.get("j13-theme")?.value === "dark" ? "dark" : "light";
|
||||
|
||||
@@ -113,35 +119,33 @@ export default async function RootLayout({
|
||||
<a href="#main" className="skip-link">
|
||||
跳到主要内容
|
||||
</a>
|
||||
<Header
|
||||
initialUser={user}
|
||||
initialUnread={unread}
|
||||
initialChatUnread={chatUnread}
|
||||
initialTheme={theme}
|
||||
siteName={settings.site_name}
|
||||
allowRegister={settings.allow_register}
|
||||
/>
|
||||
<main
|
||||
id="main"
|
||||
tabIndex={-1}
|
||||
className="flex-1 w-full max-w-[1440px] mx-auto px-4 sm:px-6 py-7 sm:py-9 outline-none"
|
||||
>
|
||||
<MotionProvider initial={motionCfg}>
|
||||
<CommentsPolicyProvider allowComments={settings.allow_comments !== false}>
|
||||
<MotionProvider initial={motionCfg}>
|
||||
<CommentsPolicyProvider allowComments={settings.allow_comments !== false}>
|
||||
<PostLinkProvider openInNewTab={settings.post_link_new_tab !== false}>
|
||||
<CodeFoldProvider
|
||||
initialEnabled={settings.code_block_auto_fold}
|
||||
initialFoldLines={settings.code_block_fold_lines}
|
||||
>
|
||||
{children}
|
||||
<SiteChrome
|
||||
initialIsAdmin={isAdmin}
|
||||
user={user}
|
||||
unread={unread}
|
||||
chatUnread={chatUnread}
|
||||
theme={theme}
|
||||
siteName={settings.site_name}
|
||||
allowRegister={settings.allow_register}
|
||||
>
|
||||
{children}
|
||||
</SiteChrome>
|
||||
</CodeFoldProvider>
|
||||
</CommentsPolicyProvider>
|
||||
</MotionProvider>
|
||||
</main>
|
||||
<Footer siteName={settings.site_name} />
|
||||
</PostLinkProvider>
|
||||
</CommentsPolicyProvider>
|
||||
</MotionProvider>
|
||||
<Toaster />
|
||||
<TipHost />
|
||||
<AccountGuard />
|
||||
<ThemeSync initialAccent={accent || ""} />
|
||||
<VisitBeacon />
|
||||
<RealtimeProvider userId={user ? user.id : null} />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user