From b318fbd779adfdf66f6d83df18e606d0d3fe4e04 Mon Sep 17 00:00:00 2001 From: egortriston Date: Tue, 8 Jul 2025 00:12:31 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BA=D0=B0=D1=80=D1=82=D0=BE=D1=87=D0=BA=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ArticleCard.tsx | 40 +++++++++-- src/components/BestPriceItem.tsx | 64 ++++++++++++++++++ src/components/index/BestPriceSection.tsx | 47 ++++++------- src/components/index/NewArrivalsSection.tsx | 74 +++++++++++---------- src/components/index/TopSalesSection.tsx | 62 +++++++++-------- src/styles/my.css | 14 ++++ 6 files changed, 211 insertions(+), 90 deletions(-) create mode 100644 src/components/BestPriceItem.tsx diff --git a/src/components/ArticleCard.tsx b/src/components/ArticleCard.tsx index 7b10b13..3bd263c 100644 --- a/src/components/ArticleCard.tsx +++ b/src/components/ArticleCard.tsx @@ -10,9 +10,10 @@ interface ArticleCardProps { article: PartsAPIArticle; index: number; onVisibilityChange?: (index: number, isVisible: boolean) => void; + image?: string; // optional image override } -const ArticleCard: React.FC = memo(({ article, index, onVisibilityChange }) => { +const ArticleCard: React.FC = memo(({ article, index, onVisibilityChange, image }) => { const [shouldShow, setShouldShow] = useState(false); const [isChecking, setIsChecking] = useState(true); @@ -21,6 +22,12 @@ const ArticleCard: React.FC = memo(({ article, index, onVisibi enabled: !!article.artId }); + // MOCK: fallback image if none loaded + const fallbackImage = + image || // use prop if provided + imageUrl || + '/images/162615.webp'; // путь к картинке из public или любой другой + // Проверяем и очищаем данные артикула и бренда const articleNumber = article.artArticleNr?.trim(); const brandName = article.artSupBrand?.trim(); @@ -28,7 +35,10 @@ const ArticleCard: React.FC = memo(({ article, index, onVisibi // Используем хук для получения цен только если есть и артикул, и бренд const { getPriceData, addToCart } = useCatalogPrices(); const shouldFetchPrices = articleNumber && brandName && articleNumber !== '' && brandName !== ''; - const priceData = shouldFetchPrices ? getPriceData(articleNumber, brandName) : { minPrice: null, cheapestOffer: null, isLoading: false, hasOffers: false }; + // MOCK: fallback price data + const priceData = shouldFetchPrices + ? getPriceData(articleNumber, brandName) + : { minPrice: 17087, cheapestOffer: null, isLoading: false, hasOffers: true }; // Определяем, должен ли отображаться товар useEffect(() => { @@ -66,9 +76,29 @@ const ArticleCard: React.FC = memo(({ article, index, onVisibi return ; } - // Не отображаем ничего если товар не должен показываться + // MOCK: всегда показывать карточку для демо if (!shouldShow) { - return null; + // return null; + // MOCK: показываем карточку даже если не должен + // (можно убрать это после подключения реальных данных) + // Формируем название товара + const title = [brandName || 'N/A', articleNumber || 'N/A'].filter(part => part !== 'N/A').join(', '); + const brand = brandName || 'Unknown'; + let priceText = 'от 17 087 ₽'; + return ( + {}} + /> + ); } // Формируем название товара @@ -104,7 +134,7 @@ const ArticleCard: React.FC = memo(({ article, index, onVisibi return ( void; +} + +const BestPriceItem: React.FC = ({ + image, + discount, + price, + oldPrice, + title, + brand, + onAddToCart, +}) => { + return ( +
+
+
+ + + +
+
+
+ {title} +
{discount}
+
+
+
+
{price}
+
{oldPrice}
+
+
+
{title}
+ +
+
+ + + +
+
+
+
+
+
+ ); +}; + +export default BestPriceItem; \ No newline at end of file diff --git a/src/components/index/BestPriceSection.tsx b/src/components/index/BestPriceSection.tsx index 7fa6bd1..c96245b 100644 --- a/src/components/index/BestPriceSection.tsx +++ b/src/components/index/BestPriceSection.tsx @@ -1,4 +1,26 @@ import React from "react"; +import BestPriceItem from "../BestPriceItem"; + +// Моковые данные для лучших цен +const bestPriceItems = [ + { + image: "images/162615.webp", + discount: "-35%", + price: "от 17 087 ₽", + oldPrice: "22 347 ₽", + title: 'Аккумуляторная батарея TYUMEN BATTERY "STANDARD", 6CT-60L, 60', + brand: "TYUMEN BATTERY", + }, + // ...добавьте еще 7 карточек для примера + ...Array(7).fill(0).map((_, i) => ({ + image: "images/162615.webp", + discount: "-35%", + price: `от ${(17087 + i * 1000).toLocaleString('ru-RU')} ₽`, + oldPrice: `${(22347 + i * 1000).toLocaleString('ru-RU')} ₽`, + title: `Товар №${i + 2}`, + brand: `Бренд ${i + 2}`, + })) +]; const BestPriceSection: React.FC = () => (
@@ -10,29 +32,8 @@ const BestPriceSection: React.FC = () => ( Показать все
- {[...Array(8)].map((_, i) => ( -
-
-
-
-
-
-35%
-
-
-
-
от 17 087 ₽
-
22 347 ₽
-
-
-
Аккумуляторная батарея TYUMEN BATTERY "STANDARD", 6CT-60L, 60
- -
-
-
-
-
-
-
+ {bestPriceItems.map((item, i) => ( + ))}
diff --git a/src/components/index/NewArrivalsSection.tsx b/src/components/index/NewArrivalsSection.tsx index 2fbc904..ec74c45 100644 --- a/src/components/index/NewArrivalsSection.tsx +++ b/src/components/index/NewArrivalsSection.tsx @@ -1,4 +1,40 @@ import React from "react"; +import ArticleCard from "../ArticleCard"; +import { PartsAPIArticle } from "@/types/partsapi"; + +// Моковые данные для новых поступлений +const newArrivalsArticles: PartsAPIArticle[] = [ + { + artId: "1", + artArticleNr: "6CT-60L", + artSupBrand: "TYUMEN BATTERY", + supBrand: "TYUMEN BATTERY", + supId: 1, + productGroup: "Аккумуляторная батарея", + ptId: 1, + }, + { + artId: "2", + artArticleNr: "A0001", + artSupBrand: "Borsehung", + supBrand: "Borsehung", + supId: 2, + productGroup: "Масляный фильтр", + ptId: 2, + }, + // ...добавьте еще 6 статей для примера + ...Array(6).fill(0).map((_, i) => ({ + artId: `${i+3}`, + artArticleNr: `ART${i+3}`, + artSupBrand: `Brand${i+3}`, + supBrand: `Brand${i+3}`, + supId: i+3, + productGroup: `Product Group ${i+3}`, + ptId: i+3, + })) +]; + +const imagePath = "images/162615.webp"; const NewArrivalsSection: React.FC = () => (
@@ -8,42 +44,8 @@ const NewArrivalsSection: React.FC = () => (

Новое поступление

- {[...Array(8)].map((_, i) => ( -
-
-
-
-
- Новое поступление: Аккумуляторная батарея TYUMEN BATTERY -
-35%
-
-
-
-
от 17 087 ₽
-
22 347 ₽
-
-
-
-
Аккумуляторная батарея TYUMEN BATTERY "STANDARD", 6CT-60L, 60
-
Borsehung
-
- -
-
-
-
-
-
-
+ {newArrivalsArticles.map((article, i) => ( + ))}
diff --git a/src/components/index/TopSalesSection.tsx b/src/components/index/TopSalesSection.tsx index f622498..40ffc65 100644 --- a/src/components/index/TopSalesSection.tsx +++ b/src/components/index/TopSalesSection.tsx @@ -1,4 +1,38 @@ import React from "react"; +import ArticleCard from "../ArticleCard"; +import { PartsAPIArticle } from "@/types/partsapi"; + +// Моковые данные для топ продаж +const topSalesArticles: PartsAPIArticle[] = [ + { + artId: "1", + artArticleNr: "6CT-60L", + artSupBrand: "TYUMEN BATTERY", + supBrand: "TYUMEN BATTERY", + supId: 1, + productGroup: "Аккумуляторная батарея", + ptId: 1, + }, + { + artId: "2", + artArticleNr: "A0001", + artSupBrand: "Borsehung", + supBrand: "Borsehung", + supId: 2, + productGroup: "Масляный фильтр", + ptId: 2, + }, + // ...добавьте еще 6 статей для примера + ...Array(6).fill(0).map((_, i) => ({ + artId: `${i+3}`, + artArticleNr: `ART${i+3}`, + artSupBrand: `Brand${i+3}`, + supBrand: `Brand${i+3}`, + supId: i+3, + productGroup: `Product Group ${i+3}`, + ptId: i+3, + })) +]; const TopSalesSection: React.FC = () => (
@@ -8,32 +42,8 @@ const TopSalesSection: React.FC = () => (

Топ продаж

- {[...Array(8)].map((_, i) => ( -
-
-
-
-
-
-35%
-
-
-
-
от 17 087 ₽
-
22 347 ₽
-
-
-
-
Аккумуляторная батарея TYUMEN BATTERY "STANDARD", 6CT-60L, 60
-
Borsehung
-
- -
-
-
-
-
-
-
+ {topSalesArticles.map((article, i) => ( + ))}
diff --git a/src/styles/my.css b/src/styles/my.css index c4bdba4..1b4a9a0 100644 --- a/src/styles/my.css +++ b/src/styles/my.css @@ -788,7 +788,14 @@ body { .flex-block-15-copy { width: 235px!important; min-width: 235px!important; +} +.nameitembp { + flex: 0 auto; + align-self: auto; + height: 60px; + width: 130px; + overflow: hidden; } @media screen and (max-width: 991px) { .flex-block-15-copy { @@ -811,6 +818,13 @@ body { min-width: 160px !important; padding: 15px; } + .nameitembp { + height: 36px; + width: 95px; + font-size: 12px; + line-height: 18px; + overflow: hidden; + } }