163 lines
3.6 KiB
TypeScript
163 lines
3.6 KiB
TypeScript
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
|
|
import {
|
|
apiClient,
|
|
ApiErrorCode,
|
|
apiErrorCode,
|
|
isApiErrorCode,
|
|
} from "@/shared/api";
|
|
|
|
import type {
|
|
CreateBankCard,
|
|
CreateBankOperation,
|
|
CreateExpenseCategory,
|
|
UpdateBankCard,
|
|
UpdateBankOperation,
|
|
UpdateExpenseCategory,
|
|
} from "./types";
|
|
|
|
async function mutationData<T>(
|
|
request: Promise<{ data?: T; error?: unknown }>,
|
|
) {
|
|
const { data, error } = await request;
|
|
// eslint-disable-next-line @typescript-eslint/only-throw-error -- Preserve generated ProblemDetails for apiErrorCode and field-error consumers.
|
|
if (error) throw error;
|
|
|
|
return data;
|
|
}
|
|
|
|
function useBankMutationOptions() {
|
|
const queryClient = useQueryClient();
|
|
|
|
const invalidate = () =>
|
|
queryClient.invalidateQueries({
|
|
predicate: ({ queryKey }) => {
|
|
const [method, path] = queryKey;
|
|
|
|
return (
|
|
method === "get"
|
|
&& typeof path === "string"
|
|
&& (path === "/api/v1/bank-cards"
|
|
|| path.startsWith("/api/v1/bank-cards/"))
|
|
);
|
|
},
|
|
});
|
|
|
|
return {
|
|
onError: (error: unknown) => {
|
|
const errorCode = apiErrorCode(error);
|
|
|
|
return [
|
|
ApiErrorCode.BankDependentRefunds,
|
|
ApiErrorCode.BankIntentConflict,
|
|
ApiErrorCode.BankRefundLimit,
|
|
ApiErrorCode.BankVersionConflict,
|
|
ApiErrorCode.BankWriteConflict,
|
|
].some(code => isApiErrorCode(errorCode, code))
|
|
? invalidate()
|
|
: undefined;
|
|
},
|
|
onSuccess: invalidate,
|
|
retry: false,
|
|
} as const;
|
|
}
|
|
|
|
function useCreateBankCard() {
|
|
const options = useBankMutationOptions();
|
|
|
|
return useMutation({
|
|
...options,
|
|
mutationFn: (body: CreateBankCard) =>
|
|
mutationData(apiClient.POST("/api/v1/bank-cards", { body })),
|
|
});
|
|
}
|
|
|
|
function useCreateBankOperation() {
|
|
const options = useBankMutationOptions();
|
|
|
|
return useMutation({
|
|
...options,
|
|
mutationFn: (body: CreateBankOperation) =>
|
|
mutationData(apiClient.POST("/api/v1/bank-cards/operations", { body })),
|
|
});
|
|
}
|
|
|
|
function useCreateExpenseCategory() {
|
|
const options = useBankMutationOptions();
|
|
|
|
return useMutation({
|
|
...options,
|
|
mutationFn: (body: CreateExpenseCategory) =>
|
|
mutationData(apiClient.POST("/api/v1/bank-cards/categories", { body })),
|
|
});
|
|
}
|
|
|
|
function useDeleteBankOperation() {
|
|
const options = useBankMutationOptions();
|
|
|
|
return useMutation({
|
|
...options,
|
|
mutationFn: ({ id, version }: { id: string; version: number }) =>
|
|
mutationData(
|
|
apiClient.DELETE("/api/v1/bank-cards/operations/{id}", {
|
|
params: { path: { id }, query: { version } },
|
|
}),
|
|
),
|
|
});
|
|
}
|
|
|
|
function useUpdateBankCard() {
|
|
const options = useBankMutationOptions();
|
|
|
|
return useMutation({
|
|
...options,
|
|
mutationFn: ({ body, id }: { body: UpdateBankCard; id: string }) =>
|
|
mutationData(
|
|
apiClient.PATCH("/api/v1/bank-cards/{id}", {
|
|
body,
|
|
params: { path: { id } },
|
|
}),
|
|
),
|
|
});
|
|
}
|
|
|
|
function useUpdateBankOperation() {
|
|
const options = useBankMutationOptions();
|
|
|
|
return useMutation({
|
|
...options,
|
|
mutationFn: ({ body, id }: { body: UpdateBankOperation; id: string }) =>
|
|
mutationData(
|
|
apiClient.PATCH("/api/v1/bank-cards/operations/{id}", {
|
|
body,
|
|
params: { path: { id } },
|
|
}),
|
|
),
|
|
});
|
|
}
|
|
|
|
function useUpdateExpenseCategory() {
|
|
const options = useBankMutationOptions();
|
|
|
|
return useMutation({
|
|
...options,
|
|
mutationFn: ({ body, id }: { body: UpdateExpenseCategory; id: string }) =>
|
|
mutationData(
|
|
apiClient.PATCH("/api/v1/bank-cards/categories/{id}", {
|
|
body,
|
|
params: { path: { id } },
|
|
}),
|
|
),
|
|
});
|
|
}
|
|
|
|
export {
|
|
useCreateBankCard,
|
|
useCreateBankOperation,
|
|
useCreateExpenseCategory,
|
|
useDeleteBankOperation,
|
|
useUpdateBankCard,
|
|
useUpdateBankOperation,
|
|
useUpdateExpenseCategory,
|
|
};
|