Обновлены компоненты для улучшения обработки групп быстрого поиска и деталей узлов. Внесены изменения в логику отображения подкатегорий в VinCategory и VinLeftbar, добавлены комментарии для ясности. Исправлены условия пропуска запросов и обновлены типы для поддержки SSD узлов.

This commit is contained in:
Bivekich
2025-07-01 22:24:59 +03:00
parent 1613732775
commit 58991e4226
6 changed files with 218 additions and 256 deletions

View File

@ -25,9 +25,17 @@ const QuickGroupItem: React.FC<QuickGroupItemProps> = ({ group, level, onGroupCl
const handleGroupClick = () => { const handleGroupClick = () => {
if (canShowDetails) { if (canShowDetails) {
// Если это конечная группа с поиском деталей - переходим к просмотру деталей
onGroupClick(group); onGroupClick(group);
} else if (hasChildren) { } else if (hasChildren) {
// Если это родительская группа с подгруппами
if (group.children?.some(child => child.link)) {
// Есть подгруппы с активным поиском - показываем пользователю выбор
setIsExpanded(!isExpanded);
} else {
// Все подгруппы неактивны - просто разворачиваем
setIsExpanded(!isExpanded); setIsExpanded(!isExpanded);
}
} }
}; };
@ -69,6 +77,11 @@ const QuickGroupItem: React.FC<QuickGroupItemProps> = ({ group, level, onGroupCl
Доступен поиск Доступен поиск
</span> </span>
)} )}
{hasChildren && !canShowDetails && (
<span className="ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800">
{group.children?.filter(child => child.link).length || 0} подгрупп
</span>
)}
</p> </p>
</div> </div>
</div> </div>
@ -143,8 +156,10 @@ const QuickDetailSection: React.FC<QuickDetailSectionProps> = ({
}; };
const handleUnitClick = (unit: LaximoUnit) => { const handleUnitClick = (unit: LaximoUnit) => {
console.log('🔍 Выбран узел для детального просмотра:', unit.name, 'ID:', unit.unitid); setSelectedUnit({
setSelectedUnit(unit); ...unit,
ssd: unit.ssd || ssd // Сохраняем правильный SSD в selectedUnit
});
}; };
const handleBackFromUnit = () => { const handleBackFromUnit = () => {
@ -198,7 +213,7 @@ const QuickDetailSection: React.FC<QuickDetailSectionProps> = ({
<UnitDetailsSection <UnitDetailsSection
catalogCode={catalogCode} catalogCode={catalogCode}
vehicleId={vehicleId} vehicleId={vehicleId}
ssd={ssd} ssd={selectedUnit.ssd || ssd} // Используем SSD узла
unitId={selectedUnit.unitid} unitId={selectedUnit.unitid}
unitName={selectedUnit.name} unitName={selectedUnit.name}
onBack={handleBackFromUnit} onBack={handleBackFromUnit}

View File

@ -22,19 +22,24 @@ const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd,
setSelectedCategory(null); setSelectedCategory(null);
}, [activeTab]); }, [activeTab]);
// Запрос для "Узлы" // Запрос для "Общие" (QuickGroups)
const { data: categoriesData, loading: categoriesLoading, error: categoriesError } = useQuery(GET_LAXIMO_CATEGORIES, { const { data: quickGroupsData, loading: quickGroupsLoading, error: quickGroupsError } = useQuery(GET_LAXIMO_QUICK_GROUPS, {
variables: { catalogCode: catalogCode || '', vehicleId: vehicleId || '', ssd: ssd || '' }, variables: { catalogCode: catalogCode || '', vehicleId: vehicleId || '', ssd: ssd || '' },
skip: !catalogCode || !vehicleId || activeTab !== 'uzly', skip: !catalogCode || !vehicleId || activeTab !== 'uzly',
errorPolicy: 'all' errorPolicy: 'all'
}); });
// Запрос для получения units (подкатегорий) в режиме "Узлы" // Запрос для "От производителя" (Categories)
const { data: categoriesData, loading: categoriesLoading, error: categoriesError } = useQuery(GET_LAXIMO_CATEGORIES, {
variables: { catalogCode: catalogCode || '', vehicleId: vehicleId || '', ssd: ssd || '' },
skip: !catalogCode || !vehicleId || activeTab !== 'manufacturer',
errorPolicy: 'all'
});
// Запрос для получения units (подкатегорий) в режиме "От производителя"
const [getUnits] = useLazyQuery(GET_LAXIMO_UNITS, { const [getUnits] = useLazyQuery(GET_LAXIMO_UNITS, {
onCompleted: (data) => { onCompleted: (data) => {
console.log('Units loaded:', data);
if (data && data.laximoUnits && lastCategoryIdRef.current) { if (data && data.laximoUnits && lastCategoryIdRef.current) {
console.log('Setting units for category:', lastCategoryIdRef.current, data.laximoUnits);
setUnitsByCategory(prev => ({ setUnitsByCategory(prev => ({
...prev, ...prev,
[lastCategoryIdRef.current!]: data.laximoUnits || [] [lastCategoryIdRef.current!]: data.laximoUnits || []
@ -46,16 +51,9 @@ const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd,
} }
}); });
// Запрос для "От производителя" const categories = activeTab === 'uzly' ? (quickGroupsData?.laximoQuickGroups || []) : (categoriesData?.laximoCategories || []);
const { data: quickGroupsData, loading: quickGroupsLoading, error: quickGroupsError } = useQuery(GET_LAXIMO_QUICK_GROUPS, { const loading = activeTab === 'uzly' ? quickGroupsLoading : categoriesLoading;
variables: { catalogCode: catalogCode || '', vehicleId: vehicleId || '', ssd: ssd || '' }, const error = activeTab === 'uzly' ? quickGroupsError : categoriesError;
skip: !catalogCode || !vehicleId || activeTab !== 'manufacturer',
errorPolicy: 'all'
});
const categories = activeTab === 'uzly' ? (categoriesData?.laximoCategories || []) : (quickGroupsData?.laximoQuickGroups || []);
const loading = activeTab === 'uzly' ? categoriesLoading : quickGroupsLoading;
const error = activeTab === 'uzly' ? categoriesError : quickGroupsError;
const handleBack = () => { const handleBack = () => {
setSelectedCategory(null); setSelectedCategory(null);
@ -68,7 +66,8 @@ const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd,
return; return;
} }
if (activeTab === 'manufacturer') { if (activeTab === 'uzly') {
// Логика для вкладки "Общие" (QuickGroups)
if (category.children && category.children.length > 0) { if (category.children && category.children.length > 0) {
setSelectedCategory(category); setSelectedCategory(category);
} else if (category.link && onQuickGroupSelect) { } else if (category.link && onQuickGroupSelect) {
@ -77,7 +76,7 @@ const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd,
onNodeSelect(category); onNodeSelect(category);
} }
} else { } else {
// Логика для вкладки "Узлы" // Логика для вкладки "От производителя" (Categories)
if (category.children && category.children.length > 0) { if (category.children && category.children.length > 0) {
setSelectedCategory(category); setSelectedCategory(category);
} else { } else {
@ -85,7 +84,6 @@ const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd,
const categoryId = category.categoryid || category.quickgroupid || category.id; const categoryId = category.categoryid || category.quickgroupid || category.id;
if (!unitsByCategory[categoryId] && catalogCode && vehicleId) { if (!unitsByCategory[categoryId] && catalogCode && vehicleId) {
lastCategoryIdRef.current = categoryId; lastCategoryIdRef.current = categoryId;
console.log('Loading units for category:', { categoryId, category });
getUnits({ getUnits({
variables: { variables: {
catalogCode, catalogCode,
@ -101,8 +99,8 @@ const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd,
}; };
const handleSubcategoryClick = (subcat: any) => { const handleSubcategoryClick = (subcat: any) => {
if (activeTab === 'uzly' && onNodeSelect) { if (activeTab === 'manufacturer' && onNodeSelect) {
// Для режима "Узлы" при клике на подкатегорию открываем KnotIn // Для режима "От производителя" при клике на подкатегорию открываем KnotIn
onNodeSelect({ onNodeSelect({
...subcat, ...subcat,
unitid: subcat.unitid || subcat.categoryid || subcat.quickgroupid || subcat.id unitid: subcat.unitid || subcat.categoryid || subcat.quickgroupid || subcat.id
@ -130,11 +128,11 @@ const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd,
// Определяем, какие подкатегории показывать // Определяем, какие подкатегории показывать
let subcategories: any[] = []; let subcategories: any[] = [];
if (selectedCategory) { if (selectedCategory) {
if (activeTab === 'manufacturer') { if (activeTab === 'uzly') {
// Для вкладки "От производителя" используем children // Для вкладки "Общие" используем children
subcategories = selectedCategory.children || []; subcategories = selectedCategory.children || [];
} else { } else {
// Для вкладки "Узлы" используем либо children, либо units // Для вкладки "От производителя" используем либо children, либо units
if (selectedCategory.children && selectedCategory.children.length > 0) { if (selectedCategory.children && selectedCategory.children.length > 0) {
subcategories = selectedCategory.children; subcategories = selectedCategory.children;
} else { } else {

View File

@ -73,7 +73,6 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
console.error('SSD обязателен для поиска по названию'); console.error('SSD обязателен для поиска по названию');
return; return;
} }
console.log('SEARCH PARAMS', { catalogCode, vehicleId, searchQuery: searchQuery.trim(), ssd });
executeSearch({ executeSearch({
variables: { variables: {
catalogCode, catalogCode,
@ -102,7 +101,7 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
query: searchQuery query: searchQuery
}); });
} }
}, [searchResults, loading, error, searchQuery, onSearchResults]); }, [searchResults, loading, error, searchQuery]);
// --- Новый блок: вычисляем доступность поиска --- // --- Новый блок: вычисляем доступность поиска ---
const isSearchAvailable = !!catalogCode && vehicleId !== undefined && vehicleId !== null && !!ssd && ssd.trim() !== ''; const isSearchAvailable = !!catalogCode && vehicleId !== undefined && vehicleId !== null && !!ssd && ssd.trim() !== '';
@ -112,10 +111,9 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
const showTips = isSearchAvailable && !searchQuery.trim() && !loading; const showTips = isSearchAvailable && !searchQuery.trim() && !loading;
// --- QuickGroups (от производителя) --- // --- QuickGroups (от производителя) ---
const [selectedQuickGroup, setSelectedQuickGroup] = useState<any | null>(null);
const { data: quickGroupsData, loading: quickGroupsLoading, error: quickGroupsError } = useQuery(GET_LAXIMO_QUICK_GROUPS, { const { data: quickGroupsData, loading: quickGroupsLoading, error: quickGroupsError } = useQuery(GET_LAXIMO_QUICK_GROUPS, {
variables: { catalogCode, vehicleId, ssd }, variables: { catalogCode, vehicleId, ssd },
skip: !catalogCode || vehicleId === undefined || vehicleId === null || activeTab !== 'manufacturer', skip: !catalogCode || vehicleId === undefined || vehicleId === null,
errorPolicy: 'all' errorPolicy: 'all'
}); });
const quickGroups = quickGroupsData?.laximoQuickGroups || []; const quickGroups = quickGroupsData?.laximoQuickGroups || [];
@ -136,57 +134,15 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
const handleQuickGroupClick = (group: any) => { const handleQuickGroupClick = (group: any) => {
if (group.link) { if (group.link) {
setSelectedQuickGroup(group); // Передаем выбранную группу в родительский компонент для отображения справа
if (onQuickGroupSelect) {
onQuickGroupSelect(group);
}
} else { } else {
handleQuickGroupToggle(group.quickgroupid); handleQuickGroupToggle(group.quickgroupid);
} }
}; };
// Детали выбранной группы (если link: true)
console.log('QuickDetail QUERY VARS', {
catalogCode,
vehicleId,
quickGroupId: selectedQuickGroup?.quickgroupid,
ssd
});
const skipQuickDetail =
!selectedQuickGroup ||
!catalogCode ||
vehicleId === undefined ||
vehicleId === null ||
!selectedQuickGroup?.quickgroupid ||
!ssd ||
ssd.trim() === '';
console.log('QuickDetail QUERY VARS', {
catalogCode,
vehicleId,
quickGroupId: selectedQuickGroup?.quickgroupid,
ssd: ssd ? `${ssd.substring(0, 30)}...` : 'отсутствует'
});
console.log('QuickDetail SKIP CONDITIONS', {
hasSelectedQuickGroup: !!selectedQuickGroup,
hasCatalogCode: !!catalogCode,
hasVehicleId: vehicleId !== undefined && vehicleId !== null,
hasQuickGroupId: !!selectedQuickGroup?.quickgroupid,
hasSsd: !!ssd && ssd.trim() !== '',
skipQuickDetail
});
const { data: quickDetailData, loading: quickDetailLoading, error: quickDetailError } = useQuery(GET_LAXIMO_QUICK_DETAIL, {
variables: selectedQuickGroup?.quickgroupid && !skipQuickDetail ? {
catalogCode,
vehicleId,
quickGroupId: selectedQuickGroup.quickgroupid,
ssd
} : undefined,
skip: skipQuickDetail,
errorPolicy: 'all'
});
const quickDetail = quickDetailData?.laximoQuickDetail;
// === Полнотекстовый поиск деталей (аналогично FulltextSearchSection) === // === Полнотекстовый поиск деталей (аналогично FulltextSearchSection) ===
const [fulltextQuery, setFulltextQuery] = useState(''); const [fulltextQuery, setFulltextQuery] = useState('');
const [executeFulltextSearch, { data: fulltextData, loading: fulltextLoading, error: fulltextError }] = useLazyQuery(GET_LAXIMO_FULLTEXT_SEARCH, { errorPolicy: 'all' }); const [executeFulltextSearch, { data: fulltextData, loading: fulltextLoading, error: fulltextError }] = useLazyQuery(GET_LAXIMO_FULLTEXT_SEARCH, { errorPolicy: 'all' });
@ -243,7 +199,7 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
isSearching: true isSearching: true
}); });
} }
}, [fulltextData, fulltextLoading, fulltextError, onSearchResults]); }, [fulltextData, fulltextLoading, fulltextError, fulltextQuery]);
const handleFulltextKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { const handleFulltextKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
@ -258,7 +214,7 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
if (onActiveTabChange) { if (onActiveTabChange) {
onActiveTabChange(activeTab); onActiveTabChange(activeTab);
} }
}, [activeTab, onActiveTabChange]); }, [activeTab]);
// Если нет данных о транспортном средстве, показываем заглушку // Если нет данных о транспортном средстве, показываем заглушку
if (!vehicleInfo) { if (!vehicleInfo) {
@ -336,9 +292,13 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
e.preventDefault(); e.preventDefault();
if (searchQuery) setSearchQuery(''); if (searchQuery) setSearchQuery('');
setActiveTab('uzly'); setActiveTab('uzly');
// Очищаем выбранную группу при смене таба
if (onQuickGroupSelect) {
onQuickGroupSelect(null);
}
}} }}
> >
Узлы Общие
</a> </a>
<a <a
href="#" href="#"
@ -353,6 +313,10 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
e.preventDefault(); e.preventDefault();
if (searchQuery) setSearchQuery(''); if (searchQuery) setSearchQuery('');
setActiveTab('manufacturer'); setActiveTab('manufacturer');
// Очищаем выбранную группу при смене таба
if (onQuickGroupSelect) {
onQuickGroupSelect(null);
}
}} }}
> >
От производителя От производителя
@ -360,6 +324,112 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
</div> </div>
{/* Tab content start */} {/* Tab content start */}
{activeTab === 'uzly' ? ( {activeTab === 'uzly' ? (
// Общие (QuickGroups - бывшие "От производителя")
quickGroupsLoading ? (
<div style={{ padding: 16, textAlign: 'center' }}>Загружаем группы быстрого поиска...</div>
) : quickGroupsError ? (
<div style={{ color: 'red', padding: 16 }}>Ошибка загрузки групп: {quickGroupsError.message}</div>
) : (
<>
{(quickGroups as QuickGroup[]).map((group: QuickGroup) => {
const hasChildren = group.children && group.children.length > 0;
const isOpen = expandedQuickGroups.has(group.quickgroupid);
if (!hasChildren) {
return (
<a
href="#"
key={group.quickgroupid}
className="dropdown-link-3 w-dropdown-link"
onClick={(e) => {
e.preventDefault();
handleQuickGroupClick(group);
}}
>
{group.name}
</a>
);
}
return (
<div
key={group.quickgroupid}
data-hover="false"
data-delay="0"
className={`dropdown-4 w-dropdown${isOpen ? " w--open" : ""}`}
>
<div
className={`dropdown-toggle-3 w-dropdown-toggle${isOpen ? " w--open" : ""}`}
onClick={() => handleQuickGroupToggle(group.quickgroupid)}
style={{ cursor: "pointer" }}
>
<div className="w-icon-dropdown-toggle"></div>
<div className="text-block-56">{group.name}</div>
</div>
<nav className={`dropdown-list-4 w-dropdown-list${isOpen ? " w--open" : ""}`}>
{group.children?.map((child: QuickGroup) => {
const hasSubChildren = child.children && child.children.length > 0;
const isChildOpen = expandedQuickGroups.has(child.quickgroupid);
if (!hasSubChildren) {
return (
<a
href="#"
key={child.quickgroupid}
className="dropdown-link-3 w-dropdown-link "
onClick={(e) => {
e.preventDefault();
handleQuickGroupClick(child);
}}
>
{child.name}
</a>
);
}
return (
<div
key={child.quickgroupid}
data-hover="false"
data-delay="0"
className={`dropdown-4 w-dropdown pl-0${isChildOpen ? " w--open" : ""}`}
>
<div
className={`dropdown-toggle-card w-dropdown-toggle pl-0${isChildOpen ? " w--open" : ""}`}
onClick={() => handleQuickGroupToggle(child.quickgroupid)}
style={{ cursor: "pointer" }}
>
<div className="w-icon-dropdown-toggle"></div>
<div className="text-block-56">{child.name}</div>
</div>
<nav className={`dropdown-list-4 w-dropdown-list pl-0${isChildOpen ? " w--open" : ""}`}>
{child.children?.map((subChild: QuickGroup) => (
<a
href="#"
key={subChild.quickgroupid}
className="dropdown-link-3 w-dropdown-link "
onClick={(e) => {
e.preventDefault();
handleQuickGroupClick(subChild);
}}
>
{subChild.name}
</a>
))}
</nav>
</div>
);
})}
</nav>
</div>
);
})}
</>
)
) : (
// От производителя (Categories - узлы)
categoriesLoading ? ( categoriesLoading ? (
<div style={{ padding: 16, textAlign: 'center' }}>Загружаем категории...</div> <div style={{ padding: 16, textAlign: 'center' }}>Загружаем категории...</div>
) : categoriesError ? ( ) : categoriesError ? (
@ -415,160 +485,6 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
})} })}
</> </>
) )
) : (
// Manufacturer tab content (QuickGroups)
quickGroupsLoading ? (
<div style={{ padding: 16, textAlign: 'center' }}>Загружаем группы быстрого поиска...</div>
) : quickGroupsError ? (
<div style={{ color: 'red', padding: 16 }}>Ошибка загрузки групп: {quickGroupsError.message}</div>
) : (
<>
{(quickGroups as QuickGroup[]).map((group: QuickGroup) => {
const hasChildren = group.children && group.children.length > 0;
const isOpen = expandedQuickGroups.has(group.quickgroupid);
if (!hasChildren) {
return (
<a
href="#"
key={group.quickgroupid}
className="dropdown-link-3 w-dropdown-link"
onClick={(e) => {
e.preventDefault();
if (group.link && onQuickGroupSelect) {
onQuickGroupSelect(group);
}
}}
>
{group.name}
</a>
);
}
return (
<div
key={group.quickgroupid}
data-hover="false"
data-delay="0"
className={`dropdown-4 w-dropdown${isOpen ? " w--open" : ""}`}
>
<div
className={`dropdown-toggle-3 w-dropdown-toggle${isOpen ? " w--open" : ""}`}
onClick={() => handleQuickGroupToggle(group.quickgroupid)}
style={{ cursor: "pointer" }}
>
<div className="w-icon-dropdown-toggle"></div>
<div className="text-block-56">{group.name}</div>
</div>
<nav className={`dropdown-list-4 w-dropdown-list${isOpen ? " w--open" : ""}`}>
{group.children?.map((child: QuickGroup) => {
const hasSubChildren = child.children && child.children.length > 0;
const isChildOpen = expandedQuickGroups.has(child.quickgroupid);
if (!hasSubChildren) {
return (
<a
href="#"
key={child.quickgroupid}
className="dropdown-link-3 w-dropdown-link "
onClick={(e) => {
e.preventDefault();
if (child.link && onQuickGroupSelect) {
onQuickGroupSelect(child);
}
}}
>
{child.name}
</a>
);
}
return (
<div
key={child.quickgroupid}
data-hover="false"
data-delay="0"
className={`dropdown-4 w-dropdown pl-0${isChildOpen ? " w--open" : ""}`}
>
<div
className={`dropdown-toggle-card w-dropdown-toggle pl-0${isChildOpen ? " w--open" : ""}`}
onClick={() => handleQuickGroupToggle(child.quickgroupid)}
style={{ cursor: "pointer" }}
>
<div className="w-icon-dropdown-toggle"></div>
<div className="text-block-56">{child.name}</div>
</div>
<nav className={`dropdown-list-4 w-dropdown-list pl-0${isChildOpen ? " w--open" : ""}`}>
{child.children?.map((subChild: QuickGroup) => (
<a
href="#"
key={subChild.quickgroupid}
className="dropdown-link-3 w-dropdown-link "
onClick={(e) => {
e.preventDefault();
if (subChild.link && onQuickGroupSelect) {
onQuickGroupSelect(subChild);
}
}}
>
{subChild.name}
</a>
))}
</nav>
</div>
);
})}
</nav>
</div>
);
})}
{/* Quick Detail Modal */}
{selectedQuickGroup && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50">
<div className="bg-white rounded-lg max-w-2xl w-full max-h-[90vh] overflow-y-auto p-6">
<div className="flex justify-between items-center mb-4">
<h3 className="text-lg font-semibold">{selectedQuickGroup.name}</h3>
<button
onClick={() => setSelectedQuickGroup(null)}
className="text-gray-500 hover:text-gray-700"
>
</button>
</div>
{quickDetailLoading ? (
<div className="text-center py-4">Загружаем детали...</div>
) : quickDetailError ? (
<div className="text-red-600 py-4">Ошибка загрузки деталей: {quickDetailError.message}</div>
) : quickDetail?.units?.length > 0 ? (
<div className="space-y-4">
{quickDetail.units.map((unit: any) => (
<div key={unit.unitid} className="border border-gray-200 rounded-lg p-4">
<div className="font-medium text-gray-900 mb-2">{unit.name}</div>
{unit.details && unit.details.length > 0 && (
<div className="space-y-2">
{unit.details.map((detail: any) => (
<div key={detail.detailid} className="flex items-center justify-between bg-gray-50 p-2 rounded">
<span className="font-medium text-gray-700">{detail.name}</span>
<span className="text-sm bg-blue-100 text-blue-800 px-2 py-1 rounded">
OEM: {detail.oem}
</span>
</div>
))}
</div>
)}
</div>
))}
</div>
) : (
<div className="text-center text-gray-500 py-4">Нет деталей для этой группы</div>
)}
</div>
</div>
)}
</>
)
)} )}
{/* Tab content end */} {/* Tab content end */}
</div> </div>

