Merge pull request 'ура епте' (#10) from end into main
Reviewed-on: #10
This commit is contained in:
@ -1,83 +1,138 @@
|
|||||||
import React, { useState, useRef } from "react";
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { useQuery, useLazyQuery } from "@apollo/client";
|
import { useQuery, useLazyQuery } from '@apollo/client';
|
||||||
import { GET_LAXIMO_CATEGORIES, GET_LAXIMO_UNITS } from "@/lib/graphql/laximo";
|
import { GET_LAXIMO_CATEGORIES, GET_LAXIMO_QUICK_GROUPS, GET_LAXIMO_UNITS } from '@/lib/graphql/laximo';
|
||||||
|
|
||||||
interface VinCategoryProps {
|
interface VinCategoryProps {
|
||||||
catalogCode: string;
|
catalogCode: string;
|
||||||
vehicleId: string;
|
vehicleId: string;
|
||||||
ssd?: string;
|
ssd: string;
|
||||||
onNodeSelect?: (node: any) => void;
|
onNodeSelect?: (node: any) => void;
|
||||||
|
activeTab: 'uzly' | 'manufacturer';
|
||||||
|
onQuickGroupSelect?: (group: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd, onNodeSelect }) => {
|
const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd, onNodeSelect, activeTab, onQuickGroupSelect }) => {
|
||||||
const { data: categoriesData, loading: categoriesLoading, error: categoriesError } = useQuery(GET_LAXIMO_CATEGORIES, {
|
const [selectedCategory, setSelectedCategory] = useState<any>(null);
|
||||||
variables: { catalogCode, vehicleId, ssd },
|
|
||||||
skip: !catalogCode || vehicleId === undefined || vehicleId === null,
|
|
||||||
errorPolicy: "all",
|
|
||||||
});
|
|
||||||
const categories = categoriesData?.laximoCategories || [];
|
|
||||||
|
|
||||||
const [unitsByCategory, setUnitsByCategory] = useState<{ [key: string]: any[] }>({});
|
const [unitsByCategory, setUnitsByCategory] = useState<{ [key: string]: any[] }>({});
|
||||||
const [getUnits] = useLazyQuery(GET_LAXIMO_UNITS, {
|
|
||||||
onCompleted: (data) => {
|
|
||||||
if (data && data.laximoUnits && lastCategoryIdRef.current) {
|
|
||||||
setUnitsByCategory((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[lastCategoryIdRef.current!]: data.laximoUnits || [],
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const [selectedCategory, setSelectedCategory] = useState<any | null>(null);
|
|
||||||
const lastCategoryIdRef = useRef<string | null>(null);
|
const lastCategoryIdRef = useRef<string | null>(null);
|
||||||
|
|
||||||
// Если выбрана категория — показываем подкатегории (children или units)
|
// Сброс выбранной категории при смене вкладки
|
||||||
let subcategories: any[] = [];
|
useEffect(() => {
|
||||||
if (selectedCategory) {
|
setSelectedCategory(null);
|
||||||
if (selectedCategory.children && selectedCategory.children.length > 0) {
|
}, [activeTab]);
|
||||||
subcategories = selectedCategory.children;
|
|
||||||
} else {
|
|
||||||
subcategories = unitsByCategory[selectedCategory.quickgroupid] || [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleCategoryClick = (cat: any) => {
|
// Запрос для "Узлы"
|
||||||
if (cat.children && cat.children.length > 0) {
|
const { data: categoriesData, loading: categoriesLoading, error: categoriesError } = useQuery(GET_LAXIMO_CATEGORIES, {
|
||||||
setSelectedCategory(cat);
|
variables: { catalogCode, vehicleId, ssd },
|
||||||
} else {
|
skip: !catalogCode || vehicleId === undefined || vehicleId === null || activeTab !== 'uzly',
|
||||||
// Если нет children, грузим units (подкатегории)
|
errorPolicy: 'all'
|
||||||
if (!unitsByCategory[cat.quickgroupid]) {
|
});
|
||||||
lastCategoryIdRef.current = cat.quickgroupid;
|
|
||||||
getUnits({ variables: { catalogCode, vehicleId, ssd, categoryId: cat.quickgroupid } });
|
// Запрос для получения units (подкатегорий) в режиме "Узлы"
|
||||||
|
const [getUnits] = useLazyQuery(GET_LAXIMO_UNITS, {
|
||||||
|
onCompleted: (data) => {
|
||||||
|
console.log('Units loaded:', data);
|
||||||
|
if (data && data.laximoUnits && lastCategoryIdRef.current) {
|
||||||
|
console.log('Setting units for category:', lastCategoryIdRef.current, data.laximoUnits);
|
||||||
|
setUnitsByCategory(prev => ({
|
||||||
|
...prev,
|
||||||
|
[lastCategoryIdRef.current!]: data.laximoUnits || []
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
setSelectedCategory(cat);
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.error('Error loading units:', error);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
|
// Запрос для "От производителя"
|
||||||
|
const { data: quickGroupsData, loading: quickGroupsLoading, error: quickGroupsError } = useQuery(GET_LAXIMO_QUICK_GROUPS, {
|
||||||
|
variables: { catalogCode, vehicleId, ssd },
|
||||||
|
skip: !catalogCode || vehicleId === undefined || vehicleId === null || 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubcategoryClick = (subcat: any) => {
|
const handleCategoryClick = (category: any) => {
|
||||||
if (onNodeSelect) {
|
if (activeTab === 'manufacturer') {
|
||||||
onNodeSelect({
|
if (category.children && category.children.length > 0) {
|
||||||
...subcat,
|
setSelectedCategory(category);
|
||||||
unitid: subcat.unitid || subcat.quickgroupid || subcat.id,
|
} else if (category.link && onQuickGroupSelect) {
|
||||||
});
|
onQuickGroupSelect(category);
|
||||||
|
} else if (onNodeSelect) {
|
||||||
|
onNodeSelect(category);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Логика для вкладки "Узлы"
|
||||||
|
if (category.children && category.children.length > 0) {
|
||||||
|
setSelectedCategory(category);
|
||||||
|
} else {
|
||||||
|
// Если нет children, грузим units (подкатегории)
|
||||||
|
const categoryId = category.categoryid || category.quickgroupid || category.id;
|
||||||
|
if (!unitsByCategory[categoryId]) {
|
||||||
|
lastCategoryIdRef.current = categoryId;
|
||||||
|
console.log('Loading units for category:', { categoryId, category });
|
||||||
|
getUnits({
|
||||||
|
variables: {
|
||||||
|
catalogCode,
|
||||||
|
vehicleId,
|
||||||
|
ssd,
|
||||||
|
categoryId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setSelectedCategory(category);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (categoriesLoading) return <div>Загрузка категорий...</div>;
|
const handleSubcategoryClick = (subcat: any) => {
|
||||||
if (categoriesError) return <div style={{ color: "red" }}>Ошибка: {categoriesError.message}</div>;
|
if (activeTab === 'uzly' && onNodeSelect) {
|
||||||
|
// Для режима "Узлы" при клике на подкатегорию открываем KnotIn
|
||||||
|
onNodeSelect({
|
||||||
|
...subcat,
|
||||||
|
unitid: subcat.unitid || subcat.categoryid || subcat.quickgroupid || subcat.id
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
handleCategoryClick(subcat);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (loading) return <div>Загрузка категорий...</div>;
|
||||||
|
if (error) return <div style={{ color: "red" }}>Ошибка: {error.message}</div>;
|
||||||
|
|
||||||
|
// Определяем, какие подкатегории показывать
|
||||||
|
let subcategories: any[] = [];
|
||||||
|
if (selectedCategory) {
|
||||||
|
if (activeTab === 'manufacturer') {
|
||||||
|
// Для вкладки "От производителя" используем children
|
||||||
|
subcategories = selectedCategory.children || [];
|
||||||
|
} else {
|
||||||
|
// Для вкладки "Узлы" используем либо children, либо units
|
||||||
|
if (selectedCategory.children && selectedCategory.children.length > 0) {
|
||||||
|
subcategories = selectedCategory.children;
|
||||||
|
} else {
|
||||||
|
const categoryId = selectedCategory.categoryid || selectedCategory.quickgroupid || selectedCategory.id;
|
||||||
|
subcategories = unitsByCategory[categoryId] || [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-layout-vflex flex-block-14-copy-copy">
|
<div className="w-layout-vflex flex-block-14-copy-copy">
|
||||||
{!selectedCategory ? (
|
{!selectedCategory ? (
|
||||||
// Список категорий
|
// Список категорий
|
||||||
categories.map((cat: any, idx: number) => (
|
categories.map((cat: any, idx: number) => (
|
||||||
<div
|
<div
|
||||||
className="div-block-131"
|
className="div-block-131"
|
||||||
key={cat.quickgroupid || cat.id || idx}
|
key={cat.quickgroupid || cat.categoryid || cat.id || idx}
|
||||||
onClick={() => handleCategoryClick(cat)}
|
onClick={() => handleCategoryClick(cat)}
|
||||||
style={{ cursor: "pointer" }}
|
style={{ cursor: "pointer" }}
|
||||||
>
|
>
|
||||||
@ -91,7 +146,7 @@ const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd,
|
|||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
// Список подкатегорий (children или units)
|
// Список подкатегорий
|
||||||
<>
|
<>
|
||||||
<div className="div-block-131" onClick={handleBack} style={{ cursor: "pointer", fontWeight: 500 }}>
|
<div className="div-block-131" onClick={handleBack} style={{ cursor: "pointer", fontWeight: 500 }}>
|
||||||
<div className="text-block-57">← Назад</div>
|
<div className="text-block-57">← Назад</div>
|
||||||
@ -106,23 +161,23 @@ const VinCategory: React.FC<VinCategoryProps> = ({ catalogCode, vehicleId, ssd,
|
|||||||
{subcategories.map((subcat: any, idx: number) => (
|
{subcategories.map((subcat: any, idx: number) => (
|
||||||
<div
|
<div
|
||||||
className="div-block-131"
|
className="div-block-131"
|
||||||
key={subcat.quickgroupid || subcat.unitid || subcat.id || idx}
|
key={subcat.quickgroupid || subcat.categoryid || subcat.unitid || subcat.id || idx}
|
||||||
onClick={() => handleSubcategoryClick(subcat)}
|
onClick={() => handleSubcategoryClick(subcat)}
|
||||||
style={{ cursor: "pointer" }}
|
style={{ cursor: "pointer" }}
|
||||||
>
|
>
|
||||||
<div className="text-block-57">{subcat.name}</div>
|
<div className="text-block-57">{subcat.name}</div>
|
||||||
<div className="w-embed">
|
<div className="w-embed">
|
||||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect x="24" width="24" height="24" rx="12" transform="rotate(90 24 0)" fill="currentcolor"></rect>
|
<rect x="24" width="24" height="24" rx="12" transform="rotate(90 24 0)" fill="currentcolor"></rect>
|
||||||
<path fillRule="evenodd" clipRule="evenodd" d="M10.9303 17L10 16.0825L14.1395 12L10 7.91747L10.9303 7L16 12L10.9303 17Z" fill="white"></path>
|
<path fillRule="evenodd" clipRule="evenodd" d="M10.9303 17L10 16.0825L14.1395 12L10 7.91747L10.9303 7L16 12L10.9303 17Z" fill="white"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default VinCategory;
|
export default VinCategory;
|
@ -18,6 +18,8 @@ interface VinLeftbarProps {
|
|||||||
isSearching?: boolean;
|
isSearching?: boolean;
|
||||||
}) => void;
|
}) => void;
|
||||||
onNodeSelect?: (node: any) => void;
|
onNodeSelect?: (node: any) => void;
|
||||||
|
onActiveTabChange?: (tab: 'uzly' | 'manufacturer') => void;
|
||||||
|
onQuickGroupSelect?: (group: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface QuickGroup {
|
interface QuickGroup {
|
||||||
@ -27,7 +29,7 @@ interface QuickGroup {
|
|||||||
children?: QuickGroup[];
|
children?: QuickGroup[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, onNodeSelect }) => {
|
const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, onNodeSelect, onActiveTabChange, onQuickGroupSelect }) => {
|
||||||
const catalogCode = vehicleInfo.catalog;
|
const catalogCode = vehicleInfo.catalog;
|
||||||
const vehicleId = vehicleInfo.vehicleid;
|
const vehicleId = vehicleInfo.vehicleid;
|
||||||
const ssd = vehicleInfo.ssd;
|
const ssd = vehicleInfo.ssd;
|
||||||
@ -252,6 +254,12 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
|
|||||||
|
|
||||||
const fulltextResults = fulltextData?.laximoFulltextSearch?.details || [];
|
const fulltextResults = fulltextData?.laximoFulltextSearch?.details || [];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (onActiveTabChange) {
|
||||||
|
onActiveTabChange(activeTab);
|
||||||
|
}
|
||||||
|
}, [activeTab, onActiveTabChange]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-layout-vflex vinleftbar">
|
<div className="w-layout-vflex vinleftbar">
|
||||||
{/* === Форма полнотекстового поиска === */}
|
{/* === Форма полнотекстового поиска === */}
|
||||||
@ -358,11 +366,11 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
|
|||||||
data-delay="0"
|
data-delay="0"
|
||||||
className={`dropdown-4 w-dropdown${isOpen ? " w--open" : ""}`}
|
className={`dropdown-4 w-dropdown${isOpen ? " w--open" : ""}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`dropdown-toggle-card w-dropdown-toggle${isOpen ? " w--open" : ""}`}
|
className={`dropdown-toggle-3 w-dropdown-toggle${isOpen ? " w--open" : ""}`}
|
||||||
onClick={() => handleToggle(idx, category.quickgroupid)}
|
onClick={() => handleToggle(idx, category.quickgroupid)}
|
||||||
style={{ cursor: "pointer" }}
|
style={{ cursor: "pointer" }}
|
||||||
>
|
>
|
||||||
<div className="w-icon-dropdown-toggle"></div>
|
<div className="w-icon-dropdown-toggle"></div>
|
||||||
<div className="text-block-56">{category.name}</div>
|
<div className="text-block-56">{category.name}</div>
|
||||||
</div>
|
</div>
|
||||||
@ -415,8 +423,8 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
|
|||||||
className="dropdown-link-3 w-dropdown-link"
|
className="dropdown-link-3 w-dropdown-link"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (group.link) {
|
if (group.link && onQuickGroupSelect) {
|
||||||
handleQuickGroupClick(group);
|
onQuickGroupSelect(group);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -453,8 +461,8 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
|
|||||||
className="dropdown-link-3 w-dropdown-link "
|
className="dropdown-link-3 w-dropdown-link "
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (child.link) {
|
if (child.link && onQuickGroupSelect) {
|
||||||
handleQuickGroupClick(child);
|
onQuickGroupSelect(child);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -486,8 +494,8 @@ const VinLeftbar: React.FC<VinLeftbarProps> = ({ vehicleInfo, onSearchResults, o
|
|||||||
className="dropdown-link-3 w-dropdown-link "
|
className="dropdown-link-3 w-dropdown-link "
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (subChild.link) {
|
if (subChild.link && onQuickGroupSelect) {
|
||||||
handleQuickGroupClick(subChild);
|
onQuickGroupSelect(subChild);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
101
src/components/vin/VinQuick.tsx
Normal file
101
src/components/vin/VinQuick.tsx
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { useQuery } from '@apollo/client';
|
||||||
|
import { GET_LAXIMO_QUICK_DETAIL } from '@/lib/graphql/laximo';
|
||||||
|
import BrandSelectionModal from '../BrandSelectionModal';
|
||||||
|
|
||||||
|
interface VinQuickProps {
|
||||||
|
quickGroup: any;
|
||||||
|
catalogCode: string;
|
||||||
|
vehicleId: string;
|
||||||
|
ssd: string;
|
||||||
|
onBack: () => void;
|
||||||
|
onNodeSelect: (unit: any) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const VinQuick: React.FC<VinQuickProps> = ({ quickGroup, catalogCode, vehicleId, ssd, onBack, onNodeSelect }) => {
|
||||||
|
const { data, loading, error } = useQuery(GET_LAXIMO_QUICK_DETAIL, {
|
||||||
|
variables: {
|
||||||
|
catalogCode,
|
||||||
|
vehicleId,
|
||||||
|
quickGroupId: quickGroup.quickgroupid,
|
||||||
|
ssd
|
||||||
|
},
|
||||||
|
skip: !quickGroup || !quickGroup.quickgroupid
|
||||||
|
});
|
||||||
|
const quickDetail = data?.laximoQuickDetail;
|
||||||
|
|
||||||
|
const [isBrandModalOpen, setIsBrandModalOpen] = useState(false);
|
||||||
|
const [selectedDetail, setSelectedDetail] = useState<any>(null);
|
||||||
|
|
||||||
|
const handleUnitClick = (unit: any) => {
|
||||||
|
onNodeSelect({
|
||||||
|
...unit,
|
||||||
|
unitid: unit.unitid,
|
||||||
|
name: unit.name,
|
||||||
|
catalogCode,
|
||||||
|
vehicleId,
|
||||||
|
ssd
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleDetailClick = (detail: any) => {
|
||||||
|
setSelectedDetail(detail);
|
||||||
|
setIsBrandModalOpen(true);
|
||||||
|
};
|
||||||
|
const handleCloseBrandModal = () => {
|
||||||
|
setIsBrandModalOpen(false);
|
||||||
|
setSelectedDetail(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full">
|
||||||
|
{/* <button onClick={onBack} className="mb-4 px-4 py-2 bg-gray-200 rounded self-start">Назад</button> */}
|
||||||
|
{loading ? (
|
||||||
|
<div className="text-center py-4">Загружаем детали...</div>
|
||||||
|
) : error ? (
|
||||||
|
<div className="text-red-600 py-4">Ошибка загрузки деталей: {error.message}</div>
|
||||||
|
) : quickDetail && quickDetail.units ? (
|
||||||
|
quickDetail.units.map((unit: any) => (
|
||||||
|
<div key={unit.unitid} className="w-layout-vflex flex-block-14-copy-copy">
|
||||||
|
<div className="knotinfo">
|
||||||
|
{unit.imageurl || unit.largeimageurl ? (
|
||||||
|
<img
|
||||||
|
src={unit.largeimageurl ? unit.largeimageurl.replace('%size%', '250') : unit.imageurl.replace('%size%', '250')}
|
||||||
|
alt={unit.name}
|
||||||
|
className="image-26"
|
||||||
|
onError={e => { (e.currentTarget as HTMLImageElement).src = '/images/image-44.jpg'; }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<img src="/images/image-44.jpg" alt="Нет изображения" className="image-26" />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="knot-img">
|
||||||
|
<h1 className="heading-19">{unit.name}</h1>
|
||||||
|
|
||||||
|
{unit.details && unit.details.length > 0 && unit.details.map((detail: any) => (
|
||||||
|
<div className="w-layout-hflex flex-block-115" key={detail.detailid}>
|
||||||
|
<div className="oemnuber">{detail.oem}</div>
|
||||||
|
<div className="partsname">{detail.name}</div>
|
||||||
|
<a href="#" className="button-3 w-button" onClick={e => { e.preventDefault(); handleDetailClick(detail); }}>Показать цены</a>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<a href="#" className="showallparts w-button" onClick={e => { e.preventDefault(); handleUnitClick(unit); }}>Подробнее</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className="text-center text-gray-500 py-4">Нет деталей для этой группы</div>
|
||||||
|
)}
|
||||||
|
{isBrandModalOpen && selectedDetail && (
|
||||||
|
<BrandSelectionModal
|
||||||
|
isOpen={isBrandModalOpen}
|
||||||
|
onClose={handleCloseBrandModal}
|
||||||
|
articleNumber={selectedDetail.oem}
|
||||||
|
detailName={selectedDetail.name}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default VinQuick;
|
@ -15,7 +15,11 @@ import VinCategory from '@/components/vin/VinCategory';
|
|||||||
import PartDetailCard from '@/components/PartDetailCard';
|
import PartDetailCard from '@/components/PartDetailCard';
|
||||||
import VinPartCard from '@/components/vin/VinPartCard';
|
import VinPartCard from '@/components/vin/VinPartCard';
|
||||||
import KnotIn from '@/components/vin/KnotIn';
|
import KnotIn from '@/components/vin/KnotIn';
|
||||||
import KnotParts from '@/components/vin/KnotParts';
|
import KnotParts from '@/components/vin/KnotParts';
|
||||||
|
import VinQuick from '@/components/vin/VinQuick';
|
||||||
|
import CatalogSubscribe from '@/components/CatalogSubscribe';
|
||||||
|
import MobileMenuBottomSection from '@/components/MobileMenuBottomSection';
|
||||||
|
|
||||||
|
|
||||||
interface LaximoVehicleInfo {
|
interface LaximoVehicleInfo {
|
||||||
vehicleid: string;
|
vehicleid: string;
|
||||||
@ -53,6 +57,7 @@ const VehicleDetailsPage = () => {
|
|||||||
const [searchType, setSearchType] = useState<'quickgroups' | 'categories' | 'fulltext'>(defaultSearchType);
|
const [searchType, setSearchType] = useState<'quickgroups' | 'categories' | 'fulltext'>(defaultSearchType);
|
||||||
const [showKnot, setShowKnot] = useState(false);
|
const [showKnot, setShowKnot] = useState(false);
|
||||||
const [foundParts, setFoundParts] = useState<any[]>([]);
|
const [foundParts, setFoundParts] = useState<any[]>([]);
|
||||||
|
const [activeTab, setActiveTab] = useState<'uzly' | 'manufacturer'>('uzly');
|
||||||
const [searchState, setSearchState] = useState<{
|
const [searchState, setSearchState] = useState<{
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
error: any;
|
error: any;
|
||||||
@ -65,6 +70,7 @@ const VehicleDetailsPage = () => {
|
|||||||
isSearching: false
|
isSearching: false
|
||||||
});
|
});
|
||||||
const [selectedNode, setSelectedNode] = useState<any | null>(null);
|
const [selectedNode, setSelectedNode] = useState<any | null>(null);
|
||||||
|
const [selectedQuickGroup, setSelectedQuickGroup] = useState<any | null>(null);
|
||||||
const handleCategoryClick = (e?: React.MouseEvent) => {
|
const handleCategoryClick = (e?: React.MouseEvent) => {
|
||||||
if (e) e.preventDefault();
|
if (e) e.preventDefault();
|
||||||
setShowKnot(true);
|
setShowKnot(true);
|
||||||
@ -291,6 +297,8 @@ const VehicleDetailsPage = () => {
|
|||||||
setSearchState({ loading, error, query, isSearching: isSearching || false });
|
setSearchState({ loading, error, query, isSearching: isSearching || false });
|
||||||
}}
|
}}
|
||||||
onNodeSelect={setSelectedNode}
|
onNodeSelect={setSelectedNode}
|
||||||
|
onActiveTabChange={(tab) => setActiveTab(tab)}
|
||||||
|
onQuickGroupSelect={setSelectedQuickGroup}
|
||||||
/>
|
/>
|
||||||
{searchState.isSearching ? (
|
{searchState.isSearching ? (
|
||||||
<div className="knot-parts">
|
<div className="knot-parts">
|
||||||
@ -342,12 +350,23 @@ const VehicleDetailsPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
) : showKnot ? (
|
) : showKnot ? (
|
||||||
<VinKnot />
|
<VinKnot />
|
||||||
|
) : selectedQuickGroup ? (
|
||||||
|
<VinQuick
|
||||||
|
quickGroup={selectedQuickGroup}
|
||||||
|
catalogCode={vehicleInfo.catalog}
|
||||||
|
vehicleId={vehicleInfo.vehicleid}
|
||||||
|
ssd={vehicleInfo.ssd}
|
||||||
|
onBack={() => setSelectedQuickGroup(null)}
|
||||||
|
onNodeSelect={setSelectedNode}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<VinCategory
|
<VinCategory
|
||||||
catalogCode={vehicleInfo.catalog}
|
catalogCode={vehicleInfo.catalog}
|
||||||
vehicleId={vehicleInfo.vehicleid}
|
vehicleId={vehicleInfo.vehicleid}
|
||||||
ssd={vehicleInfo.ssd}
|
ssd={vehicleInfo.ssd}
|
||||||
onNodeSelect={setSelectedNode}
|
onNodeSelect={setSelectedNode}
|
||||||
|
activeTab={activeTab}
|
||||||
|
onQuickGroupSelect={setSelectedQuickGroup}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
@ -378,10 +397,15 @@ const VehicleDetailsPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<section className="section-3">
|
||||||
|
<CatalogSubscribe />
|
||||||
|
</section>
|
||||||
|
<Footer />
|
||||||
|
<MobileMenuBottomSection />
|
||||||
|
|
||||||
{/* ====== ВРЕМЕННЫЙ МАКЕТ ДЛЯ ВЕРСТКИ (конец) ====== */}
|
{/* ====== ВРЕМЕННЫЙ МАКЕТ ДЛЯ ВЕРСТКИ (конец) ====== */}
|
||||||
|
|
||||||
{/* Навигация */}
|
{/* Навигация
|
||||||
<nav className="bg-white border-b">
|
<nav className="bg-white border-b">
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
<div className="flex items-center justify-between h-16">
|
<div className="flex items-center justify-between h-16">
|
||||||
@ -409,7 +433,7 @@ const VehicleDetailsPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{/* Информация об автомобиле */}
|
Информация об автомобиле
|
||||||
<div className="bg-white border-b">
|
<div className="bg-white border-b">
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
||||||
<div className="flex items-center space-x-4 mb-6">
|
<div className="flex items-center space-x-4 mb-6">
|
||||||
@ -429,7 +453,7 @@ const VehicleDetailsPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Предупреждение об ошибке */}
|
Предупреждение об ошибке
|
||||||
{hasError && (
|
{hasError && (
|
||||||
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4 mb-6">
|
<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4 mb-6">
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
@ -450,7 +474,7 @@ const VehicleDetailsPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Отладочная информация */}
|
Отладочная информация
|
||||||
<div className="bg-gray-50 border border-gray-200 rounded-lg p-4 mb-6">
|
<div className="bg-gray-50 border border-gray-200 rounded-lg p-4 mb-6">
|
||||||
<h4 className="text-sm font-medium text-gray-900 mb-3">
|
<h4 className="text-sm font-medium text-gray-900 mb-3">
|
||||||
🔧 Отладочная информация
|
🔧 Отладочная информация
|
||||||
@ -481,7 +505,7 @@ const VehicleDetailsPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Характеристики автомобиля */}
|
Характеристики автомобиля
|
||||||
{vehicleInfo.attributes && vehicleInfo.attributes.length > 0 && (
|
{vehicleInfo.attributes && vehicleInfo.attributes.length > 0 && (
|
||||||
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
|
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
|
||||||
{vehicleInfo.attributes.map((attr, index) => (
|
{vehicleInfo.attributes.map((attr, index) => (
|
||||||
@ -495,7 +519,7 @@ const VehicleDetailsPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Способы поиска запчастей */}
|
Способы поиска запчастей
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<h2 className="text-xl font-bold text-gray-900 mb-2">Поиск запчастей</h2>
|
<h2 className="text-xl font-bold text-gray-900 mb-2">Поиск запчастей</h2>
|
||||||
@ -504,7 +528,7 @@ const VehicleDetailsPage = () => {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Диагностический компонент */}
|
Диагностический компонент
|
||||||
<LaximoDiagnostic
|
<LaximoDiagnostic
|
||||||
catalogCode={vehicleInfo.catalog}
|
catalogCode={vehicleInfo.catalog}
|
||||||
vehicleId={vehicleInfo.vehicleid}
|
vehicleId={vehicleInfo.vehicleid}
|
||||||
@ -517,7 +541,7 @@ const VehicleDetailsPage = () => {
|
|||||||
searchType={searchType}
|
searchType={searchType}
|
||||||
onSearchTypeChange={setSearchType}
|
onSearchTypeChange={setSearchType}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div> */}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user