// Page principale — Budget Renouvellement SI 2027 - Itinova // Design: Corporate Modernism — Sidebar bleu marine + grille de cards + vue liste import { useState } from 'react'; import { Monitor, Laptop, Euro, Search, SortAsc, SortDesc, Filter, Building2, AlertTriangle, CheckCircle, ChevronDown, LayoutGrid, List, } from 'lucide-react'; import { AppSidebar } from '../components/AppSidebar'; import { AnneeSelectorBar } from '../components/AnneeSelectorBar'; import { useAnnee } from '../contexts/AnneeContext'; import { useBudgetData } from '../hooks/useBudgetData'; import { formatEuros, formatNumber } from '../lib/format'; import { EtablissementCard } from '../components/EtablissementCard'; import { EtablissementDetail } from '../components/EtablissementDetail'; import { EtablissementListView } from '../components/EtablissementListView'; import { KpiCard } from '../components/KpiCard'; import type { Etablissement, SortField, FilterType } from '../types/budget'; type ViewMode = 'grid' | 'list'; export default function Home() { const { meta, etablissements, totalEtablissements, hasInventaire, search, setSearch, sortField, sortOrder, toggleSort, filterType, setFilterType, } = useBudgetData(); const { annee } = useAnnee(); // Les données de parc proviennent uniquement d'un import inventaire const hasDonnees = hasInventaire; const [selectedEtab, setSelectedEtab] = useState(null); const [sidebarCollapsed, setSidebarCollapsed] = useState(false); const [viewMode, setViewMode] = useState('grid'); const sortOptions: { value: SortField; label: string }[] = [ { value: 'budget_total', label: 'Budget total' }, { value: 'nom', label: 'Nom' }, { value: 'code', label: 'Code' }, { value: 'nb_fixes_renouveler', label: 'PC Fixes à renouveler' }, { value: 'nb_portables_renouveler', label: 'PC Portables à renouveler' }, ]; const filterOptions: { value: FilterType; label: string }[] = [ { value: 'all', label: 'Tous les établissements' }, { value: 'has_budget', label: 'Avec budget de renouvellement' }, { value: 'no_budget', label: 'Sans renouvellement nécessaire' }, ]; return (
setSidebarCollapsed(c => !c)} /> {/* Contenu principal */}
{/* En-tête */}

Renouvellement PC {annee}

{totalEtablissements} établissements Itinova — Vétusté du parc PC

{etablissements.length} affiché{etablissements.length > 1 ? 's' : ''}
{/* KPIs globaux — uniquement si données disponibles */} {hasDonnees && (
)} {/* Barre de filtres + toggle vue — uniquement si données disponibles */} {hasDonnees && (
{/* Recherche */}
setSearch(e.target.value)} className="w-full pl-9 pr-3 py-2 text-sm bg-muted/50 border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary transition-colors" />
{/* Filtre */}
{/* Tri (masqué en vue liste car tri par colonne) */} {viewMode === 'grid' && (
Trier par :
)} {/* Spacer */}
{/* Toggle vue vignettes / liste */}
)} {/* Contenu — vue vignettes ou liste */}
{!hasDonnees ? (

Aucun inventaire importé

Importez l'export ISI-APP via le bouton Imports & Données dans le menu de gauche pour afficher les données de vétusté et les budgets de renouvellement.

) : etablissements.length === 0 ? (

Aucun établissement trouvé

Modifiez vos critères de recherche ou de filtre.

) : viewMode === 'grid' ? (
{etablissements.map((etab, index) => ( setSelectedEtab(etab)} index={index} /> ))}
) : ( setSelectedEtab(etab)} sortField={sortField} sortOrder={sortOrder} onSort={toggleSort} /> )}
{/* Panneau de détail */} {selectedEtab && ( setSelectedEtab(null)} coutFixe={meta.cout_fixe} coutPortable={meta.cout_portable} seuilFixesAns={meta.seuil_fixes_ans} seuilPortablesAns={meta.seuil_portables_ans} /> )}
); }