prices and shit

This commit is contained in:
54CHA
2025-07-18 19:15:25 +03:00
parent f3d21959c9
commit 649ddbfa8a

View File

@ -167,49 +167,7 @@ export default function Catalog() {
const allArticles = articlesData?.partsAPIArticles || [];
// Сначала загружаем параметры фильтрации для PartsIndex
const { data: paramsData, loading: paramsLoading, error: paramsError } = useQuery<PartsIndexParamsData, PartsIndexParamsVariables>(
GET_PARTSINDEX_CATALOG_PARAMS,
{
variables: {
catalogId: catalogId as string,
groupId: groupId as string,
lang: 'ru',
q: searchQuery || undefined,
params: undefined // Параметры для получения самих фильтров
},
skip: !isPartsIndexMode || !groupId, // Пропускаем запрос если нет groupId
fetchPolicy: 'cache-first'
}
);
// Преобразование выбранных фильтров в строку параметров для GraphQL (стабильное мемоизирование)
const apiParamsString = useMemo((): string | undefined => {
if (!paramsData?.partsIndexCatalogParams?.list || Object.keys(selectedFilters).length === 0) {
return undefined;
}
const apiParams: Record<string, any> = {};
paramsData.partsIndexCatalogParams.list.forEach((param: any) => {
const selectedValues = selectedFilters[param.name];
if (selectedValues && selectedValues.length > 0) {
// Находим соответствующие значения из API данных
const matchingValues = param.values.filter((value: any) =>
selectedValues.includes(value.title || value.value)
);
if (matchingValues.length > 0) {
// Используем ID параметра из API и значения
apiParams[param.id] = matchingValues.map((v: any) => v.value);
}
}
});
return Object.keys(apiParams).length > 0 ? JSON.stringify(apiParams) : undefined;
}, [paramsData, selectedFilters]);
// Теперь загружаем товары PartsIndex с реактивными переменными (включая фильтры)
// Загружаем товары PartsIndex
const { data: entitiesData, loading: entitiesLoading, error: entitiesError, refetch: refetchEntities } = useQuery<PartsIndexEntitiesData, PartsIndexEntitiesVariables>(
GET_PARTSINDEX_CATALOG_ENTITIES,
{
@ -220,13 +178,29 @@ export default function Catalog() {
limit: PARTSINDEX_PAGE_SIZE,
page: partsIndexPage,
q: searchQuery || undefined,
params: apiParamsString // ✅ Теперь реактивно отслеживает изменения фильтров
params: undefined // Будем обновлять через refetch
},
skip: !isPartsIndexMode || !groupId, // Пропускаем запрос если нет groupId
fetchPolicy: 'cache-and-network'
}
);
// Загружаем параметры фильтрации для PartsIndex
const { data: paramsData, loading: paramsLoading, error: paramsError, refetch: refetchParams } = useQuery<PartsIndexParamsData, PartsIndexParamsVariables>(
GET_PARTSINDEX_CATALOG_PARAMS,
{
variables: {
catalogId: catalogId as string,
groupId: groupId as string,
lang: 'ru',
q: searchQuery || undefined,
params: undefined // Будем обновлять через refetch
},
skip: !isPartsIndexMode || !groupId, // Пропускаем запрос если нет groupId
fetchPolicy: 'cache-first'
}
);
// allEntities больше не используется - используем allLoadedEntities
// Хук для загрузки цен товаров PartsIndex
@ -316,6 +290,32 @@ export default function Catalog() {
}
}, [entitiesData, isFilterChanging]);
// Преобразование выбранных фильтров в формат PartsIndex API
const convertFiltersToPartsIndexParams = useMemo((): Record<string, any> => {
if (!paramsData?.partsIndexCatalogParams?.list || Object.keys(selectedFilters).length === 0) {
return {};
}
const apiParams: Record<string, any> = {};
paramsData.partsIndexCatalogParams.list.forEach((param: any) => {
const selectedValues = selectedFilters[param.name];
if (selectedValues && selectedValues.length > 0) {
// Находим соответствующие значения из API данных
const matchingValues = param.values.filter((value: any) =>
selectedValues.includes(value.title || value.value)
);
if (matchingValues.length > 0) {
// Используем ID параметра из API и значения
apiParams[param.id] = matchingValues.map((v: any) => v.value);
}
}
});
return apiParams;
}, [paramsData, selectedFilters]);
// Функция автоматической подгрузки дополнительных страниц PartsIndex
const autoLoadMoreEntities = useCallback(async () => {
if (isAutoLoading || !hasMoreEntities || !isPartsIndexMode) {
@ -363,10 +363,10 @@ export default function Catalog() {
setIsAutoLoading(true);
try {
console.log('🔄 Автоподгрузка: загружаем следующую страницу PartsIndex...');
// Используем уже вычисленную строку параметров
const paramsString = apiParamsString;
console.log('🔄 Автоподгрузка: загружаем следующую страницу PartsIndex...');
const apiParams = convertFiltersToPartsIndexParams;
const paramsString = Object.keys(apiParams).length > 0 ? JSON.stringify(apiParams) : undefined;
const result = await refetchEntities({
catalogId: catalogId as string,
@ -743,25 +743,91 @@ export default function Catalog() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isPartsAPIMode, searchQuery, JSON.stringify(selectedFilters), filteredArticles.length]);
// Простая логика сброса при изменении фильтров - убираем сложные refetch
// Обновляем видимые товары при изменении поиска или фильтров для PartsIndex
useEffect(() => {
if (isPartsIndexMode) {
console.log('🔄 Фильтры изменились, сбрасываем локальное состояние');
// Сбрасываем локальное состояние при изменении фильтров
setPartsIndexPage(1);
setCurrentUserPage(1);
setAccumulatedEntities([]);
setEntitiesWithOffers([]);
setVisibleEntities([]);
setEntitiesCache(new Map());
// При изменении поиска или фильтров сбрасываем пагинацию
setShowEmptyState(false);
setIsFilterChanging(true);
// Apollo автоматически перезагрузит данные при изменении переменных
// Если изменился поисковый запрос или фильтры, нужно перезагрузить данные с сервера
if (searchQuery.trim() || Object.keys(selectedFilters).length > 0) {
console.log('🔍 Поисковый запрос или фильтры изменились, сбрасываем пагинацию');
// Устанавливаем флаг изменения фильтров
setIsFilterChanging(true);
setPartsIndexPage(1);
setCurrentUserPage(1);
setHasMoreEntities(true);
setAccumulatedEntities([]);
setEntitiesWithOffers([]);
setEntitiesCache(new Map());
// Вычисляем параметры фильтрации прямо здесь, чтобы избежать зависимости от useMemo
let apiParams: Record<string, any> = {};
if (paramsData?.partsIndexCatalogParams?.list && Object.keys(selectedFilters).length > 0) {
paramsData.partsIndexCatalogParams.list.forEach((param: any) => {
const selectedValues = selectedFilters[param.name];
if (selectedValues && selectedValues.length > 0) {
// Находим соответствующие значения из API данных
const matchingValues = param.values.filter((value: any) =>
selectedValues.includes(value.title || value.value)
);
if (matchingValues.length > 0) {
// Используем ID параметра из API и значения
apiParams[param.id] = matchingValues.map((v: any) => v.value);
}
}
});
}
const paramsString = Object.keys(apiParams).length > 0 ? JSON.stringify(apiParams) : undefined;
console.log('🔄 Запуск refetch с новыми фильтрами:', {
searchQuery,
selectedFilters,
apiParams,
paramsString,
catalogId,
groupId
});
// Также обновляем параметры фильтрации
refetchParams({
catalogId: catalogId as string,
groupId: groupId as string,
lang: 'ru',
q: searchQuery || undefined,
params: paramsString
}).then(result => {
console.log('✅ refetchParams результат:', result);
}).catch(error => {
console.error('❌ refetchParams ошибка:', error);
});
refetchEntities({
catalogId: catalogId as string,
groupId: groupId as string,
lang: 'ru',
limit: PARTSINDEX_PAGE_SIZE,
page: 1,
q: searchQuery || undefined,
params: paramsString
}).then(result => {
console.log('✅ refetchEntities результат:', result.data?.partsIndexCatalogEntities?.list?.length || 0, 'товаров');
}).catch(error => {
console.error('❌ refetchEntities ошибка:', error);
});
} else {
// Если нет активных фильтров, сбрасываем флаг
if (isFilterChanging) {
setIsFilterChanging(false);
}
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isPartsIndexMode, searchQuery, JSON.stringify(selectedFilters)]);
}, [isPartsIndexMode, searchQuery, JSON.stringify(selectedFilters), paramsData]);
// Управляем показом пустого состояния с задержкой
useEffect(() => {