diff --git a/src/app/routes.tsx b/src/app/routes.tsx index f7186e4..82bc8b7 100644 --- a/src/app/routes.tsx +++ b/src/app/routes.tsx @@ -3,6 +3,7 @@ import { Routes } from "react-router"; import { Route } from "react-router"; import Main from "../pages/Main/Main"; import About from "../pages/About/About"; +import Contacts from "../pages/Contacts/Contacts"; import Products from "../pages/Products/Products"; import ItemPage from "../pages/ItemPage/ItemPage"; @@ -13,10 +14,11 @@ function AppRoutes() { } /> } /> } /> + } /> } /> ) } -export default AppRoutes; \ No newline at end of file +export default AppRoutes; diff --git a/src/components/Banner/Banner.module.css b/src/components/Banner/Banner.module.css index 7d2835d..94d9b27 100644 --- a/src/components/Banner/Banner.module.css +++ b/src/components/Banner/Banner.module.css @@ -29,20 +29,25 @@ top: 180px; color: white; max-width: 500px; z-index: 2; +font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } .textBlock h1 { -font-size: 36px; -font-weight: 700; -line-height: 1.3; +font-size: 42px; +font-weight: 800; +line-height: 1.14; +letter-spacing: 0; +text-transform: none; } .textBlock h2 { font-size: 20px; -font-weight: 400; -opacity: 0.8; +font-weight: 700; +opacity: 0.9; +letter-spacing: 0.08em; +text-transform: uppercase; } @@ -113,4 +118,4 @@ font-size: 16px; height: 42px; padding: 0 20px; } -} \ No newline at end of file +} diff --git a/src/components/Banner/Banner.tsx b/src/components/Banner/Banner.tsx index 68d49bf..3fbd128 100644 --- a/src/components/Banner/Banner.tsx +++ b/src/components/Banner/Banner.tsx @@ -1,71 +1,64 @@ -import styles from './Banner.module.css' import React from "react"; import { Carousel } from "antd"; -import Button from '../Button/Button.tsx'; -import banner_img1 from '../../assets/images/mainPage/ChatGPT-Image-Oct-1_-2025_-05_29_18-PM.png' -import banner_img2 from '../../assets/images/mainPage/296170994030930.jpg' -import { useNavigate } from 'react-router-dom'; +import { useNavigate } from "react-router-dom"; +import styles from "./Banner.module.css"; +import Button from "../Button/Button.tsx"; +import banner_img1 from "../../assets/images/mainPage/ChatGPT-Image-Oct-1_-2025_-05_29_18-PM.png"; +import banner_img2 from "../../assets/images/mainPage/296170994030930.jpg"; export interface SlideItem { -id: number; -image: string; -title: string; -subtitle: string; -description: string; + id: number; + image: string; + title: string; + subtitle: string; + description: string; } - const slides: SlideItem[] = [ - { - id: 1, - image: banner_img1, - title: "ПРОИЗВОДСТВО", - subtitle: "ТРУБ, ФИТИНГОВ, КОЛЕН И ОТВОДОВ", - description: "ДЛЯ ВНЕШНЕЙ И ВНУТРЕННЕЙ КАНАЛИЗАЦИИ", - }, - { - id: 2, - image: banner_img2, - title: "ПРОИЗВОДСТВО", - subtitle: "ТРУБ, ФИТИНГОВ, КОЛЕН И ОТВОДОВ", - description: "ДЛЯ ВНЕШНЕЙ И ВНУТРЕННЕЙ КАНАЛИЗАЦИИ", - } + { + id: 1, + image: banner_img1, + title: "Производство", + subtitle: "Труб, фитингов, колен и отводов", + description: "для внешней и внутренней канализации", + }, + { + id: 2, + image: banner_img2, + title: "Производство", + subtitle: "Труб, фитингов, колен и отводов", + description: "для внешней и внутренней канализации", + }, ]; - const BannerSlider: React.FC = () => { -const navigate = useNavigate(); + const navigate = useNavigate(); -const handleClick = () => { - navigate('/products') - console.log('Кнопка нажата!'); - }; + const handleClick = () => { + navigate("/products"); + }; -return ( + return (
- - {slides.map((slide) => ( -
-
-
-

{slide.title}

-

- {slide.subtitle} -
{slide.description} -

-
- banner -
-
- ))} -
+ + {slides.map((slide) => ( +
+
+
+

{slide.title}

+

+ {slide.subtitle} +
{slide.description} +

+
+ banner +
+
+ ))} +
- ); + ); }; - -export default BannerSlider; \ No newline at end of file +export default BannerSlider; diff --git a/src/components/Categories/Categories.module.css b/src/components/Categories/Categories.module.css index 1347134..8408a75 100644 --- a/src/components/Categories/Categories.module.css +++ b/src/components/Categories/Categories.module.css @@ -1,145 +1,124 @@ .wrapper { -width: 100%; -margin-top: 40px; + width: 100%; +} + +.head { + max-width: 760px; + margin-bottom: 28px; +} + +.kicker { + display: inline-block; + margin-bottom: 14px; + color: var(--lightblue); + font-size: 14px; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; } .header { -font-size: 24px; -font-weight: 700; -margin-bottom: 20px; + margin: 0; + color: #111111; + font-size: clamp(30px, 4vw, 46px); + font-weight: 800; + line-height: 1.16; } +.head p { + margin: 18px 0 0; + color: #3f4652; + font-size: 18px; + line-height: 1.7; +} .grid { -display: grid; -grid-template-columns: repeat(4, 1fr); -grid-auto-rows: 230px; -gap: 0; + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 22px; } .card { -position: relative; -overflow: hidden; -border: 1px solid #ececec; + position: relative; + min-height: 420px; + overflow: hidden; + border: 1px solid #e7ebf0; + border-radius: 8px; + background: #f8fafc; + cursor: pointer; + box-shadow: 0 18px 50px rgba(17, 31, 51, 0.05); } - .image { -width: 100%; -height: 100%; -object-fit: cover; + width: 100%; + height: 100%; + min-height: 420px; + display: block; + object-fit: cover; + transition: transform 0.4s ease; } - -.highlight { -grid-column: span 2; -grid-row: span 2; -} - - .overlay { -position: absolute; -left: 40px; -bottom: 40px; -color: white; -max-width: 320px; + position: absolute; + left: 28px; + right: 28px; + bottom: 28px; + max-width: 360px; + padding: 24px; + border-radius: 8px; + background: rgba(255, 255, 255, 0.92); + color: #151515; + box-shadow: 0 16px 40px rgba(0, 0, 0, 0.16); } - .overlay h3 { -font-size: 22px; -font-weight: 700; + margin: 0; + color: #111111; + font-size: 26px; + font-weight: 800; + line-height: 1.2; } - .overlay h4 { -margin-top: 4px; -font-size: 16px; -opacity: 0.9; -} - - -.button { -margin-top: 20px; -background: #ffd400 !important; -color: black !important; -border: none !important; -font-weight: 600; -} - - -.titleSmall { -position: absolute; -bottom: 15px; -left: 15px; -font-size: 15px; -font-weight: 600; + margin: 8px 0 22px; + color: #596474; + font-size: 16px; + font-weight: 600; + line-height: 1.4; } .card:hover .image { -transform: scale(1.05); -transition: transform 0.4s ease; + transform: scale(1.04); } - -.card:hover { -cursor: pointer; -background-color: #ffd400; -} - - -.highlight:hover .overlay h3, -.highlight:hover .overlay h4 { -transform: translateX(4px); -transition: all 0.3s ease; -} - - -.titleSmall { -transition: transform 0.3s ease, opacity 0.3s ease; -} - - -.card:hover .titleSmall { -transform: translateY(-4px); -opacity: 0.9; -} - -/* Mobile */ @media (max-width: 900px) { -.grid { -grid-template-columns: repeat(2, 1fr); -} -.highlight { -grid-column: span 2; -} + .grid { + grid-template-columns: 1fr; + } } -@media (max-width: 665px){ - .header { - font-size: 20px; - - } +@media (max-width: 560px) { + .head p { + font-size: 16px; + } - .overlay h3 { -font-size: 16px; + .card, + .image { + min-height: 330px; + } + .overlay { + left: 18px; + right: 18px; + bottom: 18px; + padding: 20px; + } + + .overlay h3 { + font-size: 22px; + } + + .overlay h4 { + font-size: 14px; + } } - - -.overlay h4 { -margin-top: 4px; -font-size: 14px; - -} -} - -@media (max-width: 600px) { -.grid { -grid-template-columns: 1fr; -} -.highlight { -grid-column: span 1; -grid-row: span 1; -} -} \ No newline at end of file diff --git a/src/components/Categories/Categories.tsx b/src/components/Categories/Categories.tsx index f5f06a6..0d94ebe 100644 --- a/src/components/Categories/Categories.tsx +++ b/src/components/Categories/Categories.tsx @@ -1,89 +1,70 @@ import React from "react"; +import { useNavigate } from "react-router-dom"; import styles from "./Categories.module.css"; import Button from "../Button/Button"; -import category_internal1 from "../../assets/images/mainPage/category_internal1.jpg" -import category_interna2 from "../../assets/images/mainPage/category_internal2.jpg" -import { useAppSelector, useAppDispatch } from "../../app/hooks"; -import { useNavigate } from "react-router-dom"; +import category_internal1 from "../../assets/images/mainPage/category_internal1.jpg"; +import category_interna2 from "../../assets/images/mainPage/category_internal2.jpg"; interface CategoryItem { -id: number; -title: string; -subtitle?: string; -image: string; -highlight?: boolean; + id: number; + title: string; + subtitle?: string; + image: string; + highlight?: boolean; } const categories: CategoryItem[] = [ -{ -id: 1, -title: "Труба ПВХ", -subtitle: "для НАРУЖНОЙ канализации", -image: category_interna2, -highlight: true, -}, -/*{ id: 2, title: "КОЛЕНА И ОТВОДЫ", image: "/images/cat-paraffin.jpg" }, -{ id: 3, title: "ЗАГЛУШКИ И РЕВИЗИИ", image: "/images/cat-hold.jpg" }, -{ id: 4, title: "ПЕРЕХОДЫ", image: "/images/cat-wash.jpg" }, -{ id: 5, title: "ТРОЙНИКИ", image: "/images/cat-resin.jpg" }, -{ id: 6, title: "МУФТЫ", image: "/images/cat-scraper.jpg" }, -{ id: 7, title: "ПЕРЕХОДЫ", image: "/images/cat-cork.jpg" },*/ -{ -id: 2, -title: "Труба ПВХ", -subtitle: "для ВНУТРЕННЕЙ канализации", -highlight: true, -image: category_internal1, -}, - - + { + id: 1, + title: "Труба ПВХ", + subtitle: "для наружной канализации", + image: category_interna2, + highlight: true, + }, + { + id: 2, + title: "Труба ПВХ", + subtitle: "для внутренней канализации", + image: category_internal1, + highlight: true, + }, ]; - const CategoriesGrid: React.FC = () => { -const navigate = useNavigate(); + const navigate = useNavigate(); -const handleClick = () => { - navigate('/products'); - console.log('Кнопка нажата!'); -}; + const handleClick = () => { + navigate("/products"); + }; -return ( -
-

КАТЕГОРИИ ТОВАРОВ

+ return ( +
+
+ Продукция +

Категории товаров

+

+ Основные позиции для наружной и внутренней канализации. Полный каталог + доступен в разделе продукции. +

+
- -
+
{categories.map((cat) => ( -
- {cat.title} - {cat.highlight && ( -
-

{cat.title}

- {cat.subtitle &&

{cat.subtitle}

} -
- )} - - - {!cat.highlight && ( -
- {cat.title} - {cat.subtitle && {cat.subtitle}} -
- )} +
+ {cat.title} +
+

{cat.title}

+ {cat.subtitle &&

{cat.subtitle}

} +
+
))} -
-
-); +
+
+ ); }; - -export default CategoriesGrid; \ No newline at end of file +export default CategoriesGrid; diff --git a/src/components/ContactProduct/ContactProduct.module.css b/src/components/ContactProduct/ContactProduct.module.css index bcc2f9d..7952dd6 100644 --- a/src/components/ContactProduct/ContactProduct.module.css +++ b/src/components/ContactProduct/ContactProduct.module.css @@ -3,6 +3,7 @@ align-items: center; justify-content: space-between; padding: 0px 0; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } .left { @@ -20,11 +21,22 @@ } .title{ - font-size: 20px; + margin: 0 0 12px; + color: var(--lightblue); + font-size: 14px; + font-weight: 700; + letter-spacing: 0.08em; + line-height: 1.2; + text-transform: uppercase; } .subtitle{ - font-size: 28px; + margin: 0 0 28px; + color: #111111; + font-size: clamp(30px, 4vw, 46px); + font-weight: 800; + letter-spacing: 0; + line-height: 1.16; } .carousel { @@ -51,7 +63,10 @@ position: relative; bottom: 20px; left: 40px; color: white; - font-size: 22px; + font-size: 16px; + font-weight: 700; + letter-spacing: 0.04em; + line-height: 1.3; } .arrows { @@ -67,7 +82,9 @@ position: relative; height: 48px; background: white; border: 1px solid #ccc; - font-size: 22px; + font-size: 20px; + font-weight: 700; + line-height: 1; cursor: pointer; } @@ -89,7 +106,15 @@ position: relative; } @media (max-width: 665px){ + .title { + font-size: 13px; + } + + .subtitle { + font-size: 30px; + } + .arrow { - font-size: 20px; + font-size: 18px; + } } -} \ No newline at end of file diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx index 4c00949..516ec78 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/components/Footer/Footer.tsx @@ -16,9 +16,10 @@ const Footer: React.FC = () => {
- O КОМПАНИИ - ПРОДУКЦИЯ - setIsOpen(true)}>ПРАЙС-ЛИСТ + O КОМПАНИИ + ПРОДУКЦИЯ + КОНТАКТЫ + setIsOpen(true)}>ПРАЙС-ЛИСТ
diff --git a/src/components/Header/Header.module.css b/src/components/Header/Header.module.css index f726915..6ca967a 100644 --- a/src/components/Header/Header.module.css +++ b/src/components/Header/Header.module.css @@ -26,10 +26,10 @@ position: relative; color: black; text-decoration: none; - padding: 1.8rem 1.8rem; + padding: 1.2rem 1.2rem; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-weight: 500; - font-size: 1.1rem; + font-size: 1.0rem; transition: all 0.3s ease; overflow: hidden; } @@ -109,6 +109,7 @@ .headerMenu a:nth-child(1) { animation-delay: 0.1s; } .headerMenu a:nth-child(2) { animation-delay: 0.2s; } .headerMenu a:nth-child(3) { animation-delay: 0.3s; } +.headerMenu a:nth-child(4) { animation-delay: 0.4s; } @keyframes slideIn { to { @@ -223,4 +224,4 @@ transition: all 0.3s ease; /*filter: brightness(0) invert(1);*/ } -} \ No newline at end of file +} diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index d38953d..7907da4 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -33,8 +33,9 @@ const dispatch = useAppDispatch(); {/* НАВИГАЦИЯ */}
setMenuOpen(false)}>ГЛАВНАЯ - setMenuOpen(false)}>О КОМПАНИИ - {setMenuOpen(false); dispatch(setSelectedCategory(null))}}>ПРОДУКЦИЯ + setMenuOpen(false)}>О КОМПАНИИ + {setMenuOpen(false); dispatch(setSelectedCategory(null))}}>ПРОДУКЦИЯ + setMenuOpen(false)}>КОНТАКТЫ
@@ -42,4 +43,4 @@ const dispatch = useAppDispatch(); ) } -export default Header; \ No newline at end of file +export default Header; diff --git a/src/components/Modal/Modal.module.css b/src/components/Modal/Modal.module.css new file mode 100644 index 0000000..f60b4e9 --- /dev/null +++ b/src/components/Modal/Modal.module.css @@ -0,0 +1,98 @@ +.modalRoot :global(.ant-modal-content) { + overflow: hidden; + padding: 0; + border-radius: 24px; + + box-shadow: 0 24px 70px rgba(0, 0, 0, 0.2); +} + +.modalRoot :global(.ant-modal-close) { + top: 18px; + right: 18px; + border-radius: 50%; + color: #222; + +} + +.modalRoot :global(.ant-modal-close:hover) { + background: #ffffff; + transform: translateY(-1px); +} + +.modalBox { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + padding: 46px 44px 38px; + text-align: center; +} + +.modalBox::before { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + border: 1px solid rgba(255, 212, 0, 0.35); + border-radius: 24px; +} + +.iconWrap { + display: grid; + place-items: center; + width: 78px; + height: 78px; + margin-bottom: 22px; + border-radius: 50%; + background: #fff4a8; + box-shadow: 0 14px 30px rgba(255, 212, 0, 0.3); +} + +.icon { + color: #111111; + font-size: 42px; +} + +.title { + max-width: 360px; + margin: 0; + font-size: 30px; + font-weight: 700; +} + +.subtitle { + max-width: 350px; + margin: 12px 0 28px; + color: #636363; + font-size: 16px; + line-height: 1.55; +} + +@media (max-width: 560px) { + .modalRoot :global(.ant-modal) { + max-width: calc(100vw - 28px); + } + + .modalBox { + padding: 40px 24px 30px; + } + + .iconWrap { + width: 68px; + height: 68px; + margin-bottom: 18px; + } + + .icon { + font-size: 36px; + } + + .title { + font-size: 24px; + } + + .subtitle { + margin-bottom: 24px; + font-size: 15px; + } +} diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx new file mode 100644 index 0000000..e060008 --- /dev/null +++ b/src/components/Modal/Modal.tsx @@ -0,0 +1,44 @@ +import { CheckCircleFilled } from "@ant-design/icons"; +import { Modal } from "antd"; +import { motion } from "framer-motion"; +import React from "react"; +import styles from "./Modal.module.css"; +import Button from "../Button/Button"; + +interface Props { + open: boolean; + onClose: () => void; +} + +const Modalka: React.FC = ({ open, onClose }) => { + return ( + + +
+ +
+ +

Спасибо за обращение!

+

+ Мы свяжемся с вами в ближайшее время. Хорошего дня! +

+ + - + + ); }; -export default CategoryFilters; \ No newline at end of file +export default CategoryFilters; diff --git a/src/features/catalog/Pagination.tsx b/src/features/catalog/Pagination.tsx index 9dcff40..cc8d527 100644 --- a/src/features/catalog/Pagination.tsx +++ b/src/features/catalog/Pagination.tsx @@ -3,32 +3,50 @@ import styles from "./Catalog.module.css"; import { useAppSelector, useAppDispatch } from "../../app/hooks"; import { setPage, fetchProductsByCategory } from "./productsSlice"; -interface Props { categoryId: number } +interface Props { + categoryId: number; +} const Pagination: React.FC = ({ categoryId }) => { const dispatch = useAppDispatch(); - const { total, page, limit } = useAppSelector(s => s.products); + const { total, page, limit } = useAppSelector((s) => s.products); const totalPages = Math.ceil(total / limit); + if (totalPages <= 1) return null; - const go = (p:number) => { + const go = (p: number) => { dispatch(setPage(p)); dispatch(fetchProductsByCategory({ categoryId, page: p, limit })); window.scrollTo({ top: 200, behavior: "smooth" }); - } + }; return (
- +
- {Array.from({length: totalPages}, (_,i) => i+1).map(p => ( - + {Array.from({ length: totalPages }, (_, i) => i + 1).map((p) => ( + ))}
- +
); }; -export default Pagination; \ No newline at end of file + +export default Pagination; diff --git a/src/features/catalog/SidebarCategories.tsx b/src/features/catalog/SidebarCategories.tsx index 1e7cf65..90cb134 100644 --- a/src/features/catalog/SidebarCategories.tsx +++ b/src/features/catalog/SidebarCategories.tsx @@ -5,35 +5,42 @@ import { fetchCategories, setSelectedCategory } from "./categoriesSlice"; import { fetchProductsByCategory, setFilters, setPage } from "./productsSlice"; const SidebarCategories: React.FC = () => { - const dispatch = useAppDispatch(); - const { items, selectedCategoryId, loading } = useAppSelector(s => s.categories); + const dispatch = useAppDispatch(); + const { items, selectedCategoryId, loading } = useAppSelector((s) => s.categories); - useEffect(() => { - dispatch(fetchCategories()); - }, [dispatch]); + useEffect(() => { + dispatch(fetchCategories()); + }, [dispatch]); - const onClick = (catId: number) => { + const onClick = (catId: number) => { dispatch(setSelectedCategory(catId)); - dispatch(setFilters({})); // сброс фильтров + dispatch(setFilters({})); dispatch(setPage(1)); dispatch(fetchProductsByCategory({ categoryId: catId, page: 1, limit: 9 })); }; - return( - - ) -} -export default SidebarCategories; \ No newline at end of file + return ( + + ); +}; + +export default SidebarCategories; diff --git a/src/pages/About/About.module.css b/src/pages/About/About.module.css index 9052e5f..1a767a2 100644 --- a/src/pages/About/About.module.css +++ b/src/pages/About/About.module.css @@ -11,7 +11,6 @@ .story, .principles, .production { - width: 100%; max-width: 1200px; margin: 0 auto; } diff --git a/src/pages/Contacts/Contacts.module.css b/src/pages/Contacts/Contacts.module.css new file mode 100644 index 0000000..434a5e7 --- /dev/null +++ b/src/pages/Contacts/Contacts.module.css @@ -0,0 +1,233 @@ +.page { + width: 100%; + min-height: 70vh; + padding: 126px 20px 96px; + background: #ffffff; + box-sizing: border-box; + color: #151515; +} + +.hero, +.mapBlock { + max-width: 1200px; + margin: 0 auto; +} + +.hero { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(360px, 0.82fr); + gap: 56px; + align-items: start; +} + +.heroText { + min-width: 0; +} + +.kicker { + display: inline-block; + margin-bottom: 16px; + color: var(--lightblue); + font-size: 14px; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.hero h1 { + max-width: 760px; + margin: 0; + color: #111111; + font-size: clamp(38px, 5vw, 64px); + line-height: 1.06; +} + +.hero p { + max-width: 640px; + margin: 26px 0 0; + color: #3f4652; + font-size: 19px; + line-height: 1.7; +} + +.contactPanel { + display: grid; + gap: 18px; + padding: 28px; + border: 1px solid #e7ebf0; + border-radius: 8px; + background: linear-gradient(135deg, #f7fbff 0%, #ffffff 62%, #fff7cf 100%); + box-shadow: 0 18px 50px rgba(17, 31, 51, 0.07); +} + +.contactItem { + display: grid; + grid-template-columns: 52px minmax(0, 1fr); + gap: 16px; + padding: 20px; + border: 1px solid #e7ebf0; + border-radius: 8px; + background: rgba(255, 255, 255, 0.84); +} + +.icon { + display: flex; + align-items: center; + justify-content: center; + width: 52px; + height: 52px; + border-radius: 8px; + background: #fff2a6; + color: #111111; + font-size: 24px; +} + +.label { + display: block; + margin-bottom: 8px; + color: #77808c; + font-size: 13px; + font-weight: 700; + letter-spacing: 0.06em; + text-transform: uppercase; +} + +.contactItem p { + margin: 0; + color: #202733; + font-size: 18px; + line-height: 1.55; +} + +.contactItem a { + color: #151515; + font-size: 18px; + font-weight: 700; + text-decoration: none; + transition: color 0.2s ease; +} + +.contactItem a:hover { + color: var(--darkblue); +} + +.links { + display: flex; + flex-direction: column; + gap: 8px; +} + +.mapBlock { + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; + margin-top: 42px; + padding: 30px; + border: 1px solid #e7ebf0; + border-radius: 8px; + background: #f8fafc; +} + +.mapPlaceholder { + display: flex; + align-items: center; + gap: 18px; + min-width: 0; + color: #202733; +} + +.mapPlaceholder svg { + flex: 0 0 auto; + color: var(--lightblue); + font-size: 34px; +} + +.mapPlaceholder strong, +.mapPlaceholder span { + display: block; +} + +.mapPlaceholder strong { + font-size: 20px; + line-height: 1.35; +} + +.mapPlaceholder span { + margin-top: 4px; + color: #596474; + font-size: 15px; +} + +.mapLink { + display: inline-flex; + align-items: center; + justify-content: center; + flex: 0 0 auto; + min-height: 50px; + padding: 0 24px; + border-radius: 50px; + background: #ffd400; + color: #111111; + font-size: 15px; + font-weight: 700; + text-decoration: none; + transition: background 0.2s ease, transform 0.2s ease; +} + +.mapLink:hover { + background: #ffe667; + transform: translateY(-2px); +} + +@media (max-width: 980px) { + .page { + padding-top: 104px; + } + + .hero { + grid-template-columns: 1fr; + gap: 34px; + } + + .mapBlock { + align-items: flex-start; + flex-direction: column; + } +} + +@media (max-width: 560px) { + .page { + padding: 92px 16px 72px; + } + + .hero h1 { + font-size: 34px; + } + + .hero p { + font-size: 16px; + } + + .contactPanel { + padding: 18px; + } + + .contactItem { + grid-template-columns: 1fr; + padding: 18px; + } + + .mapBlock { + padding: 22px; + } + + .mapPlaceholder { + align-items: flex-start; + } + + .mapLink { + width: 100%; + box-sizing: border-box; + } +} diff --git a/src/pages/Contacts/Contacts.tsx b/src/pages/Contacts/Contacts.tsx new file mode 100644 index 0000000..0547721 --- /dev/null +++ b/src/pages/Contacts/Contacts.tsx @@ -0,0 +1,98 @@ +import { + EnvironmentOutlined, + MailOutlined, + PhoneOutlined, +} from "@ant-design/icons"; +import SEO from "../../shared/ui/SEO"; +import styles from "./Contacts.module.css"; + +const phones = [ + { + label: "+7 910 121 09 62", + href: "tel:+79101210962", + }, +]; + +const Contacts = () => { + return ( + <> + + +
+
+
+ Контакты +

Свяжитесь с нами по вопросам продукции и поставок

+

+ Подскажем по ассортименту, наличию, срокам производства и условиям + сотрудничества. +

+
+ +
+
+
+ +
+
+ Адрес производства и склада +

+ Нижегородская область, г. Дзержинск, Автозаводское шоссе, 70А +

+
+
+ + + + +
+
+ +
+
+ +
+ Дзержинск, Автозаводское шоссе, 70А + Производство и склад RK-Plastic Tech +
+
+ + Открыть в Яндекс Картах + +
+
+ + ); +}; + +export default Contacts; diff --git a/src/pages/ItemPage/ItemPage.module.css b/src/pages/ItemPage/ItemPage.module.css index b13e316..ff2f3d6 100644 --- a/src/pages/ItemPage/ItemPage.module.css +++ b/src/pages/ItemPage/ItemPage.module.css @@ -1,193 +1,247 @@ .page { - background: #f5f5f5; min-height: 100vh; + padding: 126px 20px 96px; + background: #ffffff; + color: #151515; + box-sizing: border-box; } -.resetLink { - text-decoration: none; - color: inherit; - cursor: pointer; - font-size: 16px; - color: #f5c400; - +.loading { + min-height: 60vh; + padding-top: 140px; + color: #596474; + text-align: center; + font-size: 18px; +} + +.top, +.hero, +.details { + width: 100%; + max-width: 1200px; + margin: 0 auto; } .top { - background: #000; - padding: 15px 40px; - padding-top: 100px; -} - -.short{ - font-size: 14px; - margin-top: 30px; - margin-bottom: 40px; + margin-bottom: 22px; } .back { - color: white; - background: none; - border: none; + display: inline-flex; + align-items: center; + gap: 10px; + min-height: 44px; + padding: 0 18px; + border: 1px solid #d7dce3; + border-radius: 50px; + background: #ffffff; + color: #151515; cursor: pointer; - font-weight: 600; + font-size: 14px; + font-weight: 700; + transition: border-color 0.2s ease, transform 0.2s ease; +} + +.back:hover { + border-color: #111111; + transform: translateY(-1px); } .hero { - display: flex; - min-height: 500px; + display: grid; + grid-template-columns: minmax(320px, 0.9fr) minmax(0, 1.1fr); + gap: 30px; + align-items: stretch; +} + +.left, +.right, +.details { + border: 1px solid #e7ebf0; + border-radius: 8px; } .left { - flex: 1; - background: #fff; display: flex; align-items: center; justify-content: center; + min-height: 520px; + padding: 46px; + background: #f8fafc; } .left img { - max-width: 400px; -} - -.rightContent{ - padding-right: 100px; - + display: block; + width: 100%; + max-width: 430px; + max-height: 430px; + object-fit: contain; } .right { - flex: 1; - background: linear-gradient( - rgba(44, 44, 44, 0.9), - rgba(44, 44, 44, 0.9) - ), - url("../../assets/images/otkrytie-novogo-proizvodstva-v-g.Krymsk.jpeg"); - color: white; - padding: 90px; display: flex; flex-direction: column; justify-content: center; + padding: 48px; + background: linear-gradient(135deg, #f7fbff 0%, #ffffff 58%, #fff7cf 100%); + box-shadow: 0 18px 50px rgba(17, 31, 51, 0.06); } .breadcrumbs { - font-size: 16px; - color: #f5c400; - margin-bottom: 20px; + display: flex; + flex-wrap: wrap; + gap: 8px; + align-items: center; + margin-bottom: 28px; + color: #77808c; + font-size: 14px; + line-height: 1.4; } -.download { - margin-top: 30px; - background: #f5c400; - border: none; - padding: 15px 40px; - border-radius: 30px; - font-weight: bold; +.breadcrumbs a { + color: #596474; + text-decoration: none; cursor: pointer; + transition: color 0.2s ease; +} + +.breadcrumbs a:hover { + color: #111111; +} + +.kicker { + display: inline-block; + margin-bottom: 14px; + color: var(--lightblue); + font-size: 13px; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.title { + max-width: 720px; + margin: 0; + color: #111111; + font-size: clamp(32px, 4vw, 54px); + line-height: 1.08; +} + +.short { + max-width: 620px; + margin: 24px 0 0; + color: #3f4652; + font-size: 17px; + line-height: 1.7; +} + +.status { + width: fit-content; + margin: 28px 0 24px; + padding: 8px 14px; + border-radius: 50px; + background: #fff7cf; + color: #111111; + font-size: 14px; + font-weight: 700; +} + +.details { + overflow: hidden; + margin-top: 30px; + background: #ffffff; } .tabs { display: flex; - border-top: 1px solid #ddd; + gap: 0; + border-bottom: 1px solid #e7ebf0; + background: #f8fafc; } .tabs button { - flex: 1; - padding: 20px; + min-height: 58px; + padding: 0 30px; border: none; - background: #eee; + border-right: 1px solid #e7ebf0; + background: transparent; + color: #596474; cursor: pointer; + font-size: 15px; + font-weight: 800; + letter-spacing: 0.04em; + text-transform: uppercase; + transition: background 0.2s ease, color 0.2s ease; } -.active { - background: white; - font-weight: bold; +.tabs button:hover { + color: #111111; +} + +.tabs .active { + background: #ffffff; + color: #111111; } .content { - padding: 40px; - background: white; + padding: 36px; } -.attrRow { - display: flex; - justify-content: space-between; - padding: 10px 0; - border-bottom: 1px solid #eee; +.content h2 { + margin: 0 0 18px; + color: #151515; + font-size: clamp(26px, 3vw, 36px); + line-height: 1.16; } -.title{ - font-size: 28px; +.content p { + max-width: 900px; + margin: 0 0 14px; + color: #3f4652; + font-size: 17px; + line-height: 1.75; } -@media (max-width: 1024px) { - .hero { - flex-direction: column-reverse; - } - - .top { - padding: 20px; - padding-top: 100px; - } - - .right { - padding: 50px; - } - - .rightContent { - padding-right: 100px; - } - - .left img { - max-width: 300px; - } - - .left{ - padding: 20px; - } -} - -/* ================= MOBILE ================= */ - -@media (max-width: 768px) { - .top { - padding: 15px 20px; - padding-top: 100px; - +@media (max-width: 980px) { + .page { + padding-top: 104px; } .hero { - flex-direction: column-reverse; + grid-template-columns: 1fr; } .left { - padding: 20px; + min-height: 360px; + } +} + +@media (max-width: 560px) { + .page { + padding: 92px 16px 72px; + } + + .left, + .right, + .content { + padding: 22px; + } + + .left { + min-height: 280px; } .left img { - max-width: 250px; + max-height: 260px; } - .right { - padding: 30px 20px; + .title { + font-size: 30px; } - .breadcrumbs{ - font-size: 14px; - } - - .title{ - font-size: 20px; - } - - .short { - margin-top: 20px; - margin-bottom: 25px; - font-size: 10px; - } - - .download { - width: 100%; - padding: 14px; - text-align: center; + .short, + .content p { + font-size: 16px; } .tabs { @@ -195,88 +249,8 @@ } .tabs button { - padding: 14px; - font-size: 14px; - } - - .content { - padding: 20px; - } - - .attrRow { - flex-direction: column; - align-items: flex-start; - gap: 4px; + width: 100%; + border-right: none; + border-bottom: 1px solid #e7ebf0; } } - -@media (max-width: 665){ - .download { - font-size: 14px; - } - - .tabs button { - font-size: 14px; - } - - .short{ - margin-top: 30px; - margin-bottom: 40px; -} - -.back { - color: white; - background: none; - border: none; - cursor: pointer; - font-weight: 600; -} - -.hero { - display: flex; - min-height: 500px; -} - -.left { - flex: 1; - background: #fff; - display: flex; - align-items: center; - justify-content: center; -} - -.left img { - max-width: 400px; -} - -.rightContent{ - padding-right: 100px; - -} - -} - -/* ================= SMALL MOBILE ================= */ - -@media (max-width: 480px) { - .top { - padding-top: 100px; - } - - .left img { - max-width: 200px; - } - - .right { - padding: 20px 15px; - } - - .download { - font-size: 14px; - } - - .tabs button { - font-size: 13px; - } -} - diff --git a/src/pages/ItemPage/ItemPage.tsx b/src/pages/ItemPage/ItemPage.tsx index df631c4..4d67a25 100644 --- a/src/pages/ItemPage/ItemPage.tsx +++ b/src/pages/ItemPage/ItemPage.tsx @@ -1,13 +1,12 @@ 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 { fetchProductById, setSelectedProducts } from "../../features/catalog/productsSlice"; +import { fetchProductById } from "../../features/catalog/productsSlice"; import styles from "./ItemPage.module.css"; -import type { CategoryAtributes, CategoryAtrVals } from "../../types/categories"; import Button from "../../components/Button/Button"; import PriceLisForm from "../../components/PriceLisForm/PriceLisForm"; import ProductAttributes from "../../components/Table/ProducTable"; -import { p, title } from "framer-motion/client"; import Link from "antd/es/typography/Link"; import { setSelectedCategory } from "../../features/catalog/categoriesSlice"; @@ -16,103 +15,108 @@ const ItemPage = () => { const dispatch = useAppDispatch(); const navigate = useNavigate(); const { items, loading } = useAppSelector((state) => state.products); - const { items: cats, selectedCategoryId } = useAppSelector(s => s.categories); + const { items: cats, selectedCategoryId } = useAppSelector((s) => s.categories); const [activeTab, setActiveTab] = useState<"desc" | "chars">("desc"); - const [open, setOpen] = useState(false); useEffect(() => { if (id) dispatch(fetchProductById(id)); - }, [id]); + }, [dispatch, id]); const product = items.find((item) => item.id === Number(id)); - const category = cats.find((cat) => cat.id === Number(selectedCategoryId)) + const category = cats.find((cat) => cat.id === Number(selectedCategoryId)); - if ((loading || !product)) return
Загрузка...
; - if(!category) return
Загрузка...
; + if (loading || !product) { + return
Загрузка...
; + } + + if (!category) { + return
Загрузка...
; + } return ( -
- setOpen(false)}/> +
+ setOpen(false)} /> +
-
+
{product.name}
-
- {navigate('/products'); dispatch(setSelectedCategory(null))}} style={{ textDecoration: 'none', color: 'inherit', fontSize: "16px" }}>КАТЕГОРИИ / navigate('/products')} style={{ textDecoration: 'none', color: 'inherit', fontSize: "16px" }}>{category?.name} / navigate(`/product/${id}`)} style={{ textDecoration: 'none', color: 'inherit', fontSize: "16px" }}>{product.name} + { + navigate("/products"); + dispatch(setSelectedCategory(null)); + }} + > + Категории + + / + navigate("/products")}>{category.name} + / + {product.name}
+ Карточка товара

