Files
protekauto-frontend/src/components/VehiclePartsSearchSection.tsx
egortriston d62db55160 checkbox
2025-06-29 15:44:36 +03:00

271 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from 'react';
import { LaximoCatalogInfo } from '@/types/laximo';
import QuickGroupsSection from './QuickGroupsSection';
import CategoriesSection from './CategoriesSection';
import FulltextSearchSection from './FulltextSearchSection';
interface LaximoVehicleInfo {
vehicleid: string;
name: string;
ssd: string;
brand: string;
catalog: string;
attributes: Array<{
key: string;
name: string;
value: string;
}>;
}
interface VehiclePartsSearchSectionProps {
catalogInfo: LaximoCatalogInfo;
vehicleInfo: LaximoVehicleInfo;
searchType: 'quickgroups' | 'categories' | 'fulltext';
onSearchTypeChange: (type: 'quickgroups' | 'categories' | 'fulltext') => void;
}
const VehiclePartsSearchSection: React.FC<VehiclePartsSearchSectionProps> = ({
catalogInfo,
vehicleInfo,
searchType,
onSearchTypeChange
}) => {
// Проверяем поддержку функций согласно документации Laximo
const supportsQuickGroups = catalogInfo.features.some(f => f.name === 'quickgroups');
const supportsFullTextSearch = catalogInfo.features.some(f => f.name === 'fulltextsearch');
console.log('🔧 VehiclePartsSearchSection - Поддерживаемые функции:');
console.log('📋 Все features:', catalogInfo.features.map(f => f.name));
console.log('🚀 quickgroups поддерживается:', supportsQuickGroups);
console.log('🔍 fulltextsearch поддерживается:', supportsFullTextSearch);
const searchOptions = [
{
id: 'quickgroups' as const,
name: 'Группы быстрого поиска',
description: 'Поиск запчастей по группам быстрого поиска Laximo (ListQuickGroup)',
enabled: supportsQuickGroups,
requiresSSD: true,
icon: (
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
)
},
{
id: 'categories' as const,
name: 'Категории узлов каталога',
description: 'Поиск через структуру оригинального каталога (ListCategories)',
enabled: true, // Always available according to documentation
requiresSSD: false,
icon: (
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
)
},
{
id: 'fulltext' as const,
name: 'Поиск деталей по названию',
description: 'Введите часть названия детали (SearchVehicleDetails)',
enabled: supportsFullTextSearch,
requiresSSD: true,
icon: (
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
)
}
];
// Если текущий тип поиска не поддерживается, переключаемся на поддерживаемый
React.useEffect(() => {
const currentOption = searchOptions.find(option => option.id === searchType);
if (!currentOption?.enabled) {
// Приоритет: quickgroups -> categories -> fulltext
if (supportsQuickGroups && vehicleInfo.ssd) {
onSearchTypeChange('quickgroups');
} else {
onSearchTypeChange('categories'); // categories всегда доступны
}
}
}, [catalogInfo, vehicleInfo, searchType, onSearchTypeChange, supportsQuickGroups]);
const handleSearchTypeChange = (type: 'quickgroups' | 'categories' | 'fulltext') => {
const option = searchOptions.find(opt => opt.id === type);
if (!option?.enabled) {
console.warn(`Тип поиска ${type} не поддерживается каталогом ${catalogInfo.code}`);
return;
}
if (option.requiresSSD && (!vehicleInfo.ssd || vehicleInfo.ssd.trim() === '')) {
alert(`Для использования "${option.name}" необходимы данные автомобиля (SSD). Пожалуйста, выберите автомобиль заново.`);
return;
}
console.log(`🔄 Переключение на тип поиска: ${type}`);
onSearchTypeChange(type);
};
return (
<div className="space-y-6">
{/* Заголовок с информацией о каталоге */}
<div className="bg-white rounded-lg border p-6">
<div className="flex items-center justify-between mb-4">
<div>
<h2 className="text-lg font-semibold text-gray-900">
Способы поиска запчастей
</h2>
<p className="text-sm text-gray-600 mt-1">
Выберите предпочтительный способ поиска для каталога {catalogInfo.name}
</p>
</div>
{/* Индикатор поддерживаемых функций */}
<div className="text-right">
<div className="text-xs text-gray-500 mb-1">Поддерживаемые функции:</div>
<div className="flex space-x-2">
{supportsQuickGroups && (
<span className="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-green-100 text-green-800">
QuickGroups
</span>
)}
{supportsFullTextSearch && (
<span className="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-blue-100 text-blue-800">
FullText
</span>
)}
<span className="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-gray-100 text-gray-800">
Categories
</span>
</div>
</div>
</div>
{/* Селектор типов поиска */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{searchOptions.map((option) => (
<button
key={option.id}
onClick={() => handleSearchTypeChange(option.id)}
disabled={!option.enabled}
className={`
relative p-4 border rounded-lg text-left transition-all duration-200
${searchType === option.id && option.enabled
? 'border-red-500 bg-red-50 ring-2 ring-red-200'
: option.enabled
? 'border-gray-200 bg-white hover:border-gray-300 hover:bg-gray-50'
: 'border-gray-200 bg-gray-50 cursor-not-allowed opacity-60'
}
`}
>
<div className="flex items-start space-x-3">
<div className={`flex-shrink-0 ${option.enabled ? 'text-gray-600' : 'text-gray-400'}`}>
{option.icon}
</div>
<div className="flex-1 min-w-0">
<h3 className={`text-sm font-medium ${option.enabled ? 'text-gray-900' : 'text-gray-500'}`}>
{option.name}
</h3>
<p className={`text-xs mt-1 ${option.enabled ? 'text-gray-600' : 'text-gray-400'}`}>
{option.description}
</p>
{/* Индикаторы требований */}
<div className="mt-2 flex items-center space-x-2">
{option.requiresSSD && (
<span className={`text-xs px-2 py-0.5 rounded ${
vehicleInfo.ssd
? 'bg-green-100 text-green-700'
: 'bg-yellow-100 text-yellow-700'
}`}>
{vehicleInfo.ssd ? '✓ SSD доступен' : '⚠ Требует SSD'}
</span>
)}
{!option.enabled && (
<span className="text-xs px-2 py-0.5 rounded bg-red-100 text-red-700">
Не поддерживается
</span>
)}
</div>
</div>
</div>
{/* Индикатор выбранного состояния */}
{searchType === option.id && option.enabled && (
<div className="absolute top-2 right-2">
<svg className="w-5 h-5 text-red-600" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
</svg>
</div>
)}
</button>
))}
</div>
</div>
{/* Отображение выбранного компонента поиска */}
<div className="min-h-[400px]">
{searchType === 'quickgroups' && supportsQuickGroups && (
<QuickGroupsSection
catalogCode={vehicleInfo.catalog}
vehicleId={vehicleInfo.vehicleid}
ssd={vehicleInfo.ssd}
/>
)}
{searchType === 'categories' && (
<CategoriesSection
catalogCode={vehicleInfo.catalog}
vehicleId={vehicleInfo.vehicleid}
ssd={vehicleInfo.ssd}
/>
)}
{searchType === 'fulltext' && supportsFullTextSearch && (
<FulltextSearchSection
catalogCode={vehicleInfo.catalog}
vehicleId={vehicleInfo.vehicleid}
ssd={vehicleInfo.ssd}
/>
)}
</div>
{/* Информационная панель */}
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
<div className="flex">
<div className="flex-shrink-0">
<svg className="h-5 w-5 text-blue-400" viewBox="0 0 20 20" fill="currentColor">
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
</svg>
</div>
<div className="ml-3">
<h3 className="text-sm font-medium text-blue-800">
Информация о способах поиска
</h3>
<div className="mt-2 text-sm text-blue-700">
<ul className="list-disc list-inside space-y-1">
<li><strong>Группы быстрого поиска</strong> - используют функцию Laximo ListQuickGroup для быстрого доступа к категориям</li>
<li><strong>Категории узлов каталога</strong> - навигация по структуре оригинального каталога производителя</li>
<li><strong>Поиск по названию</strong> - полнотекстовый поиск деталей по их наименованию</li>
</ul>
{vehicleInfo.ssd ? (
<p className="mt-2 text-green-700">
Данные автомобиля (SSD) доступны - все функции активны
</p>
) : (
<p className="mt-2 text-yellow-700">
Некоторые функции требуют данных автомобиля (SSD)
</p>
)}
</div>
</div>
</div>
</div>
</div>
);
};
export default VehiclePartsSearchSection;