import React, { useEffect, useMemo, useState } from 'react'; import { Text, View, FlatList, Alert } from 'react-native'; import Icon from 'react-native-vector-icons/Ionicons'; import { useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { getStyles } from './customers.styles'; import { useTheme } from '../../theme'; import { useAppDispatch, useAppSelector, RootState } from '@store'; import { getCustomers, deleteCustomer, resetCustomersState } from './thunk'; import { CustomerItem } from '@interfaces'; import { SearchInput, Loader, StatCard, CustomerItemCard } from '@components'; import { CustomersStackParamList } from '../../navigation/customersStack'; import { route } from '@utils'; type CustomersScreenNavigationProp = NativeStackNavigationProp< CustomersStackParamList, 'customersList' >; export const CustomersScreen = () => { const { theme: colors } = useTheme(); const styles = getStyles(colors); const dispatch = useAppDispatch(); const navigation = useNavigation(); const [searchTerm, setSearchTerm] = useState(''); const [selectedFilter, setSelectedFilter] = useState<'all' | 'active' | 'inactive'>('all'); const { items, loading, error, successMessage, deleteError } = useAppSelector( (state: RootState) => state.customers, ); useEffect(() => { dispatch(getCustomers()); }, [dispatch]); useEffect(() => { if (successMessage) { Alert.alert('Success', successMessage); dispatch(resetCustomersState()); } else if (deleteError) { Alert.alert('Error', deleteError); dispatch(resetCustomersState()); } }, [successMessage, deleteError, dispatch]); // Stats const totalCount = items.length; const activeCount = items.filter(c => c.active === '1').length; const inactiveCount = items.filter(c => c.active !== '1').length; const statCards = [ { label: 'Total', count: totalCount, color: colors.icon, key: 'all' }, { label: 'Active', count: activeCount, color: '#10B981', key: 'active' }, { label: 'Inactive', count: inactiveCount, color: '#EF4444', key: 'inactive' }, ] as const; // Filtered list const filteredCustomers = useMemo(() => { return items.filter(c => { const matchesSearch = searchTerm ? c.company?.toLowerCase().includes(searchTerm.toLowerCase()) || c.fullname?.toLowerCase().includes(searchTerm.toLowerCase()) || c.email?.toLowerCase().includes(searchTerm.toLowerCase()) : true; const matchesFilter = selectedFilter === 'all' ? true : selectedFilter === 'active' ? c.active === '1' : c.active !== '1'; return matchesSearch && matchesFilter; }); }, [items, searchTerm, selectedFilter]); const handleCustomerPress = (customer: CustomerItem) => { navigation.navigate(route.customerDetails, { userid: customer.userid, customer, }); }; const handleDeleteCustomer = (customer: CustomerItem) => { Alert.alert( 'Delete Customer', `Are you sure you want to delete "${customer.company || customer.fullname || 'this customer'}"? This action cannot be undone.`, [ { text: 'Cancel', style: 'cancel' }, { text: 'Delete', style: 'destructive', onPress: () => { dispatch(deleteCustomer({ userid: customer.userid })); }, }, ], ); }; const renderCustomer = ({ item }: { item: CustomerItem }) => ( handleCustomerPress(item)} onDelete={() => handleDeleteCustomer(item)} /> ); return ( {/* Search Header */} {/* Stat Cards - Grid aligned across the screen width */} {statCards.map(s => ( setSelectedFilter(prev => (prev === s.key ? 'all' : s.key)) } /> ))} {/* Customer List */} {loading ? ( ) : error ? ( {error} ) : ( item.userid} style={{ flex: 1 }} contentContainerStyle={styles.listContent} renderItem={renderCustomer} ListEmptyComponent={() => ( No Customers Found {searchTerm ? `No customers match "${searchTerm}". Try a different search.` : 'No customers yet. They will appear here.'} )} /> )} ); };