Files
policy-ui/app/composables/useReferralChannels.ts
Jordan Weingarten 67482f6629 WIP jordan
2026-04-16 11:11:44 -05:00

68 lines
3.4 KiB
TypeScript

/**
* Referral channel registry — persisted in localStorage.
* Used across the app: quick leads, customer registration, reporting.
*/
import { useLocalStorageRef } from '~/utils/useLocalStorageRef'
export interface ReferralChannel {
id: string
name: string
type: 'person' | 'company' | 'digital' | 'event' | 'other'
contactName: string
contactPhone: string
contactEmail: string
note: string
active: boolean
createdAt: string
}
const KEY = 'policy-ui-referral-channels-v1'
const SEED_CHANNELS: ReferralChannel[] = [
{ id: 'ref-001', name: 'Roberto Jiménez', type: 'person', contactName: 'Roberto Jiménez', contactPhone: '+506 8834-2291', contactEmail: 'rjimenez@email.com', note: 'Long-time VIP client — strong auto & life referrals', active: true, createdAt: '2024-06-10T10:00:00Z' },
{ id: 'ref-002', name: 'Constructora Delta', type: 'company', contactName: 'Ing. Carlos Mora', contactPhone: '+506 2245-8800', contactEmail: 'cmora@delta.cr', note: 'Construction company — fleet and liability leads', active: true, createdAt: '2024-08-15T10:00:00Z' },
{ id: 'ref-003', name: 'Instagram Ads', type: 'digital', contactName: '', contactPhone: '', contactEmail: '', note: 'Paid social campaigns — auto & health focus', active: true, createdAt: '2025-01-10T10:00:00Z' },
{ id: 'ref-004', name: 'Google Ads', type: 'digital', contactName: '', contactPhone: '', contactEmail: '', note: 'Search campaigns — high intent leads', active: true, createdAt: '2025-01-10T10:00:00Z' },
{ id: 'ref-005', name: 'Expo Comercio 2025', type: 'event', contactName: 'Comité Organizador', contactPhone: '+506 2222-0000', contactEmail: 'info@expocomercio.cr', note: 'Annual trade expo — collected 40+ contacts', active: false, createdAt: '2025-03-20T10:00:00Z' },
{ id: 'ref-006', name: 'Cámara de Comercio', type: 'company', contactName: 'Patricia Arias', contactPhone: '+506 2233-5500', contactEmail: 'parias@camara.cr', note: 'Chamber of commerce partnership — corporate referrals', active: true, createdAt: '2024-11-05T10:00:00Z' },
{ id: 'ref-007', name: 'Walk-in / Oficina', type: 'other', contactName: '', contactPhone: '', contactEmail: '', note: 'Foot traffic to main office', active: true, createdAt: '2024-01-01T10:00:00Z' },
]
export function useReferralChannels() {
const channels = useLocalStorageRef<ReferralChannel[]>(KEY, () => [])
// Seed on first use
if (import.meta.client && channels.value.length === 0) {
channels.value = [...SEED_CHANNELS]
}
function addChannel(entry: Omit<ReferralChannel, 'id' | 'createdAt'>) {
const channel: ReferralChannel = {
id: 'ref-' + (crypto.randomUUID?.() ?? String(Date.now())).slice(0, 8),
createdAt: new Date().toISOString(),
...entry,
}
channels.value = [channel, ...channels.value]
return channel
}
function updateChannel(id: string, updates: Partial<Omit<ReferralChannel, 'id' | 'createdAt'>>) {
channels.value = channels.value.map(c =>
c.id === id ? { ...c, ...updates } : c
)
}
function removeChannel(id: string) {
channels.value = channels.value.filter(c => c.id !== id)
}
const activeChannels = computed(() => channels.value.filter(c => c.active))
/** Flat list for use in dropdowns */
const channelOptions = computed(() =>
activeChannels.value.map(c => ({ label: c.name, value: c.id }))
)
return { channels, activeChannels, channelOptions, addChannel, updateChannel, removeChannel }
}