import { useState } from 'react'; import { View, Text, ScrollView, TouchableOpacity, ActivityIndicator, Linking } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useLocalSearchParams, router } from 'expo-router'; import { useQuery } from '@tanstack/react-query'; import { api } from '../../../services/api'; const TABS = ['Profile', 'Subscription', 'Invoices', 'Payments']; const STATUS_COLOR: Record = { ACTIVE: '#166534', SUSPENDED: '#92400E', CANCELLED: '#991B1B', PENDING: '#475569', }; const STATUS_BG: Record = { ACTIVE: '#DCFCE7', SUSPENDED: '#FEF3C7', CANCELLED: '#FEE2E2', PENDING: '#F1F5F9', }; const INV_STATUS: Record = { PAID: { label: 'Paid', color: '#166534', bg: '#DCFCE7' }, UNPAID: { label: 'Unpaid', color: '#92400E', bg: '#FEF3C7' }, OVERDUE: { label: 'Overdue', color: '#991B1B', bg: '#FEE2E2' }, PARTIAL: { label: 'Partial', color: '#0E7490', bg: '#CFFAFE' }, VOID: { label: 'Void', color: '#6B7280', bg: '#F1F5F9' }, }; function InfoRow({ label, value, onPress, isLast }: { label: string; value?: string | null; onPress?: () => void; isLast?: boolean }) { return ( {label} {value ?? '—'} ); } export default function ClientDetailScreen() { const { id } = useLocalSearchParams<{ id: string }>(); const [tab, setTab] = useState('Profile'); const { data: client, isLoading } = useQuery({ queryKey: ['client', id], queryFn: () => api.get(`/api/v1/clients/${id}`).then(r => r.data), }); const { data: subData, isLoading: subLoading } = useQuery({ queryKey: ['client-subscription', id], queryFn: () => api.get(`/api/v1/subscriptions?clientId=${id}&limit=1`).then(r => r.data?.data?.[0] ?? r.data?.[0] ?? null), enabled: tab === 'Subscription', }); const { data: invoices, isLoading: invLoading } = useQuery({ queryKey: ['client-invoices', id], queryFn: () => api.get(`/api/v1/invoices?clientId=${id}&limit=20`).then(r => r.data?.data ?? r.data ?? []), enabled: tab === 'Invoices', }); const { data: payments, isLoading: payLoading } = useQuery({ queryKey: ['client-payments', id], queryFn: () => api.get(`/api/v1/payments?clientId=${id}&limit=20`).then(r => r.data?.data ?? r.data ?? []), enabled: tab === 'Payments', }); if (isLoading) { return ( ); } const statusColor = STATUS_COLOR[client?.status] ?? '#475569'; const statusBg = STATUS_BG[client?.status] ?? '#F1F5F9'; return ( {/* Header */} router.back()} style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 12 }} activeOpacity={0.7} hitSlop={{ top: 10, bottom: 10, left: 0, right: 20 }}> ← Back {client?.firstName} {client?.lastName} {client?.accountNumber} {client?.status} {/* Tabs */} {TABS.map(t => ( setTab(t)} style={{ flex: 1, paddingVertical: 14, alignItems: 'center', borderBottomWidth: 2.5, borderBottomColor: tab === t ? '#0891B2' : 'transparent' }} activeOpacity={0.7} > {t} ))} {/* PROFILE */} {tab === 'Profile' && ( client?.phone && Linking.openURL(`tel:${client.phone}`)} /> )} {/* SUBSCRIPTION */} {tab === 'Subscription' && ( subLoading ? ( ) : !subData ? ( No active subscription ) : ( {subData.nextBillingDate && ( Next billing date {new Date(subData.nextBillingDate).toLocaleDateString('en-PH', { year: 'numeric', month: 'long', day: 'numeric' })} )} ) )} {/* INVOICES */} {tab === 'Invoices' && ( invLoading ? ( ) : !invoices?.length ? ( No invoices yet ) : ( invoices.map((inv: any) => { const st = INV_STATUS[inv.status] ?? { label: inv.status, color: '#6B7280', bg: '#F1F5F9' }; return ( {inv.invoiceNumber} {st.label} Due: {inv.dueDate ? new Date(inv.dueDate).toLocaleDateString() : '—'} ₱{Number(inv.amount ?? inv.totalAmount ?? 0).toLocaleString()} {inv.balance > 0 && ( Balance: ₱{Number(inv.balance).toLocaleString()} )} ); }) ) )} {/* PAYMENTS */} {tab === 'Payments' && ( payLoading ? ( ) : ( <> router.push({ pathname: '/(app)/payments/record', params: { prefillClientId: id, prefillName: `${client?.firstName} ${client?.lastName}`, prefillAccountNumber: client?.accountNumber } })} activeOpacity={0.8} > + Record Payment {!payments?.length ? ( No payments recorded ) : ( payments.map((p: any) => ( {p.paymentMethod} {p.paymentDate ? new Date(p.paymentDate).toLocaleDateString('en-PH') : new Date(p.createdAt).toLocaleDateString('en-PH')} {p.referenceNumber && Ref: {p.referenceNumber}} ₱{Number(p.amount).toLocaleString()} )) )} ) )} ); }