113 lines
4.8 KiB
TypeScript
113 lines
4.8 KiB
TypeScript
import React from 'react';
|
|
import { View, Text, TouchableOpacity } from 'react-native';
|
|
import Icon from 'react-native-vector-icons/Ionicons';
|
|
import { useTheme } from '@theme';
|
|
import { getStyles } from './leadItemCard.styles';
|
|
import { LeadItemCardProps } from './leadItemCard.props';
|
|
import { getInitials, handleEmailPress, handlePhonePress, toRgba, formatDate } from '@utils';
|
|
|
|
export const LeadItemCard: React.FC<LeadItemCardProps> = ({ item, onPress }) => {
|
|
const { theme: colors, isDark } = useTheme();
|
|
const styles = getStyles(colors);
|
|
|
|
const accent = item.color?.startsWith('#') ? item.color : '#5B4CF5';
|
|
const tint = (a: number) => toRgba(accent, isDark ? a + 0.08 : a);
|
|
|
|
return (
|
|
<TouchableOpacity style={styles.cardWrapper} onPress={onPress} activeOpacity={0.8}>
|
|
<View style={styles.card}>
|
|
<View style={[styles.leftStrip, { backgroundColor: accent }]} />
|
|
|
|
<View style={styles.cardInner}>
|
|
<View style={styles.topSection}>
|
|
<View style={[styles.avatar, { backgroundColor: accent }]}>
|
|
<Text style={styles.avatarText}>{getInitials(item.name)}</Text>
|
|
</View>
|
|
|
|
<View style={styles.meta}>
|
|
<Text style={styles.name} numberOfLines={1}>
|
|
{item.name || 'No Name'}
|
|
</Text>
|
|
|
|
{(item.company || item.title) && (
|
|
<View style={styles.companyRow}>
|
|
{item.company && (
|
|
<>
|
|
<Icon name="business-outline" size={11} color={colors.textMuted} />
|
|
<Text style={styles.companyText} numberOfLines={1}>{item.company}</Text>
|
|
</>
|
|
)}
|
|
{item.company && item.title && <View style={styles.dot} />}
|
|
{item.title && (
|
|
<Text style={styles.titleText} numberOfLines={1}>{item.title}</Text>
|
|
)}
|
|
</View>
|
|
)}
|
|
|
|
<View style={[styles.statusBadge, { backgroundColor: tint(0.10) }]}>
|
|
<View style={[styles.statusDot, { backgroundColor: accent }]} />
|
|
<Text style={[styles.statusText, { color: accent }]}>
|
|
{item.status_name || item.status || 'No Status'}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
|
|
{(item.email || item.phonenumber) && (
|
|
<>
|
|
<View style={styles.separator} />
|
|
<View style={styles.contacts}>
|
|
{item.email && (
|
|
<View style={styles.contactRow}>
|
|
<View style={[styles.iconWrap, { backgroundColor: tint(0.08) }]}>
|
|
<Icon name="mail-outline" size={13} color={accent} />
|
|
</View>
|
|
<Text style={styles.contactText} numberOfLines={1}>{item.email}</Text>
|
|
<TouchableOpacity
|
|
style={[styles.actionBtn, { backgroundColor: tint(0.08) }]}
|
|
onPress={() => handleEmailPress(item.email)}
|
|
hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
|
|
<Icon name="send-outline" size={12} color={accent} />
|
|
</TouchableOpacity>
|
|
</View>
|
|
)}
|
|
|
|
{item.phonenumber && (
|
|
<View style={styles.contactRow}>
|
|
<View style={[styles.iconWrap, { backgroundColor: tint(0.08) }]}>
|
|
<Icon name="call-outline" size={13} color={accent} />
|
|
</View>
|
|
<Text style={styles.contactText} numberOfLines={1}>{item.phonenumber}</Text>
|
|
<TouchableOpacity
|
|
style={[styles.actionBtn, { backgroundColor: tint(0.08) }]}
|
|
onPress={() => handlePhonePress(item.phonenumber)}
|
|
hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
|
|
<Icon name="call-outline" size={12} color={accent} />
|
|
</TouchableOpacity>
|
|
</View>
|
|
)}
|
|
</View>
|
|
</>
|
|
)}
|
|
|
|
<View style={styles.footer}>
|
|
{(item.source_name || item.source) ? (
|
|
<View style={styles.sourcePill}>
|
|
<Icon name="radio-outline" size={10} color={colors.textMuted} />
|
|
<Text style={styles.sourceText}>{item.source_name || item.source}</Text>
|
|
</View>
|
|
) : <View />}
|
|
|
|
{item.dateadded && (
|
|
<View style={styles.dateRow}>
|
|
<Icon name="time-outline" size={10} color={colors.textMuted} />
|
|
<Text style={styles.dateText}>{formatDate(item.dateadded)}</Text>
|
|
</View>
|
|
)}
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</TouchableOpacity>
|
|
);
|
|
};
|