mirror of
https://github.com/R0m1k3/Regisflow.git
synced 2026-10-24 15:48:17 +02:00
Improve the way users confirm deletions of sales and user accounts
Replaces native confirm() dialogs with AlertDialog modals from shadcn/ui in SalesHistory and Administration components. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 91318273-c764-4fd4-be04-bdc12c38af32 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/af392dda-fd07-4339-ad27-aa15ea23c8ed.jpg
This commit is contained in:
1 parent
c8164a1699
commit
04aff6fbbe
3 files changed
+112
-37
No files matched your search
@@ -7,6 +7,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
|
|||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogDescription } from "@/components/ui/dialog";
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogDescription } from "@/components/ui/dialog";
|
||||||
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
@@ -258,16 +259,12 @@ export default function Administration() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteUser = async (user: User) => {
|
const handleDeleteUser = (user: User) => {
|
||||||
if (window.confirm(`Êtes-vous sûr de vouloir supprimer l'utilisateur "${user.username}" ?`)) {
|
deleteUserMutation.mutate(user.id);
|
||||||
await deleteUserMutation.mutateAsync(user.id);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteStore = async (store: Store) => {
|
const handleDeleteStore = (store: Store) => {
|
||||||
if (window.confirm(`Êtes-vous sûr de vouloir supprimer le magasin "${store.name}" ?`)) {
|
deleteStoreMutation.mutate(store.id);
|
||||||
await deleteStoreMutation.mutateAsync(store.id);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getRoleBadge = (role: string) => {
|
const getRoleBadge = (role: string) => {
|
||||||
@@ -518,14 +515,38 @@ export default function Administration() {
|
|||||||
>
|
>
|
||||||
<Edit className="h-4 w-4" />
|
<Edit className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<AlertDialog>
|
||||||
variant="ghost"
|
<AlertDialogTrigger asChild>
|
||||||
size="sm"
|
<Button
|
||||||
onClick={() => handleDeleteUser(user)}
|
variant="ghost"
|
||||||
disabled={user.role === 'administrator'}
|
size="sm"
|
||||||
>
|
disabled={user.role === 'administrator'}
|
||||||
<Trash2 className="h-4 w-4 text-red-600" />
|
>
|
||||||
</Button>
|
<Trash2 className="h-4 w-4 text-red-600" />
|
||||||
|
</Button>
|
||||||
|
</AlertDialogTrigger>
|
||||||
|
<AlertDialogContent>
|
||||||
|
<AlertDialogHeader>
|
||||||
|
<AlertDialogTitle>Confirmer la suppression</AlertDialogTitle>
|
||||||
|
<AlertDialogDescription>
|
||||||
|
Êtes-vous sûr de vouloir supprimer l'utilisateur "{user.username}" ? Cette action est irréversible.
|
||||||
|
<br /><br />
|
||||||
|
<strong>Nom complet :</strong> {user.firstName} {user.lastName}<br />
|
||||||
|
<strong>Email :</strong> {user.email || "Non renseigné"}<br />
|
||||||
|
<strong>Rôle :</strong> {user.role}
|
||||||
|
</AlertDialogDescription>
|
||||||
|
</AlertDialogHeader>
|
||||||
|
<AlertDialogFooter>
|
||||||
|
<AlertDialogCancel>Annuler</AlertDialogCancel>
|
||||||
|
<AlertDialogAction
|
||||||
|
onClick={() => handleDeleteUser(user)}
|
||||||
|
className="bg-red-600 hover:bg-red-700"
|
||||||
|
>
|
||||||
|
Supprimer
|
||||||
|
</AlertDialogAction>
|
||||||
|
</AlertDialogFooter>
|
||||||
|
</AlertDialogContent>
|
||||||
|
</AlertDialog>
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
@@ -819,13 +840,37 @@ export default function Administration() {
|
|||||||
>
|
>
|
||||||
<Edit className="h-4 w-4" />
|
<Edit className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<AlertDialog>
|
||||||
variant="ghost"
|
<AlertDialogTrigger asChild>
|
||||||
size="sm"
|
<Button
|
||||||
onClick={() => handleDeleteStore(store)}
|
variant="ghost"
|
||||||
>
|
size="sm"
|
||||||
<Trash2 className="h-4 w-4 text-red-600" />
|
>
|
||||||
</Button>
|
<Trash2 className="h-4 w-4 text-red-600" />
|
||||||
|
</Button>
|
||||||
|
</AlertDialogTrigger>
|
||||||
|
<AlertDialogContent>
|
||||||
|
<AlertDialogHeader>
|
||||||
|
<AlertDialogTitle>Confirmer la suppression</AlertDialogTitle>
|
||||||
|
<AlertDialogDescription>
|
||||||
|
Êtes-vous sûr de vouloir supprimer le magasin "{store.name}" ? Cette action est irréversible.
|
||||||
|
<br /><br />
|
||||||
|
<strong>Adresse :</strong> {store.address || "Non renseignée"}<br />
|
||||||
|
<strong>Téléphone :</strong> {store.phone || "Non renseigné"}<br />
|
||||||
|
<strong>Email :</strong> {store.email || "Non renseigné"}
|
||||||
|
</AlertDialogDescription>
|
||||||
|
</AlertDialogHeader>
|
||||||
|
<AlertDialogFooter>
|
||||||
|
<AlertDialogCancel>Annuler</AlertDialogCancel>
|
||||||
|
<AlertDialogAction
|
||||||
|
onClick={() => handleDeleteStore(store)}
|
||||||
|
className="bg-red-600 hover:bg-red-700"
|
||||||
|
>
|
||||||
|
Supprimer
|
||||||
|
</AlertDialogAction>
|
||||||
|
</AlertDialogFooter>
|
||||||
|
</AlertDialogContent>
|
||||||
|
</AlertDialog>
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogFooter, DialogDescription } from '@/components/ui/dialog';
|
||||||
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from '@/components/ui/alert-dialog';
|
||||||
import { useToast } from '@/hooks/use-toast';
|
import { useToast } from '@/hooks/use-toast';
|
||||||
import { useStoreContext } from '@/hooks/useStoreContext';
|
import { useStoreContext } from '@/hooks/useStoreContext';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
@@ -70,10 +71,8 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleDeleteSale = async (sale: Sale) => {
|
const handleDeleteSale = (sale: Sale) => {
|
||||||
if (confirm(`Êtes-vous sûr de vouloir supprimer cette vente ?`)) {
|
deleteSaleMutation.mutate(sale.id);
|
||||||
deleteSaleMutation.mutate(sale.id);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportToCSV = () => {
|
const exportToCSV = () => {
|
||||||
@@ -280,14 +279,38 @@ export default function SalesHistory({ canDelete = false }: SalesHistoryProps) {
|
|||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
{canDelete && (
|
{canDelete && (
|
||||||
<Button
|
<AlertDialog>
|
||||||
variant="ghost"
|
<AlertDialogTrigger asChild>
|
||||||
size="sm"
|
<Button
|
||||||
onClick={() => handleDeleteSale(sale)}
|
variant="ghost"
|
||||||
disabled={deleteSaleMutation.isPending}
|
size="sm"
|
||||||
>
|
disabled={deleteSaleMutation.isPending}
|
||||||
<Trash2 className="h-4 w-4 text-red-600" />
|
>
|
||||||
</Button>
|
<Trash2 className="h-4 w-4 text-red-600" />
|
||||||
|
</Button>
|
||||||
|
</AlertDialogTrigger>
|
||||||
|
<AlertDialogContent>
|
||||||
|
<AlertDialogHeader>
|
||||||
|
<AlertDialogTitle>Confirmer la suppression</AlertDialogTitle>
|
||||||
|
<AlertDialogDescription>
|
||||||
|
Êtes-vous sûr de vouloir supprimer cette vente ? Cette action est irréversible.
|
||||||
|
<br /><br />
|
||||||
|
<strong>Client :</strong> {sale.nom} {sale.prenom}<br />
|
||||||
|
<strong>Article :</strong> {sale.typeArticle}<br />
|
||||||
|
<strong>Date :</strong> {formatDateTime(sale.timestamp!)}
|
||||||
|
</AlertDialogDescription>
|
||||||
|
</AlertDialogHeader>
|
||||||
|
<AlertDialogFooter>
|
||||||
|
<AlertDialogCancel>Annuler</AlertDialogCancel>
|
||||||
|
<AlertDialogAction
|
||||||
|
onClick={() => handleDeleteSale(sale)}
|
||||||
|
className="bg-red-600 hover:bg-red-700"
|
||||||
|
>
|
||||||
|
Supprimer
|
||||||
|
</AlertDialogAction>
|
||||||
|
</AlertDialogFooter>
|
||||||
|
</AlertDialogContent>
|
||||||
|
</AlertDialog>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|||||||
@@ -151,4 +151,11 @@ Preferred communication style: Simple, everyday language.
|
|||||||
- ✅ Generated default admin account (admin/admin123) for initial setup
|
- ✅ Generated default admin account (admin/admin123) for initial setup
|
||||||
- ✅ Updated all components to work with database instead of local storage
|
- ✅ Updated all components to work with database instead of local storage
|
||||||
- ✅ Added session-based authentication with PostgreSQL session store
|
- ✅ Added session-based authentication with PostgreSQL session store
|
||||||
- ✅ Implemented comprehensive API with proper validation and error handling
|
- ✅ Implemented comprehensive API with proper validation and error handling
|
||||||
|
|
||||||
|
### User Experience Improvements (January 9, 2025)
|
||||||
|
- ✅ Fixed authentication flow issues with login/logout redirects
|
||||||
|
- ✅ Replaced native browser confirm() dialogs with modern AlertDialog modals
|
||||||
|
- ✅ Enhanced deletion confirmations in sales history and administration panels
|
||||||
|
- ✅ Improved visual feedback with detailed confirmation dialogs showing item details
|
||||||
|
- ✅ Added proper modal management with shadcn/ui AlertDialog components
|
||||||
Reference in new issue
Block a user