feat: replace prompt-based document rejection with a dedicated modal interface

This commit is contained in:
sazzadulalambd
2026-05-05 02:53:49 +06:00
parent 291d9ca68b
commit 376b4e0cac

View File

@@ -259,6 +259,10 @@ export default function KYCDetailPage() {
const [showAddDocModal, setShowAddDocModal] = useState(false); const [showAddDocModal, setShowAddDocModal] = useState(false);
const [newDocName, setNewDocName] = useState(''); const [newDocName, setNewDocName] = useState('');
const [showUploadDocModal, setShowUploadDocModal] = useState(false); const [showUploadDocModal, setShowUploadDocModal] = useState(false);
const [showRejectDocModal, setShowRejectDocModal] = useState(false);
const [rejectDocId, setRejectDocId] = useState<string | null>(null);
const [rejectReason, setRejectReason] = useState('');
const [uploadDocId, setUploadDocId] = useState<string | null>(null); const [uploadDocId, setUploadDocId] = useState<string | null>(null);
useEffect(() => { useEffect(() => {
@@ -333,16 +337,24 @@ export default function KYCDetailPage() {
} : null); } : null);
}; };
const handleRejectDocument = (docId: string) => { const openRejectDocModal = (docId: string) => {
const reason = prompt('Enter rejection reason:'); setRejectDocId(docId);
if (reason) { setRejectReason('');
setRequest(prev => prev ? { setShowRejectDocModal(true);
...prev, };
requiredDocuments: prev.requiredDocuments.map(doc =>
doc.id === docId ? { ...doc, status: 'rejected' as const, rejectedReason: reason } : doc const handleRejectDocument = () => {
) if (!request || !rejectDocId || !rejectReason.trim()) return;
} : null); setRequest(prev => prev ? {
} ...prev,
requiredDocuments: prev.requiredDocuments.map(doc =>
doc.id === rejectDocId ? { ...doc, status: 'rejected' as const, rejectedReason: rejectReason } : doc
)
} : null);
setShowRejectDocModal(false);
setRejectDocId(null);
setRejectReason('');
toast.success('Document rejected');
}; };
const handleUploadDocument = (e: React.ChangeEvent<HTMLInputElement>) => { const handleUploadDocument = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -654,11 +666,14 @@ export default function KYCDetailPage() {
{doc.status === 'uploaded' && ( {doc.status === 'uploaded' && (
<> <>
<button onClick={() => handleApproveDocument(doc.id)} className="p-1 bg-green-100 text-green-600 rounded hover:bg-green-200" title="Approve"><CheckCircle className="w-4 h-4" /></button> <button onClick={() => handleApproveDocument(doc.id)} className="p-1 bg-green-100 text-green-600 rounded hover:bg-green-200" title="Approve"><CheckCircle className="w-4 h-4" /></button>
<button onClick={() => handleRejectDocument(doc.id)} className="p-1 bg-red-100 text-red-600 rounded hover:bg-red-200" title="Reject"><XCircle className="w-4 h-4" /></button> <button onClick={() => openRejectDocModal(doc.id)} className="p-1 bg-red-100 text-red-600 rounded hover:bg-red-200" title="Reject"><XCircle className="w-4 h-4" /></button>
</> </>
)} )}
{doc.status === 'approved' && <span className="text-xs px-2 py-1 bg-green-100 text-green-700 rounded-full">Approved</span>} {doc.status === 'approved' && <span className="text-xs px-2 py-1 bg-green-100 text-green-700 rounded-full">Approved</span>}
{doc.status === 'rejected' && <span className="text-xs px-2 py-1 bg-red-100 text-red-700 rounded-full">Rejected</span>} {doc.status === 'rejected' && <span className="text-xs px-2 py-1 bg-red-100 text-red-700 rounded-full">Rejected</span>}
{doc.status === 'rejected' && doc.rejectedReason && (
<div className="text-xs text-red-600 mt-1 italic">Reason: {doc.rejectedReason}</div>
)}
{doc.status === 'pending' && <span className="text-xs px-2 py-1 bg-amber-100 text-amber-700 rounded-full">Pending</span>} {doc.status === 'pending' && <span className="text-xs px-2 py-1 bg-amber-100 text-amber-700 rounded-full">Pending</span>}
</div> </div>
</div> </div>
@@ -826,6 +841,31 @@ export default function KYCDetailPage() {
</div> </div>
</div> </div>
)} )}
{showRejectDocModal && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-xl shadow-xl w-full max-w-md">
<div className="p-4 border-b border-slate-100 flex justify-between items-center">
<h3 className="font-semibold text-red-600">Reject Document</h3>
<button onClick={() => setShowRejectDocModal(false)} className="text-slate-400 hover:text-slate-600">×</button>
</div>
<div className="p-4">
<label className="text-sm font-medium text-slate-600 mb-2 block">Rejection Reason</label>
<textarea
value={rejectReason}
onChange={(e) => setRejectReason(e.target.value)}
className="w-full px-3 py-2 border border-slate-200 rounded-lg text-sm"
rows={4}
placeholder="Enter reason for rejection..."
/>
</div>
<div className="p-4 border-t border-slate-100 flex justify-end gap-2">
<button onClick={() => setShowRejectDocModal(false)} className="px-4 py-2 border border-slate-200 text-slate-600 rounded-lg">Cancel</button>
<button onClick={handleRejectDocument} disabled={!rejectReason.trim()} className="px-4 py-2 bg-red-600 text-white rounded-lg disabled:opacity-50">Reject</button>
</div>
</div>
</div>
)}
</div> </div>
); );
} }