68 lines
3.4 KiB
TypeScript
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 }
|
|
}
|