Files
HKSingleParty/03_source/frontend/src/actions/product.ts
louiscklaw b7cd25b614 build ok,
2025-06-15 11:28:24 +08:00

174 lines
4.3 KiB
TypeScript

// 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<ProductsData>(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<ProductData>(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<SearchResultsData>(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 };
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];
return { ...currentData, products };
},
false
);
}
// ----------------------------------------------------------------------
export async function updateProduct(productData: Partial<IProductItem>) {
/**
* 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
);
}