# 🏁 ÉnoncĂ© FINAL — « Boss de fin » Dernier jour. Tu as tout l'arsenal : composants, props, state, lifting state up, `useEffect`, `fetch`, formulaire, tri, filtre, React Router, `localStorage`. Aujourd'hui, place Ă  la pratique libre. Un seul module est **obligatoire** : le **Module L** (la page dĂ©tail, le vrai boss). Les autres forment un **menu** : pioche dans l'ordre que tu veux, fais-en le plus possible. Chacun est court et indĂ©pendant. | Module | Tu fais | Niveau | |---|---|---| | **L** | Page dĂ©tail **complĂšte** (donnĂ©es centralisĂ©es dans `App`) — *obligatoire* | ⭐⭐⭐ | | M | Bouton « au hasard » (`useNavigate`) | ⭐⭐ | | N | Le Hall of Fame des jeux les plus likĂ©s | ⭐⭐ | | O | Bouton « supprimer » un jeu | ⭐⭐ | | P | ThĂšme sombre qui se souvient du choix | ⭐⭐ | | Q | Mode Versus : deux jeux s'affrontent | ⭐⭐ | | R | Filtre par Type (2d / 3d) | ⭐⭐ | | S | Statistiques (total, moyenne d'annĂ©e) | ⭐⭐ | | T | Page « 404 » pour les URL inconnues | ⭐⭐ | | U | Tri ascendant ↔ descendant | ⭐ | | V | Custom hook `useLocalStorage` (refacto) | ⭐⭐⭐ | --- ## 🔑 Module L — Le boss : centraliser les donnĂ©es dans `App` (obligatoire) Dans `CORRECTION_page_detail.md` tu as fait une version simple (la page dĂ©tail re-`fetch` toute seule). Ses limites : les jeux **ajoutĂ©s au formulaire** et les **likes** n'arrivent pas dans le dĂ©tail, parce que chacun vit dans son coin. On corrige ça proprement. L'idĂ©e : le `fetch`, la liste `jeux` **et** les likes doivent vivre **au-dessus** des deux pages → dans `App`, qui les passe ensuite **en props** aux routes. ### L.1 — Remonter le `fetch` et les Ă©tats dans `App.jsx` ```jsx import { useState, useEffect } from "react"; import { Routes, Route } from "react-router-dom"; import Header from "./components/Header"; import Footer from "./components/Footer"; import Accueil from "./pages/Accueil"; import Detail from "./pages/Detail"; function App() { const [jeux, setJeux] = useState([]); const [likes, setLikes] = useState(() => JSON.parse(localStorage.getItem("likes") || "{}") ); useEffect(() => { fetch("/zelda.json").then((r) => r.json()).then(setJeux); }, []); useEffect(() => { localStorage.setItem("likes", JSON.stringify(likes)); }, [likes]); function liker(id) { setLikes((prev) => ({ ...prev, [id]: (prev[id] || 0) + 1 })); } return ( <>
} /> } />