feat(panel): özet kartları, anlık durum ve hızlı harcama ekleme
- Gelir, sabit gider, toplam birikim, devreden borç kartları - Anlık durum: kalan harcanabilir ve günlük harcama önerisi - Grup planlanan/gerçekleşen (Haftalık/Aylık) - "Harcama Ekle": masaüstünde başlıkta, mobilde yüzen düğme - Yükleniyor iskeleti, boş durumlar, açık dönem yokken son dönem özeti Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,13 @@
|
||||
* Kayıt değişince dönemin tüm sorguları yenilenir (`queryKeys.period(id)` öneki):
|
||||
* liste, özet (`spent_total`, `remaining`) ve bütçe (`spent`) birlikte güncellenir.
|
||||
*/
|
||||
import { keepPreviousData, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import {
|
||||
keepPreviousData,
|
||||
useMutation,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
type QueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
import type { Entry } from '@/types/Entry'
|
||||
import type { EntryCreateRequest } from '@/types/EntryCreateRequest'
|
||||
import type { EntryUpdateRequest } from '@/types/EntryUpdateRequest'
|
||||
@@ -12,6 +18,14 @@ import { api } from './api'
|
||||
import { queryKeys } from './query'
|
||||
|
||||
/** Bir tarih aralığının kayıtları (ikisi de dahil); en yeni başta */
|
||||
/** Kayıt değişince: dönemin tüm verileri + Panel istatistikleri (harcanan) */
|
||||
function refresh(qc: QueryClient, periodId: string) {
|
||||
return Promise.all([
|
||||
qc.invalidateQueries({ queryKey: queryKeys.period(periodId) }),
|
||||
qc.invalidateQueries({ queryKey: queryKeys.stats }),
|
||||
])
|
||||
}
|
||||
|
||||
export function useEntries(periodId: string, range: { from: string; to: string }) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.entries(periodId, range),
|
||||
@@ -26,7 +40,7 @@ export function useCreateEntry(periodId: string) {
|
||||
const qc = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (body: EntryCreateRequest) => api.post<Entry>(`/periods/${periodId}/entries`, body),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: queryKeys.period(periodId) }),
|
||||
onSuccess: () => refresh(qc, periodId),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -36,7 +50,7 @@ export function useUpdateEntry(periodId: string) {
|
||||
return useMutation({
|
||||
mutationFn: ({ id, ...body }: EntryUpdateRequest & { id: string }) =>
|
||||
api.patch<Entry>(`/entries/${id}`, body),
|
||||
onSettled: () => qc.invalidateQueries({ queryKey: queryKeys.period(periodId) }),
|
||||
onSettled: () => refresh(qc, periodId),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -45,7 +59,7 @@ export function useDeleteEntry(periodId: string) {
|
||||
const qc = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (id: string) => api.delete(`/entries/${id}`),
|
||||
onSettled: () => qc.invalidateQueries({ queryKey: queryKeys.period(periodId) }),
|
||||
onSettled: () => refresh(qc, periodId),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,6 +67,6 @@ export function useRestoreEntry(periodId: string) {
|
||||
const qc = useQueryClient()
|
||||
return useMutation({
|
||||
mutationFn: (id: string) => api.post<Entry>(`/entries/${id}/restore`),
|
||||
onSettled: () => qc.invalidateQueries({ queryKey: queryKeys.period(periodId) }),
|
||||
onSettled: () => refresh(qc, periodId),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user