"use client"; import React, { useState, useEffect } from "react"; import { getSnapshots } from "../api/get-snapshots"; import { deleteSnapshot } from "../api/delete-snapshot"; import { useGridStore } from "@/features/grid/store/use-grid-store"; import { useRouter } from "next/navigation"; import { Trash2, UploadCloud, Calendar, Store, History, ChevronRight, Loader2, } from "lucide-react"; import { SuccessModal } from "@/components/shared/success-modal"; import { isStaleServerActionError, STALE_ACTION_MESSAGE } from "@/lib/stale-action"; import { ConfirmModal } from "@/components/shared/confirm-modal"; const formatDate = (date: Date) => { return new Intl.DateTimeFormat("fr-FR", { day: "numeric", month: "long", year: "numeric", hour: "2-digit", minute: "2-digit" }).format(date); }; interface SnapshotListProps { type?: "snapshot" | "export"; } export function SnapshotList({ type }: SnapshotListProps) { const [snapshots, setSnapshots] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [isDeleting, setIsDeleting] = useState(null); const [modal, setModal] = useState<{ isOpen: boolean; title: string; message: string; variant?: "success" | "error"; action?: { label: string; onClick: () => void }; }>({ isOpen: false, title: "", message: "" }); /** * Onglet resté ouvert pendant un déploiement : les identifiants de Server * Action ont changé côté serveur. On propose le rechargement au lieu * d'afficher une erreur technique incompréhensible. */ const modalErreur = (err: unknown, titre: string, message: string) => isStaleServerActionError(err) ? { isOpen: true, title: "Page à recharger", message: STALE_ACTION_MESSAGE, variant: "error" as const, action: { label: "Recharger la page", onClick: () => window.location.reload() }, } : { isOpen: true, title: titre, message, variant: "error" as const }; const [confirmModal, setConfirmModal] = useState<{ isOpen: boolean; title: string; message: string; variant?: "danger" | "default"; onConfirm: () => void; }>({ isOpen: false, title: "", message: "", onConfirm: () => { } }); const restoreSnapshot = useGridStore(state => state.restoreSnapshot); const router = useRouter(); const fetchSnapshots = async () => { setLoading(true); try { const data = await getSnapshots(type); setSnapshots(data); } catch (err) { setError(isStaleServerActionError(err) ? STALE_ACTION_MESSAGE : "Impossible de charger les données."); } finally { setLoading(false); } }; useEffect(() => { fetchSnapshots(); }, [type]); const handleDelete = (id: number) => { setConfirmModal({ isOpen: true, title: "Supprimer", message: `Supprimer cet ${type === 'export' ? 'export' : 'snapshot'} définitivement ?`, variant: "danger", onConfirm: async () => { setIsDeleting(id); try { const res = await deleteSnapshot(id); if (res.success) { setSnapshots(prev => prev.filter(s => s.id !== id)); setModal({ isOpen: true, title: "Action Réussie", message: "L'élément a été supprimé de votre historique." }); } else { setModal({ isOpen: true, title: "Erreur", message: "Impossible de supprimer l'élément.", variant: "error" }); } } catch (err) { setModal(modalErreur(err, "Erreur Technique", "Une erreur est survenue lors de la suppression.")); } finally { setIsDeleting(null); } }, }); }; const handleLoad = (snapshot: any) => { setConfirmModal({ isOpen: true, title: "Restaurer la session", message: `Charger la session "${snapshot.label}" ? Cela remplacera vos brouillons actuels.`, variant: "default", onConfirm: () => { const changes: Record = {}; Object.entries(snapshot.changes as any).forEach(([codein, delta]: [string, any]) => { changes[codein] = delta.after; }); restoreSnapshot(changes); const query = new URLSearchParams(); if (snapshot.codeFournisseur) query.set("fournisseur", snapshot.codeFournisseur); if (snapshot.magasin) query.set("magasin", snapshot.magasin); router.push(`/grid?${query.toString()}`); }, }); }; if (loading) { return (

Récupération de l'historique...

); } if (snapshots.length === 0) { return (

{type === "export" ? "Aucun export pour le moment" : "Aucun snapshot pour le moment"}

{type === "export" ? "Vos exports Excel apparaîtront ici pour historique." : "Capturez l'état de votre travail depuis la grille pour le retrouver ici ultérieurement."}

); } return (
{snapshots.map((s) => (

{s.label}

{s.magasin || "Magasin Inconnu"}
{formatDate(new Date(s.createdAt))} {Object.keys(s.changes as any).length} modifications enregistrées
{s.summaryJson && (
CA {(s.summaryJson.totalCa || 0).toLocaleString("fr-FR", { style: "currency", currency: "EUR", maximumFractionDigits: 0 })}
Marge {s.summaryJson.tauxMargeGlobal?.toFixed(1)}%
)}
))} setModal(prev => ({ ...prev, isOpen: false }))} title={modal.title} message={modal.message} variant={modal.variant} action={modal.action} /> setConfirmModal(prev => ({ ...prev, isOpen: false }))} onConfirm={confirmModal.onConfirm} title={confirmModal.title} message={confirmModal.message} variant={confirmModal.variant} confirmLabel={confirmModal.variant === "danger" ? "Supprimer" : "Confirmer"} />
); }