feat(ui): dashboard ana grafiği ve rapor sayfaları

- dashboard: periyot seçici ve kümülatif/dönemsel görünüm, tablo; günlük plan kartı sadeleşti
- /raporlar özet ve kategori, trend, kişi/hesap, bütçe sayfaları; ay seçici ve CSV indirme

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-07 00:29:25 +03:00
parent bc2a8a3bde
commit 29d7b29cfa
19 changed files with 1488 additions and 108 deletions
@@ -0,0 +1,61 @@
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { PeopleView } from "@/features/reports/components/people-view";
import {
CsvButton,
ToolsEnd,
MonthNav,
ReportFrame,
monthLabel,
} from "@/features/reports/components/report-frame";
import { getPeopleAccountsReport } from "@/features/reports/service";
import { tr } from "@/i18n/tr";
import { requireActiveHousehold } from "@/lib/dal";
import { budgetMonthSchema } from "@/shared/schemas/budget";
const t = tr.reports.people;
export const metadata: Metadata = { title: t.title };
/** /raporlar/kisi-hesap?ay=YYYY-MM — kişi bazlı harcama ve hesap bazlı hareket. */
export default async function PeopleReportPage({
searchParams,
}: PageProps<"/raporlar/kisi-hesap">) {
const { user, household } = await requireActiveHousehold("viewer");
const ay = budgetMonthSchema.safeParse((await searchParams).ay);
const data = await getPeopleAccountsReport(
user.id,
household.id,
ay.success ? ay.data : undefined,
);
if (!data) notFound();
return (
<ReportFrame
title={t.title}
description={t.description(monthLabel(data.month))}
tools={
<>
<MonthNav
month={data.month}
currentMonth={data.currentMonth}
path="/raporlar/kisi-hesap"
/>
<ToolsEnd>
<CsvButton
href={`/raporlar/kisi-hesap/csv?ay=${data.month}&tablo=kisi`}
label={t.csvPeople}
/>
<CsvButton
href={`/raporlar/kisi-hesap/csv?ay=${data.month}&tablo=hesap`}
label={t.csvAccounts}
/>
</ToolsEnd>
</>
}
>
{data.includesHidden ? (
<p className="text-xs text-muted-foreground">{tr.reports.includesHidden}</p>
) : null}
<PeopleView data={data} />
</ReportFrame>
);
}