// app/(tabs)/contacts.tsx import { View, Text, FlatList, TouchableOpacity, TextInput } from 'react-native'; import { useState, useCallback } from 'react'; import { useFocusEffect } from 'expo-router'; import { Plus, Search, X } from 'lucide-react-native'; import { useContactStore, Contact } from '@/store/useContactStore'; import { getDatabase } from '@/lib/database'; import { ContactCard } from '@/components/contacts/ContactCard'; import { AddContactSheet } from '@/components/contacts/AddContactSheet'; import { dbToContact } from '@/lib/contactHelpers'; export default function ContactsScreen() { const { contacts, setContacts } = useContactStore(); const [search, setSearch] = useState(''); const [statusFilter, setStatusFilter] = useState('All'); const [territoryFilter, setTerritoryFilter] = useState('All'); const [territories, setTerritories] = useState([]); const [showAdd, setShowAdd] = useState(false); const statusOptions = ['All', 'Active', 'Return Visit', 'Bible Study', 'Not Interested', 'Do Not Call']; async function loadContacts() { const db = await getDatabase(); const rows = await db.getAllAsync( 'SELECT * FROM contacts WHERE deleted_at IS NULL ORDER BY full_name ASC' ); setContacts(rows.map(dbToContact)); // Load territory codes for filter const tRows = await db.getAllAsync('SELECT territory_code FROM territories ORDER BY territory_code ASC'); setTerritories(tRows.map((r: any) => r.territory_code)); } useFocusEffect(useCallback(() => { loadContacts(); }, [])); const filtered = contacts.filter((c) => { const matchSearch = c.fullName.toLowerCase().includes(search.toLowerCase()) || (c.address?.toLowerCase().includes(search.toLowerCase()) ?? false); const matchStatus = statusFilter === 'All' || c.status === statusFilter; const matchTerritory = territoryFilter === 'All' || c.territoryCode === territoryFilter; return matchSearch && matchStatus && matchTerritory; }); return ( {/* Header */} Contacts setShowAdd(true)} className="bg-white/20 rounded-full p-2"> {/* Search */} {search ? setSearch('')}> : null} {/* Status Filter */} item} renderItem={({ item }) => ( setStatusFilter(item)} className={`px-3 py-1.5 rounded-full border ${statusFilter === item ? 'bg-primary border-primary' : 'bg-white border-gray-200'}`} > {item} )} /> {/* Territory Filter */} {territories.length > 0 && ( `t-${item}`} renderItem={({ item }) => ( setTerritoryFilter(item)} className={`px-3 py-1 rounded-full border ${territoryFilter === item ? 'bg-accent border-accent' : 'bg-white border-gray-200'}`} > {item === 'All' ? 'All Territories' : item} )} /> )} {/* List */} item.id} contentContainerStyle={{ paddingHorizontal: 16, paddingBottom: 100, paddingTop: 4, gap: 8 }} renderItem={({ item }) => } ListEmptyComponent={() => ( {search ? 'No contacts found' : 'No contacts yet'} {!search && Tap + to add your first contact} )} /> setShowAdd(false)} onSaved={() => { setShowAdd(false); loadContacts(); }} /> ); }