Assembler les couches du tableau de bord
Objectif : Relier les composants, les types métier et le service de données dans une application à fichiers séparés.
Un tableau de bord peut afficher les bonnes informations tout en devenant difficile à faire évoluer si chaque composant charge lui-même les données ou recalcule ses propres règles. Vous allez relier les fichiers du projet pour que chaque couche ait un trajet clair : le service persiste, le contexte partage les dépenses, les hooks exposent les données utiles et la page compose les composants.
Du point d’entrée à l’interface
La structure des responsabilités et les fichiers associés ont été définis dans « Cartographier les responsabilités de l’application ». Ici, vous assemblez ces éléments : main.tsx monte l’application, App.tsx compose ses grandes zones et le fournisseur de contexte rend les dépenses accessibles aux composants qui en ont besoin. Le service reste en dessous de cette interface et ne connaît pas le rendu React.
Le sens des dépendances est important : les composants appellent des hooks, les hooks s’appuient sur le contexte et celui-ci utilise le service. Ainsi, un composant d’interface n’accède pas directement à localStorage, et le service n’importe pas de composant. Les types du domaine, déjà définis dans src/types/depense.ts, servent de contrat commun entre ces fichiers.
Brancher le point d’entrée et le contexte
Le point d’entrée installe le fournisseur une seule fois autour de la page. L’élément racine doit exister dans le document de démarrage du projet ; il est ciblé ici par getElementById et l’application ne tente pas de continuer si cet élément manque.
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
import { DepensesProvider } from "./contexts/DepensesContext";
import "./styles/style.css";
const element = document.getElementById("root");
if (!element) {
throw new Error("L’élément #root est introuvable.");
}
createRoot(element).render(
<StrictMode>
<DepensesProvider>
<App />
</DepensesProvider>
</StrictMode>,
);Le fournisseur est placé au-dessus de App, car les différentes sections doivent pouvoir consulter et modifier les dépenses partagées. Cette décision ne signifie pas que chaque état doit être global : les filtres restent dans FiltresDepenses.tsx, conformément au choix établi dans « Choisir la source de vérité de chaque donnée ».
Composer la page sans y concentrer la logique
La page assemble les composants du contrat dans l’ordre correspondant au tableau de bord. Elle conserve les régions nommées et les identifiants de navigation prévus par le squelette : cette composition ne remplace pas la structure native ni les relations d’accessibilité déjà mises en place.
import Entete from "./components/Entete";
import Navigation from "./components/Navigation";
import Recapitulatif from "./components/Recapitulatif";
import FormulaireDepense from "./components/FormulaireDepense";
import FiltresDepenses from "./components/FiltresDepenses";
import ListeDepenses from "./components/ListeDepenses";
export default function App() {
return (
<div className="atelier-app">
<header className="atelier-entete">
<Entete />
<Navigation />
</header>
<main className="atelier-principal">
<Recapitulatif />
<FormulaireDepense />
<section
id="depenses"
className="atelier-liste"
aria-labelledby="titre-depenses"
>
<h2 id="titre-depenses">Dépenses</h2>
<FiltresDepenses />
<ListeDepenses />
</section>
</main>
</div>
);
}Suivre une donnée de bout en bout
À l’initialisation, DepensesContext.tsx demande les données au service depensesService.ts, puis expose l’état et les opérations via useDepenses.ts. Le formulaire appelle l’opération d’ajout exposée par ce hook ; la liste lit les dépenses et utilise l’opération de suppression. Vous avez ainsi un seul chemin de modification, sans accès direct au stockage depuis les composants.
Le récapitulatif consomme useRecapitulatifMensuel.ts pour afficher les résultats dérivés, au lieu de recopier un total dans son propre état. Le service garde les opérations de persistance ; il ne décide ni de la sélection affichée ni de la mise en page. Les détails du formulaire, des filtres et du calcul optimisé seront traités dans les leçons suivantes.
Vérifier l’assemblage
Lancez le projet et vérifiez que la page monte sans erreur, que les sections apparaissent une fois et que les composants importés correspondent bien aux exports de leurs fichiers. Ajoutez ensuite une dépense : la mise à jour doit passer par le contexte et le service, puis être visible dans la liste et dans les éléments qui dépendent de ces données. Cette vérification confirme le branchement des couches ; elle ne remplace pas les tests détaillés de saisie ou de calcul.
À retenir
- Montez le fournisseur de données au point d’entrée, au-dessus des composants qui en ont besoin.
- Laissez App composer les zones du tableau de bord plutôt que d’y concentrer les opérations métier.
- Faites circuler les dépenses par le contexte et les hooks ; réservez la persistance au service.
- Gardez les filtres locaux et les résultats calculés dans leurs hooks dédiés.
- Vérifiez le trajet d’une modification dans l’interface avant de poursuivre l’assemblage.
Vous allez maintenant compléter le flux de saisie, les catégories et les filtres, puis produire le récapitulatif mensuel optimisé.