|
|
@@ -0,0 +1,349 @@
|
|
|
+/**
|
|
|
+ * 添加信用卡页面
|
|
|
+ * @邠心vbe on 2021/05/08
|
|
|
+ */
|
|
|
+import React, { Component } from 'react';
|
|
|
+import { View, Text, StyleSheet, TextInput, Switch } from 'react-native';
|
|
|
+import apiUser from '../../api/apiUser';
|
|
|
+import Button from '../../components/Button';
|
|
|
+import apiWallet from '../../api/apiWallet';
|
|
|
+import Dialog from '../../components/Dialog';
|
|
|
+import Dropdown from '../../components/Dropdown';
|
|
|
+
|
|
|
+export default class AddCard extends Component {
|
|
|
+ constructor(props) {
|
|
|
+ super(props);
|
|
|
+ this.state = {
|
|
|
+ primary: false,
|
|
|
+ validTill: '',
|
|
|
+ countryList: [],
|
|
|
+ countryCode: '',
|
|
|
+ };
|
|
|
+ this.form = {}
|
|
|
+ }
|
|
|
+
|
|
|
+ componentDidMount() {
|
|
|
+ this.getCountryList();
|
|
|
+ }
|
|
|
+
|
|
|
+ getCountryList() {
|
|
|
+ apiUser.getCountryCode().then(res => {
|
|
|
+ if (res.data) {
|
|
|
+ const list = []
|
|
|
+ for (let item in res.data) {
|
|
|
+ if (item) {
|
|
|
+ list.push({
|
|
|
+ code: item,
|
|
|
+ name: res.data[item]
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.setState({
|
|
|
+ countryList: list
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }).catch(err => {
|
|
|
+
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ validate() {
|
|
|
+ if (!this.form.nameOnCard) {
|
|
|
+ toastShort('Please type name on card');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!this.form.cardNumber) {
|
|
|
+ toastShort('Please type card number');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!/^\d{9,}$/.test(this.form.cardNumber)) {
|
|
|
+ toastShort('Please type a correct card number');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!this.state.validTill) {
|
|
|
+ toastShort('Please type valid till');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!/^(0[1-9]|1[0-2])\/(2[1-9]|[3-5][0-9])/.test(this.state.validTill)) {
|
|
|
+ toastShort('Please type a correct valid till');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!this.form.cardCvv) {
|
|
|
+ toastShort('Please type CVV');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!/^\d{3}$/.test(this.form.cardCvv)) {
|
|
|
+ toastShort('Please type a correct CVV');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const params = this.form;
|
|
|
+ params.country = this.state.countryCode;
|
|
|
+ params.primary = this.state.primary ? 'Y' : 'N';
|
|
|
+ params.validTill = this.state.validTill;
|
|
|
+ this.addCard(params);
|
|
|
+ }
|
|
|
+
|
|
|
+ addCard(params) {
|
|
|
+ Dialog.showProgressDialog();
|
|
|
+ apiWallet.addCreditCard(params).then(res => {
|
|
|
+ Dialog.dismissLoading();
|
|
|
+ toastShort('Add card successfully');
|
|
|
+ goBack();
|
|
|
+ }).catch(err => {
|
|
|
+ Dialog.dismissLoading();
|
|
|
+ toastShort(err);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ render() {
|
|
|
+ return (
|
|
|
+ <View style={styles.container}>
|
|
|
+ <View style={styles.formView}>
|
|
|
+ <Text style={styles.label}>Name on Card</Text>
|
|
|
+ <TextInput
|
|
|
+ style={styles.cardNameInput}
|
|
|
+ placeholder={'Your name on card'}
|
|
|
+ placeholderTextColor={textPlacehoder}
|
|
|
+ maxLength={50}
|
|
|
+ onChangeText={text => this.form.nameOnCard = text}/>
|
|
|
+ </View>
|
|
|
+ <View style={styles.formView}>
|
|
|
+ <Text style={styles.label}>Card Number</Text>
|
|
|
+ <View style={styles.cardNumberRow}>
|
|
|
+ <FontAwesome
|
|
|
+ name='credit-card'
|
|
|
+ size={24}
|
|
|
+ color={colorPrimary}/>
|
|
|
+ <Text style={styles.leftLine}/>
|
|
|
+ <TextInput
|
|
|
+ style={styles.cardNumber}
|
|
|
+ placeholder='Card Number'
|
|
|
+ placeholderTextColor={textPlacehoder}
|
|
|
+ maxLength={25}
|
|
|
+ keyboardType={'numeric'}
|
|
|
+ onChangeText={text => {
|
|
|
+ this.form.cardNumber = text;
|
|
|
+ }}/>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ <View style={styles.formRow}>
|
|
|
+ <View style={styles.formColumn}>
|
|
|
+ <Text style={styles.label}>Valid Till</Text>
|
|
|
+ <TipInput
|
|
|
+ placeholder='MM/YY'
|
|
|
+ maxLength={5}
|
|
|
+ keyboardType={'numeric'}
|
|
|
+ value={this.state.validTill}
|
|
|
+ onChangeText={text => {
|
|
|
+ if (this.state.validTill.length == 2 && text.length == 3) {
|
|
|
+ if (text.indexOf('/') == -1) {
|
|
|
+ let s = this.state.validTill + '/' + text.substring(2)
|
|
|
+ this.setState({
|
|
|
+ validTill: s
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.setState({
|
|
|
+ validTill: text
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.setState({
|
|
|
+ validTill: text
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }}/>
|
|
|
+ </View>
|
|
|
+ <View style={styles.formColumn}>
|
|
|
+ <Text style={styles.label}>CVV</Text>
|
|
|
+ <TipInput
|
|
|
+ placeholder='CVV'
|
|
|
+ maxLength={6}
|
|
|
+ keyboardType={'numeric'}
|
|
|
+ onChangeText={text => {
|
|
|
+ this.form.cardCvv = text;
|
|
|
+ }}/>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ <View style={styles.formView}>
|
|
|
+ <Text style={styles.label}>Country where card was issued</Text>
|
|
|
+ <View style={styles.countryRow}>
|
|
|
+ <MaterialIcons
|
|
|
+ name='flag'
|
|
|
+ color={colorPrimary}
|
|
|
+ size={30}/>
|
|
|
+ <Dropdown
|
|
|
+ style={styles.countryPicker }
|
|
|
+ title='Country'
|
|
|
+ list={this.state.countryList}
|
|
|
+ nameKey='name'
|
|
|
+ valueKey='code'
|
|
|
+ showIcon={false}
|
|
|
+ onChange={(value, index)=> {
|
|
|
+ this.setState({
|
|
|
+ countryCode: value,
|
|
|
+ countryIndex: index
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <Text style={styles.changeText}>Change</Text>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ <View style={styles.switchRow}>
|
|
|
+ <Text
|
|
|
+ style={[styles.label, ui.flex1]}
|
|
|
+ onPress={() => {
|
|
|
+ this.setState({
|
|
|
+ primary: !this.state.primary
|
|
|
+ });
|
|
|
+ }}>Set as Primary</Text>
|
|
|
+ <Switch
|
|
|
+ value={this.state.primary}
|
|
|
+ trackColor={isIOS ? { false: "#B2B2B2", true: colorAccent } : null}
|
|
|
+ onValueChange={v => {
|
|
|
+ this.setState({
|
|
|
+ primary: v
|
|
|
+ });
|
|
|
+ }}/>
|
|
|
+ </View>
|
|
|
+ <Text style={styles.tipsText}>Your card may be charged to make sure it’s vailid.That amount will be automatically refunded.</Text>
|
|
|
+ <Text style={styles.tipsText}>By adding a card,you have read and agree to our terms and conditions.</Text>
|
|
|
+ <Text style={ui.flex1}></Text>
|
|
|
+ <View style={styles.buttonView}>
|
|
|
+ <Button
|
|
|
+ text='Save'
|
|
|
+ elevation={1.5}
|
|
|
+ onClick={() => {
|
|
|
+ this.validate();
|
|
|
+ }}/>
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const TipInput = ({onChangeText, maxLength, placeholder, keyboardType, value}) => {
|
|
|
+ return (
|
|
|
+ <View style={styles.cardInputView}>
|
|
|
+ <TextInput
|
|
|
+ style={styles.cardInput}
|
|
|
+ placeholder={placeholder}
|
|
|
+ placeholderTextColor={textPlacehoder}
|
|
|
+ maxLength={maxLength}
|
|
|
+ keyboardType={keyboardType}
|
|
|
+ onChangeText={onChangeText}
|
|
|
+ value={value}/>
|
|
|
+ <MaterialIcons
|
|
|
+ name='info-outline'
|
|
|
+ color='#999'
|
|
|
+ size={16}/>
|
|
|
+ </View>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const styles = StyleSheet.create({
|
|
|
+ container: {
|
|
|
+ flex: 1,
|
|
|
+ backgroundColor: 'white'
|
|
|
+ },
|
|
|
+ formView: {
|
|
|
+ paddingTop: 16,
|
|
|
+ paddingLeft: 16,
|
|
|
+ paddingRight: 16,
|
|
|
+ paddingBottom: 4
|
|
|
+ },
|
|
|
+ formRow: {
|
|
|
+ paddingTop: 12,
|
|
|
+ paddingLeft: 8,
|
|
|
+ paddingRight: 8,
|
|
|
+ paddingBottom: 8,
|
|
|
+ alignItems: 'center',
|
|
|
+ flexDirection: 'row'
|
|
|
+ },
|
|
|
+ formColumn: {
|
|
|
+ flex: 1,
|
|
|
+ paddingLeft: 8,
|
|
|
+ paddingRight: 8
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ color: '#333',
|
|
|
+ fontSize: 14
|
|
|
+ },
|
|
|
+ leftLine: {
|
|
|
+ width: 1,
|
|
|
+ height: 20,
|
|
|
+ marginLeft: 16,
|
|
|
+ backgroundColor: colorAccent
|
|
|
+ },
|
|
|
+ cardNumberRow: {
|
|
|
+ paddingTop: 8,
|
|
|
+ alignItems: 'center',
|
|
|
+ flexDirection: 'row',
|
|
|
+ },
|
|
|
+ cardNumber: {
|
|
|
+ flex: 1,
|
|
|
+ color: '#333',
|
|
|
+ fontSize: 16,
|
|
|
+ paddingLeft: 4,
|
|
|
+ },
|
|
|
+ cardNameInput: {
|
|
|
+ color: '#333',
|
|
|
+ fontSize: 14,
|
|
|
+ paddingBottom: 2,
|
|
|
+ borderBottomColor: '#EEE',
|
|
|
+ borderBottomWidth: 1
|
|
|
+ },
|
|
|
+ cardInputView: {
|
|
|
+ paddingTop: 16,
|
|
|
+ paddingLeft: 2,
|
|
|
+ paddingRight: 2,
|
|
|
+ paddingBottom: 2,
|
|
|
+ alignItems: 'center',
|
|
|
+ flexDirection: 'row',
|
|
|
+ borderBottomColor: '#EEE',
|
|
|
+ borderBottomWidth: 1
|
|
|
+ },
|
|
|
+ cardInput: {
|
|
|
+ flex: 1,
|
|
|
+ padding: 0,
|
|
|
+ color: '#333',
|
|
|
+ fontSize: 14,
|
|
|
+ },
|
|
|
+ countryRow: {
|
|
|
+ paddingTop: 8,
|
|
|
+ paddingBottom: 4,
|
|
|
+ alignItems: 'flex-end',
|
|
|
+ flexDirection: 'row',
|
|
|
+ borderBottomWidth: 1,
|
|
|
+ borderBottomColor: '#EEE'
|
|
|
+ },
|
|
|
+ countryPicker: {
|
|
|
+ flex: 1,
|
|
|
+ color: '#333',
|
|
|
+ fontSize: 14,
|
|
|
+ paddingTop: 4,
|
|
|
+ paddingLeft: 16
|
|
|
+ },
|
|
|
+ changeText: {
|
|
|
+ right: 0,
|
|
|
+ bottom: 0,
|
|
|
+ padding: 10,
|
|
|
+ color: '#12A5F9',
|
|
|
+ fontSize: 12,
|
|
|
+ position: 'absolute',
|
|
|
+ backgroundColor: 'white',
|
|
|
+ },
|
|
|
+ switchRow: {
|
|
|
+ padding: 16,
|
|
|
+ alignItems: 'center',
|
|
|
+ flexDirection: 'row',
|
|
|
+ },
|
|
|
+ tipsText: {
|
|
|
+ color: '#333',
|
|
|
+ fontSize: 12,
|
|
|
+ padding: 16,
|
|
|
+ },
|
|
|
+ buttonView: {
|
|
|
+ padding: 16,
|
|
|
+ marginBottom: 16
|
|
|
+ }
|
|
|
+})
|