"use client"; import { useEffect, useState, useTransition } from "react"; import { HeatmapGrid } from "@/features/grid/components/heatmap-grid"; import { FloatingSummaryBar } from "@/features/grid/components/floating-summary-bar"; import { BulkActionToolbar } from "@/features/grid/components/bulk-action-toolbar"; import { GridFilterBar } from "@/features/grid/components/grid-filter-bar"; import { ExportDropdown } from "@/features/grid/components/export-dropdown"; import { useGridStore } from "@/features/grid/store/use-grid-store"; import { useSaveDrafts } from "@/features/grid/hooks/use-save-drafts"; import type { ProductRow } from "@/types/grid"; import { CheckCircle, AlertCircle, Loader2 } from "lucide-react"; import { useSearchParams } from "next/navigation"; import { computeProductScores } from "@/lib/score-engine"; interface GridClientProps { initialRows: ProductRow[]; codeFournisseur: string; nomFournisseur: string; fournisseurs: { code: string; nom: string }[]; magasins: { code: string; nom: string }[]; magasin: string; } export function GridClient({ initialRows, nomFournisseur, fournisseurs, magasins, magasin }: GridClientProps) { const setRows = useGridStore((s) => s.setRows); const setActiveGridQuery = useGridStore((s) => s.setActiveGridQuery); const searchParams = useSearchParams(); const [selectedCodeins, setSelectedCodeins] = useState([]); const [isPending, startTransition] = useTransition(); const [saveStatus, setSaveStatus] = useState<"idle" | "success" | "error">("idle"); const visibleCodeins = initialRows.map(r => r.codein); const { save, hasDrafts, count } = useSaveDrafts(magasin, visibleCodeins); const [isMounted, setIsMounted] = useState(false); useEffect(() => { setIsMounted(true); }, []); // Sync active search params to the store useEffect(() => { if (!isMounted) return; const currentQueryString = searchParams.toString(); // Set the active query, ensuring it starts with ? if not empty setActiveGridQuery(currentQueryString ? `?${currentQueryString}` : ""); }, [searchParams, setActiveGridQuery, isMounted]); useEffect(() => { if (!isMounted) return; // Optimisation : On évite le JSON.parse(JSON.stringify()) qui est très lourd sur 1000 lignes // On passe directement les initialRows au moteur de score, ou on fait une copie superficielle si nécessaire. // Le moteur de score doit idéalement retourner de nouveaux objets. const scoredRows = computeProductScores([...initialRows]); setRows(scoredRows); }, [initialRows, setRows, isMounted]); const handleSave = () => { startTransition(async () => { const result = await save(); setSaveStatus(result.success ? "success" : "error"); setTimeout(() => setSaveStatus("idle"), 3000); }); }; if (!isMounted) { return
Initialisation de la grille...
; } const activeStoreNom = magasins.find(m => m.code === magasin)?.nom || "National (Total)"; return (
{/* Header */}

Révision d'Assortiment

{nomFournisseur} {" "}• {activeStoreNom} {" "}• {initialRows.length} références

{hasDrafts && ( )}
{/* Filters */}
{/* Bulk toolbar (contextual) */}
setSelectedCodeins([])} />
{/* Main grid */}
{/* Summary bar */}
); }