mirror of
https://github.com/R0m1k3/CollectFlow.git
synced 2026-10-14 18:58:17 +02:00
feat: Implement snapshot and export listing, restoration, and deletion with a new success modal and floating summary bar.
This commit is contained in:
1 parent
a93b1b36fc
commit
c842c2447a
3 files changed
+158
-8
No files matched your search
@@ -6,6 +6,7 @@ import { useSaveDrafts } from "@/features/grid/hooks/use-save-drafts";
|
||||
import { Loader2, CheckCircle, AlertCircle, RotateCcw, Camera } from "lucide-react";
|
||||
import { useState, useTransition } from "react";
|
||||
import { saveSnapshot } from "@/features/snapshots/api/save-snapshot";
|
||||
import { SuccessModal } from "@/components/shared/success-modal";
|
||||
|
||||
function Stat({ label, value, sub }: { label: string; value: string; sub?: string }) {
|
||||
// Determine color based on label to match the prototype
|
||||
@@ -25,6 +26,11 @@ export function FloatingSummaryBar() {
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const [isSavingSnapshot, setIsSavingSnapshot] = useState(false);
|
||||
const [saveStatus, setSaveStatus] = useState<"idle" | "success" | "error">("idle");
|
||||
const [modal, setModal] = useState<{ isOpen: boolean, title: string, message: string }>({
|
||||
isOpen: false,
|
||||
title: "",
|
||||
message: ""
|
||||
});
|
||||
|
||||
const visibleCodeins = rows.map(r => r.codein);
|
||||
const { save, hasDrafts, count } = useSaveDrafts(filters.magasin || "TOTAL", visibleCodeins);
|
||||
@@ -75,7 +81,13 @@ export function FloatingSummaryBar() {
|
||||
});
|
||||
|
||||
if (res.success) {
|
||||
if (!labelOverride) alert("Snapshot enregistré avec succès ! Retrouvez-le dans la page Snapshots.");
|
||||
if (!labelOverride) {
|
||||
setModal({
|
||||
isOpen: true,
|
||||
title: "Snapshot Enregistré",
|
||||
message: "Votre session de travail a été sauvegardée avec succès."
|
||||
});
|
||||
}
|
||||
return res.snapshotId;
|
||||
} else {
|
||||
throw new Error(res.error);
|
||||
@@ -84,7 +96,11 @@ export function FloatingSummaryBar() {
|
||||
console.error(err);
|
||||
if (!labelOverride) {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
alert(`Erreur lors de la création du snapshot : ${msg}`);
|
||||
setModal({
|
||||
isOpen: true,
|
||||
title: "Erreur Snapshot",
|
||||
message: `Impossible de créer le snapshot : ${msg}`
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
setIsSavingSnapshot(false);
|
||||
@@ -219,6 +235,13 @@ export function FloatingSummaryBar() {
|
||||
{isPending ? "Validation..." : "Valider"}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<SuccessModal
|
||||
isOpen={modal.isOpen}
|
||||
onClose={() => setModal(prev => ({ ...prev, isOpen: false }))}
|
||||
title={modal.title}
|
||||
message={modal.message}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -13,8 +13,8 @@ import {
|
||||
History,
|
||||
ChevronRight,
|
||||
Loader2,
|
||||
AlertCircle
|
||||
} from "lucide-react";
|
||||
import { SuccessModal } from "@/components/shared/success-modal";
|
||||
|
||||
const formatDate = (date: Date) => {
|
||||
return new Intl.DateTimeFormat("fr-FR", {
|
||||
@@ -35,6 +35,11 @@ export function SnapshotList({ type }: SnapshotListProps) {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [isDeleting, setIsDeleting] = useState<number | null>(null);
|
||||
const [modal, setModal] = useState<{ isOpen: boolean, title: string, message: string }>({
|
||||
isOpen: false,
|
||||
title: "",
|
||||
message: ""
|
||||
});
|
||||
|
||||
const restoreSnapshot = useGridStore(state => state.restoreSnapshot);
|
||||
const router = useRouter();
|
||||
@@ -62,11 +67,24 @@ export function SnapshotList({ type }: SnapshotListProps) {
|
||||
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 {
|
||||
alert("Erreur lors de la suppression.");
|
||||
setModal({
|
||||
isOpen: true,
|
||||
title: "Erreur",
|
||||
message: "Impossible de supprimer l'élément."
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
alert("Erreur technique lors de la suppression.");
|
||||
setModal({
|
||||
isOpen: true,
|
||||
title: "Erreur Technique",
|
||||
message: "Une erreur est survenue lors de la suppression."
|
||||
});
|
||||
} finally {
|
||||
setIsDeleting(null);
|
||||
}
|
||||
@@ -75,8 +93,6 @@ export function SnapshotList({ type }: SnapshotListProps) {
|
||||
const handleLoad = (snapshot: any) => {
|
||||
if (!window.confirm(`Charger la session "${snapshot.label}" ? Cela remplacera vos brouillons actuels.`)) return;
|
||||
|
||||
// Les changements sont stockés sous forme d'objet { codein: { before, after } }
|
||||
// On doit re-transformer en Record<string, GammeCode>
|
||||
const changes: Record<string, string> = {};
|
||||
Object.entries(snapshot.changes as any).forEach(([codein, delta]: [string, any]) => {
|
||||
changes[codein] = delta.after;
|
||||
@@ -84,7 +100,6 @@ export function SnapshotList({ type }: SnapshotListProps) {
|
||||
|
||||
restoreSnapshot(changes);
|
||||
|
||||
// Redirection vers la grille avec les filtres du snapshot
|
||||
const query = new URLSearchParams();
|
||||
if (snapshot.codeFournisseur) query.set("fournisseur", snapshot.codeFournisseur);
|
||||
if (snapshot.magasin) query.set("magasin", snapshot.magasin);
|
||||
@@ -187,6 +202,13 @@ export function SnapshotList({ type }: SnapshotListProps) {
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<SuccessModal
|
||||
isOpen={modal.isOpen}
|
||||
onClose={() => setModal(prev => ({ ...prev, isOpen: false }))}
|
||||
title={modal.title}
|
||||
message={modal.message}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user