From b208b378458f10ed1934331d65ca6da33b9d84f6 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Sivakumar Date: Sun, 19 Jul 2026 16:35:49 +0530 Subject: [PATCH] fix: show real uploaded documents/profile data on verification review, use reference numbers The verification review page was rendering hardcoded mock documents and mock profile data instead of the real API response, so admins never saw what customers actually submitted. Wires it to the real documents/payload fields. Also replaces raw UUID displays with the new human-readable reference_number across verification, support, orders, and users. Co-Authored-By: Claude Sonnet 5 --- src/routes/admin/order.tsx | 7 +- src/routes/admin/support.tsx | 4 ++ src/routes/admin/users/index.tsx | 2 +- src/routes/admin/verification/[id].tsx | 91 ++++++++++++++++++++----- src/routes/admin/verification/index.tsx | 6 +- 5 files changed, 86 insertions(+), 24 deletions(-) diff --git a/src/routes/admin/order.tsx b/src/routes/admin/order.tsx index f0584fa..a108f87 100644 --- a/src/routes/admin/order.tsx +++ b/src/routes/admin/order.tsx @@ -19,6 +19,7 @@ function authHeaders(): Record { type Order = { id: string; + reference_number: string; payu_txnid?: string; amount_inr: number; tracecoins_credited: number; @@ -76,7 +77,7 @@ export default function OrderPage() { let data = orders() ?? []; if (q) { data = data.filter((o) => { - const txn = (o.payu_txnid || o.id || '').toLowerCase(); + const txn = (o.payu_txnid || o.reference_number || '').toLowerCase(); const email = (o.user_email || '').toLowerCase(); const pkg = (o.package_name || '').toLowerCase(); const status = (o.status || '').toLowerCase(); @@ -109,7 +110,7 @@ export default function OrderPage() { const exportCsv = () => { const headers = ['Order', 'User Email', 'Package', 'TraceCoins', 'Total', 'Status', 'Created']; const rows = filtered().map((item) => [ - item.payu_txnid || item.id, + item.payu_txnid || item.reference_number, item.user_email || '—', item.package_name || '—', item.tracecoins_credited ?? '—', @@ -224,7 +225,7 @@ export default function OrderPage() { {(item) => ( - {item.payu_txnid || item.id} + {item.payu_txnid || item.reference_number} {item.user_email || '—'} {item.package_name || '—'} diff --git a/src/routes/admin/support.tsx b/src/routes/admin/support.tsx index 59c64cc..6c14018 100644 --- a/src/routes/admin/support.tsx +++ b/src/routes/admin/support.tsx @@ -20,6 +20,7 @@ function authHeaders(contentType = false): Record { type SupportCase = { id: string; + reference_number: string; title: string; description: string; type: @@ -515,6 +516,9 @@ export default function SupportPage() {
{item.title}
+
+ {item.reference_number} +
{item.description}
diff --git a/src/routes/admin/users/index.tsx b/src/routes/admin/users/index.tsx index d0f376b..8c0dd65 100644 --- a/src/routes/admin/users/index.tsx +++ b/src/routes/admin/users/index.tsx @@ -119,7 +119,7 @@ export default function UsersManagementPage() { const mapped: ExternalUserRecord[] = (Array.isArray(data) ? data : []).map((u: any) => ({ id: u.id, - userCode: u.id.slice(0, 8).toUpperCase(), + userCode: u.reference_number || String(u.id).slice(0, 8).toUpperCase(), name: u.first_name || u.last_name ? `${u.first_name || ""} ${u.last_name || ""}`.trim() diff --git a/src/routes/admin/verification/[id].tsx b/src/routes/admin/verification/[id].tsx index 3b6f7af..714dd13 100644 --- a/src/routes/admin/verification/[id].tsx +++ b/src/routes/admin/verification/[id].tsx @@ -36,6 +36,17 @@ type DocRequestRow = { note: string; }; +type SubmittedDocument = { + type: string; + value: string; + status: string; +}; + +const formatFieldLabel = (key: string) => + String(key || '') + .replace(/_/g, ' ') + .replace(/\b\w/g, (c) => c.toUpperCase()); + type FieldRevision = { id: string; field: string; @@ -67,7 +78,10 @@ export default function VerificationReviewDetailPage() { } }); - const [docs, setDocs] = createSignal([ + // Catalog of document types that can be requested from the applicant (used by the + // "Request Documents" action form). This is not the applicant's actual uploaded + // documents — those come from `verif().documents` via the `uploadedDocs` memo below. + const [requestCatalog, setRequestCatalog] = createSignal([ { key: 'identity', title: 'Identity Proof', hint: 'Passport, DL or National ID', enabled: true, reason: 'Expired', note: 'Please upload a current valid ID with clear expiry date.' }, { key: 'address', title: 'Address Proof', hint: 'Utility bill or bank statement (last 3 months)', enabled: false, reason: 'Not Readable', note: '' }, { key: 'portfolio', title: 'Professional Portfolio', hint: 'Link or PDF showcasing previous work', enabled: false, reason: 'Insufficient', note: '' }, @@ -76,6 +90,30 @@ export default function VerificationReviewDetailPage() { { key: 'experience', title: 'Experience Certificate', hint: 'Employment letters from previous employers', enabled: false, reason: 'Missing', note: '' }, ]); + // Real customer-uploaded documents, from the fetched verification's `documents` field. + const uploadedDocs = createMemo(() => { + const list = verif()?.documents; + return Array.isArray(list) ? list : []; + }); + + // Real submitted profile data, from the fetched verification's `payload` field. + const payloadFullName = createMemo(() => { + const payload = verif()?.payload ?? {}; + const name = [payload.first_name, payload.last_name].filter(Boolean).join(' ').trim(); + return name || payload.company_name || payload.full_name || '—'; + }); + + const payloadEntries = createMemo>(() => { + const payload = verif()?.payload ?? {}; + const skipKeys = new Set(['first_name', 'last_name', 'company_name', 'full_name', 'documents']); + return Object.entries(payload).filter(([key, value]) => { + if (skipKeys.has(key)) return false; + if (value == null || value === '') return false; + if (typeof value === 'object') return false; + return true; + }); + }); + const [deadline, setDeadline] = createSignal('2026-04-08'); const [notifyUser, setNotifyUser] = createSignal(true); const [markActionRequired, setMarkActionRequired] = createSignal(true); @@ -111,10 +149,10 @@ export default function VerificationReviewDetailPage() { return 'none'; }); - const requestCount = createMemo(() => docs().filter((d) => d.enabled).length + revisionRows().length); + const requestCount = createMemo(() => requestCatalog().filter((d) => d.enabled).length + revisionRows().length); const updateDocRow = (key: string, patch: Partial) => { - setDocs((prev) => prev.map((row) => (row.key === key ? { ...row, ...patch } : row))); + setRequestCatalog((prev) => prev.map((row) => (row.key === key ? { ...row, ...patch } : row))); }; const openRequestDocuments = () => { @@ -136,7 +174,7 @@ export default function VerificationReviewDetailPage() { }; const sendDocumentRequest = async () => { - const selected = docs().filter((d) => d.enabled); + const selected = requestCatalog().filter((d) => d.enabled); if (selected.length === 0) { setActionMsg('Select at least one document to request.'); return; } const message = selected .map((d) => `${d.title} — ${d.reason}${d.note ? ': ' + d.note : ''}`) @@ -283,7 +321,7 @@ export default function VerificationReviewDetailPage() {
-

Review Submission: #{params.id}

+

Review Submission: #{verif()?.reference_number ?? params.id}

Applicant verification detail and action flow.

@@ -335,7 +373,7 @@ export default function VerificationReviewDetailPage() {

Submission Summary

- Sub ID#{params.id} + Sub ID#{verif()?.reference_number ?? params.id} Date Submitted2026-04-01 ReviewerAdmin User Pending Requests{requestCount()} @@ -369,7 +407,7 @@ export default function VerificationReviewDetailPage() {

Request Documents

Select missing or invalid documents and send one clear request.

- + {(row) => (
updateDocRow(row.key, { enabled: e.currentTarget.checked })} style="margin-top:4px;width:16px;height:16px;accent-color:#FF5E13" /> @@ -467,25 +505,42 @@ export default function VerificationReviewDetailPage() {

Profile Data

-

Full Name

Sarah Jenkins

-

Role

Professional Photographer

+

Full Name

{payloadFullName()}

+

Role

{verif()?.role_key ?? roleLabel()}

-

Visual storyteller with a passion for capturing authentic moments. Specializing in high-end wedding and lifestyle photography with focus on natural lighting and candid emotions.

+ 0} fallback={

No submitted profile data available.

}> +
+ + {([key, value]) => ( +
+

{formatFieldLabel(key)}

+

{String(value)}

+
+ )} +
+
+
- {['Document', 'Current State', 'Action'].map((h) => )} + {['Document', 'File', 'Status'].map((h) => )} - {(row) => ( - - - - - - )} + 0} fallback={}> + {(doc) => ( + + + + + + )} +
{h}
{h}
{row.title}

{row.hint}

{row.enabled ? 'Requested' : 'Received'}
No documents uploaded yet.
{formatFieldLabel(doc.type)} + —}> + View Document + + {formatFieldLabel(doc.status)}
diff --git a/src/routes/admin/verification/index.tsx b/src/routes/admin/verification/index.tsx index 0827601..f8609ec 100644 --- a/src/routes/admin/verification/index.tsx +++ b/src/routes/admin/verification/index.tsx @@ -6,6 +6,7 @@ type VerificationPriority = 'HIGH' | 'MEDIUM' | 'LOW'; type VerificationRow = { id: string; + reference_number: string; applicantName: string; requestType: | 'Profile Approval' @@ -185,6 +186,7 @@ export default function VerificationManagementPage() { return { id: v.id, + reference_number: v.reference_number || v.id, applicantName: v.user_name || 'Applicant', requestType: (isJob ? 'Job Approval' : (isRequirement ? 'Service Seeker Requirement' : 'Profile Approval')) as VerificationRow['requestType'], roleLabel: toTitle(v.role_key || 'User'), @@ -712,7 +714,7 @@ export default function VerificationManagementPage() { const p = priorityUi(row.priority); return ( - #{row.id} + #{row.reference_number} {row.requestType}
@@ -788,7 +790,7 @@ export default function VerificationManagementPage() {
-

#{selectedRow()!.id}

+

#{selectedRow()!.reference_number}

{selectedRow()!.requestType}