mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-09-30 07:43:14 +00:00
70 lines
2.4 KiB
TypeScript
70 lines
2.4 KiB
TypeScript
|
|
// Pricing library domain — TanStack Query hooks + query keys (the only public surface).
|
||
|
|
import { keepPreviousData, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||
|
|
import { toast } from 'react-toastify';
|
||
|
|
import { pricingLibraryApi } from './api';
|
||
|
|
import type {
|
||
|
|
CreatePricingLibraryItemRequest,
|
||
|
|
PricingLibraryListParams,
|
||
|
|
UpdatePricingLibraryItemRequest,
|
||
|
|
} from './types';
|
||
|
|
|
||
|
|
export const pricingLibraryKeys = {
|
||
|
|
all: ['pricingLibrary'] as const,
|
||
|
|
lists: () => [...pricingLibraryKeys.all, 'list'] as const,
|
||
|
|
list: (params: PricingLibraryListParams) => [...pricingLibraryKeys.lists(), params] as const,
|
||
|
|
};
|
||
|
|
|
||
|
|
/** Paginated pricing library list (PricingLibraryPage). keepPreviousData
|
||
|
|
* keeps rows/totalCount rendered while a new page fetches (prevents
|
||
|
|
* TablePagination's count collapsing to 0 mid-fetch). */
|
||
|
|
export function usePricingLibraryList(params: PricingLibraryListParams = {}) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: pricingLibraryKeys.list(params),
|
||
|
|
queryFn: () => pricingLibraryApi.list(params),
|
||
|
|
placeholderData: keepPreviousData,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useCreatePricingLibraryItem() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (data: CreatePricingLibraryItemRequest) => pricingLibraryApi.create(data),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: pricingLibraryKeys.lists() });
|
||
|
|
toast.success('Pricing item created');
|
||
|
|
},
|
||
|
|
onError: (error: Error) => {
|
||
|
|
toast.error(`Failed to create item: ${error.message}`);
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useUpdatePricingLibraryItem() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({ id, data }: { id: string; data: UpdatePricingLibraryItemRequest }) =>
|
||
|
|
pricingLibraryApi.update(id, data),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: pricingLibraryKeys.lists() });
|
||
|
|
toast.success('Pricing item updated');
|
||
|
|
},
|
||
|
|
onError: (error: Error) => {
|
||
|
|
toast.error(`Failed to update item: ${error.message}`);
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useDeletePricingLibraryItem() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (id: string) => pricingLibraryApi.remove(id),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: pricingLibraryKeys.lists() });
|
||
|
|
toast.success('Pricing item deleted');
|
||
|
|
},
|
||
|
|
onError: (error: Error) => {
|
||
|
|
toast.error(`Failed to delete item: ${error.message}`);
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|