import { useState } from 'react'; import { View, Text, FlatList, TouchableOpacity, TextInput, ActivityIndicator, RefreshControl, Alert, Modal, KeyboardAvoidingView, Platform, ScrollView, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { router } from 'expo-router'; import { api } from '../../../services/api'; import { useAuthStore } from '../../../stores/authStore'; const STATUS_CONFIG: Record = { NEW: { label: 'New', color: '#0891B2', bg: '#ECFEFF' }, CONTACTED: { label: 'Contacted', color: '#D97706', bg: '#FEF3C7' }, INTERESTED: { label: 'Interested', color: '#7C3AED', bg: '#F5F3FF' }, CONVERTED: { label: 'Converted', color: '#166534', bg: '#DCFCE7' }, LOST: { label: 'Lost', color: '#6B7280', bg: '#F1F5F9' }, }; export default function LeadsScreen() { const { user } = useAuthStore(); const qc = useQueryClient(); const [search, setSearch] = useState(''); const [showAdd, setShowAdd] = useState(false); const [newName, setNewName] = useState(''); const [newPhone, setNewPhone] = useState(''); const [newAddress, setNewAddress] = useState(''); const [newNotes, setNewNotes] = useState(''); const [saving, setSaving] = useState(false); const { data, isLoading, refetch, isRefetching } = useQuery({ queryKey: ['leads'], queryFn: () => api.get('/api/v1/leads?limit=100').then(r => r.data?.data ?? r.data ?? []), }); const leads: any[] = (data ?? []).filter((l: any) => `${l.firstName} ${l.lastName} ${l.phone}`.toLowerCase().includes(search.toLowerCase()) ); const addLead = async () => { const parts = newName.trim().split(' '); const firstName = parts[0] ?? ''; const lastName = parts.slice(1).join(' ') || '—'; if (!firstName) { Alert.alert('Required', 'Enter the lead\'s name.'); return; } if (!newPhone.trim()) { Alert.alert('Required', 'Enter a contact number.'); return; } setSaving(true); try { await api.post('/api/v1/leads', { firstName, lastName, phone: newPhone.trim(), ...(newAddress.trim() ? { address: newAddress.trim() } : {}), ...(newNotes.trim() ? { notes: newNotes.trim() } : {}), }); setShowAdd(false); setNewName(''); setNewPhone(''); setNewAddress(''); setNewNotes(''); qc.invalidateQueries({ queryKey: ['leads'] }); refetch(); } catch (e: any) { Alert.alert('Error', e?.response?.data?.message ?? 'Could not save lead.'); } finally { setSaving(false); } }; const renderLead = ({ item: l }: { item: any }) => { const cfg = STATUS_CONFIG[l.status] ?? STATUS_CONFIG.NEW; return ( router.push(`/(app)/leads/${l.id}`)} activeOpacity={0.7} style={{ backgroundColor: '#fff', borderRadius: 14, padding: 16, marginBottom: 10, borderWidth: 1, borderColor: '#F1F5F9', flexDirection: 'row', alignItems: 'center' }} > {/* Avatar circle */} {l.firstName?.[0]?.toUpperCase() ?? '?'} {l.firstName} {l.lastName !== '—' ? l.lastName : ''} {l.phone} {l.notes ? {l.notes} : null} {cfg.label} ); }; return ( {/* Header */} Leads {leads.length} prospect{leads.length !== 1 ? 's' : ''} setShowAdd(true)} style={{ backgroundColor: '#fff', borderRadius: 20, paddingHorizontal: 14, paddingVertical: 8, flexDirection: 'row', alignItems: 'center', gap: 6 }} > + Add Lead {/* Search */} {search.length > 0 && ( setSearch('')}> × )} {isLoading ? ( ) : ( i.id} renderItem={renderLead} contentContainerStyle={{ padding: 16, paddingBottom: 40 }} refreshControl={} ListEmptyComponent={ 👥 No leads yet Tap + Add Lead to record a prospect } /> )} {/* Add Lead Modal */} setShowAdd(false)}> setShowAdd(false)} /> New Lead Full Name * Contact Number * Address (optional) Notes (optional) {saving ? : Save Lead} ); }