import React, { memo, useMemo } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import Ionicons from '@react-native-vector-icons/ionicons'; import { useTheme } from '../../../theme'; import type { CardPhysicalDelivery } from '../../../types/app'; import { formatDate } from '../../../utils/formatters'; import { getCardDeliveryProgressIndex, getCardDeliveryStatusLabel, } from '../utils/cardCopy'; interface CardDeliveryStatusProps { delivery: CardPhysicalDelivery; compact?: boolean; } type DeliveryStep = { id: string; label: string; }; const CardDeliveryStatusComponent = ({ delivery, compact = false, }: CardDeliveryStatusProps) => { const theme = useTheme(); const statusLabel = getCardDeliveryStatusLabel(delivery); const progressIndex = getCardDeliveryProgressIndex(delivery); const steps = useMemo( () => delivery.mode === 'home' ? [ { id: 'processing', label: 'Requested' }, { id: 'personalizing', label: 'Prepared' }, { id: 'shipped', label: 'In transit' }, { id: 'delivered', label: 'Delivered' }, ] : [ { id: 'processing', label: 'Requested' }, { id: 'personalizing', label: 'Prepared' }, { id: 'ready-for-pickup', label: 'At branch' }, { id: 'delivered', label: 'Collected' }, ], [delivery.mode], ); const accentColor = delivery.status === 'delivered' ? theme.colors.accentStrong : delivery.status === 'ready-for-pickup' ? theme.colors.warning : theme.colors.primary; const accentBackground = delivery.status === 'delivered' ? `${theme.colors.accent}12` : delivery.status === 'ready-for-pickup' ? `${theme.colors.warning}14` : `${theme.colors.primary}12`; const modeLabel = delivery.mode === 'home' ? 'Home delivery' : 'Branch pickup'; return ( Physical card delivery {statusLabel} {delivery.status === 'delivered' ? `Completed on ${formatDate(delivery.lastUpdatedAt)}` : `Expected by ${formatDate(delivery.estimatedDate)}`} {modeLabel} Tracking ID {delivery.trackingId} Destination {delivery.destinationLabel} {steps.map((step, index) => { const isCompleted = index < progressIndex; const isCurrent = index === progressIndex; const activeColor = isCompleted || isCurrent ? accentColor : theme.colors.cardBorder; const timelineDotStyle = { backgroundColor: isCompleted || isCurrent ? activeColor : 'transparent', borderColor: activeColor, }; const timelineLineStyle = { backgroundColor: index < progressIndex ? accentColor : theme.colors.cardBorder, }; return ( {isCompleted ? ( ) : null} {index !== steps.length - 1 ? ( ) : null} {step.label} ); })} {!compact ? ( Requested {formatDate(delivery.requestedAt)} Last updated {formatDate(delivery.lastUpdatedAt)} ) : null} ); }; const styles = StyleSheet.create({ container: { gap: 14, }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12, }, headerCopy: { flex: 1, gap: 4, }, eyebrow: { fontSize: 11, fontWeight: '700', textTransform: 'uppercase', letterSpacing: 0.8, }, title: { fontSize: 17, fontWeight: '800', letterSpacing: -0.2, }, subtitle: { fontSize: 13, lineHeight: 18, }, badge: { flexDirection: 'row', alignItems: 'center', gap: 6, borderRadius: 999, paddingHorizontal: 10, paddingVertical: 8, }, badgeText: { fontSize: 12, fontWeight: '700', }, metricsRow: { flexDirection: 'row', gap: 12, }, metricTile: { flex: 1, borderRadius: 18, padding: 14, gap: 6, }, metricLabel: { fontSize: 11, fontWeight: '700', textTransform: 'uppercase', letterSpacing: 0.7, }, metricValue: { fontSize: 14, fontWeight: '800', }, timelineRow: { flexDirection: 'row', alignItems: 'flex-start', }, timelineItem: { flex: 1, gap: 8, }, timelineTopRow: { flexDirection: 'row', alignItems: 'center', }, timelineDot: { width: 20, height: 20, borderRadius: 10, borderWidth: 2, alignItems: 'center', justifyContent: 'center', }, timelineLine: { flex: 1, height: 2, marginHorizontal: 6, }, timelineLabel: { fontSize: 11, fontWeight: '700', lineHeight: 15, }, footerCard: { borderRadius: 18, padding: 14, gap: 10, }, footerRow: { flexDirection: 'row', justifyContent: 'space-between', gap: 12, }, footerLabel: { fontSize: 12, fontWeight: '600', }, footerValue: { fontSize: 12, fontWeight: '800', }, }); export const CardDeliveryStatus = memo(CardDeliveryStatusComponent);