import Link from "next/link"; import { Plus, Undo2, Wallet } from "lucide-react"; import { prisma } from "@/lib/prisma"; import { requireUser } from "@/lib/rbac"; import { formatDateID, formatIDR } from "@/lib/utils"; import { PageHeader } from "@/components/ui/page-header"; import { Button } from "@/components/ui/button"; import { Card } from "@/components/ui/card"; import { Avatar } from "@/components/ui/avatar"; import { EmptyState } from "@/components/ui/empty-state"; import { MethodChip, PaymentStatusBadge } from "@/components/students/badges"; import { refundPaymentAction } from "./actions"; export const metadata = { title: "Pembayaran — Kodeva" }; type SP = Promise<{ studentId?: string; method?: string; status?: string }>; export default async function PaymentsPage({ searchParams }: { searchParams: SP }) { const user = await requireUser(); const sp = await searchParams; const payments = await prisma.payment.findMany({ where: { ...(sp.studentId ? { studentId: sp.studentId } : {}), ...(sp.method ? { method: sp.method } : {}), ...(sp.status ? { status: sp.status } : {}), }, include: { student: true, class: true }, orderBy: { paidAt: "desc" }, }); const totalPaid = payments.filter((p) => p.status === "PAID").reduce((a, p) => a + p.amount, 0); return (
} /> {payments.length === 0 ? ( } title="Belum ada pembayaran" description="Catat pembayaran prorata pertama siswa." /> ) : (
{payments.map((p) => ( ))}
Invoice Siswa Kelas Detail Nominal Metode Status
{p.invoiceNumber}

{formatDateID(p.paidAt)}

{p.student.fullName} {p.class.name} {p.meetingsPaid} × {formatIDR(p.pricePerMeeting)} {formatIDR(p.amount)} {user.role === "ADMIN" && p.status !== "REFUNDED" ? (
) : ( - )}
{/* mobile cards */}
{payments.map((p) => (
{p.invoiceNumber}

{p.student.fullName}

{p.class.name}

{formatIDR(p.amount)}

))}
)}
); }