49 lines
4.3 KiB
TypeScript
49 lines
4.3 KiB
TypeScript
import { Head, Link, router } from '@inertiajs/react';
|
|
import { useState } from 'react';
|
|
import ProfileNavigation from '@/components/profile-navigation';
|
|
import { profileJson } from '@/lib/profile-json';
|
|
import { button, control } from '@/pages/management/shared';
|
|
|
|
type RequestEntry = { id: string; status: string; reason: string; decision_reason: string | null; created_at: string };
|
|
export default function RequestProfile({ requests, types, organizations, documents }: {
|
|
requests: RequestEntry[]; types: string[]; organizations: {id: string; name: string}[]; documents: {id: string; file_name: string}[];
|
|
}) {
|
|
const [representation, setRepresentation] = useState('individual');
|
|
const [organization, setOrganization] = useState('');
|
|
const [selected, setSelected] = useState<string[]>([]);
|
|
const [proofs, setProofs] = useState<string[]>([]);
|
|
const [reason, setReason] = useState('');
|
|
const [key, setKey] = useState(() => crypto.randomUUID());
|
|
const [message, setMessage] = useState('');
|
|
const [busy, setBusy] = useState(false);
|
|
async function send() {
|
|
setBusy(true); setMessage('');
|
|
try {
|
|
const result = await profileJson('/perfil/promotor', { creation_key: key, representation_type: representation, organization_id: representation === 'individual' ? null : organization,
|
|
opportunity_types: selected, document_ids: proofs, reason });
|
|
setMessage(result.message); setKey(crypto.randomUUID()); router.reload();
|
|
} catch (error) { setMessage(error instanceof Error ? error.message : 'Resposta indisponível. Confira o acompanhamento antes de repetir.'); }
|
|
finally { setBusy(false); }
|
|
}
|
|
const toggle = (values: string[], id: string) => values.includes(id) ? values.filter(v => v !== id) : [...values, id];
|
|
return <main className="space-y-6 p-6"><Head title="Perfil de Promotor" /><ProfileNavigation />
|
|
<h1 className="text-2xl font-semibold">Solicitar perfil de Promotor</h1>
|
|
<p>A aprovação confirma identidade, representação e comprovativos. Só os tipos aprovados ficam disponíveis; o pedido não ativa o perfil.</p>
|
|
<form className="max-w-2xl space-y-4" onSubmit={e => { e.preventDefault(); void send(); }}>
|
|
<label className="block">Representação<select className={control} value={representation} onChange={e => setRepresentation(e.target.value)}>
|
|
{['individual','company','public_entity','association','partner'].map(v => <option key={v}>{v}</option>)}
|
|
</select></label>
|
|
{representation !== 'individual' && <label className="block">Organização representada<select required className={control} value={organization} onChange={e => setOrganization(e.target.value)}>
|
|
<option value="">Selecionar</option>{organizations.map(o => <option key={o.id} value={o.id}>{o.name}</option>)}
|
|
</select></label>}
|
|
<fieldset><legend>Tipos pretendidos</legend>{types.map(type => <label key={type} className="block"><input type="checkbox" checked={selected.includes(type)} onChange={() => setSelected(toggle(selected,type))} /> {type}</label>)}</fieldset>
|
|
<fieldset><legend>Comprovativos próprios analisados</legend>{documents.map(d => <label key={d.id} className="block"><input type="checkbox" checked={proofs.includes(d.id)} onChange={() => setProofs(toggle(proofs,d.id))} /> {d.file_name}</label>)}</fieldset>
|
|
{!documents.length && <p>Sem comprovativos próprios disponíveis. Pode anexar ao seu dossier no <Link className="underline" href="/balcao-virtual/painel">Balcão</Link>; o ficheiro precisa de análise antimalware concluída.</p>}
|
|
<label className="block">Fundamentação<textarea required minLength={20} maxLength={1000} className={control} value={reason} onChange={e => setReason(e.target.value)} /></label>
|
|
<button disabled={busy} className={button}>Submeter pedido de perfil</button>
|
|
</form>
|
|
<p role="status" aria-live="polite">{message}</p>
|
|
<section><h2 className="text-xl font-semibold">Acompanhamento dos meus pedidos</h2>{requests.map(r => <article key={r.id} className="border-b py-3"><p>{r.id} — {r.status}</p><p>{r.decision_reason ?? 'Aguarda revisão independente.'}</p></article>)}{!requests.length && <p>Nenhum pedido recebido.</p>}</section>
|
|
</main>;
|
|
}
|