Files
CBS-Mobile-App/src/modules/agent/components/CustomerCard.tsx
T

204 lines
5.2 KiB
TypeScript

import React from 'react';
import { View, Text, StyleSheet, Pressable } from 'react-native';
import Ionicons from '@react-native-vector-icons/ionicons';
import { useTheme } from '../../../theme';
import type { AgentCustomer } from '../types/agentTypes';
import { formatAgentCurrency, maskPhone } from '../utils/agentFormatters';
interface CustomerCardProps {
customer: AgentCustomer;
onPress?: () => void;
onAction?: () => void;
actionIcon?: string;
actionColor?: string;
}
export const CustomerCard = ({
customer,
onPress,
onAction,
actionIcon,
actionColor,
}: CustomerCardProps) => {
const theme = useTheme();
const isOverdue = customer.status === 'overdue';
const isPaid = customer.dueAmount === 0;
const statusColor = isPaid
? theme.colors.success
: isOverdue
? theme.colors.danger
: theme.colors.warning;
return (
<Pressable
style={({ pressed }) => [
styles.card,
{
backgroundColor: theme.colors.surface,
borderColor: theme.colors.cardBorder,
opacity: pressed ? 0.9 : 1,
transform: [{ scale: pressed ? 0.98 : 1 }],
},
]}
onPress={onPress}
>
<View style={styles.header}>
<View style={styles.profileInfo}>
<View style={[styles.avatar, { backgroundColor: `${theme.colors.primary}15` }]}>
<Text style={[styles.avatarText, { color: theme.colors.primary }]}>
{customer.name.charAt(0).toUpperCase()}
</Text>
</View>
<View>
<Text style={[styles.name, { color: theme.colors.textPrimary }]}>{customer.name}</Text>
<View style={styles.phoneRow}>
<Ionicons name="call-outline" size={12} color={theme.colors.textMuted} />
<Text style={[styles.phone, { color: theme.colors.textMuted }]}>
{maskPhone(customer.phone)}
</Text>
</View>
</View>
</View>
<View style={[styles.statusBadge, { backgroundColor: `${statusColor}15` }]}>
<View style={[styles.statusDot, { backgroundColor: statusColor }]} />
<Text style={[styles.statusText, { color: statusColor }]}>
{isPaid ? 'Paid' : isOverdue ? 'Overdue' : 'Pending'}
</Text>
</View>
</View>
<View style={[styles.divider, { backgroundColor: theme.colors.cardBorder }]} />
<View style={styles.detailsRow}>
<View style={styles.detailItem}>
<Text style={[styles.detailLabel, { color: theme.colors.textMuted }]}>Total Due</Text>
<Text style={[styles.detailValue, { color: isOverdue ? theme.colors.danger : theme.colors.textPrimary }]}>
{formatAgentCurrency(customer.dueAmount)}
</Text>
</View>
<View style={[styles.vDivider, { backgroundColor: theme.colors.cardBorder }]} />
<View style={styles.detailItem}>
<Text style={[styles.detailLabel, { color: theme.colors.textMuted }]}>Total Collected</Text>
<Text style={[styles.detailValue, { color: theme.colors.textPrimary }]}>
{formatAgentCurrency(customer.totalCollected)}
</Text>
</View>
{onAction && (
<Pressable
style={[styles.actionBtn, { backgroundColor: `${actionColor || theme.colors.primary}15` }]}
onPress={onAction}
>
<Ionicons name={actionIcon || 'chevron-forward'} size={18} color={actionColor || theme.colors.primary} />
</Pressable>
)}
</View>
</Pressable>
);
};
const styles = StyleSheet.create({
card: {
borderRadius: 16,
borderWidth: 1,
padding: 16,
marginBottom: 12,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.03,
shadowRadius: 8,
elevation: 2,
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-start',
},
profileInfo: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
},
avatar: {
width: 40,
height: 40,
borderRadius: 20,
alignItems: 'center',
justifyContent: 'center',
},
avatarText: {
fontSize: 16,
fontWeight: '700',
},
name: {
fontSize: 15,
fontWeight: '700',
marginBottom: 2,
},
phoneRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 4,
},
phone: {
fontSize: 12,
},
statusBadge: {
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 8,
paddingVertical: 4,
borderRadius: 12,
gap: 4,
},
statusDot: {
width: 6,
height: 6,
borderRadius: 3,
},
statusText: {
fontSize: 10,
fontWeight: '700',
textTransform: 'uppercase',
},
divider: {
height: 1,
width: '100%',
marginVertical: 12,
},
detailsRow: {
flexDirection: 'row',
alignItems: 'center',
},
detailItem: {
flex: 1,
},
detailLabel: {
fontSize: 11,
fontWeight: '500',
marginBottom: 4,
},
detailValue: {
fontSize: 14,
fontWeight: '700',
},
vDivider: {
width: 1,
height: 30,
marginHorizontal: 16,
},
actionBtn: {
width: 36,
height: 36,
borderRadius: 18,
alignItems: 'center',
justifyContent: 'center',
marginLeft: 16,
},
});