nomadweb/frontend/src/app/book/layout.tsx
eric ff7b721acb feat: NomadCNA community layer, social matching, payments, and ebook
Port meetups, discussions, gigs, dating/chat, VIP pay (ZPay/XorPay), MiroTalk live, digital academy, and ebook reader. Add persistent community_store, git-first deploy docs, and env template for production secrets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-30 09:38:13 -05:00

65 lines
2.4 KiB
TypeScript

import type { Metadata } from "next";
import { AntdRegistry } from "@ant-design/nextjs-registry";
import { Providers } from "@/components/ebook/Providers";
import { buildBookMetadata } from "@/lib/ebook/metadata";
import { getSiteConfig } from "@/lib/ebook/site-config.server";
import { getServerFeatures } from "@/lib/ebook/features.server";
import { getLocale } from "@/lib/ebook/i18n/server";
import "./ebook-globals.css";
export async function generateMetadata(): Promise<Metadata> {
const locale = await getLocale();
return buildBookMetadata(locale);
}
/**
* Book section is a self-contained surface inside nomadweb:
* - Own visual system (ebook-globals), isolated under .ebook-section
* - Locale bridged with main-site cookie/localStorage via getLocale + LocaleProvider
* - Theme driven by ThemeProvider on <html> (not a forced .dark wrapper)
* - No main Navbar / SiteShell — immersive like book.nomadro.com
* - Entry from main nav `/book`; escape via cover "← nomadro"
*/
export default async function BookLayout({
children,
}: {
children: React.ReactNode;
}) {
const locale = await getLocale();
const site = getSiteConfig();
const f = getServerFeatures();
return (
<div className="ebook-section" data-ebook-root>
<script
dangerouslySetInnerHTML={{
__html: `window.__EBOOK_FEATURES__=${JSON.stringify(f).replace(/</g, "\\u003c")};window.__LOCALE__=${JSON.stringify(locale)};(function(){try{var t=localStorage.getItem("theme");if(t==="light"||t==="sepia"||t==="dark"){document.documentElement.classList.remove("light","dark","sepia");document.documentElement.classList.add(t);}else{document.documentElement.classList.add("dark");}}catch(e){document.documentElement.classList.add("dark");}document.documentElement.style.scrollPaddingTop="0";})();`,
}}
/>
<AntdRegistry>
<Providers locale={locale}>
{children}
{f.feedback.enabled && (
<FeedbackLazy
title={f.feedback.title}
subtitle={f.feedback.subtitle}
contactEmail={site.brand.contactEmail}
xHandle={site.brand.xHandle}
/>
)}
</Providers>
</AntdRegistry>
</div>
);
}
function FeedbackLazy(props: {
title: string;
subtitle: string;
contactEmail: string;
xHandle: string;
}) {
const { FeedbackPanel } = require("@/components/ebook/FeedbackPanel");
return <FeedbackPanel {...props} />;
}