"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { reopenVerificationAction, requestReuploadAction, reviewVerificationAction, } from "@/features/organizer/actions"; const REUPLOAD_FIELD_LABELS: { value: string; label: string }[] = [ { value: "ktpImage", label: "Foto KTP" }, { value: "liveness", label: "Foto liveness (pegang kertas SETRIP)" }, { value: "nik", label: "NIK" }, { value: "bankInfo", label: "Info rekening" }, { value: "address", label: "Alamat" }, ]; type Verification = { id: string; fullName: string; /** NIK plaintext, sudah di-decrypt di server sebelum sampai ke komponen ini. */ nik: string; birthDate: Date; address: string; bankName: string; bankAccountNumber: string; bankAccountName: string; status: "PENDING" | "APPROVED" | "REJECTED"; rejectionReason: string | null; reviewedAt: Date | null; createdAt: Date; user: { id: string; name: string; email: string }; reviewedBy: { id: string; name: string; email: string } | null; }; function formatDate(d: Date): string { return new Date(d).toLocaleString("id-ID", { day: "2-digit", month: "short", year: "numeric", }); } export function ReviewCard({ verification }: { verification: Verification }) { const router = useRouter(); const [showReject, setShowReject] = useState(false); const [showReopen, setShowReopen] = useState(false); const [showReupload, setShowReupload] = useState(false); const [rejectionReason, setRejectionReason] = useState(""); const [reopenNote, setReopenNote] = useState(""); const [reuploadNote, setReuploadNote] = useState(""); const [reuploadFields, setReuploadFields] = useState([]); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); function toggleReuploadField(value: string) { setReuploadFields((prev) => prev.includes(value) ? prev.filter((v) => v !== value) : [...prev, value] ); } async function requestReupload() { setError(""); setLoading(true); const result = await requestReuploadAction( verification.id, reuploadFields, reuploadNote ); setLoading(false); if ("error" in result && result.error) { setError(result.error); return; } setShowReupload(false); setReuploadFields([]); setReuploadNote(""); router.refresh(); } async function decide(decision: "APPROVED" | "REJECTED") { setError(""); setLoading(true); const fd = new FormData(); fd.set("verificationId", verification.id); fd.set("decision", decision); if (decision === "REJECTED") fd.set("rejectionReason", rejectionReason); const result = await reviewVerificationAction(fd); setLoading(false); if (result.error) { setError(result.error); return; } setShowReject(false); setRejectionReason(""); router.refresh(); } async function reopen() { setError(""); setLoading(true); const result = await reopenVerificationAction(verification.id, reopenNote); setLoading(false); if ("error" in result && result.error) { setError(result.error); return; } setShowReopen(false); setReopenNote(""); router.refresh(); } return (

{verification.user.name}

{verification.user.email} ยท diajukan{" "} {formatDate(verification.createdAt)}

{verification.status === "REJECTED" && verification.rejectionReason && (
Alasan ditolak:{" "} {verification.rejectionReason}
)} {verification.reviewedBy && verification.reviewedAt && (

Diproses oleh {verification.reviewedBy.name} pada{" "} {formatDate(verification.reviewedAt)}

)} {verification.status === "REJECTED" && (
{error && (
{error}
)} {!showReopen ? ( ) : (