101 lines
3.3 KiB
React
101 lines
3.3 KiB
React
import { useState, useEffect } from "react";
|
||
import PageLayout from "../components/PageLayout";
|
||
import { getCart, removeFromCart, createOrder } from "../api/index";
|
||
export default function Cart() {
|
||
const [items, setItems] = useState([]);
|
||
const [loading, setLoading] = useState(true);
|
||
const [error, setError] = useState(null);
|
||
|
||
useEffect(() => {
|
||
getCart()
|
||
.then((res) => {
|
||
setItems(res.data);
|
||
})
|
||
.catch(() => setError("Не удалось загрузить товары"))
|
||
.finally(() => setLoading(false));
|
||
}, []);
|
||
|
||
const total = items.reduce((sum, ci) => sum + ci.quantity * ci.item.price, 0);
|
||
|
||
const handleCheckout = async () => {
|
||
try {
|
||
await createOrder({ delivery_address: "Уточняется" });
|
||
alert("Заказ оформлен");
|
||
setItems([]);
|
||
navigate("/shop");
|
||
} catch {
|
||
alert("Не удалось оформить заказ");
|
||
}
|
||
};
|
||
|
||
const handleRemove = async (id) => {
|
||
try {
|
||
await removeFromCart(id);
|
||
setItems((prev) => prev.filter((ci) => ci.id !== id));
|
||
} catch {
|
||
alert("Не удалось удалить");
|
||
}
|
||
};
|
||
|
||
if (loading) {
|
||
return (
|
||
<PageLayout>
|
||
<p className="text-white p-6">Загрузка товаров</p>
|
||
</PageLayout>
|
||
);
|
||
}
|
||
return (
|
||
<PageLayout>
|
||
<div className="px-6 md:px-16 text-white mb-6 grow">
|
||
<h1 className="text-2xl md:text-4xl font-medium uppercase mb-6">
|
||
Корзина
|
||
</h1>
|
||
{error && <p className="text-red-400">{error}</p>}
|
||
{items.length === 0 ? (
|
||
<p>Корзина пуста</p>
|
||
) : (
|
||
<div className="flex flex-col gap-4">
|
||
{items.map((ci) => (
|
||
<div
|
||
key={ci.id}
|
||
className="flex items-center gap-4 bg-white/5 rounded-lg p-4 border border-white/10"
|
||
>
|
||
<img
|
||
src={`/static/items/${ci.item.avatar_url}`}
|
||
alt={ci.item.name}
|
||
className="w-40 h-40 object-cover rounded-md shrink-0"
|
||
/>
|
||
<div className="grow">
|
||
<p className="font-medium text-lg">{ci.item.name}</p>
|
||
<p className="text-sm text-white/60">
|
||
{ci.quantity} {ci.item.unit} x {ci.item.price}р.
|
||
</p>
|
||
</div>
|
||
<div className="text-right font-medium whitespace-nowrap">
|
||
{ci.quantity * ci.item.price} р.
|
||
</div>
|
||
|
||
<button
|
||
onClick={() => handleRemove(ci.id)}
|
||
className="text-white/40 hover:text-red-400 transition-colors duration-400 text-xl px-2"
|
||
>
|
||
x
|
||
</button>
|
||
</div>
|
||
))}
|
||
<div className="flex items-center justify-between mt-8 pt-6 border-t border-white/20">
|
||
<span className="text-xl font-medium">Итого: {total}р.</span>
|
||
<button
|
||
className="bg-gold text-white hover:bg-red-400 transition-colors duration-400 px-8 py-3 rounded-md font-medium uppercase"
|
||
onClick={() => handleCheckout()}
|
||
>
|
||
Оформить заказ
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</PageLayout>
|
||
);
|
||
}
|