Files
kakeibo/frontend/src/features/debt/page.tsx
T

108 lines
3.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
)}
</>
)
}