Files
badoHair_fe/app/panier/page.tsx
2026-05-12 00:28:37 +00:00

159 lines
6.2 KiB
TypeScript

"use client";
import { useState } from "react";
import { Minus, Plus, X, ArrowLeft, ShoppingBag, Check } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useCart } from "@/contexts/CartContext";
import { useAuth } from "@/contexts/AuthContext";
import { useLanguage } from "@/contexts/LanguageContext";
import { createOrder } from "@/lib/api/orders";
import { ApiError } from "@/lib/api";
import Link from "next/link";
import { toast } from "sonner";
export default function Cart() {
const { items, updateQuantity, removeItem, clearCart, totalPrice } = useCart();
const { user } = useAuth();
const { t } = useLanguage();
const [loading, setLoading] = useState(false);
const [ordered, setOrdered] = useState(false);
const handleCheckout = async () => {
if (!user) {
toast.error(t("cart.login_required"));
return;
}
setLoading(true);
try {
await createOrder({
items: items.map((i) => ({ product_id: i.product.id, quantity: i.quantity })),
});
clearCart();
setOrdered(true);
} catch (err) {
const msg = err instanceof ApiError ? err.message : t("cart.error");
toast.error(msg);
} finally {
setLoading(false);
}
};
if (ordered) {
return (
<div className="min-h-screen flex items-center justify-center py-12 px-4">
<div className="text-center max-w-md">
<div className="h-16 w-16 rounded-full bg-primary/10 flex items-center justify-center mx-auto mb-6">
<Check className="h-8 w-8 text-primary" />
</div>
<h2 className="font-serif text-3xl mb-3">{t("cart.confirmed_title")}</h2>
<p className="text-muted-foreground mb-6">{t("cart.confirmed_desc")}</p>
<Link href="/boutique">
<Button variant="outline">
<ArrowLeft className="h-4 w-4 mr-2" />
{t("cart.continue_shopping")}
</Button>
</Link>
</div>
</div>
);
}
return (
<div className="min-h-screen py-8 lg:py-12">
<div className="container mx-auto px-4 lg:px-8 max-w-3xl">
<h1 className="font-serif text-3xl lg:text-4xl text-center mb-10">{t("cart.title")}</h1>
{items.length === 0 ? (
<div className="text-center py-20">
<ShoppingBag className="h-16 w-16 mx-auto mb-4 text-muted-foreground/30" />
<p className="text-muted-foreground mb-6">{t("cart.empty")}</p>
<Link href="/boutique">
<Button variant="outline">
<ArrowLeft className="h-4 w-4 mr-2" />
{t("nav.shop")}
</Button>
</Link>
</div>
) : (
<>
<div className="space-y-4">
{items.map((item) => (
<div
key={`${item.product.id}-${item.selectedColor}-${item.selectedLength}`}
className="flex gap-4 p-4 bg-card rounded-lg border border-border"
>
<img
src={item.product.image}
alt={item.product.name}
className="w-24 h-32 object-cover rounded-md"
/>
<div className="flex-1">
<div className="flex justify-between items-start">
<div>
<h3 className="font-medium">{item.product.name}</h3>
<p className="text-sm text-muted-foreground mt-0.5">
{item.selectedColor} {item.selectedLength}
</p>
</div>
<button
onClick={() => removeItem(item.product.id)}
className="text-muted-foreground hover:text-destructive"
>
<X className="h-4 w-4" />
</button>
</div>
<div className="flex items-center justify-between mt-4">
<div className="flex items-center gap-3">
<button
onClick={() => updateQuantity(item.product.id, item.quantity - 1)}
className="p-1.5 border border-border rounded-md hover:bg-muted"
>
<Minus className="h-3 w-3" />
</button>
<span className="text-sm font-medium w-6 text-center">{item.quantity}</span>
<button
onClick={() => updateQuantity(item.product.id, item.quantity + 1)}
className="p-1.5 border border-border rounded-md hover:bg-muted"
>
<Plus className="h-3 w-3" />
</button>
</div>
<span className="font-semibold">
{(item.product.price * item.quantity).toFixed(2)}
</span>
</div>
</div>
</div>
))}
</div>
<div className="mt-8 bg-card rounded-lg border border-border p-6">
<div className="flex justify-between items-center text-lg mb-4">
<span className="font-medium">{t("cart.total")}</span>
<span className="font-serif text-xl font-semibold">{totalPrice.toFixed(2)} </span>
</div>
{!user && (
<p className="text-sm text-muted-foreground mb-3 text-center">
<Link href="/connexion" className="text-primary hover:underline">{t("cart.login_link")}</Link>{" "}
{t("cart.login_suffix")}
</p>
)}
<Button
className="w-full"
size="lg"
onClick={handleCheckout}
disabled={loading || !user}
>
{loading ? t("cart.processing") : t("cart.checkout")}
</Button>
<p className="text-xs text-muted-foreground text-center mt-3">
{t("cart.payment_note")}
</p>
</div>
</>
)}
</div>
</div>
);
}