feat(defter): hafta seçici ve hızlı harcama giriş formu
- /defter: önceki/sonraki/bu hafta, haftanın harcanan/bütçe toplamı - Form: tutar, 4 grup düğmesi, kategori ve ödeme türü seçimi, tarih, açıklama - Son seçimler bu cihazda hatırlanır; sunucu hataları ilgili alana düşer Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,78 @@
|
||||
import { ComingSoon, PageHeader } from '@/components/page'
|
||||
import { useState } from 'react'
|
||||
import { useSearchParams } from 'react-router'
|
||||
import { PageError, PageHeader, PageLoading } from '@/components/page'
|
||||
import { NoPeriodCard } from '@/features/period-wizard/no-period-card'
|
||||
import { Section } from '@/features/planning/plan-read'
|
||||
import { useCategories, usePaymentMethods } from '@/lib/catalog'
|
||||
import { toIsoDate } from '@/lib/format'
|
||||
import { parseWeekParam, weekIndexFor } from '@/lib/ledger'
|
||||
import { useBudget, useCurrentPeriod } from '@/lib/periods'
|
||||
import { t } from '@/lib/strings'
|
||||
import type { Period } from '@/types/Period'
|
||||
import { EntryForm } from './entry-form'
|
||||
import { WeekPicker } from './week-picker'
|
||||
|
||||
export function LedgerPage() {
|
||||
const current = useCurrentPeriod()
|
||||
return (
|
||||
<>
|
||||
<PageHeader title={t.pages.ledger.title} description={t.pages.ledger.description} />
|
||||
<ComingSoon when="Faz 5'te" />
|
||||
{current.isPending ? (
|
||||
<PageLoading />
|
||||
) : current.isError ? (
|
||||
<PageError message={current.error.message} onRetry={current.refetch} />
|
||||
) : current.data ? (
|
||||
<LedgerView period={current.data} />
|
||||
) : (
|
||||
<NoPeriodCard />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/** Hafta adreste tutulur (`?hafta=2`): yenileyince / geri gelince aynı hafta açılır. */
|
||||
function LedgerView({ period }: { period: Period }) {
|
||||
const [params, setParams] = useSearchParams()
|
||||
const [today] = useState(() => toIsoDate(new Date()))
|
||||
const inPeriod = today >= period.start_date && today <= period.last_date
|
||||
const todayIndex = inPeriod ? weekIndexFor(period.weeks, today) : null
|
||||
const index =
|
||||
parseWeekParam(params.get('hafta'), period.weeks.length) ?? weekIndexFor(period.weeks, today)
|
||||
const week = period.weeks[index - 1]
|
||||
|
||||
const budget = useBudget(period.id)
|
||||
const categories = useCategories()
|
||||
const methods = usePaymentMethods()
|
||||
|
||||
const goTo = (n: number) =>
|
||||
setParams(n === todayIndex ? {} : { hafta: String(n) }, { replace: true })
|
||||
|
||||
const failed = [categories, methods].find((q) => q.isError)
|
||||
return (
|
||||
<div className="mx-auto max-w-3xl space-y-4">
|
||||
<WeekPicker
|
||||
weeks={period.weeks}
|
||||
index={index}
|
||||
todayIndex={todayIndex}
|
||||
budget={budget.data}
|
||||
onChange={goTo}
|
||||
/>
|
||||
<Section title={t.ledger.formTitle}>
|
||||
{failed?.error ? (
|
||||
<PageError message={failed.error.message} onRetry={failed.refetch} />
|
||||
) : !categories.data || !methods.data ? (
|
||||
<PageLoading />
|
||||
) : (
|
||||
<EntryForm
|
||||
period={period}
|
||||
week={week}
|
||||
today={today}
|
||||
categories={categories.data}
|
||||
methods={methods.data}
|
||||
onSaved={(date) => goTo(weekIndexFor(period.weeks, date))}
|
||||
/>
|
||||
)}
|
||||
</Section>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user