import React, { useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import { useQuery } from '@apollo/client'; import Head from 'next/head'; import Footer from '@/components/Footer'; import Layout from '@/components/Layout'; import VehiclePartsSearchSection from '@/components/VehiclePartsSearchSection'; import LaximoDiagnostic from '@/components/LaximoDiagnostic'; import { GET_LAXIMO_VEHICLE_INFO, GET_LAXIMO_CATALOG_INFO, GET_LAXIMO_UNIT_DETAILS } from '@/lib/graphql'; import { LaximoCatalogInfo } from '@/types/laximo'; import InfoVin from '@/components/vin/InfoVin'; import VinLeftbar from '@/components/vin/VinLeftbar'; import VinKnot from '@/components/vin/VinKnot'; import VinCategory from '@/components/vin/VinCategory'; import PartDetailCard from '@/components/PartDetailCard'; import VinPartCard from '@/components/vin/VinPartCard'; import KnotIn from '@/components/vin/KnotIn'; import KnotParts from '@/components/vin/KnotParts'; interface LaximoVehicleInfo { vehicleid: string; name: string; ssd: string; brand: string; catalog: string; attributes: Array<{ key: string; name: string; value: string; }>; } const VehicleDetailsPage = () => { const router = useRouter(); const { brand, vehicleId, oemNumber, searchType: searchTypeParam } = router.query; // Устанавливаем тип поиска из URL или по умолчанию // Важно: согласно документации Laximo, для групп быстрого поиска используется ListQuickGroup // Если в URL передан searchType=categories, мы интерпретируем это как запрос на quickgroups let defaultSearchType: 'quickgroups' | 'categories' | 'fulltext' = 'quickgroups'; if (searchTypeParam === 'categories') { // В URL categories, но мы используем quickgroups для групп быстрого поиска defaultSearchType = 'quickgroups'; console.log('🔄 URL содержит searchType=categories, интерпретируем как quickgroups (группы быстрого поиска)'); } else if (searchTypeParam === 'quickgroups') { defaultSearchType = 'quickgroups'; } else if (searchTypeParam === 'fulltext') { defaultSearchType = 'fulltext'; } // ====== ВСЕ ХУКИ В НАЧАЛЕ КОМПОНЕНТА ====== const [searchType, setSearchType] = useState<'quickgroups' | 'categories' | 'fulltext'>(defaultSearchType); const [showKnot, setShowKnot] = useState(false); const [foundParts, setFoundParts] = useState([]); const [searchState, setSearchState] = useState<{ loading: boolean; error: any; query: string; isSearching: boolean; }>({ loading: false, error: null, query: '', isSearching: false }); const [selectedNode, setSelectedNode] = useState(null); const handleCategoryClick = (e?: React.MouseEvent) => { if (e) e.preventDefault(); setShowKnot(true); }; useEffect(() => { const handler = (e: Event) => { const target = e.target as HTMLElement; if (target.classList.contains('link-2')) { e.preventDefault(); setShowKnot(true); } }; document.addEventListener('click', handler); return () => document.removeEventListener('click', handler); }, []); // ====== КОНЕЦ ХУКОВ ====== // Получаем информацию о каталоге const { data: catalogData } = useQuery<{ laximoCatalogInfo: LaximoCatalogInfo }>( GET_LAXIMO_CATALOG_INFO, { variables: { catalogCode: brand }, skip: !brand } ); // Получаем информацию о выбранном автомобиле const ssdFromQuery = Array.isArray(router.query.ssd) ? router.query.ssd[0] : router.query.ssd; const useStorage = router.query.use_storage === '1'; const ssdLengthFromUrl = router.query.ssd_length ? parseInt(router.query.ssd_length as string) : 0; // Если указано use_storage, пытаемся получить SSD из localStorage let finalSsd = ''; if (useStorage && typeof window !== 'undefined') { const vehicleKey = `vehicle_ssd_${brand}_${vehicleId}`; const storedSsd = localStorage.getItem(vehicleKey); if (storedSsd) { finalSsd = storedSsd; console.log('🔧 SSD получен из localStorage, длина:', storedSsd.length); // НЕ ОЧИЩАЕМ SSD сразу, оставляем на случай перезагрузки страницы // localStorage.removeItem(vehicleKey); } else { console.log('⚠️ SSD не найден в localStorage, ключ:', vehicleKey); console.log('🔍 Все ключи localStorage:', Object.keys(localStorage)); } } else if (ssdFromQuery && ssdFromQuery.trim() !== '') { finalSsd = ssdFromQuery; console.log('🔧 SSD получен из URL'); } console.log('🔍 Vehicle page params:', { brand, vehicleId, useStorage, ssdLengthFromUrl, ssdFromQuery: ssdFromQuery ? `${ssdFromQuery.substring(0, 50)}...` : 'отсутствует', finalSsd: finalSsd ? `${finalSsd.substring(0, 50)}...` : 'отсутствует', ssdLength: finalSsd.length }); const { data: vehicleData, loading: vehicleLoading, error: vehicleError } = useQuery<{ laximoVehicleInfo: LaximoVehicleInfo }>( GET_LAXIMO_VEHICLE_INFO, { variables: { catalogCode: brand, vehicleId: vehicleId, ...(finalSsd && { ssd: finalSsd }), localized: true }, skip: !brand || vehicleId === undefined || vehicleId === null, errorPolicy: 'all' } ); // Получаем детали выбранного узла, если он выбран const { data: unitDetailsData, loading: unitDetailsLoading, error: unitDetailsError } = useQuery( GET_LAXIMO_UNIT_DETAILS, { variables: selectedNode ? { catalogCode: selectedNode.catalogCode || selectedNode.catalog || brand, vehicleId: selectedNode.vehicleId || vehicleId, unitId: selectedNode.unitid || selectedNode.unitId, ssd: selectedNode.ssd || finalSsd || '', } : { catalogCode: '', vehicleId: '', unitId: '', ssd: '' }, skip: !selectedNode, errorPolicy: 'all', } ); const unitDetails = unitDetailsData?.laximoUnitDetails || []; // Логируем ошибки if (vehicleError) { console.error('Vehicle GraphQL error:', vehicleError); } if (vehicleLoading) { return ( <> Загрузка автомобиля...

Загружаем информацию об автомобиле...

); } // Если информация о каталоге недоступна, показываем ошибку if (!catalogData?.laximoCatalogInfo) { return ( <> Каталог не найден

