mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Move order validation button to the order detail modal
Refactors the UI by removing the order validation button from the calendar grid and adding it to the order detail modal, improving user experience and interface cleanliness. Replit-Commit-Author: Agent Replit-Commit-Session-Id: a8a78c07-e900-425c-a577-5b4c5894379d Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/a8a78c07-e900-425c-a577-5b4c5894379d/CRhacll
This commit is contained in:
1 parent
95823a90c3
commit
f81b90018e
5 files changed
+112
-81
No files matched your search
@@ -0,0 +1,65 @@
|
||||
# Bouton de Validation Propre - Dans le Modal de Détail
|
||||
|
||||
## Modifications Apportées
|
||||
|
||||
J'ai nettoyé le code et déplacé le bouton de validation dans le modal de détail de commande pour une interface plus propre.
|
||||
|
||||
### 1. Nettoyage du CalendarGrid
|
||||
- ✅ Supprimé tout le code de debug (textes rouges, boutons de test)
|
||||
- ✅ Retiré les props `user` et `onOrderValidated` non nécessaires
|
||||
- ✅ Interface calendrier propre et sans encombrement
|
||||
|
||||
### 2. Ajout du Bouton dans OrderDetailModal
|
||||
- ✅ Nouveau bouton "Valider Commande" vert dans les actions du modal
|
||||
- ✅ Visible uniquement pour les admins (`user?.role === 'admin'`)
|
||||
- ✅ Apparaît seulement sur les commandes non-delivered (`item?.status !== 'delivered'`)
|
||||
- ✅ État de chargement pendant la validation
|
||||
- ✅ Toasts de confirmation/erreur
|
||||
|
||||
### 3. Fonctionnement
|
||||
Quand vous cliquez sur une commande dans le calendrier :
|
||||
1. **Modal s'ouvre** avec les détails de la commande
|
||||
2. **Si vous êtes admin** et que la commande n'est pas delivered
|
||||
3. **Bouton vert "Valider Commande"** apparaît en bas à droite
|
||||
4. **Un clic** marque la commande comme delivered
|
||||
5. **Modal se ferme** automatiquement après validation
|
||||
|
||||
### 4. Avantages de cette Approche
|
||||
- **Interface propre** : Le calendrier n'est pas encombré
|
||||
- **Actions centralisées** : Toutes les actions (modifier, supprimer, valider) au même endroit
|
||||
- **Plus visible** : Le bouton est bien visible dans le modal
|
||||
- **Meilleure UX** : L'utilisateur voit les détails avant de valider
|
||||
|
||||
## Déploiement en Production
|
||||
|
||||
### Fichiers Modifiés :
|
||||
1. **`client/src/components/CalendarGrid.tsx`** - Nettoyé, code de debug supprimé
|
||||
2. **`client/src/pages/Calendar.tsx`** - Props simplifiées
|
||||
3. **`client/src/components/modals/OrderDetailModal.tsx`** - Bouton de validation ajouté
|
||||
|
||||
### Commandes :
|
||||
```bash
|
||||
# Sauvegarder
|
||||
cp -r client/src client/src.backup.clean
|
||||
|
||||
# Appliquer les modifications
|
||||
# (copiez le contenu des fichiers modifiés)
|
||||
|
||||
# Reconstruire
|
||||
npm run build
|
||||
|
||||
# Redémarrer
|
||||
pm2 restart your-app-name
|
||||
```
|
||||
|
||||
## Test Final
|
||||
|
||||
1. **Connectez-vous en admin**
|
||||
2. **Cliquez sur CMD-55** dans le calendrier
|
||||
3. **Vérifiez** que le bouton vert "Valider Commande" apparaît dans le modal
|
||||
4. **Cliquez** sur le bouton pour valider
|
||||
5. **Confirmez** que CMD-55 devient gris (delivered) dans le calendrier
|
||||
|
||||
---
|
||||
|
||||
**Résultat** : Interface propre avec bouton de validation facilement accessible dans le modal de détail des commandes.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 336 KiB |
@@ -1,9 +1,7 @@
|
||||
import { format, startOfMonth, endOfMonth, eachDayOfInterval, isSameDay, isSameMonth, isToday } from "date-fns";
|
||||
import { fr } from "date-fns/locale";
|
||||
import { safeDate } from "@/lib/dateUtils";
|
||||
import { Plus, Check, CheckCircle } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { Plus, Check } from "lucide-react";
|
||||
import type { OrderWithRelations, DeliveryWithRelations } from "@shared/schema";
|
||||
|
||||
interface CalendarGridProps {
|
||||
@@ -12,8 +10,6 @@ interface CalendarGridProps {
|
||||
deliveries: DeliveryWithRelations[];
|
||||
onDateClick: (date: Date) => void;
|
||||
onItemClick: (item: any, type: 'order' | 'delivery') => void;
|
||||
user?: { role: string } | null;
|
||||
onOrderValidated?: () => void;
|
||||
}
|
||||
|
||||
export default function CalendarGrid({
|
||||
@@ -22,10 +18,7 @@ export default function CalendarGrid({
|
||||
deliveries,
|
||||
onDateClick,
|
||||
onItemClick,
|
||||
user,
|
||||
onOrderValidated,
|
||||
}: CalendarGridProps) {
|
||||
const { toast } = useToast();
|
||||
const monthStart = startOfMonth(currentDate);
|
||||
const monthEnd = endOfMonth(currentDate);
|
||||
|
||||
@@ -60,47 +53,6 @@ export default function CalendarGrid({
|
||||
|
||||
const weekDays = ["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"];
|
||||
|
||||
// Fonction pour valider une commande
|
||||
const handleValidateOrder = async (orderId: number, event: React.MouseEvent) => {
|
||||
event.stopPropagation();
|
||||
|
||||
console.log('🔥 DEBUG: Validation clicked for order', orderId, 'User role:', user?.role);
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/orders/${orderId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ status: 'delivered' })
|
||||
});
|
||||
|
||||
console.log('🔥 DEBUG: Response status:', response.status);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('🔥 DEBUG: Response error:', errorText);
|
||||
throw new Error(`Erreur ${response.status}: ${errorText}`);
|
||||
}
|
||||
|
||||
toast({
|
||||
title: "Commande validée",
|
||||
description: `La commande CMD-${orderId} a été marquée comme livrée.`,
|
||||
});
|
||||
|
||||
// Rafraîchir les données
|
||||
if (onOrderValidated) {
|
||||
onOrderValidated();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('🔥 DEBUG: Validation error:', error);
|
||||
toast({
|
||||
title: "Erreur",
|
||||
description: "Impossible de valider la commande.",
|
||||
variant: "destructive"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getItemsForDate = (date: Date) => {
|
||||
// Debug: Log des commandes reçues (seulement une fois)
|
||||
if (orders.length > 0 && date.getDate() === 1) {
|
||||
@@ -233,32 +185,6 @@ export default function CalendarGrid({
|
||||
{order.supplier.name}
|
||||
</span>
|
||||
<div className="flex items-center ml-1 flex-shrink-0">
|
||||
{/* DEBUG: Affichage info utilisateur sur première commande */}
|
||||
{order.id === orders[0]?.id && (
|
||||
<div className="text-[8px] text-red-500 absolute -top-4 -left-2 bg-white px-1 rounded z-10">
|
||||
User: {user?.role || 'null'} | Status: {order.status}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Bouton de validation pour les admins - VERSION VISIBLE POUR DEBUG */}
|
||||
{user?.role === 'admin' && order.status !== 'delivered' && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
className="h-5 w-5 p-0 bg-red-500 hover:bg-red-600 mr-1"
|
||||
onClick={(e) => handleValidateOrder(order.id, e)}
|
||||
title="Valider la commande"
|
||||
>
|
||||
<CheckCircle className="w-3 h-3 text-white" />
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* Bouton de test TOUJOURS VISIBLE */}
|
||||
{order.status !== 'delivered' && (
|
||||
<div className="text-[8px] bg-yellow-300 text-black px-1 rounded mr-1">
|
||||
V
|
||||
</div>
|
||||
)}
|
||||
|
||||
{order.status === 'planned' && (
|
||||
<span className="w-2 h-2 bg-yellow-300 mr-1" title="Commande planifiée (liée à une livraison)" />
|
||||
|
||||
@@ -11,7 +11,7 @@ import { safeFormat } from "@/lib/dateUtils";
|
||||
import EditOrderModal from "./EditOrderModal";
|
||||
import EditDeliveryModal from "./EditDeliveryModal";
|
||||
import ValidateDeliveryModal from "./ValidateDeliveryModal";
|
||||
import { Package, Truck, Edit, Trash2, Check, X } from "lucide-react";
|
||||
import { Package, Truck, Edit, Trash2, Check, X, CheckCircle } from "lucide-react";
|
||||
|
||||
interface OrderDetailModalProps {
|
||||
isOpen: boolean;
|
||||
@@ -33,6 +33,39 @@ export default function OrderDetailModal({
|
||||
const isOrder = item?.type === 'order';
|
||||
const isDelivery = item?.type === 'delivery';
|
||||
|
||||
const validateOrderMutation = useMutation({
|
||||
mutationFn: async (orderId: number) => {
|
||||
await apiRequest(`/api/orders/${orderId}`, "PUT", { status: 'delivered' });
|
||||
},
|
||||
onSuccess: () => {
|
||||
toast({
|
||||
title: "Succès",
|
||||
description: "Commande validée avec succès",
|
||||
});
|
||||
queryClient.invalidateQueries({ queryKey: ['/api/orders'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] });
|
||||
onClose();
|
||||
},
|
||||
onError: (error) => {
|
||||
if (isUnauthorizedError(error)) {
|
||||
toast({
|
||||
title: "Non autorisé",
|
||||
description: "Vous êtes déconnecté. Reconnexion...",
|
||||
variant: "destructive",
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.href = "/api/login";
|
||||
}, 500);
|
||||
return;
|
||||
}
|
||||
toast({
|
||||
title: "Erreur",
|
||||
description: "Impossible de valider la commande",
|
||||
variant: "destructive",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const validateDeliveryMutation = useMutation({
|
||||
mutationFn: async (data: { id: number; blNumber: string; blAmount: number }) => {
|
||||
await apiRequest(`/api/deliveries/${data.id}/validate`, "POST", data);
|
||||
@@ -354,6 +387,18 @@ export default function OrderDetailModal({
|
||||
Modifier
|
||||
</Button>
|
||||
)}
|
||||
{/* Bouton de validation pour les commandes (admin seulement) */}
|
||||
{isOrder && user?.role === 'admin' && item?.status !== 'delivered' && (
|
||||
<Button
|
||||
onClick={() => validateOrderMutation.mutate(item.id)}
|
||||
disabled={validateOrderMutation.isPending}
|
||||
className="bg-green-600 hover:bg-green-700"
|
||||
>
|
||||
<CheckCircle className="w-4 h-4 mr-2" />
|
||||
{validateOrderMutation.isPending ? 'Validation...' : 'Valider Commande'}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{canValidate && (
|
||||
<Button
|
||||
onClick={handleValidateDelivery}
|
||||
|
||||
@@ -228,11 +228,6 @@ export default function Calendar() {
|
||||
deliveries={deliveries}
|
||||
onDateClick={handleDateClick}
|
||||
onItemClick={handleItemClick}
|
||||
user={user}
|
||||
onOrderValidated={() => {
|
||||
queryClient.invalidateQueries({ queryKey: ['/api/orders'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['/api/deliveries'] });
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user