WIP jordan

This commit is contained in:
Jordan Weingarten
2026-04-16 11:11:44 -05:00
parent ff2d7b18b5
commit 67482f6629
163 changed files with 50627 additions and 728 deletions

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
usePageTitle('Claims')
</script>
<template>
<div class="mx-auto max-w-2xl py-16 text-center">
<div class="inline-flex flex-col items-center gap-4">
<span
class="inline-flex items-center rounded-full px-3 py-1 text-[11px] font-semibold uppercase tracking-wider"
style="background: rgba(1, 105, 111, 0.06); color: #01696f;"
>Coming soon</span>
<h1 class="text-2xl font-semibold tracking-tight text-[var(--text-primary)]">Claims</h1>
<p class="text-[14px] leading-relaxed text-[var(--text-muted)]">
File, track, and manage insurance claims from first notice through resolution.
</p>
</div>
</div>
</template>

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
usePageTitle('Collections')
</script>
<template>
<div class="mx-auto max-w-2xl py-16 text-center">
<div class="inline-flex flex-col items-center gap-4">
<span
class="inline-flex items-center rounded-full px-3 py-1 text-[11px] font-semibold uppercase tracking-wider"
style="background: rgba(1, 105, 111, 0.06); color: #01696f;"
>Coming soon</span>
<h1 class="text-2xl font-semibold tracking-tight text-[var(--text-primary)]">Collections</h1>
<p class="text-[14px] leading-relaxed text-[var(--text-muted)]">
Track outstanding balances, manage payment follow-ups, and reconcile carrier accounts.
</p>
</div>
</div>
</template>

View File

