mirror of
http://88.130.71.182:3000/BlitTech/badoHair_fe.git
synced 2026-06-13 11:13:57 +00:00
Update May 12 by Elvis
This commit is contained in:
@@ -1,14 +1,62 @@
|
||||
"use client";
|
||||
|
||||
import { Minus, Plus, X, ArrowLeft, ShoppingBag } from "lucide-react";
|
||||
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, totalPrice } = useCart();
|
||||
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">
|
||||
@@ -30,29 +78,49 @@ export default function Cart() {
|
||||
<>
|
||||
<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
|
||||
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>
|
||||
<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">
|
||||
<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">
|
||||
<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">
|
||||
<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>
|
||||
<span className="font-semibold">
|
||||
{(item.product.price * item.quantity).toFixed(2)} €
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,14 +132,27 @@ export default function Cart() {
|
||||
<span className="font-medium">{t("cart.total")}</span>
|
||||
<span className="font-serif text-xl font-semibold">{totalPrice.toFixed(2)} €</span>
|
||||
</div>
|
||||
<Button className="w-full" size="lg">
|
||||
{t("cart.checkout")}
|
||||
{!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">Paiement sécurisé par Stripe</p>
|
||||
<p className="text-xs text-muted-foreground text-center mt-3">
|
||||
{t("cart.payment_note")}
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user