Files
nutriscan/hooks/useSearchCache.ts
Evandro Fonseca Junior e4ed666074 feat(results-page): enhance search with caching, pagination, and UI tweaks
- Add dynamic rendering and Node.js runtime config to location API for better performance
- Improve ProductCardSkeleton with dark mode styling for consistent theming
- Simplify Hero search placeholder to focus on product name input
- Integrate caching, pagination, and cache clearing in results page for optimized search experience and user control
2025-10-09 01:53:42 -03:00

219 lines
4.7 KiB
TypeScript

"use client";
import { useState, useEffect, useCallback } from "react";
import { Product } from "@/lib/openFoodFactsApi";
import { cacheManager, CachedSearch, FilterRecord } from "@/lib/cacheManager";
export interface SearchCacheState {
isLoading: boolean;
isCached: boolean;
searchId: string | null;
progress: {
currentPage: number;
totalPages: number;
loadedProducts: number;
totalProducts: number;
} | null;
error: string | null;
}
export interface UseSearchCacheReturn {
state: SearchCacheState;
getCachedSearch: (
query: string,
country: string,
filters?: FilterRecord
) => CachedSearch | null;
saveSearch: (
query: string,
country: string,
products: Product[],
totalCount: number,
filters?: FilterRecord
) => string;
clearCache: (
query?: string,
country?: string,
filters?: FilterRecord
) => void;
clearAllCaches: () => void;
getCacheStats: () => ReturnType<typeof cacheManager.getCacheStats>;
updateProgress: (
currentPage: number,
totalPages: number,
loadedProducts: number,
totalProducts: number
) => void;
setError: (error: string | null) => void;
setLoading: (loading: boolean) => void;
}
export function useSearchCache(): UseSearchCacheReturn {
const [state, setState] = useState<SearchCacheState>({
isLoading: false,
isCached: false,
searchId: null,
progress: null,
error: null,
});
const getCachedSearch = useCallback(
(
query: string,
country: string,
filters?: FilterRecord
): CachedSearch | null => {
try {
const cached = cacheManager.getSearch(query, country, filters);
setState((prev) => ({
...prev,
isCached: !!cached,
searchId: cached?.searchId || null,
error: null,
}));
return cached;
} catch (error) {
console.error("Erro ao buscar cache:", error);
setState((prev) => ({
...prev,
error: "Erro ao acessar cache",
}));
return null;
}
},
[]
);
const saveSearch = useCallback(
(
query: string,
country: string,
products: Product[],
totalCount: number,
filters?: FilterRecord
): string => {
try {
const searchId = cacheManager.saveSearch(
query,
country,
products,
totalCount,
filters
);
setState((prev) => ({
...prev,
searchId,
isCached: true,
error: null,
}));
return searchId;
} catch (error) {
console.error("Erro ao salvar cache:", error);
setState((prev) => ({
...prev,
error: "Erro ao salvar cache",
}));
return "";
}
},
[]
);
const clearCache = useCallback(
(query?: string, country?: string, filters?: FilterRecord) => {
try {
if (query && country) {
cacheManager.removeSearch(query, country, filters);
setState((prev) => ({
...prev,
isCached: false,
searchId: null,
}));
} else {
cacheManager.clearAllCaches();
setState((prev) => ({
...prev,
isCached: false,
searchId: null,
}));
}
} catch (error) {
console.error("Erro ao limpar cache:", error);
setState((prev) => ({
...prev,
error: "Erro ao limpar cache",
}));
}
},
[]
);
const clearAllCaches = useCallback(() => {
clearCache();
}, [clearCache]);
const getCacheStats = useCallback(() => {
return cacheManager.getCacheStats();
}, []);
const updateProgress = useCallback(
(
currentPage: number,
totalPages: number,
loadedProducts: number,
totalProducts: number
) => {
setState((prev) => ({
...prev,
progress: {
currentPage,
totalPages,
loadedProducts,
totalProducts,
},
}));
},
[]
);
const setError = useCallback((error: string | null) => {
setState((prev) => ({
...prev,
error,
}));
}, []);
const setLoading = useCallback((loading: boolean) => {
setState((prev) => ({
...prev,
isLoading: loading,
error: loading ? null : prev.error,
}));
}, []);
// Limpar estado quando componente desmonta
useEffect(() => {
return () => {
setState({
isLoading: false,
isCached: false,
searchId: null,
progress: null,
error: null,
});
};
}, []);
return {
state,
getCachedSearch,
saveSearch,
clearCache,
clearAllCaches,
getCacheStats,
updateProgress,
setError,
setLoading,
};
}