chore: add ansible backend docker frontend-prep
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user