205 lines
6.7 KiB
TypeScript
205 lines
6.7 KiB
TypeScript
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
import { apiSend } from "../client";
|
|
import { keys } from "../keys";
|
|
import {
|
|
BudgetSchema,
|
|
SettingsSchema,
|
|
LendingSchema,
|
|
RevalueResultSchema,
|
|
SubscriptionSchema,
|
|
} from "../schemas";
|
|
|
|
// --- transactions ---
|
|
|
|
export const useCategorize = () => {
|
|
const qc = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (b: { matchKey: string; category: string; kind?: "income" | "expense" }) =>
|
|
apiSend("POST", "/transactions/categorize", b),
|
|
onSuccess: () => {
|
|
qc.invalidateQueries({ queryKey: ["transactions"] });
|
|
qc.invalidateQueries({ queryKey: ["analyze"] });
|
|
qc.invalidateQueries({ queryKey: keys.budget });
|
|
},
|
|
});
|
|
};
|
|
|
|
export const useRenameTxn = () => {
|
|
const qc = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (b: { matchKey: string; name: string }) => apiSend("POST", "/transactions/rename", b),
|
|
onSuccess: () => qc.invalidateQueries({ queryKey: ["transactions"] }),
|
|
});
|
|
};
|
|
|
|
export const useSetNote = () => {
|
|
const qc = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (b: { id: number; note: string }) => apiSend("PUT", `/transactions/${b.id}/note`, { note: b.note }),
|
|
onSuccess: () => qc.invalidateQueries({ queryKey: ["transactions"] }),
|
|
});
|
|
};
|
|
|
|
// --- budget ---
|
|
|
|
export const usePutBudget = () => {
|
|
const qc = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (b: {
|
|
dayLimit: string;
|
|
weekLimit: string;
|
|
monthLimit: string;
|
|
plannedIncomeManual: string;
|
|
categories: { name: string; day: string; week: string; month: string }[];
|
|
}) => apiSend("PUT", "/budget", b, BudgetSchema),
|
|
onSuccess: () => qc.invalidateQueries({ queryKey: keys.budget }),
|
|
});
|
|
};
|
|
|
|
// --- settings ---
|
|
|
|
export const useSaveSettings = () => {
|
|
const qc = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (b: {
|
|
holderName: string;
|
|
employer: string;
|
|
salaryKeywords: string[];
|
|
payDays: number[];
|
|
ownAccounts: string[];
|
|
peerAccounts: string[];
|
|
hideAmounts?: boolean;
|
|
}) => apiSend("PUT", "/settings", b, SettingsSchema),
|
|
onSuccess: () => qc.invalidateQueries({ queryKey: keys.settings }),
|
|
});
|
|
};
|
|
|
|
// --- categories ---
|
|
|
|
export const useCategoryMutations = () => {
|
|
const qc = useQueryClient();
|
|
const invalidate = () => {
|
|
qc.invalidateQueries({ queryKey: keys.categories });
|
|
qc.invalidateQueries({ queryKey: keys.budget });
|
|
qc.invalidateQueries({ queryKey: ["transactions"] });
|
|
};
|
|
const add = useMutation({
|
|
mutationFn: (b: { name: string; kind?: "income" | "expense"; parent?: string; icon?: string }) =>
|
|
apiSend("POST", "/categories", b),
|
|
onSuccess: invalidate,
|
|
});
|
|
const update = useMutation({
|
|
mutationFn: (b: { oldName: string; newName?: string; parent?: string | null; icon?: string | null }) =>
|
|
apiSend("PUT", "/categories", b),
|
|
onSuccess: invalidate,
|
|
});
|
|
const remove = useMutation({
|
|
mutationFn: (name: string) => apiSend("DELETE", `/categories?name=${encodeURIComponent(name)}`),
|
|
onSuccess: invalidate,
|
|
});
|
|
return { add, update, delete: remove };
|
|
};
|
|
|
|
// --- manual assets ---
|
|
|
|
export const useManualAssetMutations = () => {
|
|
const qc = useQueryClient();
|
|
const invalidate = () => {
|
|
qc.invalidateQueries({ queryKey: keys.manualAssets });
|
|
qc.invalidateQueries({ queryKey: keys.networth });
|
|
};
|
|
const add = useMutation({
|
|
mutationFn: (b: {
|
|
name: string;
|
|
category?: string;
|
|
value: string;
|
|
acquiredValue?: string;
|
|
currency?: string;
|
|
condition?: string;
|
|
isLiability?: boolean;
|
|
}) => apiSend("POST", "/manual-assets", b),
|
|
onSuccess: invalidate,
|
|
});
|
|
const remove = useMutation({
|
|
mutationFn: (name: string) => apiSend("DELETE", `/manual-assets/${encodeURIComponent(name)}`),
|
|
onSuccess: invalidate,
|
|
});
|
|
const revalue = useMutation({
|
|
mutationFn: (name: string) => apiSend("POST", `/manual-assets/${encodeURIComponent(name)}/revalue`, undefined, RevalueResultSchema),
|
|
onSuccess: invalidate,
|
|
});
|
|
return { add, delete: remove, revalue };
|
|
};
|
|
|
|
// --- lending ---
|
|
|
|
export const useLendingMutations = () => {
|
|
const qc = useQueryClient();
|
|
const invalidate = () => qc.invalidateQueries({ queryKey: keys.lending });
|
|
const create = useMutation({
|
|
mutationFn: (b: { person: string; amount: string; lentOn: string; dueOn?: string; note?: string; txnId?: number }) =>
|
|
apiSend("POST", "/lending", b, LendingSchema),
|
|
onSuccess: invalidate,
|
|
});
|
|
const remove = useMutation({
|
|
mutationFn: (id: number) => apiSend("DELETE", `/lending/${id}`),
|
|
onSuccess: invalidate,
|
|
});
|
|
const addRepayment = useMutation({
|
|
mutationFn: (b: { id: number; amount: string; paidOn: string; note?: string; txnId?: number }) =>
|
|
apiSend("POST", `/lending/${b.id}/repayments`, { amount: b.amount, paidOn: b.paidOn, note: b.note, txnId: b.txnId }, LendingSchema),
|
|
onSuccess: invalidate,
|
|
});
|
|
const deleteRepayment = useMutation({
|
|
mutationFn: (b: { id: number; repaymentId: number }) => apiSend("DELETE", `/lending/${b.id}/repayments/${b.repaymentId}`),
|
|
onSuccess: invalidate,
|
|
});
|
|
return { create, delete: remove, addRepayment, deleteRepayment };
|
|
};
|
|
|
|
// --- subscriptions ---
|
|
|
|
export const useSubscriptionMutations = () => {
|
|
const qc = useQueryClient();
|
|
const invalidate = () => {
|
|
qc.invalidateQueries({ queryKey: keys.subscriptions });
|
|
qc.invalidateQueries({ queryKey: keys.budget });
|
|
};
|
|
const setSubscription = useMutation({
|
|
mutationFn: (b: { matchKey: string; name?: string; active: boolean }) => apiSend("POST", "/subscriptions", b),
|
|
onSuccess: invalidate,
|
|
});
|
|
const createManualSub = useMutation({
|
|
mutationFn: (b: { name: string; amount: string; category?: string; nextDue?: string }) =>
|
|
apiSend("POST", "/manual-subscriptions", b, SubscriptionSchema),
|
|
onSuccess: invalidate,
|
|
});
|
|
const deleteManualSub = useMutation({
|
|
mutationFn: (id: number) => apiSend("DELETE", `/manual-subscriptions/${id}`),
|
|
onSuccess: invalidate,
|
|
});
|
|
return { setSubscription, createManualSub, deleteManualSub };
|
|
};
|
|
|
|
// --- savings goals ---
|
|
|
|
export const useSavingsGoalMutations = () => {
|
|
const qc = useQueryClient();
|
|
const invalidate = () => qc.invalidateQueries({ queryKey: keys.budget });
|
|
const post = useMutation({
|
|
mutationFn: (b: {
|
|
originalName?: string;
|
|
name: string;
|
|
target: string;
|
|
monthlyContribution?: string;
|
|
accountId?: number;
|
|
targetDate?: string;
|
|
}) => apiSend("POST", "/savings-goals", b, BudgetSchema),
|
|
onSuccess: invalidate,
|
|
});
|
|
const remove = useMutation({
|
|
mutationFn: (name: string) => apiSend("DELETE", `/savings-goals/${encodeURIComponent(name)}`, undefined, BudgetSchema),
|
|
onSuccess: invalidate,
|
|
});
|
|
return { post, delete: remove };
|
|
};
|