big refactor
This commit is contained in:
@@ -1,11 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import { useQuickLeads, type QuickLead } from '~/composables/useQuickLeads'
|
||||
|
||||
usePageTitle('Quick Leads')
|
||||
|
||||
const { leads, addLead, removeLead, recentLeads } = useQuickLeads()
|
||||
const toast = useToast()
|
||||
|
||||
/* ── Types ── */
|
||||
interface QuickLead {
|
||||
id: string
|
||||
name: string
|
||||
phone: string
|
||||
email: string
|
||||
product: string
|
||||
source: string
|
||||
priority: 'normal' | 'high' | 'urgent'
|
||||
note: string
|
||||
agent: string
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
/* ── Storage ── */
|
||||
const STORAGE_KEY = 'policy-ui.quick-leads'
|
||||
|
||||
function loadLeads(): QuickLead[] {
|
||||
if (import.meta.client) {
|
||||
try {
|
||||
const raw = localStorage.getItem(STORAGE_KEY)
|
||||
if (raw) {
|
||||
return JSON.parse(raw) as QuickLead[]
|
||||
}
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
function saveLeads(leads: QuickLead[]) {
|
||||
if (import.meta.client) {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(leads))
|
||||
} catch { /* quota */ }
|
||||
}
|
||||
}
|
||||
|
||||
/* ── State ── */
|
||||
const leads = ref<QuickLead[]>(loadLeads())
|
||||
|
||||
watch(leads, (v) => {
|
||||
saveLeads(v)
|
||||
}, { deep: true })
|
||||
|
||||
function addLead(lead: Omit<QuickLead, 'id' | 'createdAt'>) {
|
||||
const newLead: QuickLead = {
|
||||
id: crypto.randomUUID?.() ?? String(Date.now() + Math.random()),
|
||||
createdAt: new Date().toISOString(),
|
||||
...lead,
|
||||
}
|
||||
leads.value = [newLead, ...leads.value]
|
||||
}
|
||||
|
||||
function removeLead(id: string) {
|
||||
leads.value = leads.value.filter(l => l.id !== id)
|
||||
}
|
||||
|
||||
function recentLeads(days: number): QuickLead[] {
|
||||
const cutoff = Date.now() - days * 86400000
|
||||
return leads.value.filter(l => new Date(l.createdAt).getTime() > cutoff)
|
||||
}
|
||||
|
||||
/* ── Form state ── */
|
||||
const formOpen = ref(false)
|
||||
const name = ref('')
|
||||
@@ -103,27 +164,6 @@ function formatDate(iso: string) {
|
||||
if (diff < 172800000) return 'Yesterday'
|
||||
return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })
|
||||
}
|
||||
|
||||
/* ── Seed demo data if empty ── */
|
||||
onMounted(() => {
|
||||
if (leads.value.length === 0) {
|
||||
const now = Date.now()
|
||||
const demoLeads: Omit<QuickLead, 'id'>[] = [
|
||||
{ name: 'Diego Herrera', phone: '+506 6100-4422', email: 'diego.h@gmail.com', product: 'Auto', source: 'referral', priority: 'high', note: 'Referred by Roberto Jiménez — needs fleet quote for 3 vehicles', agent: 'Marco V.', createdAt: new Date(now - 2 * 86400000).toISOString() },
|
||||
{ name: 'Valeria Núñez', phone: '+506 8899-1100', email: '', product: 'Auto', source: 'walk-in', priority: 'normal', note: 'Walk-in, interested in comprehensive auto', agent: 'Ana R.', createdAt: new Date(now - 4 * 86400000).toISOString() },
|
||||
{ name: 'Patricia Mora', phone: '+506 7700-3311', email: 'patricia.mora@empresa.cr', product: 'Health', source: 'website', priority: 'urgent', note: 'Corporate group health RFP — 20 employees, need response by Friday', agent: 'Ana R.', createdAt: new Date(now - 1 * 86400000).toISOString() },
|
||||
{ name: 'José Ramírez', phone: '+506 6045-8820', email: 'jramirez@outlook.com', product: 'Life', source: 'phone', priority: 'normal', note: 'Interested in term life, age 45', agent: 'Marco V.', createdAt: new Date(now - 6 * 86400000).toISOString() },
|
||||
{ name: 'Lucía Castillo', phone: '+506 8312-5500', email: '', product: 'Auto', source: 'social', priority: 'high', note: 'Instagram DM — new car, wants quote ASAP', agent: 'Marco V.', createdAt: new Date(now - 3 * 86400000).toISOString() },
|
||||
]
|
||||
// Insert with proper IDs
|
||||
for (const entry of demoLeads.reverse()) {
|
||||
leads.value = [{
|
||||
id: crypto.randomUUID?.() ?? String(Date.now() + Math.random()),
|
||||
...entry,
|
||||
}, ...leads.value]
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
Reference in New Issue
Block a user