diff --git a/client/src/contexts/AnneeContext.tsx b/client/src/contexts/AnneeContext.tsx index 3c4bebd..99457da 100644 --- a/client/src/contexts/AnneeContext.tsx +++ b/client/src/contexts/AnneeContext.tsx @@ -6,6 +6,21 @@ import { createContext, useContext, useState, ReactNode } from 'react'; export const ANNEES_DISPONIBLES = [2025, 2026, 2027, 2028, 2029, 2030]; export const ANNEE_DEFAUT = 2027; +const PARAMETRES_STORAGE_KEY = 'itinova_budget_parametres'; + +function getAnneeDefautFromParametres(): number { + try { + const raw = localStorage.getItem(PARAMETRES_STORAGE_KEY); + if (raw) { + const parsed = JSON.parse(raw); + if (typeof parsed.anneeDefaut === 'number' && ANNEES_DISPONIBLES.includes(parsed.anneeDefaut)) { + return parsed.anneeDefaut; + } + } + } catch { /* ignore */ } + return ANNEE_DEFAUT; +} + interface AnneeContextType { annee: number; setAnnee: (a: number) => void; @@ -20,8 +35,12 @@ export function AnneeProvider({ children }: { children: ReactNode }) { const [annee, setAnneeState] = useState(() => { try { const stored = localStorage.getItem('itinova_annee_selectionnee'); - const parsed = stored ? parseInt(stored, 10) : ANNEE_DEFAUT; - return ANNEES_DISPONIBLES.includes(parsed) ? parsed : ANNEE_DEFAUT; + if (stored) { + const parsed = parseInt(stored, 10); + if (ANNEES_DISPONIBLES.includes(parsed)) return parsed; + } + // Pas de session mémorisée → utiliser l'année par défaut des paramètres + return getAnneeDefautFromParametres(); } catch { return ANNEE_DEFAUT; } }); diff --git a/client/src/contexts/ParametresContext.tsx b/client/src/contexts/ParametresContext.tsx index 017decf..d9f126a 100644 --- a/client/src/contexts/ParametresContext.tsx +++ b/client/src/contexts/ParametresContext.tsx @@ -8,6 +8,7 @@ export interface Parametres { seuilPortablesAns: number; coutFixe: number; coutPortable: number; + anneeDefaut: number; } const DEFAULTS: Parametres = { @@ -15,6 +16,7 @@ const DEFAULTS: Parametres = { seuilPortablesAns: 4, coutFixe: 450, coutPortable: 1000, + anneeDefaut: 2027, }; const STORAGE_KEY = 'itinova_budget_parametres'; @@ -29,6 +31,7 @@ function loadFromStorage(): Parametres { seuilPortablesAns: typeof parsed.seuilPortablesAns === 'number' ? parsed.seuilPortablesAns : DEFAULTS.seuilPortablesAns, coutFixe: typeof parsed.coutFixe === 'number' ? parsed.coutFixe : DEFAULTS.coutFixe, coutPortable: typeof parsed.coutPortable === 'number' ? parsed.coutPortable : DEFAULTS.coutPortable, + anneeDefaut: typeof parsed.anneeDefaut === 'number' ? parsed.anneeDefaut : DEFAULTS.anneeDefaut, }; } catch { return DEFAULTS; diff --git a/client/src/pages/Parametres.tsx b/client/src/pages/Parametres.tsx index a66b8df..8814595 100644 --- a/client/src/pages/Parametres.tsx +++ b/client/src/pages/Parametres.tsx @@ -14,7 +14,9 @@ import { ChevronLeft, Info, BarChart3, + Calendar, } from 'lucide-react'; +import { ANNEES_DISPONIBLES } from '../contexts/AnneeContext'; import { AppSidebar } from '../components/AppSidebar'; import { useParametres, PARAMETRES_DEFAULTS } from '../contexts/ParametresContext'; import { formatEuros } from '../lib/format'; @@ -25,6 +27,7 @@ interface FieldState { seuilPortablesAns: number; coutFixe: number; coutPortable: number; + anneeDefaut: number; } function SliderInput({ @@ -123,7 +126,8 @@ export default function Parametres() { draft.seuilFixesAns !== parametres.seuilFixesAns || draft.seuilPortablesAns !== parametres.seuilPortablesAns || draft.coutFixe !== parametres.coutFixe || - draft.coutPortable !== parametres.coutPortable; + draft.coutPortable !== parametres.coutPortable || + draft.anneeDefaut !== parametres.anneeDefaut; const handleSave = () => { setParametres(draft); @@ -300,6 +304,45 @@ export default function Parametres() { /> + {/* Section année par défaut */} +
+
+ +

+ Année d'ouverture par défaut +

+
+

+ L'année sélectionnée au démarrage de l'application lorsqu'aucune session précédente n'est mémorisée. +

+
+
+
+ +
+
+

Année par défaut

+

Exercice ouvert au premier lancement

+
+
+ {ANNEES_DISPONIBLES.map(a => ( + + ))} +
+
+
+
+ {/* Aperçu de l'impact */}
@@ -314,6 +357,7 @@ export default function Parametres() { { label: 'Seuil PC Portables', value: `${draft.seuilPortablesAns} ans`, changed: draft.seuilPortablesAns !== parametres.seuilPortablesAns }, { label: 'Coût fixe unitaire', value: formatEuros(draft.coutFixe), changed: draft.coutFixe !== parametres.coutFixe }, { label: 'Coût portable unitaire', value: formatEuros(draft.coutPortable), changed: draft.coutPortable !== parametres.coutPortable }, + { label: 'Année par défaut', value: `${draft.anneeDefaut}`, changed: draft.anneeDefaut !== parametres.anneeDefaut }, ].map((item) => (