mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-17 20:27:10 +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
@@ -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