Завершение rebase с обновленными компонентами
This commit is contained in:
@ -54,26 +54,40 @@ const createFilters = (result: any, loadedAnalogs: any): FilterConfig[] => {
|
||||
});
|
||||
}
|
||||
|
||||
// Фильтр по цене
|
||||
const prices: number[] = [];
|
||||
// Получаем все доступные предложения для расчета диапазонов
|
||||
const allAvailableOffers: any[] = [];
|
||||
|
||||
// Добавляем основные предложения
|
||||
result.internalOffers?.forEach((offer: any) => {
|
||||
if (offer.price > 0) prices.push(offer.price);
|
||||
allAvailableOffers.push(offer);
|
||||
});
|
||||
result.externalOffers?.forEach((offer: any) => {
|
||||
if (offer.price > 0) prices.push(offer.price);
|
||||
allAvailableOffers.push(offer);
|
||||
});
|
||||
|
||||
// Добавляем цены аналогов
|
||||
// Добавляем предложения аналогов
|
||||
Object.values(loadedAnalogs).forEach((analog: any) => {
|
||||
analog.internalOffers?.forEach((offer: any) => {
|
||||
if (offer.price > 0) prices.push(offer.price);
|
||||
allAvailableOffers.push({
|
||||
...offer,
|
||||
deliveryDuration: offer.deliveryDays
|
||||
});
|
||||
});
|
||||
analog.externalOffers?.forEach((offer: any) => {
|
||||
if (offer.price > 0) prices.push(offer.price);
|
||||
allAvailableOffers.push({
|
||||
...offer,
|
||||
deliveryDuration: offer.deliveryTime
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if (prices.length > 0) {
|
||||
// Фильтр по цене - только если есть предложения с разными ценами
|
||||
const prices: number[] = [];
|
||||
allAvailableOffers.forEach((offer: any) => {
|
||||
if (offer.price > 0) prices.push(offer.price);
|
||||
});
|
||||
|
||||
if (prices.length > 1) {
|
||||
const minPrice = Math.min(...prices);
|
||||
const maxPrice = Math.max(...prices);
|
||||
|
||||
@ -87,26 +101,14 @@ const createFilters = (result: any, loadedAnalogs: any): FilterConfig[] => {
|
||||
}
|
||||
}
|
||||
|
||||
// Фильтр по сроку доставки
|
||||
// Фильтр по сроку доставки - только если есть предложения с разными сроками
|
||||
const deliveryDays: number[] = [];
|
||||
result.internalOffers?.forEach((offer: any) => {
|
||||
if (offer.deliveryDays && offer.deliveryDays > 0) deliveryDays.push(offer.deliveryDays);
|
||||
});
|
||||
result.externalOffers?.forEach((offer: any) => {
|
||||
if (offer.deliveryTime && offer.deliveryTime > 0) deliveryDays.push(offer.deliveryTime);
|
||||
});
|
||||
|
||||
// Добавляем сроки доставки аналогов
|
||||
Object.values(loadedAnalogs).forEach((analog: any) => {
|
||||
analog.internalOffers?.forEach((offer: any) => {
|
||||
if (offer.deliveryDays && offer.deliveryDays > 0) deliveryDays.push(offer.deliveryDays);
|
||||
});
|
||||
analog.externalOffers?.forEach((offer: any) => {
|
||||
if (offer.deliveryTime && offer.deliveryTime > 0) deliveryDays.push(offer.deliveryTime);
|
||||
});
|
||||
allAvailableOffers.forEach((offer: any) => {
|
||||
const days = offer.deliveryDays || offer.deliveryTime || offer.deliveryDuration;
|
||||
if (days && days > 0) deliveryDays.push(days);
|
||||
});
|
||||
|
||||
if (deliveryDays.length > 0) {
|
||||
if (deliveryDays.length > 1) {
|
||||
const minDays = Math.min(...deliveryDays);
|
||||
const maxDays = Math.max(...deliveryDays);
|
||||
|
||||
@ -120,26 +122,13 @@ const createFilters = (result: any, loadedAnalogs: any): FilterConfig[] => {
|
||||
}
|
||||
}
|
||||
|
||||
// Фильтр по количеству наличия
|
||||
// Фильтр по количеству наличия - только если есть предложения с разными количествами
|
||||
const quantities: number[] = [];
|
||||
result.internalOffers?.forEach((offer: any) => {
|
||||
allAvailableOffers.forEach((offer: any) => {
|
||||
if (offer.quantity && offer.quantity > 0) quantities.push(offer.quantity);
|
||||
});
|
||||
result.externalOffers?.forEach((offer: any) => {
|
||||
if (offer.quantity && offer.quantity > 0) quantities.push(offer.quantity);
|
||||
});
|
||||
|
||||
// Добавляем количества аналогов
|
||||
Object.values(loadedAnalogs).forEach((analog: any) => {
|
||||
analog.internalOffers?.forEach((offer: any) => {
|
||||
if (offer.quantity && offer.quantity > 0) quantities.push(offer.quantity);
|
||||
});
|
||||
analog.externalOffers?.forEach((offer: any) => {
|
||||
if (offer.quantity && offer.quantity > 0) quantities.push(offer.quantity);
|
||||
});
|
||||
});
|
||||
|
||||
if (quantities.length > 0) {
|
||||
if (quantities.length > 1) {
|
||||
const minQuantity = Math.min(...quantities);
|
||||
const maxQuantity = Math.max(...quantities);
|
||||
|
||||
@ -163,35 +152,24 @@ const getBestOffers = (offers: any[]) => {
|
||||
if (validOffers.length === 0) return [];
|
||||
|
||||
const result: { offer: any; type: string }[] = [];
|
||||
const usedOfferIds = new Set<string>();
|
||||
|
||||
// 1. Самая низкая цена (среди всех предложений)
|
||||
const lowestPriceOffer = [...validOffers].sort((a, b) => a.price - b.price)[0];
|
||||
if (lowestPriceOffer) {
|
||||
result.push({ offer: lowestPriceOffer, type: 'Самая низкая цена' });
|
||||
usedOfferIds.add(`${lowestPriceOffer.articleNumber}-${lowestPriceOffer.price}-${lowestPriceOffer.deliveryDuration}`);
|
||||
}
|
||||
|
||||
// 2. Самый дешевый аналог (только среди аналогов)
|
||||
// 2. Самый дешевый аналог (только среди аналогов) - всегда показываем если есть аналоги
|
||||
const analogOffers = validOffers.filter(offer => offer.isAnalog);
|
||||
if (analogOffers.length > 0) {
|
||||
const cheapestAnalogOffer = [...analogOffers].sort((a, b) => a.price - b.price)[0];
|
||||
const analogId = `${cheapestAnalogOffer.articleNumber}-${cheapestAnalogOffer.price}-${cheapestAnalogOffer.deliveryDuration}`;
|
||||
|
||||
if (!usedOfferIds.has(analogId)) {
|
||||
result.push({ offer: cheapestAnalogOffer, type: 'Самый дешевый аналог' });
|
||||
usedOfferIds.add(analogId);
|
||||
}
|
||||
result.push({ offer: cheapestAnalogOffer, type: 'Самый дешевый аналог' });
|
||||
}
|
||||
|
||||
// 3. Самая быстрая доставка (среди всех предложений)
|
||||
const fastestDeliveryOffer = [...validOffers].sort((a, b) => a.deliveryDuration - b.deliveryDuration)[0];
|
||||
if (fastestDeliveryOffer) {
|
||||
const fastestId = `${fastestDeliveryOffer.articleNumber}-${fastestDeliveryOffer.price}-${fastestDeliveryOffer.deliveryDuration}`;
|
||||
|
||||
if (!usedOfferIds.has(fastestId)) {
|
||||
result.push({ offer: fastestDeliveryOffer, type: 'Самая быстрая доставка' });
|
||||
}
|
||||
result.push({ offer: fastestDeliveryOffer, type: 'Самая быстрая доставка' });
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -376,7 +354,101 @@ export default function SearchResult() {
|
||||
|
||||
const hasOffers = result && (result.internalOffers.length > 0 || result.externalOffers.length > 0);
|
||||
const hasAnalogs = result && result.analogs.length > 0;
|
||||
const searchResultFilters = createFilters(result, loadedAnalogs);
|
||||
|
||||
// Создаем динамические фильтры на основе доступных данных с учетом активных фильтров
|
||||
const searchResultFilters = useMemo(() => {
|
||||
const baseFilters = createFilters(result, loadedAnalogs);
|
||||
|
||||
// Если нет активных фильтров, возвращаем базовые фильтры
|
||||
if (!filtersAreActive) {
|
||||
return baseFilters;
|
||||
}
|
||||
|
||||
// Создаем динамические фильтры с учетом других активных фильтров
|
||||
return baseFilters.map(filter => {
|
||||
if (filter.type !== 'range') {
|
||||
return filter;
|
||||
}
|
||||
|
||||
// Для каждого диапазонного фильтра пересчитываем границы на основе
|
||||
// предложений, отфильтрованных другими фильтрами (исключая текущий)
|
||||
let relevantOffers = allOffers;
|
||||
|
||||
// Применяем все фильтры кроме текущего
|
||||
relevantOffers = allOffers.filter(offer => {
|
||||
// Фильтр по бренду (если это не фильтр производителя)
|
||||
if (filter.title !== 'Производитель' && selectedBrands.length > 0 && !selectedBrands.includes(offer.brand)) {
|
||||
return false;
|
||||
}
|
||||
// Фильтр по цене (если это не фильтр цены)
|
||||
if (filter.title !== 'Цена (₽)' && priceRange && (offer.price < priceRange[0] || offer.price > priceRange[1])) {
|
||||
return false;
|
||||
}
|
||||
// Фильтр по сроку доставки (если это не фильтр доставки)
|
||||
if (filter.title !== 'Срок доставки (дни)' && deliveryRange) {
|
||||
const deliveryDays = offer.deliveryDuration;
|
||||
if (deliveryDays < deliveryRange[0] || deliveryDays > deliveryRange[1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Фильтр по количеству (если это не фильтр количества)
|
||||
if (filter.title !== 'Количество (шт.)' && quantityRange) {
|
||||
const quantity = offer.quantity;
|
||||
if (quantity < quantityRange[0] || quantity > quantityRange[1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Фильтр по поисковой строке
|
||||
if (filterSearchTerm) {
|
||||
const searchTerm = filterSearchTerm.toLowerCase();
|
||||
const brandMatch = offer.brand.toLowerCase().includes(searchTerm);
|
||||
const articleMatch = offer.articleNumber.toLowerCase().includes(searchTerm);
|
||||
const nameMatch = offer.name.toLowerCase().includes(searchTerm);
|
||||
if (!brandMatch && !articleMatch && !nameMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// Пересчитываем диапазон на основе отфильтрованных предложений
|
||||
if (filter.title === 'Цена (₽)') {
|
||||
const prices = relevantOffers.filter(o => o.price > 0).map(o => o.price);
|
||||
if (prices.length > 0) {
|
||||
return {
|
||||
...filter,
|
||||
min: Math.floor(Math.min(...prices)),
|
||||
max: Math.ceil(Math.max(...prices))
|
||||
};
|
||||
}
|
||||
} else if (filter.title === 'Срок доставки (дни)') {
|
||||
const deliveryDays = relevantOffers
|
||||
.map(o => o.deliveryDuration)
|
||||
.filter(d => d && d > 0);
|
||||
if (deliveryDays.length > 0) {
|
||||
return {
|
||||
...filter,
|
||||
min: Math.min(...deliveryDays),
|
||||
max: Math.max(...deliveryDays)
|
||||
};
|
||||
}
|
||||
} else if (filter.title === 'Количество (шт.)') {
|
||||
const quantities = relevantOffers
|
||||
.map(o => o.quantity)
|
||||
.filter(q => q && q > 0);
|
||||
if (quantities.length > 0) {
|
||||
return {
|
||||
...filter,
|
||||
min: Math.min(...quantities),
|
||||
max: Math.max(...quantities)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return filter;
|
||||
});
|
||||
}, [result, loadedAnalogs, filtersAreActive, allOffers, selectedBrands, priceRange, deliveryRange, quantityRange, filterSearchTerm]);
|
||||
|
||||
const bestOffersData = getBestOffers(filteredOffers);
|
||||
|
||||
|
||||
@ -406,6 +478,8 @@ export default function SearchResult() {
|
||||
}
|
||||
}, [q, article, router.query]);
|
||||
|
||||
|
||||
|
||||
// Удаляем старую заглушку - теперь обрабатываем все типы поиска
|
||||
|
||||
const minPrice = useMemo(() => {
|
||||
|
Reference in New Issue
Block a user