feat(ui): aynî kayıt kartları, ödeme ve birikim diyalogları, fiyat tablosu sayfası

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-05 12:37:48 +03:00
parent 9781cd9ed2
commit 3cd8d98324
9 changed files with 1119 additions and 7 deletions
@@ -9,6 +9,8 @@ import { Card, CardContent, CardDescription, CardHeader } from "@/components/ui/
import { tr } from "@/i18n/tr";
import { cn } from "@/lib/utils";
import { formatDate, formatMoney } from "@/shared/format";
import { InKindSection } from "@/features/in-kind/components/in-kind-section";
import type { InKindView } from "@/features/in-kind/service";
import type { ContactStatement } from "../service";
import { ContactEntryDialog, ContactFormDialog, type EntryMode } from "./contact-dialogs";
import { ContactBalance, DueBadge } from "./contacts-view";
@@ -31,7 +33,13 @@ function Delta({ minor }: { minor: number }) {
}
/** Cari ekstresi: hareketler (yeniden eskiye) ve yürüyen bakiye (+ bana borçlu, − ben borçluyum). */
export function ContactStatementView({ data }: { data: ContactStatement }) {
export function ContactStatementView({
data,
inKind,
}: {
data: ContactStatement;
inKind: InKindView[];
}) {
const c = data.contact;
const [entry, setEntry] = useState<EntryMode | null>(null);
const [editing, setEditing] = useState(false);
@@ -90,6 +98,8 @@ export function ContactStatementView({ data }: { data: ContactStatement }) {
</CardContent>
</Card>
<InKindSection contactId={c.id} items={inKind} canWrite={canWrite} />
<h2 className="text-base font-medium">{t.statement}</h2>
{data.rows.length === 0 && c.openingBalanceMinor === 0 ? (
<Card>
@@ -60,7 +60,16 @@ export function DueBadge({ contact }: { contact: ContactView }) {
return <Badge variant="outline">{t.due.on(d(contact.dueDate))}</Badge>;
}
export function ContactsView({ data, canWrite }: { data: ContactList; canWrite: boolean }) {
export function ContactsView({
data,
inKind,
canWrite,
}: {
data: ContactList;
/** Açık aynî kayıtlar (cari kimliği → yön ve kalan miktar). */
inKind: Record<string, { direction: "debt" | "receivable"; label: string }[]>;
canWrite: boolean;
}) {
const [form, setForm] = useState<{ contact: ContactView | null } | null>(null);
const [entry, setEntry] = useState<EntryMode | null>(null);
const [archivedOpen, setArchivedOpen] = useState(false);
@@ -94,6 +103,11 @@ export function ContactsView({ data, canWrite }: { data: ContactList; canWrite:
<span>{t.relations[c.relation]}</span>
{c.lastActivity ? <span>· {t.lastActivity(d(c.lastActivity))}</span> : null}
<DueBadge contact={c} />
{(inKind[c.id] ?? []).map((x, i) => (
<Badge key={i} variant={x.direction === "debt" ? "destructive" : "secondary"}>
{x.label}
</Badge>
))}
</span>
</div>
<ContactBalance minor={c.balanceMinor} />