From b8422f5472847a46de7df2ec10ff8d512259bcc6 Mon Sep 17 00:00:00 2001 From: Oleg Urin Date: Fri, 22 May 2026 21:17:36 +0300 Subject: [PATCH] fix --- README.md | 8 +- src/components/Categories/Categories.tsx | 4 +- src/components/Footer/Footer.tsx | 8 +- .../ModalRequestForm/ModalRequestForm.tsx | 25 +- src/components/PriceLisForm/PriceLisForm.tsx | 23 ++ src/features/MainPage/PhoneRequest.tsx | 23 ++ src/pages/About/About.module.css | 327 ++++++++++++++++++ src/pages/About/About.tsx | 156 ++++++++- 8 files changed, 560 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 52b022e..22768c4 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ { "id": 1, "name": "цвет", + "flag": "color", "vals": [ { "id": 1001, "val": "оранжевый" }, { "id": 1002, "val": "серый" }, @@ -24,6 +25,7 @@ { "id": 2, "name": "размер", + "flag": "size", "vals": [ { "id": 2001, "val": "..." }, { "id": 2002, "val": "...." }, @@ -33,6 +35,7 @@ { "id": 2, "name": "кол-во в упаковке", + "flag": "хз какой то флаг", "vals": [ { "id": 2001, "val": "2" }, { "id": 2002, "val": "4" }, @@ -48,6 +51,7 @@ { "id": 1, "name": "цвет", + "flag": "color", "vals": [ { "id": 1001, "val": "оранжевый" }, { "id": 1002, "val": "серый" }, @@ -56,6 +60,7 @@ { "id": 2, "name": "размер", + "flag": "size", "vals": [ { "id": 2001, "val": "..." }, { "id": 2002, "val": "...." }, @@ -65,6 +70,7 @@ { "id": 2, "name": "кол-во в упаковке", + "flag": "хз какой то флаг", "vals": [ { "id": 2001, "val": "2" }, { "id": 2002, "val": "4" }, @@ -158,7 +164,7 @@ GET /api/products/101 ### Получение списка товаров -**Запрос** +**Запрос** ``` GET api/productList/ ``` diff --git a/src/components/Categories/Categories.tsx b/src/components/Categories/Categories.tsx index f39f1c5..f5f06a6 100644 --- a/src/components/Categories/Categories.tsx +++ b/src/components/Categories/Categories.tsx @@ -18,7 +18,7 @@ const categories: CategoryItem[] = [ { id: 1, title: "Труба ПВХ", -subtitle: "для ВНУТРЕННЕЙ канализации", +subtitle: "для НАРУЖНОЙ канализации", image: category_interna2, highlight: true, }, @@ -31,7 +31,7 @@ highlight: true, { id: 2, title: "Труба ПВХ", -subtitle: "для НАРУЖНОЙ канализации", +subtitle: "для ВНУТРЕННЕЙ канализации", highlight: true, image: category_internal1, }, diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx index b8a4790..4c00949 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/components/Footer/Footer.tsx @@ -2,20 +2,23 @@ import React from "react"; import styles from "./Footer.module.css"; import { NavLink } from "react-router-dom"; import blackLogo from "../../assets/images/BlackLogo.jpg"; +import PriceLisForm from "../PriceLisForm/PriceLisForm"; +import { useState } from "react"; const Footer: React.FC = () => { + const [isOpen, setIsOpen] = useState(false); return ( ); }; diff --git a/src/components/ModalRequestForm/ModalRequestForm.tsx b/src/components/ModalRequestForm/ModalRequestForm.tsx index 250ed8e..b63ff58 100644 --- a/src/components/ModalRequestForm/ModalRequestForm.tsx +++ b/src/components/ModalRequestForm/ModalRequestForm.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import { Modal } from "antd"; import { motion } from "framer-motion"; import InputMask from "react-input-mask"; @@ -30,6 +30,8 @@ interface FormData { } const ModalRequestForm: React.FC = ({ open, onClose }) => { + const [isOpen, setIsOpen] = useState(false); + console.log('ModalRequestForm render, open:', open); const { register, @@ -93,6 +95,7 @@ const ModalRequestForm: React.FC = ({ open, onClose }) => { reset(); onClose(); + setIsOpen(true); } catch (error) { // Показываем ошибку Modal.error({ @@ -104,6 +107,25 @@ const ModalRequestForm: React.FC = ({ open, onClose }) => { }; return ( + <> + setIsOpen(false)} + centered + width={500} + > + +

+ Спасибо за обращение! Мы свяжемся с Вами в ближайшее время. Удачного дня! +

+
+
= ({ open, onClose }) => { + ); }; diff --git a/src/components/PriceLisForm/PriceLisForm.tsx b/src/components/PriceLisForm/PriceLisForm.tsx index 869cd94..7ba0d37 100644 --- a/src/components/PriceLisForm/PriceLisForm.tsx +++ b/src/components/PriceLisForm/PriceLisForm.tsx @@ -7,6 +7,7 @@ import { yupResolver } from "@hookform/resolvers/yup"; import styles from "./PriceLisForm.module.css"; import Button from "../Button/Button"; import { client } from "../../api/client"; +import { useState } from "react"; // ✅ Схема валидации const schema = yup.object().shape({ @@ -27,6 +28,7 @@ interface FormData { } const PriceLisForm: React.FC = ({ open, onClose }) => { + const [isOpen, setIsOpen] = useState(false); console.log('ModalRequestForm render, open:', open); const { register, @@ -85,6 +87,7 @@ const PriceLisForm: React.FC = ({ open, onClose }) => { reset(); onClose(); + setIsOpen(true); } catch (error) { Modal.error({ title: "Ошибка", @@ -95,6 +98,25 @@ const PriceLisForm: React.FC = ({ open, onClose }) => { }; return ( + <> + setIsOpen(false)} + centered + width={500} + > + +

+ Спасибо за обращение! Мы свяжемся с Вами в ближайшее время. Удачного дня! +

+
+
= ({ open, onClose }) => { + ); }; diff --git a/src/features/MainPage/PhoneRequest.tsx b/src/features/MainPage/PhoneRequest.tsx index 00d121e..796946f 100644 --- a/src/features/MainPage/PhoneRequest.tsx +++ b/src/features/MainPage/PhoneRequest.tsx @@ -8,6 +8,7 @@ import { yupResolver } from "@hookform/resolvers/yup"; import styles from "../../components/ModalRequestForm/ModalRequestForm.module.css"; import Button from "../../components/Button/Button"; import { client } from "../../api/client"; +import { useState } from "react"; // ✅ Схема валидации const schema = yup.object().shape({ @@ -30,6 +31,7 @@ interface FormData { } const ModalRequestFormQuastion: React.FC = ({ open, onClose }) => { + const [isOpen, setIsOpen] = useState(false); console.log('ModalRequestForm render, open:', open); const { register, @@ -93,6 +95,7 @@ const ModalRequestFormQuastion: React.FC = ({ open, onClose }) => { reset(); onClose(); + setIsOpen(true) } catch (error) { // Показываем ошибку Modal.error({ @@ -104,6 +107,25 @@ const ModalRequestFormQuastion: React.FC = ({ open, onClose }) => { }; return ( + <> + setIsOpen(false)} + centered + width={500} + > + +

+ Спасибо за обращение! Мы свяжемся с Вами в ближайшее время. Удачного дня! +

+
+
= ({ open, onClose }) => { + ); }; diff --git a/src/pages/About/About.module.css b/src/pages/About/About.module.css index e69de29..9052e5f 100644 --- a/src/pages/About/About.module.css +++ b/src/pages/About/About.module.css @@ -0,0 +1,327 @@ +.page { + width: 100%; + background: #fff; + color: #151515; + padding: 126px 20px 96px; + box-sizing: border-box; +} + +.hero, +.facts, +.story, +.principles, +.production { + width: 100%; + max-width: 1200px; + margin: 0 auto; +} + +.hero { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(360px, 0.92fr); + gap: 52px; + align-items: center; +} + +.heroContent { + min-width: 0; +} + +.kicker, +.sectionLabel { + display: inline-block; + color: var(--lightblue); + font-size: 14px; + font-weight: 700; + letter-spacing: 0.08em; + margin-bottom: 16px; + text-transform: uppercase; +} + +.hero h1 { + max-width: 760px; + font-size: clamp(38px, 5vw, 68px); + line-height: 1.05; + margin: 0; + color: #111; +} + +.hero p { + max-width: 650px; + margin: 28px 0 0; + font-size: 19px; + line-height: 1.7; + color: #3f4652; +} + +.heroActions { + display: flex; + flex-wrap: wrap; + gap: 16px; + margin-top: 36px; +} + +.primaryLink, +.secondaryLink { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 52px; + padding: 0 28px; + border-radius: 50px; + font-size: 15px; + font-weight: 700; + text-decoration: none; + transition: 0.25s ease; +} + +.primaryLink { + background: #ffd400; + color: #000; +} + +.primaryLink:hover { + background: #ffe667; + transform: translateY(-2px); +} + +.secondaryLink { + border: 1px solid #d7dce3; + color: #111; + background: #fff; +} + +.secondaryLink:hover { + border-color: var(--lightblue); + color: var(--darkblue); +} + +.heroImageWrap { + position: relative; + overflow: hidden; + min-height: 520px; + border-radius: 8px; + background: #edf1f6; +} + +.heroImage { + width: 100%; + height: 100%; + min-height: 520px; + display: block; + object-fit: cover; +} + +.facts { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 18px; + margin-top: 56px; +} + +.fact { + padding: 28px; + border: 1px solid #e7ebf0; + border-radius: 8px; + background: #f8fafc; +} + +.fact strong { + display: block; + font-size: 28px; + line-height: 1.15; + color: var(--darkblue); + margin-bottom: 8px; +} + +.fact span { + color: #4f5966; + font-size: 16px; + line-height: 1.5; +} + +.story { + display: grid; + grid-template-columns: 0.8fr 1.2fr; + gap: 60px; + margin-top: 92px; + align-items: start; +} + +.story h2, +.production h2 { + margin: 0; + color: #151515; + font-size: clamp(30px, 4vw, 46px); + line-height: 1.16; +} + +.storyText { + display: grid; + gap: 20px; +} + +.storyText p, +.productionText p { + margin: 0; + color: #3f4652; + font-size: 18px; + line-height: 1.75; +} + +.principles { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 22px; + margin-top: 56px; +} + +.principle { + padding: 30px; + border-radius: 8px; + border: 1px solid #e7ebf0; + background: #fff; + box-shadow: 0 18px 50px rgba(17, 31, 51, 0.06); +} + +.principleIcon { + width: 48px; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 8px; + color: var(--darkblue); + background: #eef7ff; + font-size: 24px; + margin-bottom: 24px; +} + +.principle h3 { + margin: 0 0 12px; + color: #151515; + font-size: 22px; +} + +.principle p { + margin: 0; + color: #4f5966; + font-size: 16px; + line-height: 1.65; +} + +.production { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(340px, 0.8fr); + gap: 48px; + align-items: center; + margin-top: 96px; + padding: 46px; + border-radius: 8px; + background: linear-gradient(135deg, #f7fbff 0%, #ffffff 58%, #fff7cf 100%); + border: 1px solid #e7ebf0; +} + +.productionText p { + margin-top: 22px; +} + +.checkList { + display: grid; + gap: 18px; + padding: 0; + margin: 0; + list-style: none; +} + +.checkList li { + display: flex; + gap: 12px; + align-items: flex-start; + color: #202733; + font-size: 17px; + line-height: 1.5; +} + +.checkList svg { + flex: 0 0 auto; + color: var(--lightblue); + font-size: 20px; + margin-top: 3px; +} + +@media (max-width: 980px) { + .page { + padding-top: 104px; + } + + .hero, + .story, + .production { + grid-template-columns: 1fr; + } + + .heroImageWrap, + .heroImage { + min-height: 360px; + } + + .facts, + .principles { + grid-template-columns: 1fr; + } + + .story { + gap: 28px; + margin-top: 72px; + } + + .production { + padding: 34px 26px; + } +} + +@media (max-width: 560px) { + .page { + padding: 92px 16px 72px; + } + + .hero { + gap: 34px; + } + + .hero h1 { + font-size: 34px; + } + + .hero p, + .storyText p, + .productionText p { + font-size: 16px; + } + + .heroActions { + flex-direction: column; + } + + .primaryLink, + .secondaryLink { + width: 100%; + box-sizing: border-box; + } + + .heroImageWrap, + .heroImage { + min-height: 280px; + } + + .fact, + .principle { + padding: 24px; + } + + .production { + margin-top: 72px; + padding: 28px 22px; + } +} diff --git a/src/pages/About/About.tsx b/src/pages/About/About.tsx index 942dcd5..76a7cf8 100644 --- a/src/pages/About/About.tsx +++ b/src/pages/About/About.tsx @@ -1,9 +1,149 @@ -const About = () =>{ - return( - <> -

gggggggg

- - ) -} +import { Link } from "react-router-dom"; +import { + CheckCircleOutlined, + ExperimentOutlined, + SafetyCertificateOutlined, + ToolOutlined, +} from "@ant-design/icons"; +import styles from "./About.module.css"; +import SEO from "../../shared/ui/SEO"; +import productionImage from "../../assets/images/otkrytie-novogo-proizvodstva-v-g.Krymsk.jpeg"; -export default About; \ No newline at end of file +const facts = [ + { value: "Собственное", label: "производство и техническая база" }, + { value: "Контроль", label: "сырья, геометрии и качества изделий" }, + { value: "Партнерство", label: "с монтажными, торговыми и строительными компаниями" }, +]; + +const principles = [ + { + icon: , + title: "Надежность", + text: "Выпускаем продукцию для инженерных систем, где важны стабильные характеристики, аккуратная геометрия и понятная комплектация.", + }, + { + icon: , + title: "Контроль качества", + text: "Следим за производственными этапами, проверяем параметры изделий и бережно относимся к повторяемости каждой партии.", + }, + { + icon: , + title: "Гибкость", + text: "Помогаем подобрать подходящие позиции под объект, объем закупки и требования проекта, включая контрактное производство.", + }, +]; + +const About = () => { + return ( + <> + + +
+
+
+ О компании +

Производим решения для инженерных и строительных задач

+

+ Мы развиваем современное производство ПВХ-продукции и комплектующих + для объектов, где важны надежность поставок, понятное качество и + внимательная работа с заказчиком. +

+
+ + Смотреть продукцию + + + +7 910 121 09 62 + +
+
+ +
+ Производственная площадка компании +
+
+ +
+ {facts.map((fact) => ( +
+ {fact.value} + {fact.label} +
+ ))} +
+ +
+
+ Кто мы +

Компания, которая держит фокус на производстве и результате

+
+
+

+ Наша команда работает с продукцией для водоснабжения, канализации, + монтажа и смежных инженерных направлений. Мы понимаем, что для + клиентов важны не только цена и наличие, но и предсказуемость: + сроки, качество партии, корректная консультация и спокойная + коммуникация на каждом этапе заказа. +

+

+ Поэтому мы выстраиваем процессы вокруг практических задач клиента: + помогаем с подбором номенклатуры, готовим предложения под объем, + поддерживаем партнеров в регулярных закупках и берем в работу + запросы на контрактное производство. +

+
+
+ +
+ {principles.map((item) => ( +
+
{item.icon}
+

{item.title}

+

{item.text}

+
+ ))} +
+ +
+
+ Производство +

От сырья до готовой партии

+

+ Мы уделяем внимание стабильности технологического процесса, + состоянию оборудования и качеству готовых изделий. Такой подход + помогает сохранять повторяемость продукции и уверенно работать как + с разовыми заказами, так и с постоянными поставками. +

+
+
    +
  • + + Подбираем материалы под назначение продукции +
  • +
  • + + Контролируем размеры и внешний вид изделий +
  • +
  • + + Упаковываем продукцию с учетом хранения и доставки +
  • +
  • + + Работаем с оптовыми, проектными и партнерскими заказами +
  • +
+
+
+ + ); +}; + +export default About;