feat: add shop card in cart
This commit is contained in:
@@ -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}`);
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
{/* Блок с информацией о товаре */}
|
{/* Блок с информацией о товаре */}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user