feat: Add agent verification history display to the user detail page.
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
AgentType,
|
||||
VerificationStatus,
|
||||
VerificationDocument,
|
||||
VerificationHistoryEntry,
|
||||
} from '@/services';
|
||||
|
||||
export default function UserDetailPage() {
|
||||
@@ -34,6 +35,7 @@ export default function UserDetailPage() {
|
||||
const [isLoadingDocuments, setIsLoadingDocuments] = useState(false);
|
||||
const [verificationNote, setVerificationNote] = useState('');
|
||||
const [isUpdatingVerification, setIsUpdatingVerification] = useState(false);
|
||||
const [verificationHistory, setVerificationHistory] = useState<VerificationHistoryEntry[]>([]);
|
||||
|
||||
// Helper function to check if avatar is an S3 key
|
||||
const isS3Key = (avatar: string | null | undefined): boolean => {
|
||||
@@ -50,6 +52,7 @@ export default function UserDetailPage() {
|
||||
useEffect(() => {
|
||||
if (user && user.role === 'AGENT') {
|
||||
fetchVerificationDocuments();
|
||||
fetchVerificationHistory();
|
||||
}
|
||||
}, [user?.id, user?.role]);
|
||||
|
||||
@@ -131,6 +134,15 @@ export default function UserDetailPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const fetchVerificationHistory = async () => {
|
||||
try {
|
||||
const history = await usersService.getVerificationHistory(userId);
|
||||
setVerificationHistory(history);
|
||||
} catch {
|
||||
// History may not exist yet
|
||||
}
|
||||
};
|
||||
|
||||
const handleVerification = async (status: VerificationStatus) => {
|
||||
if (!user) return;
|
||||
|
||||
@@ -149,8 +161,9 @@ export default function UserDetailPage() {
|
||||
: 'Agent verification rejected'
|
||||
);
|
||||
setVerificationNote('');
|
||||
// Refresh user data
|
||||
// Refresh user data and history
|
||||
await fetchUser();
|
||||
await fetchVerificationHistory();
|
||||
// Clear success message after 3 seconds
|
||||
setTimeout(() => setUpdateSuccess(''), 3000);
|
||||
} catch (err) {
|
||||
@@ -763,6 +776,44 @@ export default function UserDetailPage() {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Verification History */}
|
||||
{verificationHistory.length > 0 && (
|
||||
<div className="border-t border-[#e5e7eb] pt-6">
|
||||
<h3 className="text-sm font-medium text-[#00293d] mb-3">Verification History</h3>
|
||||
<div className="space-y-3">
|
||||
{verificationHistory.map((entry) => (
|
||||
<div key={entry.id} className="flex items-start gap-3 p-3 bg-gray-50 rounded-lg">
|
||||
<div className={`w-2 h-2 rounded-full mt-1.5 flex-shrink-0 ${
|
||||
entry.status === 'APPROVED' ? 'bg-green-500' :
|
||||
entry.status === 'REJECTED' ? 'bg-red-500' :
|
||||
entry.status === 'PENDING_REVIEW' ? 'bg-yellow-500' : 'bg-gray-400'
|
||||
}`} />
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={`px-2 py-0.5 text-xs font-semibold rounded-full ${
|
||||
entry.status === 'APPROVED' ? 'bg-green-100 text-green-800' :
|
||||
entry.status === 'REJECTED' ? 'bg-red-100 text-red-800' :
|
||||
entry.status === 'PENDING_REVIEW' ? 'bg-yellow-100 text-yellow-800' : 'bg-gray-100 text-gray-800'
|
||||
}`}>
|
||||
{entry.status.replace('_', ' ')}
|
||||
</span>
|
||||
<span className="text-xs text-gray-500">
|
||||
{new Date(entry.createdAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit' })}
|
||||
</span>
|
||||
</div>
|
||||
{entry.note && (
|
||||
<p className="text-sm text-gray-700 mt-1">{entry.note}</p>
|
||||
)}
|
||||
{entry.admin && (
|
||||
<p className="text-xs text-gray-500 mt-1">By: {entry.admin.email}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user