Добавлено получение баннеров для главного слайдера с использованием GraphQL. Обновлен компонент HeroSlider для отображения активных баннеров с сортировкой. Реализована логика отображения дефолтного баннера при отсутствии данных. Обновлены стили и структура компонента для улучшения пользовательского интерфейса.

This commit is contained in:
Bivekich
2025-07-15 09:03:32 +03:00
parent 9c152501db
commit 3e98f8fed6
19 changed files with 1109 additions and 342 deletions

View File

@ -1,39 +1,141 @@
import React from "react";
import { useQuery } from '@apollo/client';
import { GET_PARTSINDEX_CATEGORIES } from '@/lib/graphql';
import { useRouter } from 'next/router';
const CategoryNavSection: React.FC = () => (
<section className="catnav">
<div className="w-layout-blockcontainer batd w-container">
<div className="w-layout-hflex flex-block-108-copy">
<div className="ci1">
<div className="text-block-54-copy">Детали для ТО</div>
interface PartsIndexCatalog {
id: string;
name: string;
image?: string;
groups?: PartsIndexGroup[];
}
interface PartsIndexGroup {
id: string;
name: string;
image?: string;
subgroups?: PartsIndexSubgroup[];
entityNames?: { id: string; name: string }[];
}
interface PartsIndexSubgroup {
id: string;
name: string;
image?: string;
entityNames?: { id: string; name: string }[];
}
const CategoryNavSection: React.FC = () => {
const router = useRouter();
const { data, loading, error } = useQuery<{ partsIndexCategoriesWithGroups: PartsIndexCatalog[] }>(
GET_PARTSINDEX_CATEGORIES,
{
variables: {
lang: 'ru'
},
errorPolicy: 'all',
fetchPolicy: 'cache-first'
}
);
// Обработчик клика по категории для перехода в каталог с товарами
const handleCategoryClick = (catalog: PartsIndexCatalog) => {
console.log('🔍 Клик по категории:', { catalogId: catalog.id, categoryName: catalog.name });
// Получаем первую группу для groupId (это правильный ID для partsIndexCategory)
const firstGroup = catalog.groups?.[0];
const groupId = firstGroup?.id;
console.log('🔍 Найденная группа:', { groupId, groupName: firstGroup?.name });
// Переходим на страницу каталога с параметрами PartsIndex
router.push({
pathname: '/catalog',
query: {
partsIndexCatalog: catalog.id,
categoryName: encodeURIComponent(catalog.name),
...(groupId && { partsIndexCategory: groupId })
}
});
};
// Fallback данные на случай ошибки
const fallbackCategories = [
{ id: '1', name: 'Двигатель', image: '/images/catalog_item.png' },
{ id: '2', name: 'Трансмиссия', image: '/images/catalog_item2.png' },
{ id: '3', name: 'Подвеска', image: '/images/catalog_item3.png' },
{ id: '4', name: 'Тормоза', image: '/images/catalog_item4.png' },
{ id: '5', name: 'Электрика', image: '/images/catalog_item5.png' },
{ id: '6', name: 'Кузов', image: '/images/catalog_item6.png' },
{ id: '7', name: 'Салон', image: '/images/catalog_item7.png' },
{ id: '8', name: 'Климат', image: '/images/catalog_item8.png' },
{ id: '9', name: 'Расходники', image: '/images/catalog_item9.png' }
];
// Используем данные из API или fallback
const categories = data?.partsIndexCategoriesWithGroups || [];
const displayCategories = categories.length > 0 ? categories : fallbackCategories;
if (loading) {
return (
<div className="w-layout-blockcontainer container-2 w-container">
<div className="w-layout-hflex flex-block-6">
{Array.from({ length: 9 }).map((_, index) => (
<div key={index} className="w-layout-vflex flex-block-7">
<div className="animate-pulse bg-gray-200 h-6 w-20 rounded mb-2"></div>
</div>
))}
</div>
<div className="ci2">
<div className="text-block-54">Шины</div>
</div>
<div className="ci3">
<div className="text-block-54">Диски</div>
</div>
<div className="ci4">
<div className="text-block-54">Масла и жидкости</div>
</div>
<div className="ci5">
<div className="text-block-54">Инструменты</div>
</div>
<div className="ci6">
<div className="text-block-54">Автохимия</div>
</div>
<div className="ci7">
<div className="text-block-54">Аксессуары</div>
</div>
<div className="ci8">
<div className="text-block-54">Электрика</div>
</div>
<div className="ci9">
<div className="text-block-54">АКБ</div>
<div className="w-layout-hflex flex-block-5">
{Array.from({ length: 9 }).map((_, index) => (
<div key={index} className="w-layout-vflex flex-block-8">
<div className="animate-pulse bg-gray-200 h-32 w-full rounded"></div>
</div>
))}
</div>
</div>
);
}
return (
<div className="w-layout-blockcontainer container-2 w-container">
{/* Навигационная панель с названиями категорий */}
<div className="w-layout-hflex flex-block-6">
{displayCategories.slice(0, 9).map((catalog) => (
<div key={catalog.id} className="w-layout-vflex flex-block-7">
<div
className="text-block-10"
onClick={() => handleCategoryClick(catalog)}
style={{ cursor: 'pointer' }}
>
{catalog.name}
</div>
</div>
))}
</div>
{/* Блок с изображениями категорий */}
<div className="w-layout-hflex flex-block-5">
{displayCategories.slice(0, 9).map((catalog) => (
<div key={catalog.id} className="w-layout-vflex flex-block-8">
<img
src={catalog.image || '/images/catalog_item.png'}
loading="lazy"
alt={catalog.name}
className="image-5"
onClick={() => handleCategoryClick(catalog)}
style={{ cursor: 'pointer' }}
onError={(e) => {
const target = e.target as HTMLImageElement;
target.src = '/images/catalog_item.png';
}}
/>
</div>
))}
</div>
</div>
</section>
);
);
};
export default CategoryNavSection;