feat(borç): borç takibi ekranları (Panel kartı, /borc, /taksitler)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import { lazy, Suspense, useState } from 'react'
|
||||
import { CreditCard, Landmark } from 'lucide-react'
|
||||
import { Link } from 'react-router'
|
||||
import { paths } from '@/components/layout/nav-items'
|
||||
import { PageError, PageHeader, PageLoading } from '@/components/page'
|
||||
import { Skeleton } from '@/components/skeleton'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Section } from '@/features/planning/plan-read'
|
||||
import { useDebt } from '@/lib/debt'
|
||||
import { t } from '@/lib/strings'
|
||||
import type { DebtSnapshot } from '@/types/DebtSnapshot'
|
||||
import { DebtCard } from './debt-card'
|
||||
import { History } from './history'
|
||||
import { ImportSection } from './import-section'
|
||||
import { SnapshotForm } from './snapshot-form'
|
||||
import { TargetsEditor } from './targets-editor'
|
||||
|
||||
const DebtChart = lazy(() => import('./debt-chart'))
|
||||
const s = t.debt
|
||||
|
||||
/** /borc: toplam borç, gerçek + hedef grafiği, ölçümler, yeni ölçüm, yol haritası, içe aktarma */
|
||||
export function DebtPage() {
|
||||
const debt = useDebt()
|
||||
const [editing, setEditing] = useState<DebtSnapshot | null>(null)
|
||||
const d = debt.data
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
title={s.title}
|
||||
description={s.description}
|
||||
actions={
|
||||
<Button asChild variant="outline">
|
||||
<Link to={paths.installments}>
|
||||
<CreditCard aria-hidden />
|
||||
{s.toInstallments}
|
||||
</Link>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
{debt.isError ? (
|
||||
<PageError message={debt.error.message} onRetry={debt.refetch} />
|
||||
) : !d ? (
|
||||
<PageLoading />
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
{d.latest ? (
|
||||
<DebtCard debt={d} />
|
||||
) : (
|
||||
<section className="flex flex-col items-center gap-3 rounded-2xl border bg-card p-8 text-center">
|
||||
<div className="grid size-14 place-items-center rounded-full bg-primary/10 text-primary">
|
||||
<Landmark className="size-7" aria-hidden />
|
||||
</div>
|
||||
<h2 className="text-lg font-semibold">{s.emptyTitle}</h2>
|
||||
<p className="max-w-md text-muted-foreground">{s.emptyText}</p>
|
||||
</section>
|
||||
)}
|
||||
{d.snapshots.length > 0 && (
|
||||
<Section title={s.chartTitle}>
|
||||
<Suspense fallback={<Skeleton className="h-72" />}>
|
||||
<DebtChart debt={d} />
|
||||
</Suspense>
|
||||
</Section>
|
||||
)}
|
||||
{d.snapshots.length > 0 && (
|
||||
<Section title={s.historyTitle}>
|
||||
<History
|
||||
snapshots={d.snapshots}
|
||||
onEdit={(sn) => {
|
||||
setEditing(sn)
|
||||
document
|
||||
.getElementById('debt-form')
|
||||
?.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||||
}}
|
||||
/>
|
||||
</Section>
|
||||
)}
|
||||
<div className="grid items-start gap-4 lg:grid-cols-2">
|
||||
<div id="debt-form" className="scroll-mt-4">
|
||||
<Section title={editing ? s.formEditTitle : s.formTitle}>
|
||||
<SnapshotForm
|
||||
// Taksit planları değişince (ör. içe aktarma) kalan taksit önerisi yeniden dolsun
|
||||
key={
|
||||
editing?.id ?? `new-${d.installments.map((p) => `${p.id}:${p.version}`).join()}`
|
||||
}
|
||||
plans={d.installments}
|
||||
editing={editing ?? undefined}
|
||||
onDone={() => setEditing(null)}
|
||||
/>
|
||||
</Section>
|
||||
</div>
|
||||
<Section title={s.targetsTitle}>
|
||||
<TargetsEditor
|
||||
key={d.targets.map((x) => `${x.month}:${x.closing_target}`).join()}
|
||||
targets={d.targets}
|
||||
thisMonth={d.this_month}
|
||||
/>
|
||||
</Section>
|
||||
<Section title={s.importTitle}>
|
||||
<ImportSection />
|
||||
</Section>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user