93 lines
3.4 KiB
TypeScript
93 lines
3.4 KiB
TypeScript
import React from 'react';
|
||
import { PartsSearchHistoryItem } from '@/lib/graphql/search-history';
|
||
|
||
interface SearchHistoryDropdownProps {
|
||
isVisible: boolean;
|
||
historyItems: PartsSearchHistoryItem[];
|
||
onItemClick: (searchQuery: string) => void;
|
||
loading?: boolean;
|
||
}
|
||
|
||
const SearchHistoryDropdown: React.FC<SearchHistoryDropdownProps> = ({
|
||
isVisible,
|
||
historyItems,
|
||
onItemClick,
|
||
loading = false
|
||
}) => {
|
||
if (!isVisible) return null;
|
||
|
||
// Фильтруем уникальные запросы
|
||
const uniqueQueries = Array.from(
|
||
new Map(
|
||
historyItems.map(item => [item.searchQuery.toLowerCase(), item])
|
||
).values()
|
||
);
|
||
|
||
const getSearchTypeLabel = (type: string) => {
|
||
switch (type) {
|
||
case 'VIN':
|
||
return 'VIN';
|
||
case 'PLATE':
|
||
return 'Госномер';
|
||
case 'OEM':
|
||
case 'ARTICLE':
|
||
return 'Артикул';
|
||
default:
|
||
return 'Поиск';
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="absolute top-full left-0 right-0 bg-white border border-gray-200 rounded-lg shadow-lg mt-2 z-50 max-h-60 overflow-y-auto">
|
||
{loading ? (
|
||
<div className="p-4 text-center text-gray-500">
|
||
<div className="flex items-center justify-center">
|
||
<svg className="animate-spin w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||
</svg>
|
||
Загрузка истории...
|
||
</div>
|
||
</div>
|
||
) : uniqueQueries.length > 0 ? (
|
||
<>
|
||
<div className="p-3 border-b border-gray-100">
|
||
<h3 className="text-xs font-medium text-gray-500 uppercase tracking-wide">
|
||
Последние запросы
|
||
</h3>
|
||
</div>
|
||
{uniqueQueries.map((item) => (
|
||
<button
|
||
key={item.id}
|
||
onClick={() => onItemClick(item.searchQuery)}
|
||
className="w-full text-left p-3 hover:bg-gray-50 border-b border-gray-100 last:border-b-0 transition-colors cursor-pointer"
|
||
style={{ cursor: 'pointer' }}
|
||
>
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex-1 min-w-0">
|
||
<p className="text-sm font-medium text-gray-900 truncate">
|
||
{item.searchQuery}
|
||
</p>
|
||
<p className="text-xs text-gray-500">
|
||
{getSearchTypeLabel(item.searchType)}
|
||
</p>
|
||
</div>
|
||
<div className="ml-2 flex-shrink-0">
|
||
<svg className="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
</button>
|
||
))}
|
||
</>
|
||
) : (
|
||
<div className="p-4 text-center text-gray-500">
|
||
<p className="text-sm">История поиска пуста</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default SearchHistoryDropdown;
|