{product.name}

-

{product.description}

-
-
+
-
- - -
+
+
+ + +
-
- {activeTab === "desc" && ( -
-

ОПИСАНИЕ

-

{product.description}

-

{product.full_name}

- {!product.inStock? - ( -

в наличии

- ) : ( -

нет в наличии

- ) - } -
- )} +
+ {activeTab === "desc" && ( +
+

Описание

+

{product.description}

+

{product.full_name}

+
+ )} - {activeTab === "chars" && ( -
-

ХАРАКТЕРИСТИКИ

- {/*{product.attributes.map((attr) => ( -
- {attr.name} - {attr.vals?.map((val: CategoryAtrVals) => ( -
- {val.val} -
- ))} -
- ))}*/} - -
- )} -
-
+ {activeTab === "chars" && ( +
+

Характеристики

+ +
+ )} +
+ +
); -} +}; -export default ItemPage; \ No newline at end of file +export default ItemPage; diff --git a/src/pages/Main/Main.module.css b/src/pages/Main/Main.module.css index 13a10f6..b8a7f77 100644 --- a/src/pages/Main/Main.module.css +++ b/src/pages/Main/Main.module.css @@ -1,13 +1,19 @@ -.container{ - width: 80%; - margin: 0; - align-items: center; +.main { + display: flex; + justify-content: center; + margin: 0; + background: #ffffff; } -.main{ - margin: 0; - align-items: center; - display: flex; - align-items: center; - justify-content: center; -} \ No newline at end of file +.container { + width: 100%; + max-width: 1200px; + padding: 72px 20px 96px; + box-sizing: border-box; +} + +@media (max-width: 560px) { + .container { + padding: 52px 16px 72px; + } +} diff --git a/src/pages/Main/Main.tsx b/src/pages/Main/Main.tsx index 049fb41..25740a9 100644 --- a/src/pages/Main/Main.tsx +++ b/src/pages/Main/Main.tsx @@ -1,6 +1,4 @@ import React from 'react'; -import { Button, Row, Col } from 'antd'; -import { RocketOutlined, ArrowRightOutlined } from '@ant-design/icons'; import styles from './Main.module.css' import BannerSlider from '../../components/Banner/Banner'; import CategoriesGrid from '../../components/Categories/Categories'; @@ -14,7 +12,7 @@ const Main: React.FC = () =>{
- {} +
@@ -23,4 +21,4 @@ const Main: React.FC = () =>{ ); } -export default Main; \ No newline at end of file +export default Main; diff --git a/src/pages/Products/Products.module.css b/src/pages/Products/Products.module.css index e0b7345..8d01d04 100644 --- a/src/pages/Products/Products.module.css +++ b/src/pages/Products/Products.module.css @@ -1,297 +1,218 @@ -/* ===== ОБЩИЙ ЛЭЙАУТ ===== */ .wrapper { - -} - -.container{ - display: flex; - background: #f3f3f3; + width: 100%; min-height: 100vh; - font-family: Arial, sans-serif; - + padding: 126px 20px 96px; + background: #ffffff; + box-sizing: border-box; + color: #151515; } -/* ===== САЙДБАР ===== */ -.sidebar { - width: 280px; - background: #fff; - padding: 30px 20px; - border-right: 1px solid #e0e0e0; - - display: flex; - flex-direction: column; - padding-top: 70px; +.hero, +.container { + width: 100%; + max-width: 1200px; + margin: 0 auto; } -/* ===== ОСНОВНАЯ ЧАСТЬ ===== */ -.main { - flex: 1; - padding: 30px 40px; - padding-top: 100px; -} - -/* ===== ЛЭЙАУТ КАТАЛОГА ===== */ -.catalogLayout { - display: flex; - gap: 30px; - align-items: flex-start; -} - -/* ===== ФИЛЬТРЫ ===== */ -.filters { - width: 100%; /* 🔥 важно */ - border: 1px solid #e5e5e5; -} - -/* ===== БЛОК ТОВАРОВ ===== */ -.products { - flex: 1; - display: flex; - flex-direction: column; - gap: 25px; -} - -/* ===== GRID ===== */ -.grid { +.hero { display: grid; - grid-template-columns: repeat(3, 1fr); - border-top: 1px solid #ddd; - border-left: 1px solid #ddd; + grid-template-columns: minmax(0, 1fr) minmax(300px, 0.42fr); + gap: 48px; + align-items: end; + margin-bottom: 42px; } -/* ===== КАРТОЧКА ===== */ -.card { - background: #fff; - border-right: 1px solid #ddd; - border-bottom: 1px solid #ddd; - padding: 25px 20px; - text-align: center; - position: relative; - transition: all 0.2s ease; -} - -.card:hover { - box-shadow: 0 8px 20px rgba(0,0,0,0.08); -} - -/* ===== КАРТИНКА ===== */ -.card img { - max-height: 140px; - object-fit: contain; - margin-bottom: 15px; -} - -/* ===== НАЗВАНИЕ ===== */ -.card h3 { +.kicker { + display: inline-block; + margin-bottom: 16px; + color: var(--lightblue); font-size: 14px; - font-weight: 600; - color: #222; - min-height: 40px; -} - -/* ===== ПЛЮС КНОПКА ===== */ -.card::after { - content: "+"; - position: absolute; - right: 15px; - bottom: 15px; - color: #f5c400; - font-size: 22px; - font-weight: bold; -} - -/* ===== ПАГИНАЦИЯ ===== */ -.pagination { - display: flex; - justify-content: center; - align-items: center; - gap: 5px; -} - -.pageBtn { - width: 40px; - height: 40px; - border: 1px solid #ddd; - background: #fff; - cursor: pointer; - font-weight: 600; -} - -.pageBtn:hover { - background: #f5c400; -} - -.activePage { - background: #f5c400; - border-color: #f5c400; -} - -/* ===== ФИЛЬТРЫ СТИЛИ ===== */ -.filters h4 { - font-size: 14px; - margin-bottom: 10px; - margin-top: 20px; -} - -.filters label { - display: flex; - align-items: center; - gap: 8px; - font-size: 13px; - margin-bottom: 8px; - cursor: pointer; -} - -.filters input { - cursor: pointer; -} - -/* ===== КАТЕГОРИИ ===== */ -.sidebar h3 { - font-size: 16px; - margin-bottom: 20px; -} - -.sidebar ul { - list-style: none; - padding: 0; - margin: 0; -} - -.sidebar li { - font-size: 14px; - margin-bottom: 12px; - cursor: pointer; - color: #666; - transition: 0.2s; -} - -.sidebar li:hover { - color: #000; -} - -.activeCategory { font-weight: 700; - color: #000; + letter-spacing: 0.08em; + text-transform: uppercase; } -.mobileFilterBtn { - display: none; - margin-bottom: 15px; - padding: 12px; - background: #000; - color: white; - border: none; - cursor: pointer; +.hero h1 { + max-width: 820px; + margin: 0; + color: #111111; + font-size: clamp(38px, 5vw, 64px); + line-height: 1.06; } -/* overlay */ -.overlay { - position: fixed; - inset: 0; - background: rgba(0, 0, 0, 0.5); - z-index: 50; +.hero p { + max-width: 650px; + margin: 26px 0 0; + color: #3f4652; + font-size: 19px; + line-height: 1.7; } -/* кнопка закрытия */ +.heroCard { + display: grid; + gap: 10px; + padding: 28px; + border: 1px solid #e7ebf0; + border-radius: 8px; + background: linear-gradient(135deg, #f7fbff 0%, #ffffff 58%, #fff7cf 100%); + box-shadow: 0 18px 50px rgba(17, 31, 51, 0.07); +} + +.heroCard svg { + color: #111111; + font-size: 34px; +} + +.heroCard strong { + color: #111111; + font-size: 26px; + line-height: 1.15; +} + +.heroCard span { + color: #596474; + font-size: 15px; + line-height: 1.55; +} + +.container { + display: grid; + grid-template-columns: 280px minmax(0, 1fr); + gap: 28px; + align-items: start; +} + +.sidebar { + position: sticky; + top: 104px; + padding: 24px; + border: 1px solid #e7ebf0; + border-radius: 8px; + background: #f8fafc; +} + +.main { + min-width: 0; + padding: 30px; + border: 1px solid #e7ebf0; + border-radius: 8px; + background: #ffffff; + box-shadow: 0 18px 50px rgba(17, 31, 51, 0.05); +} + +.sectionHead { + margin-bottom: 24px; +} + +.sectionHead span { + display: block; + margin-bottom: 8px; + color: #77808c; + font-size: 13px; + font-weight: 700; + letter-spacing: 0.06em; + text-transform: uppercase; +} + +.sectionHead h2 { + margin: 0; + color: #151515; + font-size: clamp(28px, 4vw, 42px); + line-height: 1.15; +} + +.products { + display: flex; + flex-direction: column; + gap: 26px; +} + +.mobileFilterBtn, .closeBtn { display: none; - background: none; - border: none; - font-size: 20px; - cursor: pointer; - margin-top: 70px; } -/* ================= MOBILE ================= */ +@media (max-width: 980px) { + .wrapper { + padding-top: 104px; + } -@media (max-width: 600px) { - .mobileFilterBtn { - display: block; + .hero, + .container { + grid-template-columns: 1fr; + } + + .hero { + align-items: start; + gap: 28px; } .sidebar { position: fixed; - top: 0; - left: -100%; - width: 80%; - height: 100%; - background: white; - z-index: 100; - padding: 20px; + inset: 0 auto 0 -100%; + z-index: 1200; + width: min(360px, 86vw); overflow-y: auto; - transition: 0.3s; + border-radius: 0; + transition: left 0.28s ease; } .sidebarOpen { left: 0; } + .mobileFilterBtn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 10px; + min-height: 48px; + margin-bottom: 22px; + padding: 0 22px; + border: none; + border-radius: 50px; + background: #ffd400; + color: #111111; + cursor: pointer; + font-size: 15px; + font-weight: 700; + } + .closeBtn { - display: block; + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 42px; + margin-bottom: 18px; + padding: 0 18px; + border: 1px solid #d7dce3; + border-radius: 50px; + background: #ffffff; + color: #111111; + cursor: pointer; + font-weight: 700; } - - } -/* ===== АДАПТИВ ===== */ - - -@media (max-width: 1254px){ - .sidebar { - width: 220px; +@media (max-width: 560px) { + .wrapper { + padding: 92px 16px 72px; } + + .hero h1 { + font-size: 34px; + } + + .hero p { + font-size: 16px; + } + + .heroCard, .main { - padding: 0; - padding-top: 100px; -} -} - -@media (max-width: 1200px) { - .grid { - grid-template-columns: repeat(2, 1fr); - } -} - -@media (max-width: 1045px){ - .sidebar { - width: 200px; - } - -} - -@media (max-width: 827px){ - .container{ - background: white; -} -} - -@media (max-width: 768px) { - - - - - .catalogLayout { - flex-direction: column; + padding: 22px; } - .filters { + .mobileFilterBtn { width: 100%; } - - .grid { - grid-template-columns: 1fr; - } } - -@media (max-width: 600px){ - .products { - width: 100%; -} - -.main{ - justify-content: center; - -} - -} \ No newline at end of file diff --git a/src/pages/Products/Products.tsx b/src/pages/Products/Products.tsx index a04aecb..288bcbe 100644 --- a/src/pages/Products/Products.tsx +++ b/src/pages/Products/Products.tsx @@ -1,4 +1,5 @@ -import React from "react"; +import React, { useState } from "react"; +import { AppstoreOutlined, FilterOutlined } from "@ant-design/icons"; import styles from "./Products.module.css"; import SidebarCategories from "../../features/catalog/SidebarCategories"; import CategoryCards from "../../features/catalog/CategoryCards"; @@ -7,12 +8,10 @@ import ProductGrid from "../../features/catalog/ProductGrid"; import Pagination from "../../features/catalog/Pagination"; import { useAppSelector } from "../../app/hooks"; import SEO from "../../shared/ui/SEO"; -import { useState } from "react"; const ProductsPage: React.FC = () => { const { selectedCategoryId, items } = useAppSelector((s) => s.categories); const category = items.find((c) => c.id === selectedCategoryId); - const [isOpen, setIsOpen] = useState(false); return ( @@ -25,26 +24,48 @@ const ProductsPage: React.FC = () => { : "Каталог продукции: трубы ПВХ, аксессуары и комплектующие" } /> - - -
+
+
+
+ Каталог продукции +

Подберите продукцию для инженерных и строительных задач

+

+ Выберите категорию, уточните параметры и перейдите к карточке + товара, чтобы посмотреть характеристики. +

+
+ +
+ + {items.length || "Все"} категорий + Продукция, комплектующие и позиции для поставок +
+
+
-
+
+ +
+ {selectedCategoryId ? "Выбранная категория" : "Категории"} +

{category?.name || "Вся продукция"}

+
+ {!selectedCategoryId ? ( ) : ( @@ -53,9 +74,9 @@ const ProductsPage: React.FC = () => {
)} -
+
-
+ ); };