View File

@ -24,6 +24,8 @@ const VinQuick: React.FC<VinQuickProps> = ({ quickGroup, catalogCode, vehicleId,
}); });
const quickDetail = data?.laximoQuickDetail; const quickDetail = data?.laximoQuickDetail;
const [isBrandModalOpen, setIsBrandModalOpen] = useState(false); const [isBrandModalOpen, setIsBrandModalOpen] = useState(false);
const [selectedDetail, setSelectedDetail] = useState<any>(null); const [selectedDetail, setSelectedDetail] = useState<any>(null);
@ -34,7 +36,7 @@ const VinQuick: React.FC<VinQuickProps> = ({ quickGroup, catalogCode, vehicleId,
name: unit.name, name: unit.name,
catalogCode, catalogCode,
vehicleId, vehicleId,
ssd ssd: unit.ssd || ssd // Используем SSD узла, а не родительский
}); });
}; };
const handleDetailClick = (detail: any) => { const handleDetailClick = (detail: any) => {

View File

@ -46,7 +46,7 @@ const VehicleDetailsPage = () => {
if (searchTypeParam === 'categories') { if (searchTypeParam === 'categories') {
// В URL categories, но мы используем quickgroups для групп быстрого поиска // В URL categories, но мы используем quickgroups для групп быстрого поиска
defaultSearchType = 'quickgroups'; defaultSearchType = 'quickgroups';
console.log('🔄 URL содержит searchType=categories, интерпретируем как quickgroups (группы быстрого поиска)');
} else if (searchTypeParam === 'quickgroups') { } else if (searchTypeParam === 'quickgroups') {
defaultSearchType = 'quickgroups'; defaultSearchType = 'quickgroups';
} else if (searchTypeParam === 'fulltext') { } else if (searchTypeParam === 'fulltext') {
@ -109,27 +109,14 @@ const VehicleDetailsPage = () => {
const storedSsd = localStorage.getItem(vehicleKey); const storedSsd = localStorage.getItem(vehicleKey);
if (storedSsd) { if (storedSsd) {
finalSsd = storedSsd; finalSsd = storedSsd;
console.log('🔧 SSD получен из localStorage, длина:', storedSsd.length);
// НЕ ОЧИЩАЕМ SSD сразу, оставляем на случай перезагрузки страницы // НЕ ОЧИЩАЕМ SSD сразу, оставляем на случай перезагрузки страницы
// localStorage.removeItem(vehicleKey); // localStorage.removeItem(vehicleKey);
} else {
console.log('⚠️ SSD не найден в localStorage, ключ:', vehicleKey);
console.log('🔍 Все ключи localStorage:', Object.keys(localStorage));
} }
} else if (ssdFromQuery && ssdFromQuery.trim() !== '') { } else if (ssdFromQuery && ssdFromQuery.trim() !== '') {
finalSsd = ssdFromQuery; 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 }>( const { data: vehicleData, loading: vehicleLoading, error: vehicleError } = useQuery<{ laximoVehicleInfo: LaximoVehicleInfo }>(
GET_LAXIMO_VEHICLE_INFO, GET_LAXIMO_VEHICLE_INFO,
@ -141,9 +128,56 @@ const VehicleDetailsPage = () => {
localized: true localized: true
}, },
skip: !brand || vehicleId === undefined || vehicleId === null, skip: !brand || vehicleId === undefined || vehicleId === null,
errorPolicy: 'all' errorPolicy: 'all',
onCompleted: (data) => {
console.log('🔍 VehicleInfo GraphQL completed:', {
requestedVehicleId: vehicleId,
returnedVehicleId: data?.laximoVehicleInfo?.vehicleid,
vehicleName: data?.laximoVehicleInfo?.name,
ssdUsed: finalSsd?.substring(0, 50) + '...',
fullData: data
});
if (data?.laximoVehicleInfo?.vehicleid !== vehicleId) {
console.log('🚨 ОБНАРУЖЕНО НЕСООТВЕТСТВИЕ VEHICLE ID!');
console.log(`📍 URL vehicleId: ${vehicleId}`);
console.log(`📍 API vehicleId: ${data?.laximoVehicleInfo?.vehicleid}`);
} else {
console.log('✅ Vehicle ID соответствует URL');
}
},
onError: (error) => {
console.error('❌ VehicleInfo GraphQL error:', error);
}
} }
); );
// Автоматическое перенаправление на правильный vehicleId если API вернул другой ID
useEffect(() => {
if (vehicleData?.laximoVehicleInfo && vehicleData.laximoVehicleInfo.vehicleid !== vehicleId) {
const correctVehicleId = vehicleData.laximoVehicleInfo.vehicleid;
console.log(`🔄 Автоматическое перенаправление: ${vehicleId} -> ${correctVehicleId}`);
// Обновляем localStorage с правильным ключом
if (finalSsd && typeof window !== 'undefined') {
const oldKey = `vehicle_ssd_${brand}_${vehicleId}`;
const newKey = `vehicle_ssd_${brand}_${correctVehicleId}`;
// Перемещаем SSD на правильный ключ
localStorage.setItem(newKey, finalSsd);
localStorage.removeItem(oldKey);
console.log(`💾 SSD перемещен: ${oldKey} -> ${newKey}`);
}
// Строим новый URL с правильным vehicleId
const currentParams = new URLSearchParams(window.location.search);
const newUrl = `/vehicle-search/${brand}/${correctVehicleId}?${currentParams.toString()}`;
// Перенаправляем на правильный URL
router.replace(newUrl);
return;
}
}, [vehicleData, vehicleId, brand, finalSsd, router]);
// Получаем детали выбранного узла, если он выбран // Получаем детали выбранного узла, если он выбран
const { const {
@ -249,12 +283,7 @@ const VehicleDetailsPage = () => {
vehicleInfo = { ...vehicleInfo, vehicleid: fallbackVehicleId }; vehicleInfo = { ...vehicleInfo, vehicleid: fallbackVehicleId };
} }
// Логируем, что реально передаём в VinLeftbar
console.log('Передаём в VinLeftbar:', {
catalog: vehicleInfo.catalog,
vehicleid: vehicleInfo.vehicleid,
ssd: vehicleInfo.ssd
});
// Если нет данных автомобиля и есть ошибка, показываем предупреждение // Если нет данных автомобиля и есть ошибка, показываем предупреждение
const hasError = vehicleError && !vehicleData?.laximoVehicleInfo; const hasError = vehicleError && !vehicleData?.laximoVehicleInfo;

View File

@ -154,6 +154,7 @@ export interface LaximoUnit {
description?: string description?: string
imageurl?: string imageurl?: string
largeimageurl?: string largeimageurl?: string
ssd?: string // 🎯 ДОБАВЛЕНИЕ: SSD для узла
details?: LaximoDetail[] details?: LaximoDetail[]
attributes?: LaximoDetailAttribute[] attributes?: LaximoDetailAttribute[]
} }
@ -279,6 +280,7 @@ export interface LaximoUnitInfo {
description?: string description?: string
imageurl?: string imageurl?: string
largeimageurl?: string largeimageurl?: string
ssd?: string // 🎯 ДОБАВЛЕНИЕ: SSD для узла
attributes?: LaximoDetailAttribute[] attributes?: LaximoDetailAttribute[]
} }