109 lines
3.8 KiB
TypeScript
109 lines
3.8 KiB
TypeScript
/**
|
|
* ROOT LAYOUT — Shahi Kitchen (shahikitchen.se)
|
|
*
|
|
* This is the single root layout for the entire Next.js App Router application.
|
|
*
|
|
* RESPONSIBILITIES:
|
|
* - Set up global metadata (title, description, favicon) for SEO and social sharing
|
|
* - Load the premium typography system:
|
|
* • Playfair Display (display/serif) → used for headings via --font-playfair
|
|
* • Geist Sans (system UI) → body text
|
|
* • Geist Mono → code / tabular data
|
|
* - Initialize the GLOBAL CART SYSTEM:
|
|
* • CartProvider wraps the whole tree so any page/component can use `useCart()`
|
|
* • CartDrawer is rendered once at the root (slide-in basket panel)
|
|
* • Sonner <Toaster> provides beautiful toast notifications used by the cart
|
|
*
|
|
* ARCHITECTURAL NOTES:
|
|
* - We deliberately render <CartDrawer /> and <Toaster /> at the root level instead of
|
|
* inside individual pages. This guarantees only ONE instance exists and prevents
|
|
* duplicate drawers/toasts when navigating.
|
|
* - The cream/gold Shahi theme tokens live in globals.css and are referenced via
|
|
* Tailwind arbitrary values (e.g. bg-[#F8F5F0]).
|
|
*
|
|
* FUTURE DEVELOPERS:
|
|
* - To add a new global provider (theme, analytics, etc.), wrap it here.
|
|
* - WhatsApp number for orders is currently hardcoded in CartDrawer.tsx (46739381089).
|
|
* - If you ever split the cart into a separate modal library, keep the provider here.
|
|
*/
|
|
|
|
import type { Metadata } from "next";
|
|
import { Playfair_Display, Geist, Geist_Mono } from "next/font/google";
|
|
import "./globals.css";
|
|
import { Toaster } from "sonner";
|
|
import { CartProvider } from "@/components/CartContext";
|
|
import CartDrawer from "@/components/CartDrawer";
|
|
import { LanguageProvider } from "@/lib/language-context";
|
|
|
|
const playfair = Playfair_Display({
|
|
variable: "--font-playfair",
|
|
subsets: ["latin"],
|
|
weight: ["400", "500", "600", "700"],
|
|
style: ["normal", "italic"],
|
|
});
|
|
|
|
const geistSans = Geist({
|
|
variable: "--font-geist-sans",
|
|
subsets: ["latin"],
|
|
weight: ["400", "500", "600", "700"],
|
|
});
|
|
|
|
const geistMono = Geist_Mono({
|
|
variable: "--font-geist-mono",
|
|
subsets: ["latin"],
|
|
weight: ["400", "500", "600"],
|
|
});
|
|
|
|
/**
|
|
* Next.js Metadata API (static)
|
|
* These values power:
|
|
* - Browser tab title
|
|
* - Search engine results
|
|
* - Social cards (Open Graph / Twitter) when shared
|
|
*
|
|
* For dynamic per-page metadata, use `generateMetadata()` in page files.
|
|
*/
|
|
export const metadata: Metadata = {
|
|
title: "Shahi Kitchen | Authentic Indian & Pakistani Restaurant in Gothenburg",
|
|
description: "Experience Shahi flavors at Shahi Kitchen in Askim, Gothenburg. Authentic Indian & Pakistani cuisine, famous lunch buffet, and traditional sweets since 2016.",
|
|
icons: {
|
|
icon: "/favicon.ico",
|
|
},
|
|
};
|
|
|
|
/**
|
|
* RootLayout
|
|
*
|
|
* The ONLY place in the app where we initialize:
|
|
* 1. CartProvider → gives every descendant access to `useCart()` hook
|
|
* 2. CartDrawer → the actual slide-in basket UI (controlled via context)
|
|
* 3. Toaster → global toast surface used by cart (Sonner library)
|
|
*
|
|
* IMPORTANT:
|
|
* - Never wrap the entire app in another CartProvider — it will break the singleton.
|
|
* - The body uses the Shahi cream background (#F8F5F0) as the base canvas.
|
|
* - `antialiased` + font variables are applied once at the root for consistency.
|
|
*/
|
|
export default function RootLayout({
|
|
children,
|
|
}: Readonly<{
|
|
children: React.ReactNode;
|
|
}>) {
|
|
return (
|
|
<html
|
|
lang="sv"
|
|
className={`${playfair.variable} ${geistSans.variable} ${geistMono.variable} h-full antialiased`}
|
|
>
|
|
<body className="min-h-full flex flex-col bg-[#F8F5F0] text-[#2C2A26]">
|
|
<LanguageProvider>
|
|
<CartProvider>
|
|
{children}
|
|
<CartDrawer />
|
|
<Toaster position="top-center" richColors closeButton />
|
|
</CartProvider>
|
|
</LanguageProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|