Vitron-Front/app/requestHandler/use-home-hooks.ts
2026-04-29 01:44:16 +03:30

229 lines
6.9 KiB
TypeScript

import { useQuery, useInfiniteQuery } from "@tanstack/react-query";
import { useAuthToken } from "../hooks/use-root-data";
import { createHomepageApi } from "~/utils/api-client-factory";
// Home query keys
export const homeKeys = {
all: ["home"] as const,
banners: () => [...homeKeys.all, "banners"] as const,
categories: () => [...homeKeys.all, "categories"] as const,
discounts: () => [...homeKeys.all, "discounts"] as const,
forYou: () => [...homeKeys.all, "forYou"] as const,
topSellers: () => [...homeKeys.all, "topSellers"] as const,
sellerTiles: () => [...homeKeys.all, "sellerTiles"] as const,
sellerTilesAll: () => [...homeKeys.all, "sellerTilesAll"] as const,
};
/**
* Hook for fetching home page banners
* @returns Query result with home page banners
*/
export function useGetHomeBanners() {
const token = useAuthToken();
return useQuery({
queryKey: homeKeys.banners(),
queryFn: async () => {
try {
console.log("[Home Hooks] Fetching banners - Token:", !!token);
const homeApi = createHomepageApi(token);
console.log("[Home Hooks] HomepageApi created, making API call...");
const result = await homeApi.apiHomeV1BannersList();
console.log("[Home Hooks] Banners fetched successfully:", result);
return result;
} catch (error) {
console.error("Error fetching home banners:", error);
throw error;
}
},
staleTime: 5 * 60 * 1000, // 5 minutes cache
refetchOnWindowFocus: false,
});
}
/**
* Hook for fetching home page discounts with cursor pagination
* @returns Infinite query result with home page discounts
*/
export function useGetHomeDiscounts() {
const token = useAuthToken();
return useInfiniteQuery({
queryKey: homeKeys.discounts(),
queryFn: async ({ pageParam }) => {
try {
const homeApi = createHomepageApi(token);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const result = await homeApi.apiHomeV1DiscountsList({
cursor: pageParam,
pageSize: 20,
});
// API returns { next, previous, results } but type says Array
// Return the whole response to access 'next' in getNextPageParam
return result;
} catch (error) {
console.error("Error fetching home discounts:", error);
throw error;
}
},
initialPageParam: undefined as string | undefined,
getNextPageParam: (lastPage) => {
// Extract cursor from next URL
if (lastPage?.next) {
const url = new URL(lastPage.next);
return url.searchParams.get("cursor");
}
return undefined;
},
staleTime: 5 * 60 * 1000, // 5 minutes cache
refetchOnWindowFocus: false,
});
}
/**
* Hook for fetching home page "For You" products with infinite scroll
* @returns Infinite query result with personalized products
*/
export function useGetHomeForYou() {
const token = useAuthToken();
return useInfiniteQuery({
queryKey: homeKeys.forYou(),
queryFn: async ({ pageParam }) => {
try {
const homeApi = createHomepageApi(token);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const result = await homeApi.apiHomeV1ForYouList({
cursor: pageParam,
pageSize: 20,
});
// API returns { next, previous, results } but type says Array
// Return the whole response to access 'next' in getNextPageParam
return result;
} catch (error) {
console.error("Error fetching home 'For You' products:", error);
throw error;
}
},
initialPageParam: undefined as string | undefined,
getNextPageParam: (lastPage) => {
// Extract cursor from next URL
if (lastPage?.next) {
const url = new URL(lastPage.next);
return url.searchParams.get("cursor");
}
return undefined;
},
staleTime: 5 * 60 * 1000, // 5 minutes cache
refetchOnWindowFocus: false,
});
}
/**
* Hook for fetching home page top sellers with cursor pagination
* @returns Infinite query result with top selling products
*/
export function useGetHomeTopSellers() {
const token = useAuthToken();
return useInfiniteQuery({
queryKey: homeKeys.topSellers(),
queryFn: async ({ pageParam }) => {
try {
const homeApi = createHomepageApi(token);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const result = await homeApi.apiHomeV1TopSellersList({
cursor: pageParam,
pageSize: 20,
});
// API returns { next, previous, results } but type says Array
// Return the whole response to access 'next' in getNextPageParam
return result;
} catch (error) {
console.error("Error fetching home top sellers:", error);
throw error;
}
},
initialPageParam: undefined as string | undefined,
getNextPageParam: (lastPage) => {
// Extract cursor from next URL
if (lastPage?.next) {
const url = new URL(lastPage.next);
return url.searchParams.get("cursor");
}
return undefined;
},
staleTime: 5 * 60 * 1000, // 5 minutes cache
refetchOnWindowFocus: false,
});
}
/**
* Hook for fetching home page categories
* @returns Query result with home page categories
*/
export function useGetHomeCategories() {
const token = useAuthToken();
return useQuery({
queryKey: homeKeys.categories(),
queryFn: async () => {
try {
const homeApi = createHomepageApi(token);
return await homeApi.apiHomeV1CategoriesList();
} catch (error) {
console.error("Error fetching home categories:", error);
throw error;
}
},
staleTime: 20 * 60 * 1000, // 5 minutes cache
refetchOnWindowFocus: false,
});
}
/**
* Hook for fetching top 4 seller tiles for homepage
* @returns Query result with seller tiles
*/
export function useGetHomeSellerTiles() {
const token = useAuthToken();
return useQuery({
queryKey: homeKeys.sellerTiles(),
queryFn: async () => {
try {
const homeApi = createHomepageApi(token);
return await homeApi.apiHomeV1SellerTilesList();
} catch (error) {
console.error("Error fetching home seller tiles:", error);
throw error;
}
},
staleTime: 5 * 60 * 1000,
refetchOnWindowFocus: false,
});
}
/**
* Hook for fetching all seller tiles for 'See more' page
* @returns Query result with all seller tiles
*/
export function useGetAllSellerTiles() {
const token = useAuthToken();
return useQuery({
queryKey: homeKeys.sellerTilesAll(),
queryFn: async () => {
try {
const homeApi = createHomepageApi(token);
return await homeApi.apiHomeV1SellerTilesAllList();
} catch (error) {
console.error("Error fetching all seller tiles:", error);
throw error;
}
},
staleTime: 5 * 60 * 1000,
refetchOnWindowFocus: false,
});
}