big refactor
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
usePageTitle('Agents & Commissions · Settings')
|
||||
|
||||
/* ── Types ── */
|
||||
type AgentStatus = 'active' | 'inactive' | 'suspended'
|
||||
type CommissionTier = { lobId: string; lob: string; newPct: number; renewalPct: number }
|
||||
|
||||
interface CommissionTier {
|
||||
lobId: string
|
||||
lob: string
|
||||
newPct: number
|
||||
renewalPct: number
|
||||
}
|
||||
|
||||
interface Agent {
|
||||
id: string
|
||||
@@ -20,83 +25,13 @@ interface Agent {
|
||||
lastLogin: string
|
||||
}
|
||||
|
||||
/* ── Mock data ── */
|
||||
const agents = ref<Agent[]>([
|
||||
{
|
||||
id: 'AG-001', name: 'Ana Ramírez', email: 'ana.ramirez@segur-os.com', phone: '+506 8812-4455',
|
||||
role: 'Senior producer', status: 'active', hireDate: '2021-03-15',
|
||||
book: { policies: 142, gwp: 2_840_000, collected: 2_610_000, outstanding: 230_000 },
|
||||
commissionTiers: [
|
||||
{ lobId: 'auto', lob: 'Auto', newPct: 15, renewalPct: 10 },
|
||||
{ lobId: 'health', lob: 'Health', newPct: 12, renewalPct: 8 },
|
||||
{ lobId: 'life', lob: 'Life', newPct: 18, renewalPct: 12 },
|
||||
{ lobId: 'property', lob: 'Property', newPct: 14, renewalPct: 9 },
|
||||
{ lobId: 'general', lob: 'General risk', newPct: 13, renewalPct: 8 },
|
||||
],
|
||||
ytdEarned: 48_200, ytdPending: 6_400, lastLogin: '2026-04-05 08:32'
|
||||
},
|
||||
{
|
||||
id: 'AG-002', name: 'Marco Villanueva', email: 'marco.v@segur-os.com', phone: '+506 8899-2211',
|
||||
role: 'Producer', status: 'active', hireDate: '2022-08-01',
|
||||
book: { policies: 88, gwp: 1_620_000, collected: 1_480_000, outstanding: 140_000 },
|
||||
commissionTiers: [
|
||||
{ lobId: 'auto', lob: 'Auto', newPct: 14, renewalPct: 9 },
|
||||
{ lobId: 'health', lob: 'Health', newPct: 11, renewalPct: 7 },
|
||||
{ lobId: 'life', lob: 'Life', newPct: 16, renewalPct: 10 },
|
||||
{ lobId: 'property', lob: 'Property', newPct: 12, renewalPct: 8 },
|
||||
{ lobId: 'general', lob: 'General risk', newPct: 12, renewalPct: 7 },
|
||||
],
|
||||
ytdEarned: 28_600, ytdPending: 3_200, lastLogin: '2026-04-04 17:15'
|
||||
},
|
||||
{
|
||||
id: 'AG-003', name: 'Lucía Fernández', email: 'lucia.f@segur-os.com', phone: '+506 7745-3388',
|
||||
role: 'Junior producer', status: 'active', hireDate: '2024-01-10',
|
||||
book: { policies: 34, gwp: 420_000, collected: 385_000, outstanding: 35_000 },
|
||||
commissionTiers: [
|
||||
{ lobId: 'auto', lob: 'Auto', newPct: 12, renewalPct: 8 },
|
||||
{ lobId: 'health', lob: 'Health', newPct: 10, renewalPct: 6 },
|
||||
{ lobId: 'life', lob: 'Life', newPct: 14, renewalPct: 9 },
|
||||
{ lobId: 'property', lob: 'Property', newPct: 11, renewalPct: 7 },
|
||||
{ lobId: 'general', lob: 'General risk', newPct: 10, renewalPct: 6 },
|
||||
],
|
||||
ytdEarned: 8_400, ytdPending: 1_100, lastLogin: '2026-04-05 09:01'
|
||||
},
|
||||
{
|
||||
id: 'AG-004', name: 'Diego Mora', email: 'diego.m@segur-os.com', phone: '+506 6612-9944',
|
||||
role: 'Producer', status: 'suspended', hireDate: '2023-05-20',
|
||||
book: { policies: 56, gwp: 980_000, collected: 720_000, outstanding: 260_000 },
|
||||
commissionTiers: [
|
||||
{ lobId: 'auto', lob: 'Auto', newPct: 13, renewalPct: 9 },
|
||||
{ lobId: 'health', lob: 'Health', newPct: 11, renewalPct: 7 },
|
||||
{ lobId: 'life', lob: 'Life', newPct: 15, renewalPct: 10 },
|
||||
{ lobId: 'property', lob: 'Property', newPct: 12, renewalPct: 8 },
|
||||
{ lobId: 'general', lob: 'General risk', newPct: 11, renewalPct: 7 },
|
||||
],
|
||||
ytdEarned: 14_200, ytdPending: 8_800, lastLogin: '2026-03-28 11:40'
|
||||
},
|
||||
{
|
||||
id: 'AG-005', name: 'Valentina Castro', email: 'val.castro@segur-os.com', phone: '+506 8834-5566',
|
||||
role: 'Senior producer', status: 'inactive', hireDate: '2019-11-03',
|
||||
book: { policies: 0, gwp: 0, collected: 0, outstanding: 0 },
|
||||
commissionTiers: [
|
||||
{ lobId: 'auto', lob: 'Auto', newPct: 15, renewalPct: 10 },
|
||||
{ lobId: 'health', lob: 'Health', newPct: 12, renewalPct: 8 },
|
||||
{ lobId: 'life', lob: 'Life', newPct: 18, renewalPct: 12 },
|
||||
{ lobId: 'property', lob: 'Property', newPct: 14, renewalPct: 9 },
|
||||
{ lobId: 'general', lob: 'General risk', newPct: 13, renewalPct: 8 },
|
||||
],
|
||||
ytdEarned: 0, ytdPending: 0, lastLogin: '2025-12-15 14:22'
|
||||
},
|
||||
])
|
||||
|
||||
/* ── State ── */
|
||||
const agents = ref<Agent[]>([])
|
||||
const search = ref('')
|
||||
const statusFilter = ref<'all' | AgentStatus>('all')
|
||||
const selectedAgent = ref<Agent | null>(null)
|
||||
const addModalOpen = ref(false)
|
||||
const editingCommissions = ref(false)
|
||||
|
||||
/* ── Filtering ── */
|
||||
const filteredAgents = computed(() => {
|
||||
let list = agents.value
|
||||
if (statusFilter.value !== 'all') list = list.filter(a => a.status === statusFilter.value)
|
||||
@@ -110,7 +45,6 @@ const filteredAgents = computed(() => {
|
||||
return list
|
||||
})
|
||||
|
||||
/* ── Aggregate KPIs ── */
|
||||
const kpis = computed(() => {
|
||||
const active = agents.value.filter(a => a.status === 'active')
|
||||
const totalBook = agents.value.reduce((s, a) => s + a.book.gwp, 0)
|
||||
@@ -130,7 +64,6 @@ const kpis = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
/* ── Add agent modal ── */
|
||||
const newAgent = reactive({
|
||||
name: '', email: '', phone: '', role: 'Producer',
|
||||
defaultNewPct: 13, defaultRenewalPct: 8,
|
||||
@@ -177,11 +110,9 @@ function toggleAgentStatus(agent: Agent) {
|
||||
}
|
||||
|
||||
function resetCredentials(_agent: Agent) {
|
||||
// Mock: in production this would trigger a password reset email
|
||||
alert(`Password reset email would be sent to ${_agent.email}`)
|
||||
}
|
||||
|
||||
/* ── Helpers ── */
|
||||
function fmtMoney(n: number) {
|
||||
if (n >= 1_000_000) return `$${(n / 1_000_000).toFixed(1)}M`
|
||||
if (n >= 1_000) return `$${(n / 1_000).toFixed(0)}K`
|
||||
|
||||
Reference in New Issue
Block a user