Files
fishfish/frontend/src/pages/ItemPage.jsx
T
2026-06-24 13:13:09 +03:00

151 lines
5.2 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import PageLayout from "../components/PageLayout";
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { getItem, addToCart } from "../api/index";
import Arrow from "../components/Arrow";
export default function ItemPage() {
const { id } = useParams();
const [item, setItem] = useState(null);
const [loading, setLoading] = useState(true);
const [quantity, setQuantity] = useState(1);
useEffect(() => {
getItem(id)
.then((res) => setItem(res.data))
.catch(() => { })
.finally(() => setLoading(false));
}, [id]);
const isPiece = item?.unit_type === "piece";
const step = isPiece ? 1 : 0.1;
const minValue = isPiece ? 1 : 0.1;
useEffect(() => {
if (item) setQuantity(isPiece ? 1 : 0.1);
}, [item, isPiece]);
const handleIncrement = () => {
setQuantity((prev) => parseFloat((prev + step).toFixed(3)));
};
const handleDecrement = () => {
setQuantity((prev) =>
prev > minValue ? parseFloat((prev - step).toFixed(3)) : minValue,
);
};
const handleAddToCart = async () => {
try {
await addToCart({ item_id: item.id, quantity });
alert(`${item.name} добавлен в корзину`);
} catch {
alert("Не удалось добавить товар в корзину");
}
};
if (loading) {
return (
<PageLayout>
<p className="text-white p-6 md:p-16">Загрузка...</p>
</PageLayout>
);
}
if (!item) {
return (
<PageLayout>
<p className="text-white p-6 md:p-16">Товар не найден</p>
</PageLayout>
);
}
return (
<PageLayout>
<main className="px-6 md:px-16 grow w-full mb-10 text-white">
<div className="flex flex-col md:flex-row gap-8 md:gap-12 mt-6">
{/* ЛЕВО — фото */}
<div className="md:w-1/2">
<img
src={item.avatar_url}
alt={item.name}
className="w-full h-[300px] md:h-[500px] object-cover rounded-lg"
/>
</div>
{/* ПРАВО — всё инфо в одной колонке */}
<div className="md:w-1/2 flex flex-col">
<h1 className="text-2xl md:text-4xl font-medium uppercase mb-3">
{item.name}
</h1>
<p className="text-2xl md:text-3xl font-medium mb-6">
{item.price}
<span className="text-base text-white/50"> / {item.unit}</span>
</p>
<div className="flex flex-col gap-2 text-white/70 text-sm md:text-base mb-8">
<div className="flex justify-between border-b border-white/10 pb-2">
<span className="text-white/50">Категория</span>
<span>{item.category}</span>
</div>
<div className="flex justify-between border-b border-white/10 pb-2">
<span className="text-white/50">Город</span>
<span>{item.city}</span>
</div>
<div className="flex justify-between border-b border-white/10 pb-2">
<span className="text-white/50">Тип</span>
<span>{isPiece ? "Поштучно" : "На вес"}</span>
</div>
<div className="flex justify-between border-b border-white/10 pb-2">
<span className="text-white/50">В наличии</span>
<span
className={item.stock > 0 ? "text-green-400" : "text-red-400"}
>
{item.stock > 0 ? `${item.stock} ${item.unit}` : "нет"}
</span>
</div>
</div>
<div className="flex items-center gap-6 mb-6">
<span className="text-white/50 text-sm">Количество:</span>
<button
onClick={handleDecrement}
className="w-10 h-10 flex items-center justify-center bg-white/10 hover:bg-white/20 rounded font-medium text-xl cursor-pointer select-none transition-colors"
>
-
</button>
<span className="mx-2 font-mono text-sm min-w-20 text-center">
{quantity} {item.unit}
</span>
<button
onClick={handleIncrement}
className="w-10 h-10 flex items-center justify-center bg-white/10 hover:bg-white/20 rounded font-medium text-xl cursor-pointer select-none transition-colors"
>
+
</button>
</div>
<p className="text-lg mb-6">
Стоимость:{" "}
<span className="font-medium">
{parseFloat((quantity * item.price).toFixed(2))}
</span>
</p>
<button
onClick={handleAddToCart}
disabled={item.stock <= 0}
className="group flex items-center gap-4 text-base font-bold text-white cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed"
>
<span>
{item.stock > 0 ? "Добавить в корзину" : "Нет в наличии"}
</span>
<Arrow />
</button>
</div>
</div>
</main>
</PageLayout>
);
}