diff --git a/src/app/(app)/layout.tsx b/src/app/(app)/layout.tsx new file mode 100644 index 0000000..91d9b4a --- /dev/null +++ b/src/app/(app)/layout.tsx @@ -0,0 +1,7 @@ +import type { ReactNode } from 'react'; + +import { AppShell } from '@/components/shell/AppShell'; + +export default function AppLayout({ children }: { children: ReactNode }) { + return {children}; +} diff --git a/src/app/(app)/page.tsx b/src/app/(app)/page.tsx new file mode 100644 index 0000000..eb44b98 --- /dev/null +++ b/src/app/(app)/page.tsx @@ -0,0 +1,127 @@ +import { PageBody, PageHeader } from '@/components/shell/PageHeader'; +import { Badge } from '@/components/ui/Badge'; +import { Button } from '@/components/ui/Button'; +import { Card, CardHeader } from '@/components/ui/Card'; +import { ENTRIES, TILES, TODOS } from '@/lib/demo/apercu'; + +export const metadata = { title: 'Aperçu RH · PlanFlow' }; + +const TILE_SWATCH: Record = { + warn: 'bg-warn-soft border-warn', + info: 'bg-info-soft border-info', + accent: 'bg-accent-soft border-accent', + danger: 'bg-danger-soft border-danger', +}; + +export default function ApercuPage() { + return ( + + + + + + } + /> + +
+ {TILES.map((tile) => ( + + ))} +
+ +
+ + 4} + action={ + + } + /> +
    + {ENTRIES.map((entry) => ( +
  • + + {entry.initials} + + + + {entry.name} + + + {entry.job} + + + + {entry.date} + + {entry.state} +
  • + ))} +
+
+ + + +
    + {TODOS.map((todo) => ( +
  • + + + + {todo.title} + + + {todo.detail} + + + + {todo.when} + +
  • + ))} +
+
+
+
+ ); +} diff --git a/src/app/(app)/planning/semaine/page.tsx b/src/app/(app)/planning/semaine/page.tsx new file mode 100644 index 0000000..e3d1cc9 --- /dev/null +++ b/src/app/(app)/planning/semaine/page.tsx @@ -0,0 +1,78 @@ +import { WeekGrid } from '@/components/planning/WeekGrid'; +import { PageBody, PageHeader } from '@/components/shell/PageHeader'; +import { Badge } from '@/components/ui/Badge'; +import { Button } from '@/components/ui/Button'; +import { POSTE_CODES, POSTE_LABELS, posteTokens } from '@/lib/design/postes'; +import { UNASSIGNED_ROW, WEEK_DAYS, WEEK_LABEL, WEEK_ROWS } from '@/lib/demo/semaine'; + +export const metadata = { title: 'Planning · semaine 33 · PlanFlow' }; + +export default function SemainePage() { + return ( + + + + + + + } + /> + +
+ 2 alertes de convention + Samedi non publié + 5 besoins non couverts +
+ + + + +
+ ); +} + +/** + * Légende des postes. + * + * Elle n'est pas décorative : la couleur seule ne dit pas quel poste est + * lequel, et le code à trois lettres imprimé dans chaque bloc n'a de sens que + * si sa correspondance est visible sur la même page. + */ +function PosteLegend() { + return ( +
+

+ Postes +

+ +
+ ); +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 26478ce..1b19f29 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,4 +1,7 @@ import type { Metadata } from 'next'; +import { headers } from 'next/headers'; + +import { THEME_INIT_SCRIPT } from '@/components/shell/ThemeToggle'; import './globals.css'; @@ -7,14 +10,23 @@ export const metadata: Metadata = { description: 'Gestion du personnel, des plannings et des temps.', }; -export default function RootLayout({ +export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { + // Le nonce est posé par requête dans src/proxy.ts. C'est la seule façon + // d'exécuter un script inline sous notre CSP, qui n'autorise pas + // 'unsafe-inline'. + const nonce = (await headers()).get('x-nonce') ?? undefined; + return ( - - - {children} - + + +