256 lines
7.4 KiB
TypeScript
256 lines
7.4 KiB
TypeScript
import React from 'react';
|
|
import {
|
|
Image,
|
|
Modal,
|
|
ScrollView,
|
|
StyleSheet,
|
|
Text,
|
|
TouchableOpacity,
|
|
View,
|
|
} from 'react-native';
|
|
import * as Animatable from 'react-native-animatable';
|
|
|
|
export type WalletBindAction = {
|
|
key: string;
|
|
label: string;
|
|
};
|
|
|
|
export type WalletSelectRow = {
|
|
walletType: string;
|
|
label: string;
|
|
actions: WalletBindAction[];
|
|
};
|
|
|
|
export const WALLET_ICONS: Record<string, number> = {
|
|
paytm: require('../res/paytm.png'),
|
|
'paytm business': require('../res/paytm-business.png'),
|
|
phonepe: require('../res/phonepe.webp'),
|
|
'phonepe business': require('../res/phonepe-business.webp'),
|
|
'googlepay business': require('../res/googlepay-business.webp'),
|
|
'bharatpe business': require('../res/bharatpe-business.webp'),
|
|
mobikwik: require('../res/mobikwik.png'),
|
|
freecharge: require('../res/freecharge.png'),
|
|
amazonpay: require('../res/amazon.png'),
|
|
};
|
|
|
|
export const WALLET_TYPE_COLORS: Record<string, string> = {
|
|
paytm: '#002970',
|
|
'paytm business': '#002970',
|
|
phonepe: '#5a2d9c',
|
|
'phonepe business': '#5a2d9c',
|
|
'googlepay business': '#4285f4',
|
|
'bharatpe business': '#e91e63',
|
|
mobikwik: '#00bcd4',
|
|
freecharge: '#ff5722',
|
|
amazonpay: '#ff9900',
|
|
};
|
|
|
|
const TOKEN_MODE = 'Token Mode';
|
|
const OTP_MODE = 'Otp Mode';
|
|
|
|
export const WALLET_SELECT_ROWS: WalletSelectRow[] = [
|
|
{
|
|
walletType: 'paytm',
|
|
label: 'Paytm Personal',
|
|
actions: [
|
|
{ key: 'paytm_personal_token', label: TOKEN_MODE },
|
|
{ key: 'paytm_personal_otp', label: OTP_MODE },
|
|
],
|
|
},
|
|
{
|
|
walletType: 'paytm business',
|
|
label: 'Paytm Business',
|
|
actions: [{ key: 'paytm_business', label: OTP_MODE }],
|
|
},
|
|
{
|
|
walletType: 'phonepe',
|
|
label: 'PhonePe Personal',
|
|
actions: [
|
|
{ key: 'phonepe_personal_token', label: TOKEN_MODE },
|
|
{ key: 'phonepe_personal_otp', label: OTP_MODE },
|
|
],
|
|
},
|
|
{
|
|
walletType: 'phonepe business',
|
|
label: 'PhonePe Business',
|
|
actions: [
|
|
{ key: 'phonepe_business_web', label: TOKEN_MODE },
|
|
{ key: 'phonepe_business_otp', label: OTP_MODE },
|
|
],
|
|
},
|
|
{
|
|
walletType: 'googlepay business',
|
|
label: 'GooglePay Business',
|
|
actions: [{ key: 'googlepay_business', label: TOKEN_MODE }],
|
|
},
|
|
{
|
|
walletType: 'bharatpe business',
|
|
label: 'BharatPe Business',
|
|
actions: [{ key: 'bharatpe_business', label: OTP_MODE }],
|
|
},
|
|
{
|
|
walletType: 'mobikwik',
|
|
label: 'Mobikwik Personal',
|
|
actions: [
|
|
{ key: 'mobikwik_personal_token', label: TOKEN_MODE },
|
|
{ key: 'mobikwik_personal', label: OTP_MODE },
|
|
],
|
|
},
|
|
{
|
|
walletType: 'freecharge',
|
|
label: 'Freecharge Personal',
|
|
actions: [
|
|
{ key: 'freecharge_personal_token', label: TOKEN_MODE },
|
|
{ key: 'freecharge_personal', label: OTP_MODE },
|
|
],
|
|
},
|
|
{
|
|
walletType: 'amazonpay',
|
|
label: 'Amazon Pay',
|
|
actions: [{ key: 'amazonpay_personal', label: OTP_MODE }],
|
|
},
|
|
];
|
|
|
|
interface Props {
|
|
visible: boolean;
|
|
onClose: () => void;
|
|
onSelectBind: (bindKey: string) => void;
|
|
rows?: WalletSelectRow[];
|
|
}
|
|
|
|
export const WalletSelectModal: React.FC<Props> = ({
|
|
visible,
|
|
onClose,
|
|
onSelectBind,
|
|
rows = WALLET_SELECT_ROWS,
|
|
}) => (
|
|
<Modal visible={visible} transparent animationType="none" onRequestClose={onClose}>
|
|
<View style={styles.overlay}>
|
|
<Animatable.View
|
|
animation="zoomIn"
|
|
duration={220}
|
|
easing="ease-out-back"
|
|
useNativeDriver
|
|
style={styles.box}
|
|
>
|
|
<View style={styles.header}>
|
|
<Text style={styles.title}>Select Wallet Type</Text>
|
|
<TouchableOpacity onPress={onClose} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
|
|
<Text style={styles.close}>✕</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
<ScrollView bounces={false}>
|
|
{rows.map((row) => (
|
|
<View key={row.label} style={styles.row}>
|
|
{WALLET_ICONS[row.walletType] ? (
|
|
<Image
|
|
source={WALLET_ICONS[row.walletType]}
|
|
style={styles.icon}
|
|
resizeMode="contain"
|
|
/>
|
|
) : (
|
|
<View
|
|
style={[
|
|
styles.dot,
|
|
{ backgroundColor: WALLET_TYPE_COLORS[row.walletType] ?? '#888' },
|
|
]}
|
|
/>
|
|
)}
|
|
<Text style={styles.label} numberOfLines={1}>
|
|
{row.label}
|
|
</Text>
|
|
<View style={styles.actions}>
|
|
{row.actions.map((action) => (
|
|
<TouchableOpacity
|
|
key={action.key}
|
|
style={styles.actionBtn}
|
|
onPress={() => onSelectBind(action.key)}
|
|
activeOpacity={0.7}
|
|
>
|
|
<Text style={styles.actionBtnText}>{action.label}</Text>
|
|
</TouchableOpacity>
|
|
))}
|
|
</View>
|
|
</View>
|
|
))}
|
|
</ScrollView>
|
|
</Animatable.View>
|
|
</View>
|
|
</Modal>
|
|
);
|
|
|
|
const styles = StyleSheet.create({
|
|
overlay: {
|
|
flex: 1,
|
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
},
|
|
box: {
|
|
backgroundColor: '#fff',
|
|
borderRadius: 12,
|
|
padding: 16,
|
|
width: '88%',
|
|
maxHeight: '80%',
|
|
},
|
|
header: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
marginBottom: 12,
|
|
},
|
|
title: {
|
|
fontSize: 17,
|
|
fontWeight: '700',
|
|
color: '#222',
|
|
},
|
|
close: {
|
|
fontSize: 20,
|
|
color: '#999',
|
|
},
|
|
row: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
paddingVertical: 12,
|
|
borderBottomWidth: 1,
|
|
borderBottomColor: '#f0f0f0',
|
|
},
|
|
icon: {
|
|
width: 32,
|
|
height: 32,
|
|
borderRadius: 6,
|
|
marginRight: 10,
|
|
},
|
|
dot: {
|
|
width: 10,
|
|
height: 10,
|
|
borderRadius: 5,
|
|
marginRight: 10,
|
|
},
|
|
label: {
|
|
flex: 1,
|
|
fontSize: 14,
|
|
color: '#333',
|
|
marginRight: 8,
|
|
},
|
|
actions: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: 6,
|
|
},
|
|
actionBtn: {
|
|
paddingHorizontal: 8,
|
|
paddingVertical: 6,
|
|
borderRadius: 6,
|
|
backgroundColor: '#f0f4ff',
|
|
borderWidth: 1,
|
|
borderColor: '#d0daf0',
|
|
alignItems: 'center',
|
|
},
|
|
actionBtnText: {
|
|
fontSize: 11,
|
|
fontWeight: '600',
|
|
color: '#3355aa',
|
|
},
|
|
});
|