123 lines
4.0 KiB
TypeScript
123 lines
4.0 KiB
TypeScript
import { useEffect, useState } from "react";
|
||
import { useParams, useNavigate } from "react-router-dom";
|
||
import { ArrowLeftOutlined } from "@ant-design/icons";
|
||
import { useAppDispatch, useAppSelector } from "../../app/hooks";
|
||
import { fetchProductBySlug } from "../../features/catalog/productsSlice";
|
||
import styles from "./ItemPage.module.css";
|
||
import Button from "../../components/Button/Button";
|
||
import PriceLisForm from "../../components/PriceLisForm/PriceLisForm";
|
||
import ProductAttributes from "../../components/Table/ProducTable";
|
||
import Link from "antd/es/typography/Link";
|
||
import { setSelectedCategory } from "../../features/catalog/categoriesSlice";
|
||
|
||
const ItemPage = () => {
|
||
const { slug } = useParams();
|
||
const dispatch = useAppDispatch();
|
||
const navigate = useNavigate();
|
||
const { loading } = useAppSelector((state) => state.products);
|
||
const { items: cats, selectedCategoryId } = useAppSelector((s) => s.categories);
|
||
|
||
const [activeTab, setActiveTab] = useState<"desc" | "chars">("desc");
|
||
const [open, setOpen] = useState(false);
|
||
|
||
useEffect(() => {
|
||
if (slug) dispatch(fetchProductBySlug(slug));
|
||
}, [dispatch, slug]);
|
||
|
||
const product = useAppSelector((state) => state.products.selectedProduct);
|
||
const category = cats.find((cat) => cat.id === Number(selectedCategoryId));
|
||
|
||
if (loading || !product) {
|
||
return <div className={styles.loading}>Загрузка...</div>;
|
||
}
|
||
|
||
if (!category) {
|
||
return <div className={styles.loading}>Загрузка...</div>;
|
||
}
|
||
|
||
return (
|
||
<main className={styles.page}>
|
||
<PriceLisForm open={open} onClose={() => setOpen(false)} />
|
||
|
||
<div className={styles.top}>
|
||
<button className={styles.back} onClick={() => navigate(-1)}>
|
||
<ArrowLeftOutlined />
|
||
Назад в каталог
|
||
</button>
|
||
</div>
|
||
|
||
<section className={styles.hero}>
|
||
<div className={styles.left}>
|
||
<img src={product.images[0]} alt={product.name} />
|
||
</div>
|
||
|
||
<div className={styles.right}>
|
||
<div className={styles.breadcrumbs}>
|
||
<Link
|
||
onClick={() => {
|
||
navigate("/products");
|
||
dispatch(setSelectedCategory(null));
|
||
}}
|
||
>
|
||
Категории
|
||
</Link>
|
||
<span>/</span>
|
||
<Link onClick={() => navigate("/products")}>{category.name}</Link>
|
||
<span>/</span>
|
||
<span>{product.name}</span>
|
||
</div>
|
||
|
||
<span className={styles.kicker}>Карточка товара</span>
|
||
<h1 className={styles.title}>{product.name}</h1>
|
||
<p className={styles.short}>{product.description}</p>
|
||
|
||
<div className={styles.status}>
|
||
{product.inStock ? "В наличии" : "Под заказ"}
|
||
</div>
|
||
|
||
<Button label="Скачать прайс-лист" onClick={() => setOpen(true)} />
|
||
</div>
|
||
</section>
|
||
|
||
<section className={styles.details}>
|
||
<div className={styles.tabs}>
|
||
<button
|
||
className={activeTab === "desc" ? styles.active : ""}
|
||
onClick={() => setActiveTab("desc")}
|
||
>
|
||
Описание
|
||
</button>
|
||
<button
|
||
className={activeTab === "chars" ? styles.active : ""}
|
||
onClick={() => setActiveTab("chars")}
|
||
>
|
||
Характеристики
|
||
</button>
|
||
</div>
|
||
|
||
<div className={styles.content}>
|
||
{activeTab === "desc" && (
|
||
<div>
|
||
<h2>Описание</h2>
|
||
<p>{product.description}</p>
|
||
<p>{product.full_name}</p>
|
||
</div>
|
||
)}
|
||
|
||
{activeTab === "chars" && (
|
||
<div>
|
||
<h2>Характеристики</h2>
|
||
<ProductAttributes
|
||
attributes={product.attributes}
|
||
attrList={category.attributes}
|
||
/>
|
||
</div>
|
||
)}
|
||
</div>
|
||
</section>
|
||
</main>
|
||
);
|
||
};
|
||
|
||
export default ItemPage;
|