From 85c744defa3eeecbdec1bcbcf89b0817ef99910b Mon Sep 17 00:00:00 2001 From: Azmog <80716388+AzmogEx@users.noreply.github.com> Date: Thu, 18 Jun 2026 23:09:47 +0200 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20socle=20de=20refonte=20au=20S?= =?UTF-8?q?yst=C3=A8me=20de=20Design=20de=20l'=C3=89tat=20(DSFR)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - charge le DSFR (CSS/JS officiels) en statique via public/dsfr + postinstall - en-tête officiel (bloc Marianne « République Française » + nom de service) - pied de page officiel DSFR (liens institutionnels, licence etalab) - page d'accueil refondue (hero, fr-card, fr-tile, fr-callout, fr-btn) - composant Button mappé sur fr-btn - assets DSFR hors git (régénérés par `npm install`) Build OK (19 routes). Pages internes encore en Tailwind : conversion à poursuivre. Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/.gitignore | 3 + frontend/package-lock.json | 39 ++ frontend/package.json | 4 +- frontend/scripts/copy-dsfr.mjs | 19 + frontend/src/app/layout.tsx | 39 +- frontend/src/app/page.tsx | 702 +++++----------------- frontend/src/components/layout/Footer.tsx | 143 +++-- frontend/src/components/layout/Header.tsx | 307 ++++------ frontend/src/components/ui/Button.tsx | 69 +-- 9 files changed, 463 insertions(+), 862 deletions(-) create mode 100644 frontend/scripts/copy-dsfr.mjs diff --git a/frontend/.gitignore b/frontend/.gitignore index 7b8da95..afcae07 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -40,3 +40,6 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# Assets DSFR copiés par le postinstall (régénérés depuis node_modules) +/public/dsfr diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1f7173e..d79ec61 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "frontend", "version": "0.1.0", "dependencies": { + "@codegouvfr/react-dsfr": "^1.32.4", "@tanstack/react-query": "^5.90.21", "axios": "^1.13.6", "lucide-react": "^0.577.0", @@ -370,6 +371,29 @@ "specificity": "bin/cli.js" } }, + "node_modules/@codegouvfr/react-dsfr": { + "version": "1.32.4", + "resolved": "https://registry.npmjs.org/@codegouvfr/react-dsfr/-/react-dsfr-1.32.4.tgz", + "integrity": "sha512-yhjPqPObB3BsehZTRhJZ9qXwBRT2RZl0cn6hG838MlkPntTE5H5w0vU05KmKcdDBnQ0wDV59G7nnZrpKZQlNuA==", + "license": "MIT", + "dependencies": { + "tsafe": "^1.8.5", + "yargs-parser": "^21.1.1" + }, + "bin": { + "copy-dsfr-to-public": "bin/copy-dsfr-to-public.js", + "only-include-used-icons": "bin/only-include-used-icons.js", + "react-dsfr": "bin/react-dsfr.js" + }, + "peerDependencies": { + "@gouvfr/dsfr-chart": "^1.0.0" + }, + "peerDependenciesMeta": { + "@gouvfr/dsfr-chart": { + "optional": true + } + } + }, "node_modules/@csstools/color-helpers": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", @@ -8001,6 +8025,12 @@ "typescript": ">=4.8.4" } }, + "node_modules/tsafe": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/tsafe/-/tsafe-1.8.12.tgz", + "integrity": "sha512-nFRqW0ttu/2o6XTXsHiVZWJBCOaxhVqZLg7dgs3coZNsCMPXPfwz+zPHAQA+70fNnVJLAPg1EgGIqK9Q84tvAw==", + "license": "MIT" + }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -8964,6 +8994,15 @@ "dev": true, "license": "ISC" }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 5b8a183..3cf254e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,9 +7,11 @@ "build": "next build", "start": "next start", "lint": "eslint", - "test": "vitest run" + "test": "vitest run", + "postinstall": "node scripts/copy-dsfr.mjs" }, "dependencies": { + "@codegouvfr/react-dsfr": "^1.32.4", "@tanstack/react-query": "^5.90.21", "axios": "^1.13.6", "lucide-react": "^0.577.0", diff --git a/frontend/scripts/copy-dsfr.mjs b/frontend/scripts/copy-dsfr.mjs new file mode 100644 index 0000000..c84fade --- /dev/null +++ b/frontend/scripts/copy-dsfr.mjs @@ -0,0 +1,19 @@ +// Copie les assets du Système de Design de l'État (DSFR) vers public/dsfr, +// pour les servir en statique (CSS, JS, polices Marianne, icônes). +// Lancé automatiquement après `npm install` (script postinstall). +import { cpSync, rmSync, existsSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import { dirname, join } from "node:path"; + +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); +const src = join(root, "node_modules", "@codegouvfr", "react-dsfr", "dsfr"); +const dest = join(root, "public", "dsfr"); + +if (!existsSync(src)) { + console.warn("[copy-dsfr] Source DSFR introuvable, étape ignorée."); + process.exit(0); +} + +rmSync(dest, { recursive: true, force: true }); +cpSync(src, dest, { recursive: true }); +console.log("[copy-dsfr] Assets DSFR copiés vers public/dsfr."); diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 67b17c4..0feadc8 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -1,26 +1,17 @@ import type { Metadata } from "next"; -import { Inter, Poppins } from "next/font/google"; +import Script from "next/script"; import "./globals.css"; import Providers from "@/components/Providers"; -const inter = Inter({ - variable: "--font-inter", - subsets: ["latin"], - weight: ["400", "500", "600", "700"], - display: "swap", -}); - -const poppins = Poppins({ - variable: "--font-poppins", - subsets: ["latin"], - weight: ["500", "600", "700"], - display: "swap", -}); - export const metadata: Metadata = { - title: "CESIZen - Votre sant\u00e9 mentale", + title: "CESIZen - Votre santé mentale", description: - "Plateforme de gestion du stress et suivi \u00e9motionnel. Suivez vos \u00e9motions, consultez des ressources et prenez soin de votre sant\u00e9 mentale.", + "Plateforme publique de gestion du stress et de suivi émotionnel. Suivez vos émotions, consultez des ressources et prenez soin de votre santé mentale.", + icons: { + icon: [{ url: "/dsfr/favicon/favicon.svg", type: "image/svg+xml" }], + shortcut: ["/dsfr/favicon/favicon.ico"], + apple: [{ url: "/dsfr/favicon/apple-touch-icon.png" }], + }, }; export default function RootLayout({ @@ -29,9 +20,19 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - - + + + {/* Système de Design de l'État (DSFR) — feuilles de style officielles */} + + {children} + {/* JS DSFR : comportements interactifs (menu, navigation, modales) */} +