|
- import type { Metadata } from "next";
- import { GeistSans } from "geist/font/sans";
- import { GeistMono } from "geist/font/mono";
- import fs from "fs/promises";
- import path from "path";
- import { getPortals } from "@/lib/db";
- import { DEFAULT_FONT } from "@/lib/config";
- import { withBasePath } from "@/lib/url";
- import "./globals.css";
-
- export const metadata: Metadata = {
- title: "Captive Portal",
- description: "Welcome",
- };
-
- function fontFormat(ext: string): string {
- switch (ext.toLowerCase()) {
- case ".woff2": return "woff2";
- case ".woff": return "woff";
- case ".ttf": return "truetype";
- case ".otf": return "opentype";
- default: return "woff2";
- }
- }
-
- async function findSibling(regularFilename: string, suffix: string): Promise<string | null> {
- const m = regularFilename.match(/^(.*)(\.(?:woff2?|ttf|otf))$/i);
- if (!m) return null;
- const [, base, ext] = m;
- const lower = suffix.toLowerCase();
- const candidates = [
- `${base}-${suffix}${ext}`, `${base}-${lower}${ext}`,
- `${base}_${suffix}${ext}`, `${base}_${lower}${ext}`,
- `${base} ${suffix}${ext}`, `${base} ${lower}${ext}`,
- `${base}${suffix}${ext}`, `${base}${lower}${ext}`,
- ];
- try {
- const files = await fs.readdir(path.join(process.cwd(), "data", "fonts"));
- for (const c of candidates) {
- if (files.includes(c)) return c;
- }
- } catch {}
- return null;
- }
-
- export default async function RootLayout({
- children,
- }: Readonly<{ children: React.ReactNode }>) {
- // Leggi il portale per scegliere il font
- let chosenFont = DEFAULT_FONT;
- try {
- const portals = await getPortals();
- const portal = portals[0];
- if (portal && portal.fontFamily !== undefined) chosenFont = portal.fontFamily;
- } catch {}
-
- let fontStyleCss = "";
- if (chosenFont) {
- const fontUrl = (name: string) => withBasePath(`/api/fonts?name=${encodeURIComponent(name)}`);
- const faceBlock = (file: string, weight: 400 | 700, style: 'normal' | 'italic') => `
- @font-face {
- font-family: 'PortalFont';
- src: url('${fontUrl(file)}') format('${fontFormat(path.extname(file))}');
- font-style: ${style};
- font-weight: ${weight};
- font-display: swap;
- }`;
-
- const italicFile = await findSibling(chosenFont, 'Italic');
- const boldFile = await findSibling(chosenFont, 'Bold');
- const boldItalicFile = await findSibling(chosenFont, 'BoldItalic');
-
- fontStyleCss = [
- faceBlock(chosenFont, 400, 'normal'),
- italicFile ? faceBlock(italicFile, 400, 'italic') : '',
- boldFile ? faceBlock(boldFile, 700, 'normal') : '',
- boldItalicFile ? faceBlock(boldItalicFile, 700, 'italic') : '',
- `\n:root { --font-portal: 'PortalFont', Arial, Helvetica, sans-serif; }\n`,
- ].join('');
- }
-
- return (
- <html
- lang="it"
- className={`${GeistSans.variable} ${GeistMono.variable} h-full antialiased`}
- >
- <body className="min-h-full flex flex-col">
- {fontStyleCss && <style dangerouslySetInnerHTML={{ __html: fontStyleCss }} />}
- {children}
- </body>
- </html>
- );
- }
|