317 lines
7.9 KiB
TypeScript
317 lines
7.9 KiB
TypeScript
import {
|
|
keepPreviousData,
|
|
useMutation,
|
|
useQuery,
|
|
useQueryClient,
|
|
} from "@tanstack/react-query";
|
|
import {
|
|
type CreateNonPeriodicExpenseInput,
|
|
type CreatePeriodicExpenseInput,
|
|
createNonPeriodicExpense as createNonPeriodicExpenseApi,
|
|
createPeriodicExpense as createPeriodicExpenseApi,
|
|
deletePeriodicExpense as deletePeriodicExpenseApi,
|
|
fetchQuotes,
|
|
generateMonthlyExpense as generateMonthlyExpenseApi,
|
|
getDailyMinMax,
|
|
getDailyQuotes,
|
|
getExpenses,
|
|
generateTelegramCode,
|
|
getHistoricalMinMax,
|
|
getMonthlyPayedTotal,
|
|
getMonthlyTotals,
|
|
getPendingUpcomingExpenses,
|
|
getPeriodicExpenses,
|
|
getQuoteHistory,
|
|
getQuotes,
|
|
getTelegramStatus,
|
|
getTotalPending,
|
|
importExpenses,
|
|
importPeriodicExpenses,
|
|
type PayExpenseInput,
|
|
payExpense as payExpenseApi,
|
|
type UpdateExpenseInput,
|
|
updateExpense as updateExpenseApi,
|
|
updatePeriodicExpense as updatePeriodicExpenseApi,
|
|
} from "./api";
|
|
|
|
export const quoteKeys = {
|
|
all: ["quotes"] as const,
|
|
history: (type: string, startDate: string, endDate: string) =>
|
|
["quotes", type, "history", startDate, endDate] as const,
|
|
minMax: (type: string, startDate: string, endDate: string) =>
|
|
["quotes", type, "minMax", startDate, endDate] as const,
|
|
daily: (type: string, startDate: string, endDate: string) =>
|
|
["quotes", type, "daily", startDate, endDate] as const,
|
|
historicalMinMax: (type: string) =>
|
|
["quotes", type, "historicalMinMax"] as const,
|
|
};
|
|
|
|
export function useQuotes() {
|
|
return useQuery({
|
|
queryKey: quoteKeys.all,
|
|
queryFn: getQuotes,
|
|
staleTime: 30_000,
|
|
refetchInterval: 60_000,
|
|
});
|
|
}
|
|
|
|
export function useFetchQuotes() {
|
|
const queryClient = useQueryClient();
|
|
|
|
return useMutation({
|
|
mutationFn: fetchQuotes,
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: quoteKeys.all });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useQuoteHistory(
|
|
type: string,
|
|
startDate: string,
|
|
endDate: string,
|
|
) {
|
|
return useQuery({
|
|
queryKey: quoteKeys.history(type, startDate, endDate),
|
|
queryFn: () => getQuoteHistory(type, startDate, endDate),
|
|
staleTime: 30_000,
|
|
refetchInterval: 60_000,
|
|
});
|
|
}
|
|
|
|
export function useDailyMinMax(
|
|
type: string,
|
|
startDate: string,
|
|
endDate: string,
|
|
) {
|
|
return useQuery({
|
|
queryKey: quoteKeys.minMax(type, startDate, endDate),
|
|
queryFn: () => getDailyMinMax(type, startDate, endDate),
|
|
staleTime: 30_000,
|
|
refetchInterval: 60_000,
|
|
});
|
|
}
|
|
|
|
export function useDailyQuotes(
|
|
type: string,
|
|
startDate: string,
|
|
endDate: string,
|
|
) {
|
|
return useQuery({
|
|
queryKey: quoteKeys.daily(type, startDate, endDate),
|
|
queryFn: () => getDailyQuotes(type, startDate, endDate),
|
|
staleTime: 30_000,
|
|
refetchInterval: 60_000,
|
|
});
|
|
}
|
|
|
|
export function useHistoricalMinMax(type: string) {
|
|
return useQuery({
|
|
queryKey: quoteKeys.historicalMinMax(type),
|
|
queryFn: () => getHistoricalMinMax(type),
|
|
staleTime: 30_000,
|
|
});
|
|
}
|
|
|
|
// Expenses
|
|
|
|
export const expenseKeys = {
|
|
periodic: ["periodic-expenses"] as const,
|
|
all: ["expenses"] as const,
|
|
byFilters: (
|
|
status: string,
|
|
page: number,
|
|
pageSize: number,
|
|
periodicExpenseId?: number,
|
|
search?: string,
|
|
) => ["expenses", status, page, pageSize, periodicExpenseId, search] as const,
|
|
monthlyTotal: (year: number, month: number) =>
|
|
["expenses", "monthly-total", year, month] as const,
|
|
monthlyTotals: (year: number, month: number) =>
|
|
["expenses", "totals", year, month] as const,
|
|
totalPending: ["expenses", "pending-total"] as const,
|
|
pendingUpcoming: ["expenses", "pending-upcoming"] as const,
|
|
};
|
|
|
|
export function usePeriodicExpenses() {
|
|
return useQuery({
|
|
queryKey: expenseKeys.periodic,
|
|
queryFn: getPeriodicExpenses,
|
|
});
|
|
}
|
|
|
|
export function useCreatePeriodicExpense() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (data: CreatePeriodicExpenseInput) =>
|
|
createPeriodicExpenseApi(data),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: expenseKeys.periodic });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useUpdatePeriodicExpense() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: ({
|
|
id,
|
|
data,
|
|
}: {
|
|
id: number;
|
|
data: CreatePeriodicExpenseInput;
|
|
}) => updatePeriodicExpenseApi(id, data),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: expenseKeys.periodic });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useDeletePeriodicExpense() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (id: number) => deletePeriodicExpenseApi(id),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: expenseKeys.periodic });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useGenerateMonthlyExpense() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (id: number) => generateMonthlyExpenseApi(id),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: expenseKeys.all });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useExpenses(
|
|
status: string,
|
|
page: number = 1,
|
|
pageSize: number = 10,
|
|
periodicExpenseId?: number,
|
|
search?: string,
|
|
) {
|
|
return useQuery({
|
|
queryKey: expenseKeys.byFilters(
|
|
status,
|
|
page,
|
|
pageSize,
|
|
periodicExpenseId,
|
|
search,
|
|
),
|
|
placeholderData: keepPreviousData,
|
|
queryFn: () =>
|
|
getExpenses(
|
|
status === "all" ? undefined : status,
|
|
page,
|
|
pageSize,
|
|
periodicExpenseId,
|
|
search,
|
|
),
|
|
});
|
|
}
|
|
|
|
export function useMonthlyTotals(year: number, month: number) {
|
|
return useQuery({
|
|
queryKey: expenseKeys.monthlyTotals(year, month),
|
|
queryFn: () => getMonthlyTotals(year, month),
|
|
});
|
|
}
|
|
|
|
export function usePendingUpcomingExpenses() {
|
|
return useQuery({
|
|
queryKey: expenseKeys.pendingUpcoming,
|
|
queryFn: getPendingUpcomingExpenses,
|
|
});
|
|
}
|
|
|
|
export function useTotalPending() {
|
|
return useQuery({
|
|
queryKey: expenseKeys.totalPending,
|
|
queryFn: getTotalPending,
|
|
});
|
|
}
|
|
|
|
export function useMonthlyPayedTotal(year: number, month: number) {
|
|
return useQuery({
|
|
queryKey: expenseKeys.monthlyTotal(year, month),
|
|
queryFn: () => getMonthlyPayedTotal(year, month),
|
|
});
|
|
}
|
|
|
|
export function useCreateNonPeriodicExpense() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (data: CreateNonPeriodicExpenseInput) =>
|
|
createNonPeriodicExpenseApi(data),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: expenseKeys.all });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useImportExpenses() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (file: File) => importExpenses(file),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: expenseKeys.all });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useImportPeriodicExpenses() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: (file: File) => importPeriodicExpenses(file),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: expenseKeys.periodic });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function usePayExpense() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: ({ id, data }: { id: number; data: PayExpenseInput }) =>
|
|
payExpenseApi(id, data),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: expenseKeys.all });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useUpdateExpense() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: ({ id, data }: { id: number; data: UpdateExpenseInput }) =>
|
|
updateExpenseApi(id, data),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: expenseKeys.all });
|
|
},
|
|
});
|
|
}
|
|
|
|
// Telegram
|
|
|
|
export function useTelegramStatus() {
|
|
return useQuery({
|
|
queryKey: ["telegram", "status"],
|
|
queryFn: getTelegramStatus,
|
|
staleTime: 30_000,
|
|
});
|
|
}
|
|
|
|
export function useGenerateTelegramCode() {
|
|
const queryClient = useQueryClient();
|
|
return useMutation({
|
|
mutationFn: generateTelegramCode,
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ["telegram", "status"] });
|
|
},
|
|
});
|
|
}
|