import { useCart } from "../../context/useCart"; import Navbar from "../../components/Navbar"; import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { isUserAuthenticated, getProductById, getMediaUrl } from "../../api/api"; import type { Product } from "../../api/api"; import { Trash2, ShoppingCart, AlertTriangle, Leaf, X } from "lucide-react"; import "./Cart.css"; interface CartItemWithMedia { id: number; product_id: number; name_product: string; price: number; quantity: number; category: string; image: string; hasVideo: boolean; videoUrl?: string; is_reward?: boolean; } function Cart() { const navigate = useNavigate(); const { cartItems, removeFromCart, clearCart, loading, refreshCart } = useCart(); const [showClearConfirm, setShowClearConfirm] = useState(false); const [showVideo, setShowVideo] = useState(false); const [currentVideoUrl, setCurrentVideoUrl] = useState(""); const [enrichedItems, setEnrichedItems] = useState([]); const [loadingMedia, setLoadingMedia] = useState(false); useEffect(() => { if (!isUserAuthenticated()) navigate("/login/client", { replace: true }); }, [navigate]); useEffect(() => { const interval = setInterval(() => { if (!isUserAuthenticated()) navigate("/login/client", { replace: true }); }, 5000); return () => clearInterval(interval); }, [navigate]); useEffect(() => { if (!isUserAuthenticated()) { navigate("/login/client", { replace: true }); return; } refreshCart(); }, []); // eslint-disable-line react-hooks/exhaustive-deps const total = cartItems.reduce((sum, item) => sum + item.price, 0); const getProductImage = (product: Product): string => { if (!product.media || product.media.length === 0) return "https://via.placeholder.com/120x120/1a1a1a/ffffff?text=No+Image"; for (const m of product.media) { if (m && m.type === "image" && m.url) return getMediaUrl(m.url); } return "https://via.placeholder.com/120x120/1a1a1a/ffffff?text=No+Image"; }; useEffect(() => { const enrich = async () => { if (cartItems.length === 0) { setEnrichedItems([]); return; } const same = enrichedItems.length === cartItems.length && enrichedItems.every((e, i) => e.id === cartItems[i]?.id && e.product_id === cartItems[i]?.product_id); if (same) return; setLoadingMedia(true); try { const enriched = await Promise.all( cartItems.map(async (item) => { try { const res = await getProductById(item.product_id); if (res.success && res.data) { const p = res.data; const videoMedia = p.media?.find((m: { type: string; url?: string }) => m && m.type === "video"); return { ...item, image: getProductImage(p), hasVideo: !!videoMedia, videoUrl: videoMedia?.url ? getMediaUrl(videoMedia.url) : undefined, }; } } catch { /* ignore */ } return { ...item, image: "https://via.placeholder.com/120x120/1a1a1a/ffffff?text=No+Image", hasVideo: false }; }) ); setEnrichedItems(enriched); } finally { setLoadingMedia(false); } }; enrich(); }, [cartItems]); // eslint-disable-line react-hooks/exhaustive-deps const handleClearCart = async () => { if (!isUserAuthenticated()) { navigate("/login/client", { replace: true }); return; } setShowClearConfirm(false); await clearCart(); }; const handleRemoveItem = async (itemId: number) => { if (!isUserAuthenticated()) { navigate("/login/client", { replace: true }); return; } await removeFromCart(itemId); }; const handleCheckout = () => { if (!isUserAuthenticated()) { navigate("/login/client", { replace: true }); return; } navigate("/user/checkout"); }; if (loading && cartItems.length === 0) { return ( <>

Chargement du panier...

); } const displayItems = enrichedItems.length > 0 ? enrichedItems : cartItems.map(i => ({ ...i, image: "", hasVideo: false })); return ( <>
{cartItems.length === 0 ? (

Panier vide

Ajoutez des produits pour commencer

) : ( <> {/* Header */}

Mon panier

{cartItems.length} article{cartItems.length > 1 ? "s" : ""}
{/* Liste des articles */}
{loadingMedia && enrichedItems.length === 0 ? (

Chargement des médias...

) : ( displayItems.map((item, index) => (
{/* Vignette image */}
{item.image ? ( {item.name_product} { e.currentTarget.src = "https://via.placeholder.com/72x72/2d2d2d/ffffff?text=?"; }} /> ) : (
)}
{/* Infos */}

{item.name_product} {item.is_reward && ( 🎁 Récompense )}

{item.quantity}g

{item.is_reward ? ( Offert ) : ( `${item.price.toFixed(2)} €` )}

{/* Bouton supprimer */}
)) )}
{/* Footer fixe */}
Total {total.toFixed(2)} €
)}
{/* Modal vider le panier */} {showClearConfirm && (
setShowClearConfirm(false)}>
e.stopPropagation()}>

Vider le panier

Supprimer les {cartItems.length} article{cartItems.length > 1 ? "s" : ""} du panier ?

)} {/* Modal vidéo */} {showVideo && currentVideoUrl && (
{ setShowVideo(false); setCurrentVideoUrl(""); }}>
e.stopPropagation()}>
)} ); } export default Cart;