Каталог не найден

Информация о каталоге недоступна

); } // Если vehicleId отсутствует или пустой, показываем предупреждение // Важно: vehicleId может быть '0' для некоторых автомобилей, найденных по VIN if (!vehicleId || vehicleId === '') { return (

Автомобиль не выбран

Для поиска по деталям необходимо выбрать конкретный автомобиль через VIN или мастер подбора.

); } // Гарантируем, что vehicleId — строка const vehicleIdStr = Array.isArray(vehicleId) ? (vehicleId[0] || '') : (vehicleId || ''); // Для Laximo API vehicleId может быть '0' для автомобилей, найденных по VIN const fallbackVehicleId = vehicleIdStr; let vehicleInfo = vehicleData?.laximoVehicleInfo || { vehicleid: fallbackVehicleId, name: `Автомобиль ${catalogData.laximoCatalogInfo.name}`, ssd: finalSsd, brand: catalogData.laximoCatalogInfo.brand, catalog: catalogData.laximoCatalogInfo.code, attributes: [] as never[] }; // Убеждаемся, что vehicleid соответствует параметру из URL if (vehicleInfo.vehicleid !== fallbackVehicleId && fallbackVehicleId) { vehicleInfo = { ...vehicleInfo, vehicleid: fallbackVehicleId }; } // Логируем, что реально передаём в VinLeftbar console.log('Передаём в VinLeftbar:', { catalog: vehicleInfo.catalog, vehicleid: vehicleInfo.vehicleid, ssd: vehicleInfo.ssd }); // Если нет данных автомобиля и есть ошибка, показываем предупреждение const hasError = vehicleError && !vehicleData?.laximoVehicleInfo; const catalogInfo = catalogData.laximoCatalogInfo; return ( <> VIN {/* ====== ВРЕМЕННЫЙ МАКЕТ ДЛЯ ВЕРСТКИ (начало) ====== */} 0 ? vehicleInfo.attributes.map(attr => attr.value).join(' · ') : '' } />
{!selectedNode ? (
{vehicleInfo && vehicleInfo.catalog && vehicleInfo.vehicleid && vehicleInfo.ssd && ( <> { setFoundParts(results); setSearchState({ loading, error, query, isSearching: isSearching || false }); }} onNodeSelect={setSelectedNode} /> {searchState.isSearching ? (
{searchState.loading ? (

Выполняется поиск...

) : searchState.error ? (

Ошибка поиска

{searchState.error.message}

) : foundParts.length > 0 ? ( foundParts.map((detail, idx) => ( )) ) : (

По запросу "{searchState.query}" ничего не найдено

Попробуйте изменить поисковый запрос

)}
) : showKnot ? ( ) : ( )} )}
) : (
{unitDetailsLoading ? (
Загружаем детали узла...
) : unitDetailsError ? (
Ошибка загрузки деталей: {unitDetailsError.message}
) : unitDetails.length > 0 ? ( ) : (
Детали не найдены
)}
)}
{/* ====== ВРЕМЕННЫЙ МАКЕТ ДЛЯ ВЕРСТКИ (конец) ====== */} {/* Навигация */} {/* Информация об автомобиле */}
{catalogInfo.icon && ( {catalogInfo.name} { e.currentTarget.style.display = 'none'; }} /> )}

{vehicleInfo.name}

{catalogInfo.name}

{/* Предупреждение об ошибке */} {hasError && (

Предупреждение

Не удалось загрузить полную информацию об автомобиле. Отображается базовая информация.

)} {/* Отладочная информация */}

🔧 Отладочная информация

Использовать localStorage: {useStorage ? 'Да' : 'Нет'}
Длина SSD из URL: {ssdLengthFromUrl || 'не указана'}
SSD получен: {finalSsd ? 'Да' : 'Нет'}
Длина SSD: {finalSsd.length}
SSD (первые 100 символов): {finalSsd ? finalSsd.substring(0, 100) + '...' : 'отсутствует'}
{/* Характеристики автомобиля */} {vehicleInfo.attributes && vehicleInfo.attributes.length > 0 && (
{vehicleInfo.attributes.map((attr, index) => (
{attr.name}
{attr.value}
))}
)}
{/* Способы поиска запчастей */}

Поиск запчастей

Выберите способ поиска запчастей для вашего автомобиля

{/* Диагностический компонент */}
); }; export default VehicleDetailsPage;