import { trpc } from "@/lib/trpc"; import { useAuth } from "@/_core/hooks/useAuth"; import SonumLayout from "@/components/SonumLayout"; import { ChevronDown, ChevronRight, Building2, Package, Search, Filter, BarChart2 } from "lucide-react"; import { useState, useMemo } from "react"; import { EtatBadge } from "@/components/EtatBadge"; export default function SolutionsLogicielles() { const { isAuthenticated } = useAuth(); const [openIds, setOpenIds] = useState>(new Set()); const [search, setSearch] = useState(""); const [filterBloc, setFilterBloc] = useState(""); const { data: solutions, isLoading } = trpc.logiciels.toutesLesSolutions.useQuery(undefined, { enabled: isAuthenticated, }); const toggle = (id: number) => { setOpenIds((prev) => { const next = new Set(prev); if (next.has(id)) next.delete(id); else next.add(id); return next; }); }; const filtered = useMemo(() => { if (!solutions) return []; return solutions.filter((s) => { const matchSearch = !search || s.solutionNom.toLowerCase().includes(search.toLowerCase()) || s.editeurNom.toLowerCase().includes(search.toLowerCase()); const matchBloc = !filterBloc || s.blocFonctionnelNom === filterBloc; return matchSearch && matchBloc; }); }, [solutions, search, filterBloc]); const blocsUniques = useMemo(() => { if (!solutions) return []; const set = new Set(solutions.map((s) => s.blocFonctionnelNom).filter(Boolean) as string[]); return Array.from(set).sort(); }, [solutions]); const totalEtablissements = useMemo(() => { if (!solutions) return 0; const ids = new Set(); solutions.forEach((s) => s.etablissements.forEach((e) => ids.add(e.id))); return ids.size; }, [solutions]); return (
{/* En-tête */}

Solutions Logicielles

Référentiel complet des solutions numériques FEHAP

{/* Statistiques */} {solutions && (
{solutions.length}
Solutions référencées
{totalEtablissements}
Établissements équipés
{blocsUniques.length}
Blocs fonctionnels
)}
{/* Filtres */}
setSearch(e.target.value)} className="w-full pl-9 pr-4 py-2.5 text-sm bg-background border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary" />
{/* Résultat filtré */} {search || filterBloc ? (

{filtered.length} solution{filtered.length > 1 ? "s" : ""} correspondant aux critères

) : null} {/* Liste */} {isLoading ? (
{[...Array(6)].map((_, i) => (
))}
) : filtered.length === 0 ? (

Aucune solution trouvée

) : (
{filtered.map((sol) => { const isOpen = openIds.has(sol.solutionId); return (
{/* En-tête accordéon */} {/* Contenu accordéon */} {isOpen && (
{sol.etablissements.length === 0 ? (

Aucun établissement n'utilise encore cette solution.

) : ( <>
Établissements équipés
{sol.etablissements.map((etab) => (
{etab.nom} {etab.region && ( — {etab.region} )}
))}
)}
)}
); })}
)}
); }