344b1701dd
Uniform stock management for healthcare linen rooms. Licensed under the GNU AGPL v3.
30 lines
1.7 KiB
TypeScript
30 lines
1.7 KiB
TypeScript
import { SiteFooter } from "@/components/site";
|
|
import Analytics from "@/components/Analytics";
|
|
import JsonLd from "@/components/JsonLd";
|
|
import { graph, organization, website } from "@/lib/schema";
|
|
|
|
// Route group: no URL segment. Wraps every public marketing page in the same shell so the nav and
|
|
// footer are defined once. The nav itself is rendered per page so it can mark the active link.
|
|
|
|
// These pages are prerendered. Two things in them move on their own: the footer's copyright year,
|
|
// and — once, on the day plans go live — the price on every page that states one (lib/plans-live.ts).
|
|
// A minute keeps the pages served from the prerender for every reader while letting the console's
|
|
// plans switch reach the site without a deploy.
|
|
export const revalidate = 60;
|
|
export default function SiteLayout({ children }: { children: React.ReactNode }) {
|
|
return (
|
|
<div style={{ fontFamily: "var(--font-body)", color: "var(--color-text)", background: "var(--color-bg)", minHeight: "100vh", display: "flex", flexDirection: "column" }}>
|
|
{/* The link has to be the first focusable thing on the page, so it lives here rather than in
|
|
SiteNav. Its target is the page heading — PageHead carries id="content" — because each
|
|
page renders its own nav inside `children` to mark the active link, so a target on this
|
|
wrapper would land above the nav and skip nothing. */}
|
|
<a className="skip-link" href="#content">Skip to content</a>
|
|
<main style={{ flex: 1 }}>{children}</main>
|
|
<SiteFooter />
|
|
<Analytics site="marketing" />
|
|
{/* Who this is and what site it is. Stated once, on the shell every public page uses. */}
|
|
<JsonLd data={graph(organization, website)} />
|
|
</div>
|
|
);
|
|
}
|