feat: add shop card in cart

This commit is contained in:
2026-06-23 21:24:08 +03:00
parent 7a8ce9083d
commit 21a39f21d8
3 changed files with 66 additions and 13 deletions
+9 -4
View File
@@ -37,9 +37,14 @@ export const updateItem = (id, itemData) =>
export const deleteItem = (id) => axios.delete(`${API_URL}/items/${id}`); export const deleteItem = (id) => axios.delete(`${API_URL}/items/${id}`);
export const getAllCategories = () => axios.get(`${API_URL}/getCategories`) export const getAllCategories = () => axios.get(`${API_URL}/getCategories`);
export const getCart = () => axios.get(`${API_URL}/cart/`); export const getCart = () => axios.get(`${API_URL}/cart/`);
export const addToCart = (data) => axios.post(`${API_URL}/cart/`, data) export const addToCart = (data) => axios.post(`${API_URL}/cart/`, data);
export const updateCartItem = (id, data) => axios.post(`${API_URL}/cart/${id}`, data) export const updateCartItem = (id, data) =>
export const removeFromCart = (id) => axios.post(`${API_URL}/cart/${id}`) axios.post(`${API_URL}/cart/${id}`, data);
export const removeFromCart = (id) => axios.post(`${API_URL}/cart/${id}`);
export const createOrder = (data) => axios.post(`${API_URL}/orders/`, data);
export const getUserOrders = () => axios.get(`${API_URL}/orders/`);
export const getOrder = (id) => axios.get(`${API_URL}/orders/${id}`);
+5 -1
View File
@@ -20,7 +20,11 @@ export default function CardItem({ item, onAddToCart }) {
return ( return (
<div className="flex flex-col text-white w-full"> <div className="flex flex-col text-white w-full">
<div className="w-full rounded-md overflow-hidden bg-slate-800/60 flex flex-col h-100 items-center justify-center border border-slate-700/50 select-none"> <div className="w-full rounded-md overflow-hidden bg-slate-800/60 flex flex-col h-100 items-center justify-center border border-slate-700/50 select-none">
<img src={item.avatar_url} alt={item.name} className="object-cover w-full h-full object-center" /> <img
src={item.avatar_url}
alt={item.name}
className="object-cover w-full h-150 object-center"
/>
</div> </div>
{/* Блок с информацией о товаре */} {/* Блок с информацией о товаре */}
+51 -7
View File
@@ -1,6 +1,6 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import PageLayout from "../components/PageLayout"; import PageLayout from "../components/PageLayout";
import { getCart } from "../api/index"; import { getCart, removeFromCart, createOrder } from "../api/index";
export default function Cart() { export default function Cart() {
const [items, setItems] = useState([]); const [items, setItems] = useState([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
@@ -17,6 +17,26 @@ export default function Cart() {
const total = items.reduce((sum, ci) => sum + ci.quantity * ci.item.price, 0); 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) { if (loading) {
return ( return (
<PageLayout> <PageLayout>
@@ -38,16 +58,40 @@ export default function Cart() {
{items.map((ci) => ( {items.map((ci) => (
<div <div
key={ci.id} key={ci.id}
className="flex items-center justify-between border-b border-white/20 pb-3" className="flex items-center gap-4 bg-white/5 rounded-lg p-4 border border-white/10"
> >
<span className="font-medium ">{ci.item.name}</span> <img
<span> src={`/static/items/${ci.item.avatar_url}`}
{ci.quantity} x {ci.item.price}р. ={" "} 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} р. {ci.quantity * ci.item.price} р.
</span> </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>
))} ))}
<div className="mt-6 text-xl font-medium">Итого: {total}р.</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>
)} )}
</div> </div>