'use client';
import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Plus, Edit, Eye, Trash2 } from 'lucide-react';
import DataTable from '@/components/ui/DataTable';
import ActionButton from '@/components/ui/ActionButton';
import Badge from '@/components/ui/Badge';
import Modal from '@/components/ui/Modal';
import ConfirmDialog from '@/components/ui/ConfirmDialog';
import { agentsApi, apiClient } from '@/lib/api';
import { formatCurrency, formatDateTime } from '@/lib/utils';
import { useAuthStore } from '@/lib/auth-store';
const Field = ({ label, value, mono = false, truncate = false }: { label: string; value: string; mono?: boolean; truncate?: boolean }) => (
);
const SectionHeader = ({ title }: { title: string }) => (
{title}
);
export default function AgentsPage() {
const { user } = useAuthStore();
const queryClient = useQueryClient();
const [filters, setFilters] = useState({ search: '', active: '' });
const [selected, setSelected] = useState(null);
const [createModal, setCreateModal] = useState(false);
const [createForm, setCreateForm] = useState({ iamUserId: '', agentCode: '', commissionRate: '5' });
const [createError, setCreateError] = useState(null);
const createMutation = useMutation({
mutationFn: (data: any) => apiClient.post('/agents', data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['agents'] });
setCreateModal(false);
setCreateError(null);
},
onError: (e: any) => setCreateError(e?.response?.data?.message || e?.message || 'Failed to create agent'),
});
const [editModal, setEditModal] = useState(false);
const [editForm, setEditForm] = useState({ agentCode: '', commissionRate: '5', active: true });
const [editingAgent, setEditingAgent] = useState(null);
const [editError, setEditError] = useState(null);
const [deleteConfirm, setDeleteConfirm] = useState<{ isOpen: boolean; agent: any | null }>({ isOpen: false, agent: null });
const [deleteError, setDeleteError] = useState(null);
const deleteMutation = useMutation({
mutationFn: (id: string) => agentsApi.delete(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['agents'] });
setDeleteConfirm({ isOpen: false, agent: null });
setDeleteError(null);
},
onError: (e: any) => setDeleteError(e?.response?.data?.message || e?.message || 'Failed to delete agent'),
});
const editMutation = useMutation({
mutationFn: ({ id, ...data }: any) => apiClient.patch(`/agents/${id}`, data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['agents'] });
setEditModal(false);
setEditError(null);
},
onError: (e: any) => setEditError(e?.response?.data?.message || e?.message || 'Failed to update agent'),
});
const openCreateModal = () => {
setCreateForm({ iamUserId: '', agentCode: '', commissionRate: '5' });
setCreateError(null);
setCreateModal(true);
};
const openEditModal = (agent: any) => {
setEditingAgent(agent);
setEditForm({ agentCode: agent.agentCode, commissionRate: String(agent.commissionRate ?? 5), active: agent.active });
setEditError(null);
setEditModal(true);
};
const { data, isLoading } = useQuery({
queryKey: ['agents', filters],
queryFn: () => agentsApi.getAll(filters),
});
const columns = [
{
key: 'agentCode',
label: 'Agent Code',
sortable: true,
render: (agent: any) => {agent.agentCode},
},
{
key: 'user',
label: 'Name',
render: (agent: any) => (
{agent.user?.fullName || 'N/A'}
{agent.user?.email}
),
},
{
key: 'commissionRate',
label: 'Commission',
render: (agent: any) => {agent.commissionRate}%,
},
{
key: 'active',
label: 'Status',
render: (agent: any) => (
{agent.active ? 'Active' : 'Inactive'}
),
},
];
const actions = [
{
label: 'Edit',
onClick: (agent: any) => openEditModal(agent),
variant: 'secondary' as const,
icon: Edit,
},
{
label: 'Details',
onClick: (agent: any) => setSelected(agent),
variant: 'secondary' as const,
icon: Eye,
},
{
label: 'Delete',
onClick: (agent: any) => { setDeleteError(null); setDeleteConfirm({ isOpen: true, agent }); },
variant: 'danger' as const,
icon: Trash2,
},
];
return (
Agents
Manage agents and their operations
Add Agent
{ setDeleteConfirm({ isOpen: false, agent: null }); setDeleteError(null); }}
onConfirm={async () => { if (deleteConfirm.agent) await deleteMutation.mutateAsync(deleteConfirm.agent.id); }}
title="Delete Agent"
message={`Are you sure you want to delete agent ${deleteConfirm.agent?.agentCode}? This action cannot be undone.`}
confirmText="Delete"
isDanger
isLoading={deleteMutation.isPending}
error={deleteError ?? undefined}
/>
{/* Agent Details Modal */}
setSelected(null)} title="Agent Details" size="xl">
{selected && (() => {
const a = selected;
const initials = (a.user?.fullName || a.agentCode || '?').split(' ').map((w: string) => w[0]).join('').slice(0, 2).toUpperCase();
return (
{initials}
{a.user?.fullName || 'N/A'}
{a.agentCode}
{a.active ? 'Active' : 'Inactive'}
{[
{ label: 'Agent Code', value: a.agentCode || '—' },
{ label: 'Commission Rate', value: `${a.commissionRate ?? 0}%` },
{ label: 'Total Bookings', value: (a.totalBookings ?? 0).toLocaleString() },
].map(({ label, value }) => (
))}
Status
{a.active ? 'Active' : 'Inactive'}
);
})()}
{/* Create Agent Modal */}
setCreateModal(false)} title="Add Agent Profile" size="md">
{createError && (
{createError}
)}
setCreateForm({ ...createForm, iamUserId: e.target.value })}
placeholder="IAM user UUID"
/>
{user?.id && createForm.iamUserId === user.id && (
✓ Pre-filled with your logged-in user ID
)}
Links this agent profile to an IAM back-office user
setCreateModal(false)}>Cancel
createMutation.mutate({
iamUserId: createForm.iamUserId,
agentCode: createForm.agentCode || undefined,
commissionRate: parseInt(createForm.commissionRate) || 5,
})}
>
Create Agent
{/* Edit Agent Modal */}
setEditModal(false)} title="Edit Agent" size="md">
{editError && (
{editError}
)}
setEditModal(false)}>Cancel
editMutation.mutate({
id: editingAgent.id,
agentCode: editForm.agentCode,
commissionRate: parseInt(editForm.commissionRate) || 5,
active: editForm.active,
})}>Save Changes
);
}