// src/actions/product.ts // import { useMemo } from 'react'; import axiosInstance, { endpoints, fetcher } from 'src/lib/axios'; import type { IProductItem } from 'src/types/product'; import type { SWRConfiguration } from 'swr'; import useSWR, { mutate } from 'swr'; // ---------------------------------------------------------------------- const swrOptions: SWRConfiguration = { revalidateIfStale: false, revalidateOnFocus: false, revalidateOnReconnect: false, }; // ---------------------------------------------------------------------- type ProductsData = { products: IProductItem[]; }; export function useGetProducts() { const url = endpoints.product.list; const { data, isLoading, error, isValidating } = useSWR(url, fetcher, swrOptions); const memoizedValue = useMemo( () => ({ products: data?.products || [], productsLoading: isLoading, productsError: error, productsValidating: isValidating, productsEmpty: !isLoading && !isValidating && !data?.products.length, }), [data?.products, error, isLoading, isValidating] ); return memoizedValue; } // ---------------------------------------------------------------------- type ProductData = { product: IProductItem; }; export function useGetProduct(productId: string) { const url = productId ? [endpoints.product.details, { params: { productId } }] : ''; const { data, isLoading, error, isValidating } = useSWR(url, fetcher, swrOptions); const memoizedValue = useMemo( () => ({ product: data?.product, productLoading: isLoading, productError: error, productValidating: isValidating, mutate, }), [data?.product, error, isLoading, isValidating] ); return memoizedValue; } // ---------------------------------------------------------------------- type SearchResultsData = { results: IProductItem[]; }; export function useSearchProducts(query: string) { const url = query ? [endpoints.product.search, { params: { query } }] : ''; const { data, isLoading, error, isValidating } = useSWR(url, fetcher, { ...swrOptions, keepPreviousData: true, }); const memoizedValue = useMemo( () => ({ searchResults: data?.results || [], searchLoading: isLoading, searchError: error, searchValidating: isValidating, searchEmpty: !isLoading && !isValidating && !data?.results.length, }), [data?.results, error, isLoading, isValidating] ); return memoizedValue; } // ---------------------------------------------------------------------- export async function createProduct(productData: IProductItem) { /** * Work on server */ const data = { productData }; const { data: { id }, } = await axiosInstance.post(endpoints.product.create, data); /** * Work in local */ mutate( endpoints.product.list, (currentData: any) => { const currentProducts: IProductItem[] = currentData?.products; const products = [...currentProducts, { ...productData, id }]; return { ...currentData, products }; }, false ); } // ---------------------------------------------------------------------- export async function updateProduct(productData: Partial) { /** * Work on server */ const data = { productData }; await axiosInstance.put(endpoints.product.update, data); /** * Work in local */ mutate( endpoints.product.list, (currentData: any) => { const currentProducts: IProductItem[] = currentData?.products; const products = currentProducts.map((product) => product.id === productData.id ? { ...product, ...productData } : product ); return { ...currentData, products }; }, false ); } // ---------------------------------------------------------------------- export async function deleteProduct(productId: string) { /** * Work on server */ const data = { productId }; await axiosInstance.patch(endpoints.product.delete, data); /** * Work in local */ mutate( endpoints.product.list, (currentData: any) => { console.log({ currentData }); const currentProducts: IProductItem[] = currentData?.products; const products = currentProducts.filter((product) => product.id !== productId); return { ...currentData, products }; }, false ); }