"use client"; import { useState, useTransition } from "react"; import { Banknote, Check, ChevronDown, ChevronUp, Loader2, Plus, RotateCcw, Trash2, } from "lucide-react"; import { toast } from "sonner"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { deleteLoanAction, payInstallmentAction, unpayInstallmentAction, } from "@/lib/appwrite/loan-actions"; import { formatDate, formatTRY } from "@/lib/format"; import { cn } from "@/lib/utils"; import { LoanFormSheet } from "./loan-form-sheet"; import { type BankAccountOption, type InstallmentRow, LOAN_STATUS_LABEL, LOAN_TYPE_LABEL, type LoanRow, } from "./types"; type Props = { loans: LoanRow[]; installments: InstallmentRow[]; bankAccounts: BankAccountOption[]; }; export function LoansClient({ loans, installments, bankAccounts }: Props) { const [formOpen, setFormOpen] = useState(false); const [expanded, setExpanded] = useState(null); const [deleting, setDeleting] = useState(null); const [busy, startTransition] = useTransition(); const totalPrincipal = loans .filter((l) => l.status === "active") .reduce((s, l) => s + l.principal, 0); const totalRemaining = loans .filter((l) => l.status === "active") .reduce((s, l) => s + (l.totalAmount - l.paidAmount), 0); const installmentsByLoan = new Map(); for (const i of installments) { const arr = installmentsByLoan.get(i.loanId) ?? []; arr.push(i); installmentsByLoan.set(i.loanId, arr); } const togglePay = (inst: InstallmentRow) => { startTransition(async () => { const fd = new FormData(); fd.set("id", inst.id); const result = inst.paid ? await unpayInstallmentAction(fd) : await payInstallmentAction(fd); if (result.ok) { toast.success(inst.paid ? "Taksit ödenmedi olarak işaretlendi." : "Taksit ödendi olarak işaretlendi."); } else { toast.error(result.error ?? "İşlem başarısız."); } }); }; const handleDelete = () => { if (!deleting) return; startTransition(async () => { const fd = new FormData(); fd.set("id", deleting.id); const result = await deleteLoanAction(fd); if (result.ok) { toast.success("Kredi silindi."); setDeleting(null); } else { toast.error(result.error ?? "Silme başarısız."); } }); }; return (

Aktif kredi sayısı

{loans.filter((l) => l.status === "active").length}

Toplam çekilen

{formatTRY(totalPrincipal)}

Kalan ödeme

{formatTRY(totalRemaining)}

{loans.length === 0 ? (

Henüz kredi tanımlanmamış.

) : (
{loans.map((loan) => { const isOpen = expanded === loan.id; const items = installmentsByLoan.get(loan.id) ?? []; const progressPct = loan.totalAmount > 0 ? (loan.paidAmount / loan.totalAmount) * 100 : 0; return (

{loan.bankName}

· {loan.loanName} {LOAN_TYPE_LABEL[loan.loanType]} {LOAN_STATUS_LABEL[loan.status]}
{loan.bankAccountLabel && (

Hesap: {loan.bankAccountLabel}

)}
{loan.remainingCount === 0 ? "Tüm taksitler ödendi" : `${loan.remainingCount} taksit kaldı`} {formatTRY(loan.paidAmount)} / {formatTRY(loan.totalAmount)}
{isOpen && (
# Vade Anapara Faiz Toplam Durum {items.map((it) => { const overdue = !it.paid && new Date(it.dueDate) < new Date(); return ( {it.installmentNo} {formatDate(it.dueDate)} {formatTRY(it.principalPart)} {formatTRY(it.interestPart)} {formatTRY(it.amount)} ); })}
)} ); })}
)} !v && setDeleting(null)}> Krediyi sil {deleting?.bankName} — {deleting?.loanName} ve tüm taksitleri silinecek. Bu işlem geri alınamaz.
); } function Stat({ label, value }: { label: string; value: string }) { return (

{label}

{value}

); }