Удален файл интеграции с Parts Index API и обновлены компоненты для работы с корзиной и избранным. Добавлены функции для обработки добавления товаров в корзину с уведомлениями, улучшена логика работы с избранным, а также добавлены фильтры для истории поиска по производителю.

This commit is contained in:
Bivekich
2025-06-29 03:36:21 +03:00
parent d268bb3359
commit 7f91da525f
23 changed files with 685 additions and 780 deletions

View File

@ -15,6 +15,7 @@ import {
const ProfileHistoryMain = () => {
const [search, setSearch] = useState("");
const [activeTab, setActiveTab] = useState("Все");
const [selectedManufacturer, setSelectedManufacturer] = useState("Все");
const [sortField, setSortField] = useState<"date" | "manufacturer" | "name">("date");
const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc");
const [filteredItems, setFilteredItems] = useState<PartsSearchHistoryItem[]>([]);
@ -105,6 +106,14 @@ const ProfileHistoryMain = () => {
useEffect(() => {
let filtered = [...getFilteredByTime(historyItems, activeTab)];
// Фильтрация по производителю
if (selectedManufacturer !== "Все") {
filtered = filtered.filter(item =>
item.brand === selectedManufacturer ||
item.vehicleInfo?.brand === selectedManufacturer
);
}
// Поиск
if (search.trim()) {
const searchLower = search.toLowerCase();
@ -152,7 +161,7 @@ const ProfileHistoryMain = () => {
}
setFilteredItems(filtered);
}, [historyItems, search, activeTab, sortField, sortOrder]);
}, [historyItems, search, activeTab, selectedManufacturer, sortField, sortOrder]);
const handleSort = (field: "date" | "manufacturer" | "name") => {
if (sortField === field) {
@ -272,6 +281,18 @@ const ProfileHistoryMain = () => {
/>
</div>
<div className="flex gap-2">
{(selectedManufacturer !== "Все" || search.trim() || activeTab !== "Все") && (
<button
onClick={() => {
setSelectedManufacturer("Все");
setSearch("");
setActiveTab("Все");
}}
className="px-4 py-2 text-sm text-gray-600 border border-gray-200 rounded-lg hover:bg-gray-50 transition-colors"
>
Сбросить фильтры
</button>
)}
{historyItems.length === 0 && (
<button
onClick={handleCreateTestData}
@ -297,7 +318,14 @@ const ProfileHistoryMain = () => {
</div>
<div className="flex flex-col mt-5 w-full text-lg font-medium leading-tight whitespace-nowrap text-gray-950 max-md:max-w-full">
<ProfileHistoryTabs tabs={tabOptions} activeTab={activeTab} onTabChange={setActiveTab} />
<ProfileHistoryTabs
tabs={tabOptions}
activeTab={activeTab}
onTabChange={setActiveTab}
historyItems={historyItems}
selectedManufacturer={selectedManufacturer}
onManufacturerChange={setSelectedManufacturer}
/>
</div>
<div className="flex flex-col mt-5 w-full text-gray-400 max-md:max-w-full flex-1 h-full">
@ -421,6 +449,11 @@ const ProfileHistoryMain = () => {
{filteredItems.length > 0 && (
<div className="mt-4 text-center text-sm text-gray-500">
Показано {filteredItems.length} из {historyItems.length} записей
{(selectedManufacturer !== "Все" || search.trim() || activeTab !== "Все") && (
<span className="ml-2 text-blue-600">
(применены фильтры)
</span>
)}
</div>
)}
</div>

View File

@ -1,22 +1,47 @@
import React, { useState, useRef } from "react";
import { PartsSearchHistoryItem } from '@/lib/graphql/search-history';
interface ProfileHistoryTabsProps {
tabs: string[];
activeTab: string;
onTabChange: (tab: string) => void;
historyItems: PartsSearchHistoryItem[];
selectedManufacturer: string;
onManufacturerChange: (manufacturer: string) => void;
}
const manufacturers = ["Все", "VAG", "Toyota", "Ford", "BMW"];
const ProfileHistoryTabs: React.FC<ProfileHistoryTabsProps> = ({
tabs,
activeTab,
onTabChange,
historyItems,
selectedManufacturer,
onManufacturerChange,
}) => {
const [selectedManufacturer, setSelectedManufacturer] = useState(manufacturers[0]);
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
// Получаем уникальных производителей из истории поиска
const getUniqueManufacturers = () => {
const manufacturersSet = new Set<string>();
historyItems.forEach(item => {
// Добавляем бренд из поля brand
if (item.brand) {
manufacturersSet.add(item.brand);
}
// Добавляем бренд из информации об автомобиле
if (item.vehicleInfo?.brand) {
manufacturersSet.add(item.vehicleInfo.brand);
}
});
const uniqueManufacturers = Array.from(manufacturersSet).sort();
return ["Все", ...uniqueManufacturers];
};
const manufacturers = getUniqueManufacturers();
// Закрытие дропдауна при клике вне
React.useEffect(() => {
function handleClickOutside(event: MouseEvent) {
@ -34,6 +59,11 @@ const ProfileHistoryTabs: React.FC<ProfileHistoryTabsProps> = ({
};
}, [isDropdownOpen]);
const handleManufacturerSelect = (manufacturer: string) => {
onManufacturerChange(manufacturer);
setIsDropdownOpen(false);
};
return (
<div className="flex flex-wrap gap-5 w-full max-md:max-w-full">
{tabs.map((tab) => (
@ -69,20 +99,41 @@ const ProfileHistoryTabs: React.FC<ProfileHistoryTabsProps> = ({
>
<span className="truncate">{selectedManufacturer}</span>
<span className="ml-2 flex-shrink-0 flex items-center">
<svg width="20" height="20" fill="none" viewBox="0 0 20 20"><path d="M6 8l4 4 4-4" stroke="#9CA3AF" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
<svg
width="20"
height="20"
fill="none"
viewBox="0 0 20 20"
className={`transition-transform duration-200 ${isDropdownOpen ? 'rotate-180' : ''}`}
>
<path d="M6 8l4 4 4-4" stroke="#9CA3AF" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
</span>
</div>
{isDropdownOpen && (
<ul className="absolute left-0 top-full z-10 bg-white border-x border-b border-stone-300 rounded-b-lg shadow-lg w-full">
{manufacturers.map((option) => (
<li
key={option}
className={`px-6 py-4 cursor-pointer hover:bg-blue-100 ${option === selectedManufacturer ? 'bg-blue-50 font-semibold' : ''}`}
onMouseDown={() => { setSelectedManufacturer(option); setIsDropdownOpen(false); }}
>
{option}
<ul className="absolute left-0 top-full z-10 bg-white border-x border-b border-stone-300 rounded-b-lg shadow-lg w-full max-h-60 overflow-y-auto">
{manufacturers.length === 0 ? (
<li className="px-6 py-4 text-gray-400 text-center">
Нет данных
</li>
))}
) : (
manufacturers.map((manufacturer) => (
<li
key={manufacturer}
className={`px-6 py-4 cursor-pointer hover:bg-blue-100 transition-colors ${manufacturer === selectedManufacturer ? 'bg-blue-50 font-semibold text-blue-600' : ''}`}
onMouseDown={() => handleManufacturerSelect(manufacturer)}
>
{manufacturer}
{manufacturer !== "Все" && (
<span className="ml-2 text-xs text-gray-400">
({historyItems.filter(item =>
item.brand === manufacturer || item.vehicleInfo?.brand === manufacturer
).length})
</span>
)}
</li>
))
)}
</ul>
)}
</div>