fix(profile): persist uploaded document URLs and fill in missing doc config
All checks were successful
build-and-release / build (push) Successful in 1m47s
All checks were successful
build-and-release / build (push) Successful in 1m47s
Uploaded document URLs lived only in a client-side signal and were never included in the Save or Submit-for-Verification payloads (the latter sent a document_urls field the backend silently ignored), so every submitted verification case ended up with no attached documents for every role except COMPANY. Now merges doc URLs into profile_data on save/submit and repopulates them from the saved profile on reload. Also adds the missing DOC_FIELDS entries for Developer, Video Editor, Graphic Designer, Social Media Manager, and UGC Content Creator, and makes the verification-status Documents tab role-aware instead of showing 3 hardcoded generic labels. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
629a5eeebc
commit
5290e7c70f
3 changed files with 126 additions and 21 deletions
|
|
@ -661,6 +661,17 @@ export default function ProfilePage(props: Props) {
|
|||
flat[k] = String(v ?? "");
|
||||
}
|
||||
setForm(flat);
|
||||
|
||||
// Documents are saved into the same profile_data blob as basic fields —
|
||||
// pull out whichever doc keys this role expects so previously uploaded
|
||||
// files show as already-attached instead of appearing lost on reload.
|
||||
const docKeys = getDocFields(props.roleKey).map((d) => d.key);
|
||||
const savedDocs: Record<string, string> = {};
|
||||
for (const key of docKeys) {
|
||||
const val = data.profile_data[key];
|
||||
if (typeof val === "string" && val) savedDocs[key] = val;
|
||||
}
|
||||
if (Object.keys(savedDocs).length > 0) setDocUrls((prev) => ({ ...savedDocs, ...prev }));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -816,7 +827,7 @@ export default function ProfilePage(props: Props) {
|
|||
try {
|
||||
const { data, status } = await request("/api/profile", {
|
||||
method: "PATCH",
|
||||
body: { roleKey: props.roleKey, profile_data: form() },
|
||||
body: { roleKey: props.roleKey, profile_data: { ...form(), ...docUrls() } },
|
||||
});
|
||||
if (status === 200) setSaveMsg("Saved successfully.");
|
||||
else setSaveMsg((data && (data.error || data.message)) || "Failed to save. Please try again.");
|
||||
|
|
@ -847,7 +858,7 @@ export default function ProfilePage(props: Props) {
|
|||
try {
|
||||
const { data, status } = await request("/api/profile/submit-for-verification", {
|
||||
method: "POST",
|
||||
body: { roleKey: props.roleKey, document_urls: docUrls() },
|
||||
body: { roleKey: props.roleKey, profile_data: { ...form(), ...docUrls() } },
|
||||
});
|
||||
if (status === 200) {
|
||||
setVerificationStatus("PENDING");
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@
|
|||
* REVISION_REQUESTED, APPROVED, REJECTED.
|
||||
* Tabs: approval status, documents, activity
|
||||
*/
|
||||
import { For, Show, createSignal, onMount } from 'solid-js';
|
||||
import { For, Show, createMemo, createSignal, onMount } from 'solid-js';
|
||||
import { ShieldCheck, FileText, Activity } from 'lucide-solid';
|
||||
import { CARD, BTN_ORANGE, BTN_GHOST } from '~/components/DashboardShell';
|
||||
import { getDocFields } from '~/lib/profile-fields-config';
|
||||
|
||||
const API = '/api/gateway';
|
||||
const NAVY = '#0D0D2A';
|
||||
|
|
@ -159,6 +160,7 @@ export default function VerificationStatusPage(props: Props) {
|
|||
|
||||
const cfg = () => STATUS_CONFIG[status()] ?? STATUS_CONFIG.NOT_SUBMITTED;
|
||||
const currentStep = () => stepIndex(status());
|
||||
const docFields = createMemo(() => getDocFields(props.roleKey));
|
||||
const canResubmit = () => ['DOCUMENTS_REQUESTED', 'REVISION_REQUESTED', 'REJECTED'].includes(status());
|
||||
|
||||
const handleResubmit = async () => {
|
||||
|
|
@ -422,24 +424,16 @@ export default function VerificationStatusPage(props: Props) {
|
|||
</Show>
|
||||
<Show when={status() !== 'NOT_SUBMITTED'}>
|
||||
<div style={{ display: 'flex', 'flex-direction': 'column', gap: '8px' }}>
|
||||
<For each={docFields()}>
|
||||
{(doc) => (
|
||||
<div style={{ border: '1px solid #E5E7EB', 'border-radius': '10px', padding: '12px', background: '#FCFCFD' }}>
|
||||
<p style={{ margin: '0', 'font-size': '13px', 'font-weight': '600', color: '#111827' }}>Identity Proof</p>
|
||||
<p style={{ margin: '4px 0 0', 'font-size': '12px', color: '#6B7280' }}>
|
||||
{status() === 'APPROVED' ? '✓ Verified' : status() === 'REJECTED' ? '✕ Rejected' : '◌ Pending review'}
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ border: '1px solid #E5E7EB', 'border-radius': '10px', padding: '12px', background: '#FCFCFD' }}>
|
||||
<p style={{ margin: '0', 'font-size': '13px', 'font-weight': '600', color: '#111827' }}>Address Proof</p>
|
||||
<p style={{ margin: '4px 0 0', 'font-size': '12px', color: '#6B7280' }}>
|
||||
{status() === 'APPROVED' ? '✓ Verified' : status() === 'REJECTED' ? '✕ Rejected' : '◌ Pending review'}
|
||||
</p>
|
||||
</div>
|
||||
<div style={{ border: '1px solid #E5E7EB', 'border-radius': '10px', padding: '12px', background: '#FCFCFD' }}>
|
||||
<p style={{ margin: '0', 'font-size': '13px', 'font-weight': '600', color: '#111827' }}>Professional Certifications</p>
|
||||
<p style={{ margin: '0', 'font-size': '13px', 'font-weight': '600', color: '#111827' }}>{doc.label}</p>
|
||||
<p style={{ margin: '4px 0 0', 'font-size': '12px', color: '#6B7280' }}>
|
||||
{status() === 'APPROVED' ? '✓ Verified' : status() === 'REJECTED' ? '✕ Rejected' : '◌ Pending review'}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -334,6 +334,106 @@ const DOC_FIELDS: Record<string, DocField[]> = {
|
|||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
],
|
||||
DEVELOPER: [
|
||||
{
|
||||
key: 'aadhar_doc',
|
||||
label: 'Identity Proof',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
{
|
||||
key: 'address_proof',
|
||||
label: 'Address Proof',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
{
|
||||
key: 'tax_document',
|
||||
label: 'Tax Document',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
],
|
||||
VIDEO_EDITOR: [
|
||||
{
|
||||
key: 'aadhar_doc',
|
||||
label: 'Identity Proof',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
{
|
||||
key: 'address_proof',
|
||||
label: 'Address Proof',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
{
|
||||
key: 'tax_document',
|
||||
label: 'Tax Document',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
],
|
||||
GRAPHIC_DESIGNER: [
|
||||
{
|
||||
key: 'aadhar_doc',
|
||||
label: 'Identity Proof',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
{
|
||||
key: 'address_proof',
|
||||
label: 'Address Proof',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
{
|
||||
key: 'tax_document',
|
||||
label: 'Tax Document',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
],
|
||||
SOCIAL_MEDIA_MANAGER: [
|
||||
{
|
||||
key: 'aadhar_doc',
|
||||
label: 'Identity Proof',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
{
|
||||
key: 'address_proof',
|
||||
label: 'Address Proof',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
{
|
||||
key: 'tax_document',
|
||||
label: 'Tax Document',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
],
|
||||
UGC_CONTENT_CREATOR: [
|
||||
{
|
||||
key: 'aadhar_doc',
|
||||
label: 'Identity Proof',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
{
|
||||
key: 'address_proof',
|
||||
label: 'Address Proof',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
{
|
||||
key: 'tax_document',
|
||||
label: 'Tax Document',
|
||||
required: true,
|
||||
hint: 'JPG, PNG or PDF · Max 10MB',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// ── Portfolio sections per role ───────────────────────────────────────────────
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue