import React, { useState, useCallback } from "react"; import { View, Pressable, ActivityIndicator, FlatList, TextInput, } from "react-native"; import { Text } from "@/components/ui/text"; import { Card } from "@/components/ui/card"; import { useSirouRouter } from "@sirou/react-native"; import { AppRoutes } from "@/lib/routes"; import { User, Search, Building2, Plus } from "@/lib/icons"; import { ScreenWrapper } from "@/components/ScreenWrapper"; import { StandardHeader } from "@/components/StandardHeader"; import { EmptyState } from "@/components/EmptyState"; import { Button } from "@/components/ui/button"; import { api } from "@/lib/api"; import { useFocusEffect } from "expo-router"; import { useAuthStore } from "@/lib/auth-store"; import { useColorScheme } from "nativewind"; import { getPlaceholderColor } from "@/lib/colors"; interface Customer { id: string; displayName: string; email: string; phone: string; type: "INDIVIDUAL" | "COMPANY"; createdAt: string; } const TYPE_FILTERS = [ { key: "", label: "All" }, { key: "INDIVIDUAL", label: "Individual" }, { key: "COMPANY", label: "Company" }, ]; export default function CustomersScreen() { const nav = useSirouRouter(); const { colorScheme } = useColorScheme(); const isDark = colorScheme === "dark"; const [customers, setCustomers] = useState([]); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); const [loadingMore, setLoadingMore] = useState(false); const [search, setSearch] = useState(""); const [typeFilter, setTypeFilter] = useState(""); const fetchCustomers = useCallback( async (pageNum: number, isRefresh = false) => { const { isAuthenticated } = useAuthStore.getState(); if (!isAuthenticated) return; try { if (!isRefresh) { pageNum === 1 ? setLoading(true) : setLoadingMore(true); } const query: Record = { page: pageNum, limit: 10 }; if (search.trim()) query.search = search.trim(); if (typeFilter) query.type = typeFilter; const response = await api.customers.getAll({ query }); const newData = response.data; if (isRefresh) { setCustomers(newData); } else { setCustomers((prev) => pageNum === 1 ? newData : [...prev, ...newData], ); } setHasMore(response.meta.hasNextPage); setPage(pageNum); } catch (err: any) { console.error("[Customers] Fetch error:", err); setHasMore(false); } finally { setLoading(false); setRefreshing(false); setLoadingMore(false); } }, [search, typeFilter], ); useFocusEffect( useCallback(() => { setPage(1); fetchCustomers(1); }, [fetchCustomers]), ); const onRefresh = () => { setRefreshing(true); setPage(1); fetchCustomers(1, true); }; const loadMore = () => { if (hasMore && !loadingMore && !loading) { fetchCustomers(page + 1); } }; const renderItem = ({ item }: { item: Customer }) => ( nav.go("customers/[id]", { id: item.id })}> {item.type === "COMPANY" ? ( ) : ( )} {item.displayName} {item.type === "COMPANY" ? "Company" : "Individual"} {item.email || item.phone ? ( {item.email ? ( {item.email} ) : null} {item.email && item.phone ? ( ยท ) : null} {item.phone ? ( {item.phone} ) : null} ) : null} ); return ( item.id} contentContainerStyle={{ paddingBottom: 150 }} showsVerticalScrollIndicator={false} onRefresh={onRefresh} refreshing={refreshing} onEndReached={loadMore} onEndReachedThreshold={0.5} ListHeaderComponent={ <> {/* Search */} {/* Type filter */} {TYPE_FILTERS.map((f) => ( { setTypeFilter(f.key); setPage(1); }} className={`px-4 py-1.5 rounded-[4px] ${ typeFilter === f.key ? "bg-primary" : "bg-card border border-border" }`} > {f.label} ))} } ListFooterComponent={ loadingMore ? ( ) : null } ListEmptyComponent={ !loading ? ( ) : ( ) } /> ); }