Files
jiang13-bbs/frontend/components/SiteChrome.tsx

73 lines
1.7 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.
"use client";
import { useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import Header from "@/components/Header";
import Footer from "@/components/Footer";
import type { User } from "@/lib/api";
function pathIsAdmin(pathname: string | null) {
if (!pathname) return false;
return pathname === "/admin" || pathname.startsWith("/admin/");
}
/**
* 公开站 chrome 闸门:/admin 不渲染 Header/Footer/1440 main。
* 首屏用 middleware 的 x-pathname 初值保证 hydration 一致;
* 挂载后同步跟 usePathname(渲染期判定,避免 useEffect 晚一拍闪框)。
*/
export default function SiteChrome({
initialIsAdmin,
user,
unread,
chatUnread,
theme,
siteName,
allowRegister,
children,
}: {
initialIsAdmin: boolean;
user: User | null;
unread: number;
chatUnread: number;
theme: "light" | "dark";
siteName: string;
allowRegister: boolean;
children: React.ReactNode;
}) {
const pathname = usePathname();
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
// 首屏跟 SSR;之后在渲染期直接读 pathname,软导航无 Header 闪动
const isAdmin = mounted ? pathIsAdmin(pathname) : initialIsAdmin;
if (isAdmin) {
return <>{children}</>;
}
return (
<>
<Header
initialUser={user}
initialUnread={unread}
initialChatUnread={chatUnread}
initialTheme={theme}
siteName={siteName}
allowRegister={allowRegister}
/>
<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"
>
{children}
</main>
<Footer siteName={siteName} />
</>
);
}