feat: Sprint 4 complete — frontend MVP (admin dashboard + member portal)
Shadboard starter-kit (Next.js 15 + React 19 + shadcn/ui + Tailwind 4) Sprint 4.a — Admin Dashboard: - Auth: NextAuth.js v5, login page, middleware, token rotation - Dashboard: KPI cards, Recharts stock chart, quick actions - Members: TanStack Table (search/sort/paginate), add/edit forms - Distributions: multi-step form, real-time quota check, history - Stock: batch management, recall dialog, bar chart - Reports: monthly/member-list/recall, PDF/CSV download, preview Sprint 4.b — Member Portal: - Separate route group with top-nav layout (mobile-first) - Quota dashboard with radial SVG progress indicators - Distribution history with month filter - Profile/settings with password change Cross-cutting: - i18n: German (default) + English via next-intl - Dark + light mode (next-themes, user-togglable) - Playwright E2E tests (6/6 green) - Docker multi-stage build (node:22-alpine) - API proxy via Next.js rewrites Tech: Next.js 15.2.8, React 19, Tailwind 4, NextAuth v5, TanStack Table, Recharts, Zod, React Hook Form, Playwright
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import { Cairo, Lato } from "next/font/google"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
import "./globals.css"
|
||||
|
||||
import { Providers } from "@/providers"
|
||||
|
||||
import type { Metadata } from "next"
|
||||
import type { ReactNode } from "react"
|
||||
|
||||
import { Toaster as Sonner } from "@/components/ui/sonner"
|
||||
import { Toaster } from "@/components/ui/toaster"
|
||||
|
||||
// Define metadata for the application
|
||||
// More info: https://nextjs.org/docs/app/building-your-application/optimizing/metadata
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
template: "%s | CannaManage",
|
||||
default: "CannaManage",
|
||||
},
|
||||
description: "Cannabis club management platform — CannaManage",
|
||||
metadataBase: new URL(process.env.BASE_URL as string),
|
||||
}
|
||||
|
||||
// Define fonts for the application
|
||||
// More info: https://nextjs.org/docs/app/building-your-application/optimizing/fonts
|
||||
const latoFont = Lato({
|
||||
subsets: ["latin"],
|
||||
weight: ["100", "300", "400", "700", "900"],
|
||||
style: ["normal", "italic"],
|
||||
variable: "--font-lato",
|
||||
})
|
||||
const cairoFont = Cairo({
|
||||
subsets: ["arabic"],
|
||||
weight: ["400", "700"],
|
||||
style: ["normal"],
|
||||
variable: "--font-cairo",
|
||||
})
|
||||
|
||||
export default function RootLayout(props: { children: ReactNode }) {
|
||||
const { children } = props
|
||||
|
||||
return (
|
||||
<html lang="en" dir="ltr" suppressHydrationWarning>
|
||||
<body
|
||||
className={cn(
|
||||
"[&:lang(en)]:font-lato [&:lang(ar)]:font-cairo", // Set font styles based on the language
|
||||
"bg-background text-foreground antialiased overscroll-none", // Set background, text, , anti-aliasing styles, and overscroll behavior
|
||||
latoFont.variable, // Include Lato font variable
|
||||
cairoFont.variable // Include Cairo font variable
|
||||
)}
|
||||
>
|
||||
<Providers locale="de">
|
||||
{children}
|
||||
<Toaster />
|
||||
<Sonner />
|
||||
</Providers>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user