Checkpoint: Ajout bouton "Purger les données" (admin uniquement) avec boîte de dialogue de confirmation sur VeilleDashboard et AAPDashboard. Procédures tRPC veille.purge et aap.purge ajoutées côté serveur.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { useState, useMemo } from "react";
|
||||
import { useLocalAuth } from "@/contexts/LocalAuthContext";
|
||||
import { toast } from "sonner";
|
||||
import { trpc } from "@/lib/trpc";
|
||||
import { FilterBar } from "@/components/FilterBar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -17,7 +19,20 @@ import {
|
||||
ChevronRight,
|
||||
AlertCircle,
|
||||
Clock,
|
||||
Trash2,
|
||||
AlertTriangle,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { format, isPast, differenceInDays } from "date-fns";
|
||||
import { fr } from "date-fns/locale";
|
||||
@@ -88,6 +103,19 @@ function ClotureStatus({ date }: { date: Date | null | undefined }) {
|
||||
}
|
||||
|
||||
export default function AAPDashboard() {
|
||||
const { user } = useLocalAuth();
|
||||
const isAdmin = user?.role === "admin";
|
||||
const utils = trpc.useUtils();
|
||||
const purgeMutation = trpc.aap.purge.useMutation({
|
||||
onSuccess: (data) => {
|
||||
toast.success(`Purge effectuée — ${data.deleted} entrée(s) supprimée(s)`);
|
||||
utils.aap.list.invalidate();
|
||||
utils.aap.filters.invalidate();
|
||||
},
|
||||
onError: (err) => {
|
||||
toast.error(`Erreur lors de la purge : ${err.message}`);
|
||||
},
|
||||
});
|
||||
const [viewMode, setViewMode] = useState<"list" | "grid">("list");
|
||||
const [activeTab, setActiveTab] = useState<AAPCategorie | "all">("all");
|
||||
const [page, setPage] = useState(1);
|
||||
@@ -155,6 +183,40 @@ export default function AAPDashboard() {
|
||||
<Button variant={viewMode === "grid" ? "default" : "outline"} size="sm" onClick={() => setViewMode("grid")} className="gap-2">
|
||||
<LayoutGrid size={15} />Vignettes
|
||||
</Button>
|
||||
{isAdmin && (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="outline" size="sm" className="gap-2 border-destructive/50 text-destructive hover:bg-destructive hover:text-destructive-foreground ml-2">
|
||||
<Trash2 size={15} />
|
||||
Purger les données
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle className="flex items-center gap-2">
|
||||
<AlertTriangle size={20} className="text-destructive" />
|
||||
Purger tous les appels à projets
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription asChild>
|
||||
<div className="space-y-2">
|
||||
<p>Cette action va <strong>supprimer définitivement</strong> tous les appels à projets (Handicap, PA, Enfance, Précarité, Sanitaire et Autre).</p>
|
||||
<p className="text-destructive font-medium">Cette opération est irréversible. Les données ne pourront pas être récupérées.</p>
|
||||
</div>
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Annuler</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
||||
onClick={() => purgeMutation.mutate()}
|
||||
disabled={purgeMutation.isPending}
|
||||
>
|
||||
{purgeMutation.isPending ? "Purge en cours..." : "Oui, purger tous les appels à projets"}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { useState, useMemo } from "react";
|
||||
import { useLocalAuth } from "@/contexts/LocalAuthContext";
|
||||
import { toast } from "sonner";
|
||||
import { trpc } from "@/lib/trpc";
|
||||
import { FilterBar } from "@/components/FilterBar";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -26,7 +28,20 @@ import {
|
||||
Eye,
|
||||
Globe,
|
||||
BookOpen,
|
||||
Trash2,
|
||||
AlertTriangle,
|
||||
} from "lucide-react";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { format } from "date-fns";
|
||||
import { fr } from "date-fns/locale";
|
||||
@@ -214,6 +229,19 @@ function VeilleDetailDialog({
|
||||
// ─── Composant principal ──────────────────────────────────────────────────────
|
||||
|
||||
export default function VeilleDashboard() {
|
||||
const { user } = useLocalAuth();
|
||||
const isAdmin = user?.role === "admin";
|
||||
const utils = trpc.useUtils();
|
||||
const purgeMutation = trpc.veille.purge.useMutation({
|
||||
onSuccess: (data) => {
|
||||
toast.success(`Purge effectuée — ${data.deleted} entrée(s) supprimée(s)`);
|
||||
utils.veille.list.invalidate();
|
||||
utils.veille.filters.invalidate();
|
||||
},
|
||||
onError: (err) => {
|
||||
toast.error(`Erreur lors de la purge : ${err.message}`);
|
||||
},
|
||||
});
|
||||
const [viewMode, setViewMode] = useState<"list" | "grid">("list");
|
||||
const [activeTab, setActiveTab] = useState<TypeVeille | "all">("all");
|
||||
const [page, setPage] = useState(1);
|
||||
@@ -284,9 +312,42 @@ export default function VeilleDashboard() {
|
||||
<Button variant={viewMode === "grid" ? "default" : "outline"} size="sm" onClick={() => setViewMode("grid")} className="gap-2">
|
||||
<LayoutGrid size={15} />Vignettes
|
||||
</Button>
|
||||
{isAdmin && (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="outline" size="sm" className="gap-2 border-destructive/50 text-destructive hover:bg-destructive hover:text-destructive-foreground ml-2">
|
||||
<Trash2 size={15} />
|
||||
Purger les données
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle className="flex items-center gap-2">
|
||||
<AlertTriangle size={20} className="text-destructive" />
|
||||
Purger toutes les données de veille
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription asChild>
|
||||
<div className="space-y-2">
|
||||
<p>Cette action va <strong>supprimer définitivement</strong> toutes les entrées de la veille stratégique (réglementaire, concurrentielle, technologique et générale).</p>
|
||||
<p className="text-destructive font-medium">Cette opération est irréversible. Les données ne pourront pas être récupérées.</p>
|
||||
</div>
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Annuler</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
||||
onClick={() => purgeMutation.mutate()}
|
||||
disabled={purgeMutation.isPending}
|
||||
>
|
||||
{purgeMutation.isPending ? "Purge en cours..." : "Oui, purger toutes les données"}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Onglets */}
|
||||
<Tabs value={activeTab} onValueChange={(v) => { setActiveTab(v as TypeVeille | "all"); setPage(1); }}>
|
||||
<TabsList className="bg-muted/50">
|
||||
|
||||
Reference in New Issue
Block a user