@@ -0,0 +1,329 @@
<script setup lang="ts">
usePageTitle('Collectivos')
const activeTab = ref<'groups' | 'census' | 'billing'>('groups')
</script>
<template>
<div class="mx-auto max-w-5xl space-y-6 pb-12">
<!-- Header -->
<div class="max-w-2xl">
<h1 class="mt-1 text-2xl font-semibold tracking-tight text-[var(--text-primary)]">Collectivos</h1>
<p class="mt-2 text-[14px] leading-relaxed text-[var(--text-muted)]">
Manage group policies end to end from census intake through billing reconciliation.
</p>
</div>
<!-- Workspace tabs -->
<div class="col-tabs">
<button
v-for="tab in [
{ id: 'groups' as const, label: 'Active Groups', count: 12 },
{ id: 'census' as const, label: 'Census & Members', count: null },
{ id: 'billing' as const, label: 'Billing Cycles', count: 3 },
]"
:key="tab.id"
type="button"
class="col-tab"
:class="activeTab === tab.id ? 'col-tab-active' : 'col-tab-inactive'"
@click="activeTab = tab.id"
>
{{ tab.label }}
<span v-if="tab.count" class="col-tab-count" :class="activeTab === tab.id ? 'col-tab-count-active' : ''">{{ tab.count }}</span>
</button>
</div>
<!-- ═══ ACTIVE GROUPS ═══ -->
<template v-if="activeTab === 'groups'">
<div class="flex flex-wrap items-center justify-between gap-3">
<UInput icon="i-heroicons-magnifying-glass" placeholder="Search groups..." size="sm" class="w-64" />
<UButton color="primary" size="sm" icon="i-heroicons-plus">New Group Policy</UButton>
</div>
<div class="col-card">
<table class="col-table">
<thead>
<tr>
<th>Group</th>
<th>Carrier</th>
<th>Line</th>
<th>Members</th>
<th>Premium</th>
<th>Renewal</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr v-for="group in [
{ name: 'Constructora Delta S.A.', carrier: 'ASSA', line: 'Health', members: 84, premium: '$42,600', renewal: '2025-09-01', status: 'Active' },
{ name: 'Hotel Pacífico Group', carrier: 'INS', line: 'Life', members: 127, premium: '$78,200', renewal: '2025-07-15', status: 'Active' },
{ name: 'Banco Regional', carrier: 'Mapfre', line: 'Health', members: 312, premium: '$186,400', renewal: '2025-11-01', status: 'Active' },
{ name: 'Farmacia Salud', carrier: 'ASSA', line: 'Life', members: 23, premium: '$12,800', renewal: '2025-06-01', status: 'Renewal due' },
{ name: 'Transportes del Sur', carrier: 'Qualitas', line: 'Auto', members: 56, premium: '$34,100', renewal: '2025-08-15', status: 'Active' },
]" :key="group.name" class="col-table-row">
<td>
<p class="text-[13px] font-medium text-[var(--text-primary)]">{{ group.name }}</p>
</td>
<td class="text-[13px] text-[var(--text-muted)]">{{ group.carrier }}</td>
<td>
<span class="col-line-badge">{{ group.line }}</span>
</td>
<td class="text-[13px] tabular-nums text-[var(--text-primary)]">{{ group.members }}</td>
<td class="text-[13px] font-medium tabular-nums text-[var(--text-primary)]">{{ group.premium }}</td>
<td class="text-[13px] tabular-nums text-[var(--text-muted)]">{{ group.renewal }}</td>
<td>
<span
class="col-status"
:class="group.status === 'Active' ? 'col-status-active' : 'col-status-attention'"
>{{ group.status }}</span>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<!-- ═══ CENSUS & MEMBERS ═══ -->
<template v-if="activeTab === 'census'">
<div class="grid gap-4 sm:grid-cols-3">
<div class="col-action-card" v-for="action in [
{ icon: 'i-heroicons-arrow-up-tray', title: 'Upload Census', desc: 'Import a member roster from Excel or CSV. AI validates and flags issues.' },
{ icon: 'i-heroicons-user-plus', title: 'Add Members', desc: 'Add individual members to an active group, with effective date and tier.' },
{ icon: 'i-heroicons-arrow-path', title: 'Reconcile Changes', desc: 'Process additions, removals, and tier changes against the carrier file.' },
]" :key="action.title">
<div class="col-action-icon">
<UIcon :name="action.icon" style="width: 20px; height: 20px;" />
</div>
<p class="mt-3 text-[14px] font-medium text-[var(--text-primary)]">{{ action.title }}</p>
<p class="mt-1 text-[12px] leading-relaxed text-[var(--text-muted)]">{{ action.desc }}</p>
</div>
</div>
<div class="col-card">
<div class="col-card-header">
<p class="text-[14px] font-semibold text-[var(--text-primary)]">Recent census activity</p>
</div>
<div class="col-activity-list">
<div v-for="event in [
{ group: 'Constructora Delta S.A.', action: 'Census uploaded', detail: '84 members validated, 2 flagged', time: '2 hours ago' },
{ group: 'Hotel Pacífico Group', action: '3 members added', detail: 'Effective 2025-05-01, Health tier Family', time: 'Yesterday' },
{ group: 'Banco Regional', action: 'Reconciliation complete', detail: '+5 additions, -2 removals sent to Mapfre', time: '3 days ago' },
{ group: 'Farmacia Salud', action: 'Census flagged', detail: '1 duplicate ID, 1 missing DOB — pending review', time: '5 days ago' },
]" :key="event.group + event.action" class="col-activity-row">
<div class="min-w-0 flex-1">
<p class="text-[13px] text-[var(--text-primary)]">
<span class="font-medium">{{ event.group }}</span>
<span class="text-[var(--text-muted)]"> — {{ event.action }}</span>
</p>
<p class="mt-0.5 text-[12px] text-[var(--text-muted)]">{{ event.detail }}</p>
</div>
<span class="shrink-0 text-[11px] text-[var(--text-muted)]">{{ event.time }}</span>
</div>
</div>
</div>
</template>
<!-- ═══ BILLING CYCLES ═══ -->
<template v-if="activeTab === 'billing'">
<div class="grid gap-4 sm:grid-cols-3">
<div v-for="stat in [
{ label: 'Due this month', value: '3', sub: '$247,200 premium' },
{ label: 'Pending carrier confirmation', value: '1', sub: 'Awaiting INS response' },
{ label: 'Overdue', value: '0', sub: 'All current' },
]" :key="stat.label" class="col-stat-card">
<p class="text-[11px] font-semibold uppercase tracking-[0.06em] text-[#8a8a86]">{{ stat.label }}</p>
<p class="mt-1.5 text-[22px] font-semibold tabular-nums text-[var(--text-primary)]" style="font-variant-numeric: tabular-nums;">{{ stat.value }}</p>
<p class="mt-0.5 text-[12px] text-[var(--text-muted)]">{{ stat.sub }}</p>
</div>
</div>
<div class="col-card">
<div class="col-card-header">
<p class="text-[14px] font-semibold text-[var(--text-primary)]">Upcoming billing</p>
<p class="text-[13px] text-[var(--text-muted)]">Next 60 days</p>
</div>
<div class="col-activity-list">
<div v-for="bill in [
{ group: 'Farmacia Salud', period: 'Jun 2025', amount: '$12,800', due: '2025-06-01', status: 'Due soon' },
{ group: 'Hotel Pacífico Group', period: 'Jul 2025', amount: '$78,200', due: '2025-07-15', status: 'Scheduled' },
{ group: 'Transportes del Sur', period: 'Aug 2025', amount: '$34,100', due: '2025-08-15', status: 'Scheduled' },
]" :key="bill.group" class="col-activity-row">
<div class="min-w-0 flex-1">
<p class="text-[13px] font-medium text-[var(--text-primary)]">{{ bill.group }}</p>
<p class="mt-0.5 text-[12px] text-[var(--text-muted)]">{{ bill.period }} · Due {{ bill.due }}</p>
</div>
<div class="flex items-center gap-3">
<span class="text-[13px] font-medium tabular-nums text-[var(--text-primary)]">{{ bill.amount }}</span>
<span
class="col-status"
:class="bill.status === 'Due soon' ? 'col-status-attention' : 'col-status-neutral'"
>{{ bill.status }}</span>
</div>
</div>
</div>
</div>
</template>
</div>
</template>
<style scoped>
/* ── Tabs ── */
.col-tabs {
display: flex;
gap: 2px;
padding: 3px;
border-radius: 10px;
background: rgba(0, 0, 0, 0.04);
width: fit-content;
}
.col-tab {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 14px;
border-radius: 8px;
font-size: 13px;
font-weight: 500;
border: none;
cursor: pointer;
transition: all 150ms ease;
}
.col-tab-active {
background: #ffffff;
color: var(--text-primary);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}
.col-tab-inactive {
background: transparent;
color: var(--text-muted);
}
.col-tab-inactive:hover { color: var(--text-primary); }
.col-tab-count {
font-size: 11px;
font-weight: 600;
padding: 1px 6px;
border-radius: 9999px;
background: rgba(0, 0, 0, 0.06);
color: var(--text-muted);
}
.col-tab-count-active {
background: rgba(1, 105, 111, 0.1);
color: #01696f;
}
/* ── Card ── */
.col-card {
border-radius: 12px;
border: 1px solid rgba(0, 0, 0, 0.06);
background: #ffffff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
overflow: hidden;
}
.col-card-header {
padding: 20px 20px 16px;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
/* ── Table ── */
.col-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
.col-table th {
text-align: left;
padding: 10px 16px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
color: #8a8a86;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.col-table-row td {
padding: 12px 16px;
border-bottom: 1px solid rgba(0, 0, 0, 0.04);
vertical-align: middle;
}
.col-table-row:last-child td { border-bottom: none; }
.col-table-row:hover { background: rgba(0, 0, 0, 0.015); }
/* ── Badges ── */
.col-line-badge {
display: inline-flex;
padding: 2px 8px;
border-radius: 6px;
font-size: 11px;
font-weight: 600;
background: rgba(1, 105, 111, 0.06);
color: #01696f;
}
.col-status {
display: inline-flex;
padding: 2px 8px;
border-radius: 9999px;
font-size: 11px;
font-weight: 600;
}
.col-status-active {
background: rgba(15, 123, 95, 0.08);
color: #0f7b5f;
}
.col-status-attention {
background: rgba(150, 66, 25, 0.08);
color: #964219;
}
.col-status-neutral {
background: rgba(0, 0, 0, 0.04);
color: var(--text-muted);
}
/* ── Action cards ── */
.col-action-card {
padding: 20px;
border-radius: 12px;
border: 1px solid rgba(0, 0, 0, 0.06);
background: #ffffff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
cursor: pointer;
transition: all 150ms ease;
}
.col-action-card:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
border-color: rgba(1, 105, 111, 0.2);
}
.col-action-icon {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 10px;
background: rgba(1, 105, 111, 0.06);
color: #01696f;
}
/* ── Stat cards ── */
.col-stat-card {
padding: 20px;
border-radius: 12px;
border: 1px solid rgba(0, 0, 0, 0.06);
background: #ffffff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
}
/* ── Activity list ── */
.col-activity-list {
display: flex;
flex-direction: column;
}
.col-activity-row {
display: flex;
align-items: center;
gap: 12px;
padding: 14px 20px;
border-bottom: 1px solid rgba(0, 0, 0, 0.04);
}
.col-activity-row:last-child { border-bottom: none; }
.col-activity-row:hover { background: rgba(0, 0, 0, 0.015); }
</style>

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
usePageTitle('Customer Service')
</script>
<template>
<div class="mx-auto max-w-2xl py-16 text-center">
<div class="inline-flex flex-col items-center gap-4">
<span
class="inline-flex items-center rounded-full px-3 py-1 text-[11px] font-semibold uppercase tracking-wider"
style="background: rgba(1, 105, 111, 0.06); color: #01696f;"
>Coming soon</span>
<h1 class="text-2xl font-semibold tracking-tight text-[var(--text-primary)]">Customer Service</h1>
<p class="text-[14px] leading-relaxed text-[var(--text-muted)]">
Handle service requests, endorsements, and policyholder inquiries from a unified inbox.
</p>
</div>
</div>
</template>

