import { useState } from 'react'; import { View, Text, ScrollView, TouchableOpacity, ActivityIndicator, Linking } from 'react-native'; 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_COLORS: Record = { ACTIVE: '#16A34A', SUSPENDED: '#D97706', CANCELLED: '#DC2626', PENDING: '#6B7280', }; const INV_STATUS: Record = { PAID: { label: 'Paid', color: '#16A34A' }, UNPAID: { label: 'Unpaid', color: '#D97706' }, OVERDUE: { label: 'Overdue', color: '#DC2626' }, PARTIAL: { label: 'Partial', color: '#2563EB' }, VOID: { label: 'Void', color: '#6B7280' }, }; const PAYMENT_METHODS: Record = { CASH: '๐Ÿ’ต', GCASH: '๐Ÿ“ฑ', MAYA: '๐Ÿ’™', BANK: '๐Ÿฆ', }; 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 ( ); return ( {/* Header */} router.back()} className="mr-3 p-1"> โ† {client?.firstName} {client?.lastName} {client?.accountNumber} {client?.status} {/* Tabs */} {TABS.map(t => ( setTab(t)} className={`flex-1 py-3 items-center border-b-2 ${tab === t ? 'border-primary' : 'border-transparent'}`} > {t} ))} {/* PROFILE TAB */} {tab === 'Profile' && ( client?.phone && Linking.openURL(`tel:${client.phone}`)} /> )} {/* SUBSCRIPTION TAB */} {tab === 'Subscription' && ( subLoading ? ( ) : !subData ? ( ๐Ÿ“ก No active subscription ) : ( {subData.nextBillingDate && ( ๐Ÿ“… Next billing: {new Date(subData.nextBillingDate).toLocaleDateString()} )} ) )} {/* INVOICES TAB */} {tab === 'Invoices' && ( invLoading ? ( ) : !invoices?.length ? ( ๐Ÿงพ No invoices yet ) : ( invoices.map((inv: any) => { const st = INV_STATUS[inv.status] ?? { label: inv.status, color: '#6B7280' }; return ( {inv.invoiceNumber} {st.label} {inv.dueDate ? new Date(inv.dueDate).toLocaleDateString() : 'โ€”'} โ‚ฑ{Number(inv.amount ?? inv.totalAmount).toLocaleString()} {inv.balance > 0 && ( Balance: โ‚ฑ{Number(inv.balance).toLocaleString()} )} ); }) ) )} {/* PAYMENTS TAB */} {tab === 'Payments' && ( payLoading ? ( ) : !payments?.length ? ( ๐Ÿ’ณ No payments recorded ) : ( <> router.push({ pathname: '/(app)/payments/record', params: { prefillClientId: id, prefillName: `${client?.firstName} ${client?.lastName}`, prefillAccountNumber: client?.accountNumber } })} > + Record Payment {payments.map((p: any) => ( {PAYMENT_METHODS[p.paymentMethod] ?? '๐Ÿ’ณ'} {p.paymentMethod} {p.paymentDate ? new Date(p.paymentDate).toLocaleDateString() : new Date(p.createdAt).toLocaleDateString()} {p.referenceNumber && ( Ref: {p.referenceNumber} )} โ‚ฑ{Number(p.amount).toLocaleString()} ))} ) )} ); }