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,169 @@
<script setup lang="ts">
definePageMeta({ ssr: false })
usePageTitle('Quotes · Custom')
const toast = useToast()
const form = reactive({
clientName: '',
clientEmail: '',
clientPhone: '',
lineOfBusiness: '',
policyType: '',
carrier: '',
startDate: '',
endDate: '',
sumInsured: null as number | null,
premium: null as number | null,
commissionPct: null as number | null,
deductible: null as number | null,
notes: ''
})
const commissionAmount = computed(() => {
if (form.premium && form.commissionPct) return ((form.premium * form.commissionPct) / 100).toFixed(2)
return '0.00'
})
const linesOfBusiness = ['Auto', 'Health', 'Life', 'Property', 'Liability', 'Marine', 'Surety', 'Other']
const inputCls = 'w-full rounded-xl border border-[var(--sidebar-border)] bg-[var(--surface)] px-3 py-2 text-sm text-[var(--text-primary)] placeholder:text-[var(--text-muted)]'
const labelCls = 'block text-sm font-semibold text-[var(--text-muted)] mb-1.5'
async function save() {
if (!form.clientName.trim() || !form.lineOfBusiness) {
toast.add({ title: 'Missing fields', description: 'Client name and line of business are required.', color: 'warning' })
return
}
toast.add({ title: 'Quote saved', description: 'Your custom quote has been recorded.', color: 'success' })
await navigateTo('/quotes')
}
</script>
<template>
<div class="mx-auto max-w-4xl space-y-6 pb-12">
<NuxtLink to="/quotes" class="inline-flex">
<UButton color="neutral" variant="ghost" size="sm" icon="i-heroicons-arrow-left">Back to quotes</UButton>
</NuxtLink>
<div>
<h1 class="mt-1 text-2xl font-semibold tracking-tight text-[var(--text-primary)]">Custom quote entry</h1>
<p class="mt-1 text-[13px] text-[var(--text-muted)]">
Manually enter a quote for any line of business quick single-page form.
</p>
</div>
<UCard :ui="{ body: { padding: 'p-5 sm:p-6' } }">
<template #header>
<div>
<p class="text-xs font-medium text-[var(--text-muted)]">Client</p>
<h2 class="mt-0.5 text-lg font-semibold text-[var(--text-primary)]">Client information</h2>
</div>
</template>
<div class="grid gap-4 sm:grid-cols-3">
<div>
<label :class="labelCls">Client name *</label>
<input v-model="form.clientName" :class="inputCls" placeholder="Full name" />
</div>
<div>
<label :class="labelCls">Email</label>
<input v-model="form.clientEmail" type="email" :class="inputCls" placeholder="client@example.com" />
</div>
<div>
<label :class="labelCls">Phone</label>
<input v-model="form.clientPhone" type="tel" :class="inputCls" placeholder="+1 (555) 000-0000" />
</div>
</div>
</UCard>
<UCard :ui="{ body: { padding: 'p-5 sm:p-6' } }">
<template #header>
<div>
<p class="text-xs font-medium text-[var(--text-muted)]">Policy</p>
<h2 class="mt-0.5 text-lg font-semibold text-[var(--text-primary)]">Policy details</h2>
</div>
</template>
<div class="space-y-4">
<div class="grid gap-4 sm:grid-cols-2">
<div>
<label :class="labelCls">Line of business *</label>
<select v-model="form.lineOfBusiness" :class="inputCls">
<option value="" disabled>Select line</option>
<option v-for="l in linesOfBusiness" :key="l" :value="l">{{ l }}</option>
</select>
</div>
<div>
<label :class="labelCls">Policy type / description</label>
<input v-model="form.policyType" :class="inputCls" placeholder="e.g. Comprehensive auto" />
</div>
</div>
<div class="grid gap-4 sm:grid-cols-3">
<div>
<label :class="labelCls">Carrier</label>
<input v-model="form.carrier" :class="inputCls" placeholder="Carrier name" />
</div>
<div>
<label :class="labelCls">Start date</label>
<input v-model="form.startDate" type="date" :class="inputCls" />
</div>
<div>
<label :class="labelCls">End date</label>
<input v-model="form.endDate" type="date" :class="inputCls" />
</div>
</div>
<div class="grid gap-4 sm:grid-cols-2">
<div>
<label :class="labelCls">Sum insured / limit</label>
<input v-model.number="form.sumInsured" type="number" :class="inputCls" placeholder="0.00" min="0" step="0.01" />
</div>
<div>
<label :class="labelCls">Deductible</label>
<input v-model.number="form.deductible" type="number" :class="inputCls" placeholder="0.00" min="0" step="0.01" />
</div>
</div>
<div class="grid gap-4 sm:grid-cols-3">
<div>
<label :class="labelCls">Premium</label>
<input v-model.number="form.premium" type="number" :class="inputCls" placeholder="0.00" min="0" step="0.01" />
</div>
<div>
<label :class="labelCls">Commission %</label>
<input v-model.number="form.commissionPct" type="number" :class="inputCls" placeholder="0" min="0" max="100" step="0.1" />
</div>
<div>
<label :class="labelCls">Commission amount</label>
<div :class="[inputCls, 'flex items-center bg-[var(--brand-soft)]/30 font-medium']">
{{ commissionAmount }}
</div>
</div>
</div>
</div>
</UCard>
<UCard :ui="{ body: { padding: 'p-5 sm:p-6' } }">
<template #header>
<div>
<p class="text-xs font-medium text-[var(--text-muted)]">Notes</p>
<h2 class="mt-0.5 text-lg font-semibold text-[var(--text-primary)]">Special conditions</h2>
</div>
</template>
<div>
<label :class="labelCls">Special conditions / notes</label>
<textarea v-model="form.notes" :class="inputCls" rows="4" placeholder="Any additional terms, conditions, or notes..." />
</div>
</UCard>
<div class="flex items-center justify-between">
<NuxtLink to="/quotes">
<UButton color="neutral" variant="ghost" size="sm">Cancel</UButton>
</NuxtLink>
<UButton color="primary" @click="save">Save quote</UButton>
</div>
</div>
</template>