Files
projet_gestion_commande/frontend-prep/src/components/Items.tsx
T

218 lines
9.1 KiB
TypeScript

import React from "react";
import { Package, Clock, CheckCircle } from "lucide-react";
import "./Items.css";
interface OrderItem {
id: number;
command_id: number;
product_id: number;
produit: string; // ✅ API utilise "produit" pas "product_name"
quantite: number; // ✅ API utilise "quantite" pas "quantity"
prix: number; // ✅ API utilise "prix" pas "price"
status: string;
created_at: string;
// Champs additionnels de l'API
client_nom?: string;
client_prenom?: string;
client_telephone?: string;
client_username?: string;
command_address?: string;
delivery_address?: string;
livreur_assign?: string;
total_prix?: number;
}
interface ItemsModalProps {
isOpen: boolean;
onClose: () => void;
items: OrderItem[];
commandNumber?: string;
}
const ItemsModal: React.FC<ItemsModalProps> = ({
isOpen,
onClose,
items,
commandNumber,
}) => {
if (!isOpen) return null;
// Debug: Afficher les items reçus
console.log("🔍 [ITEMS_MODAL] Items reçus:", items);
console.log("🔍 [ITEMS_MODAL] Nombre items:", items.length);
if (items.length > 0) {
console.log("🔍 [ITEMS_MODAL] Premier item:", items[0]);
}
const getItemStatusLabel = (status: string): string => {
switch (status.toLowerCase()) {
case "pending":
return "En attente";
case "prepared":
return "Préparé";
case "packed":
return "Emballé";
case "delivered":
return "Livré";
default:
return status;
}
};
const getItemStatusIcon = (status: string) => {
switch (status.toLowerCase()) {
case "pending":
return <Clock size={14} />;
case "prepared":
case "packed":
return <Package size={14} />;
case "delivered":
return <CheckCircle size={14} />;
default:
return null;
}
};
const calculateTotal = (): number => {
return items.reduce((sum, item) => {
const price = item.prix || 0; // ✅ Utiliser "prix"
return sum + price;
}, 0);
};
const handleOverlayClick = (e: React.MouseEvent) => {
if (e.target === e.currentTarget) {
onClose();
}
};
return (
<div className="items-modal-overlay" onClick={handleOverlayClick}>
<div
className="items-modal-content"
onClick={(e) => e.stopPropagation()}
>
{/* Header */}
<div className="items-modal-header">
<h3>
<Package size={24} />
<span>
Articles de la commande
{commandNumber && (
<span className="command-badge">
{commandNumber}
</span>
)}
</span>
</h3>
<button
className="items-modal-close"
onClick={onClose}
aria-label="Fermer"
>
</button>
</div>
{/* Body */}
<div className="items-modal-body">
{items.length === 0 ? (
<div className="items-modal-empty">
<Package size={48} />
<p>Aucun article trouvé</p>
</div>
) : (
<>
{/* Items List */}
<div className="items-modal-list">
{items.map((item, index) => {
// Valeurs sécurisées - utiliser les vrais noms de champs de l'API
const itemPrice = item.prix || 0;
const itemQuantity = item.quantite || 0;
const itemName =
item.produit || "Produit inconnu";
const itemTotal = itemPrice;
return (
<div
key={item.id}
className="items-modal-card"
>
<div className="item-number">
#{index + 1}
</div>
<div className="item-content">
<div className="item-header">
<h4 className="item-name">
{itemName}
</h4>
<div
className={`item-status status-${(item.status || "pending").toLowerCase()}`}
>
{getItemStatusIcon(
item.status ||
"pending",
)}
<span>
{getItemStatusLabel(
item.status ||
"pending",
)}
</span>
</div>
</div>
<div className="item-details">
<div className="item-detail">
<span className="detail-label">
Quantité
</span>
<span className="detail-value">
{itemQuantity}g
</span>
</div>
<div className="item-detail">
<span className="detail-label">
Prix unitaire
</span>
<span className="detail-value">
{itemPrice.toFixed(
2,
)}
</span>
</div>
<div className="item-detail">
<span className="detail-label">
Total
</span>
<span className="detail-value detail-total">
{itemTotal.toFixed(
2,
)}
</span>
</div>
</div>
</div>
</div>
);
})}
</div>
{/* Total */}
<div className="items-modal-total">
<span>Total de la commande</span>
<strong>{calculateTotal().toFixed(2)}</strong>
</div>
</>
)}
</div>
</div>
</div>
);
};
export default ItemsModal;