import React, { memo } from 'react'; import { Pressable, StyleSheet, Text, View, } from 'react-native'; import { Icon } from '../../../components/Icon'; import LinearGradient from 'react-native-linear-gradient'; import Animated, { Extrapolation, interpolate, SharedValue, useAnimatedStyle, useSharedValue, withTiming, } from 'react-native-reanimated'; import type { BankCard } from '../../../types/app'; import { getCardStatusLabel } from '../utils/cardCopy'; import { fontFamily } from '../../../theme'; interface CardItemProps { card: BankCard; index: number; scrollX: SharedValue; cardWidth: number; itemSize: number; height?: number; } const CardItemComponent = ({ card, index, scrollX, cardWidth, itemSize, height = 220, }: CardItemProps) => { const flipProgress = useSharedValue(0); const statusLabel = getCardStatusLabel(card); const statusColor = card.status === 'blocked' ? '#FFB3BC' : card.controls.frozen ? '#FFE08C' : '#C8FACC'; const toggleFlip = () => { flipProgress.value = withTiming(flipProgress.value === 0 ? 1 : 0, { duration: 420 }); }; const carouselStyle = useAnimatedStyle(() => { const inputRange = [(index - 1) * itemSize, index * itemSize, (index + 1) * itemSize]; return { transform: [ { scale: interpolate(scrollX.value, inputRange, [0.92, 1, 0.92], Extrapolation.CLAMP), }, { translateY: interpolate(scrollX.value, inputRange, [12, 0, 12], Extrapolation.CLAMP), }, ], opacity: interpolate(scrollX.value, inputRange, [0.72, 1, 0.72], Extrapolation.CLAMP), }; }); const frontStyle = useAnimatedStyle(() => ({ transform: [ { perspective: 1200 }, { rotateY: `${interpolate(flipProgress.value, [0, 1], [0, 180])}deg` }, ], })); const backStyle = useAnimatedStyle(() => ({ transform: [ { perspective: 1200 }, { rotateY: `${interpolate(flipProgress.value, [0, 1], [180, 360])}deg` }, ], })); return ( CBS Bank {card.type.toUpperCase()} CARD {statusLabel} {card.name} {card.maskedNumber} {card.cardholderName} VALID THRU {card.expiry} NETWORK {card.network} Flip PRIMARY LINKED ACCOUNT {card.primaryLinkedAccountId} DAILY LIMIT Rs {card.limits.daily.toLocaleString('en-IN')} LINKED ACCOUNTS {card.linkedAccountIds.length} 24x7 card care ยท 1800 100 2244 Tap card again to return ); }; const styles = StyleSheet.create({ flex: { flex: 1, }, frame: { overflow: 'visible', }, face: { ...StyleSheet.absoluteFillObject, backfaceVisibility: 'hidden', }, backFace: { zIndex: 2, }, gradient: { flex: 1, borderRadius: 28, padding: 22, justifyContent: 'space-between', overflow: 'hidden', }, headerRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12, }, brandName: { color: 'white', fontSize: 18, fontFamily: fontFamily.bold, letterSpacing: -0.3, }, cardMeta: { color: 'rgba(255,255,255,0.72)', fontSize: 10, fontFamily: fontFamily.bold, letterSpacing: 1.1, marginTop: 2, }, statusBadge: { flexDirection: 'row', alignItems: 'center', gap: 8, borderRadius: 999, paddingHorizontal: 12, paddingVertical: 8, backgroundColor: 'rgba(255,255,255,0.14)', }, statusDot: { width: 8, height: 8, borderRadius: 4, }, statusBadgeText: { color: 'white', fontSize: 11, fontFamily: fontFamily.bold, }, centerBlock: { gap: 10, }, cardName: { color: 'rgba(255,255,255,0.82)', fontSize: 12, fontFamily: fontFamily.bold, letterSpacing: 0.1, }, cardNumber: { color: 'white', fontSize: 28, fontFamily: fontFamily.bold, letterSpacing: 2, }, holderName: { color: 'rgba(255,255,255,0.92)', fontSize: 14, fontFamily: fontFamily.bold, letterSpacing: 0.6, }, footerRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-end', gap: 12, }, footerLabel: { color: 'rgba(255,255,255,0.68)', fontSize: 9, fontFamily: fontFamily.bold, letterSpacing: 1, }, footerValue: { color: 'white', fontSize: 13, fontFamily: fontFamily.bold, marginTop: 4, }, flipHint: { flexDirection: 'row', alignItems: 'center', gap: 6, }, flipText: { color: 'rgba(255,255,255,0.9)', fontSize: 12, fontFamily: fontFamily.bold, }, magneticStrip: { height: 42, marginHorizontal: -22, backgroundColor: 'rgba(7, 19, 33, 0.8)', }, backSection: { gap: 6, }, backGrid: { flexDirection: 'row', gap: 12, }, backCell: { flex: 1, gap: 6, padding: 14, borderRadius: 16, backgroundColor: 'rgba(255,255,255,0.12)', }, backLabel: { color: 'rgba(255,255,255,0.68)', fontSize: 10, fontFamily: fontFamily.bold, letterSpacing: 0.9, }, backValue: { color: 'white', fontSize: 14, fontFamily: fontFamily.bold, }, backFooter: { gap: 6, }, backSupport: { color: 'rgba(255,255,255,0.82)', fontSize: 12, fontFamily: fontFamily.semibold, }, }); export const CardItem = memo(CardItemComponent);