View File

@@ -0,0 +1,114 @@
<script setup lang="ts">
usePageTitle('Facturación')
</script>
<template>
<div class="fac-page">
<div class="flex flex-wrap items-start justify-between gap-4">
<div>
<h1 class="mt-1 text-2xl font-semibold tracking-tight text-[var(--text-primary)]">Facturación</h1>
<p class="mt-2 max-w-2xl text-[14px] leading-relaxed text-[var(--text-muted)]">
Invoicing workflow for the brokerage. Generate, track, and manage invoices tied to policies, commissions, and client accounts. Integrates with carrier billing and AR to keep financials in sync.
</p>
</div>
<span
class="inline-flex items-center rounded-full px-3 py-1 text-[11px] font-semibold uppercase tracking-wider"
style="background: rgba(1, 105, 111, 0.06); color: #01696f;"
>Coming soon</span>
</div>
<!-- Feature preview -->
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
<div class="fac-card">
<div class="fac-icon" style="background: rgba(1,105,111,0.08); color: #01696f;">
<UIcon name="i-heroicons-document-text" style="width: 20px; height: 20px;" />
</div>
<h3 class="fac-card-title">Invoice generation</h3>
<p class="fac-card-desc">Create invoices from bound policies, endorsements, or manual entries. Auto-populate client data, premium breakdowns, and tax fields.</p>
</div>
<div class="fac-card">
<div class="fac-icon" style="background: rgba(124,58,237,0.08); color: #7c3aed;">
<UIcon name="i-heroicons-arrow-path" style="width: 20px; height: 20px;" />
</div>
<h3 class="fac-card-title">Recurring billing</h3>
<p class="fac-card-desc">Schedule monthly, quarterly, or annual invoices for policies with installment plans. Automatic reminders on upcoming due dates.</p>
</div>
<div class="fac-card">
<div class="fac-icon" style="background: rgba(194,123,26,0.08); color: #c27b1a;">
<UIcon name="i-heroicons-banknotes" style="width: 20px; height: 20px;" />
</div>
<h3 class="fac-card-title">Payment tracking</h3>
<p class="fac-card-desc">Record payments against invoices, mark partial payments, and flag overdue balances. Ties into the collections workstation.</p>
</div>
<div class="fac-card">
<div class="fac-icon" style="background: rgba(15,123,95,0.08); color: #0f7b5f;">
<UIcon name="i-heroicons-building-office-2" style="width: 20px; height: 20px;" />
</div>
<h3 class="fac-card-title">Carrier reconciliation</h3>
<p class="fac-card-desc">Match brokerage invoices to carrier statements. Surface discrepancies between what was billed and what was remitted.</p>
</div>
<div class="fac-card">
<div class="fac-icon" style="background: rgba(193,56,56,0.08); color: #c13838;">
<UIcon name="i-heroicons-document-arrow-down" style="width: 20px; height: 20px;" />
</div>
<h3 class="fac-card-title">PDF & export</h3>
<p class="fac-card-desc">Generate branded PDF invoices, export batches to CSV for accounting software, or integrate via API with ERP systems.</p>
</div>
<div class="fac-card">
<div class="fac-icon" style="background: rgba(190,24,93,0.08); color: #be185d;">
<UIcon name="i-heroicons-chart-bar" style="width: 20px; height: 20px;" />
</div>
<h3 class="fac-card-title">Billing analytics</h3>
<p class="fac-card-desc">Aging reports, collection rates by client segment, revenue recognition dashboards, and commission payout summaries.</p>
</div>
</div>
</div>
</template>
<style scoped>
.fac-page {
display: flex;
flex-direction: column;
gap: 24px;
max-width: 64rem;
margin: 0 auto;
padding-bottom: 3rem;
}
.fac-card {
border-radius: 12px;
border: 1px solid rgba(0,0,0,0.06);
background: #fff;
box-shadow: 0 1px 3px rgba(0,0,0,0.03);
padding: 24px;
display: flex;
flex-direction: column;
gap: 10px;
transition: all 200ms ease;
}
.fac-card:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
border-color: rgba(1,105,111,0.15);
}
.fac-icon {
display: flex;
align-items: center;
justify-content: center;
width: 36px; height: 36px;
border-radius: 10px;
}
.fac-card-title {
font-size: 15px;
font-weight: 600;
color: var(--text-primary);
}
.fac-card-desc {
font-size: 13px;
line-height: 1.5;
color: var(--text-muted);
}
</style>

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
usePageTitle('Renewals')
</script>
<template>
<div class="mx-auto max-w-2xl py-16 text-center">
<div class="inline-flex flex-col items-center gap-4">
<span
class="inline-flex items-center rounded-full px-3 py-1 text-[11px] font-semibold uppercase tracking-wider"
style="background: rgba(1, 105, 111, 0.06); color: #01696f;"
>Coming soon</span>
<h1 class="text-2xl font-semibold tracking-tight text-[var(--text-primary)]">Renewals</h1>
<p class="text-[14px] leading-relaxed text-[var(--text-muted)]">
Monitor upcoming policy expirations and manage the renewal pipeline end to end.
</p>
</div>
</div>
</template>