AddCard.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /**
  2. * 添加信用卡页面
  3. * @邠心vbe on 2021/05/08
  4. */
  5. import React, { Component } from 'react';
  6. import { View, Text, StyleSheet, TextInput, Switch } from 'react-native';
  7. import apiUser from '../../api/apiUser';
  8. import Button from '../../components/Button';
  9. import apiWallet from '../../api/apiWallet';
  10. import Dialog from '../../components/Dialog';
  11. import Dropdown from '../../components/Dropdown';
  12. export default class AddCard extends Component {
  13. constructor(props) {
  14. super(props);
  15. this.state = {
  16. primary: false,
  17. validTill: '',
  18. countryList: [],
  19. countryCode: '',
  20. };
  21. this.form = {}
  22. }
  23. componentDidMount() {
  24. this.getCountryList();
  25. }
  26. getCountryList() {
  27. apiUser.getCountryCode().then(res => {
  28. if (res.data) {
  29. const list = []
  30. for (let item in res.data) {
  31. if (item) {
  32. list.push({
  33. code: item,
  34. name: res.data[item]
  35. });
  36. }
  37. }
  38. this.setState({
  39. countryList: list
  40. });
  41. }
  42. }).catch(err => {
  43. });
  44. }
  45. validate() {
  46. if (!this.form.nameOnCard) {
  47. toastShort('Please type name on card');
  48. return;
  49. }
  50. if (!this.form.cardNumber) {
  51. toastShort('Please type card number');
  52. return;
  53. }
  54. if (!/^\d{9,}$/.test(this.form.cardNumber)) {
  55. toastShort('Please type a correct card number');
  56. return;
  57. }
  58. if (!this.state.validTill) {
  59. toastShort('Please type valid till');
  60. return;
  61. }
  62. if (!/^(0[1-9]|1[0-2])\/(2[1-9]|[3-5][0-9])/.test(this.state.validTill)) {
  63. toastShort('Please type a correct valid till');
  64. return;
  65. }
  66. if (!this.form.cardCvv) {
  67. toastShort('Please type CVV');
  68. return;
  69. }
  70. if (!/^\d{3}$/.test(this.form.cardCvv)) {
  71. toastShort('Please type a correct CVV');
  72. return;
  73. }
  74. const params = this.form;
  75. params.country = this.state.countryCode;
  76. params.primary = this.state.primary ? 'Y' : 'N';
  77. params.validTill = this.state.validTill;
  78. this.addCard(params);
  79. }
  80. addCard(params) {
  81. Dialog.showProgressDialog();
  82. apiWallet.addCreditCard(params).then(res => {
  83. Dialog.dismissLoading();
  84. toastShort('Add card successfully');
  85. goBack();
  86. }).catch(err => {
  87. Dialog.dismissLoading();
  88. toastShort(err);
  89. });
  90. }
  91. render() {
  92. return (
  93. <View style={styles.container}>
  94. <View style={styles.formView}>
  95. <Text style={styles.label}>Name on Card</Text>
  96. <TextInput
  97. style={styles.cardNameInput}
  98. placeholder={'Your name on card'}
  99. maxLength={50}
  100. onChangeText={text => this.form.nameOnCard = text}/>
  101. </View>
  102. <View style={styles.formView}>
  103. <Text style={styles.label}>Card Number</Text>
  104. <View style={styles.cardNumberRow}>
  105. <FontAwesome
  106. name='credit-card'
  107. size={24}
  108. color={colorAccent}/>
  109. <Text style={styles.leftLine}/>
  110. <TextInput
  111. style={styles.cardNumber}
  112. placeholder='Card Number'
  113. maxLength={25}
  114. keyboardType={'numeric'}
  115. onChangeText={text => {
  116. this.form.cardNumber = text;
  117. }}/>
  118. </View>
  119. </View>
  120. <View style={styles.formRow}>
  121. <View style={styles.formColumn}>
  122. <Text style={styles.label}>Valid Till</Text>
  123. <TipInput
  124. placeholder='MM/YY'
  125. maxLength={5}
  126. keyboardType={'numeric'}
  127. value={this.state.validTill}
  128. onChangeText={text => {
  129. if (this.state.validTill.length == 2 && text.length == 3) {
  130. if (text.indexOf('/') == -1) {
  131. let s = this.state.validTill + '/' + text.substring(2)
  132. this.setState({
  133. validTill: s
  134. });
  135. } else {
  136. this.setState({
  137. validTill: text
  138. });
  139. }
  140. } else {
  141. this.setState({
  142. validTill: text
  143. });
  144. }
  145. }}/>
  146. </View>
  147. <View style={styles.formColumn}>
  148. <Text style={styles.label}>CVV</Text>
  149. <TipInput
  150. placeholder='CVV'
  151. maxLength={6}
  152. keyboardType={'numeric'}
  153. onChangeText={text => {
  154. this.form.cardCvv = text;
  155. }}/>
  156. </View>
  157. </View>
  158. <View style={styles.formView}>
  159. <Text style={styles.label}>Country where card was issued</Text>
  160. <View style={styles.countryRow}>
  161. <MaterialIcons
  162. name='flag'
  163. color={colorAccent}
  164. size={30}/>
  165. <Dropdown
  166. style={styles.countryPicker }
  167. title='Country'
  168. list={this.state.countryList}
  169. nameKey='name'
  170. valueKey='code'
  171. showIcon={false}
  172. onChange={(value, index)=> {
  173. this.setState({
  174. countryCode: value,
  175. countryIndex: index
  176. });
  177. }}
  178. />
  179. <Text style={styles.changeText}>Change</Text>
  180. </View>
  181. </View>
  182. <View style={styles.switchRow}>
  183. <Text
  184. style={[styles.label, ui.flex1]}
  185. onPress={() => {
  186. this.setState({
  187. primary: !this.state.primary
  188. });
  189. }}>Set as Primary</Text>
  190. <Switch
  191. value={this.state.primary}
  192. trackColor={isIOS ? { false: "#B2B2B2", true: colorAccent } : null}
  193. onValueChange={v => {
  194. this.setState({
  195. primary: v
  196. });
  197. }}/>
  198. </View>
  199. <Text style={styles.tipsText}>Your card may be charged to make sure it’s vailid.That amount will be automatically refunded.</Text>
  200. <Text style={styles.tipsText}>By adding a card,you have read and agree to our terms and conditions.</Text>
  201. <Text style={ui.flex1}></Text>
  202. <View style={styles.buttonView}>
  203. <Button
  204. text='Save'
  205. elevation={1.5}
  206. onClick={() => {
  207. this.validate();
  208. }}/>
  209. </View>
  210. </View>
  211. );
  212. }
  213. }
  214. const TipInput = ({onChangeText, maxLength, placeholder, keyboardType, value}) => {
  215. return (
  216. <View style={styles.cardInputView}>
  217. <TextInput
  218. style={styles.cardInput}
  219. placeholder={placeholder}
  220. maxLength={maxLength}
  221. keyboardType={keyboardType}
  222. onChangeText={onChangeText}
  223. value={value}/>
  224. <MaterialIcons
  225. name='info-outline'
  226. color='#999'
  227. size={16}/>
  228. </View>
  229. );
  230. }
  231. const styles = StyleSheet.create({
  232. container: {
  233. flex: 1,
  234. backgroundColor: 'white'
  235. },
  236. formView: {
  237. paddingTop: 16,
  238. paddingLeft: 16,
  239. paddingRight: 16,
  240. paddingBottom: 4
  241. },
  242. formRow: {
  243. paddingTop: 12,
  244. paddingLeft: 8,
  245. paddingRight: 8,
  246. paddingBottom: 8,
  247. alignItems: 'center',
  248. flexDirection: 'row'
  249. },
  250. formColumn: {
  251. flex: 1,
  252. paddingLeft: 8,
  253. paddingRight: 8
  254. },
  255. label: {
  256. color: '#333',
  257. fontSize: 14
  258. },
  259. leftLine: {
  260. width: 1,
  261. height: 20,
  262. marginLeft: 16,
  263. backgroundColor: colorAccent
  264. },
  265. cardNumberRow: {
  266. paddingTop: 8,
  267. alignItems: 'center',
  268. flexDirection: 'row',
  269. },
  270. cardNumber: {
  271. flex: 1,
  272. color: '#333',
  273. fontSize: 16,
  274. paddingLeft: 4,
  275. },
  276. cardNameInput: {
  277. color: '#333',
  278. fontSize: 14,
  279. paddingBottom: 2,
  280. borderBottomColor: '#EEE',
  281. borderBottomWidth: 1
  282. },
  283. cardInputView: {
  284. paddingTop: 16,
  285. paddingLeft: 2,
  286. paddingRight: 2,
  287. paddingBottom: 2,
  288. alignItems: 'center',
  289. flexDirection: 'row',
  290. borderBottomColor: '#EEE',
  291. borderBottomWidth: 1
  292. },
  293. cardInput: {
  294. flex: 1,
  295. padding: 0,
  296. color: '#333',
  297. fontSize: 14,
  298. },
  299. countryRow: {
  300. paddingTop: 8,
  301. paddingBottom: 4,
  302. alignItems: 'flex-end',
  303. flexDirection: 'row',
  304. borderBottomWidth: 1,
  305. borderBottomColor: '#EEE'
  306. },
  307. countryPicker: {
  308. flex: 1,
  309. color: '#333',
  310. fontSize: 14,
  311. paddingTop: 4,
  312. paddingLeft: 16
  313. },
  314. changeText: {
  315. right: 0,
  316. bottom: 0,
  317. padding: 10,
  318. color: '#12A5F9',
  319. fontSize: 12,
  320. position: 'absolute',
  321. backgroundColor: 'white',
  322. },
  323. switchRow: {
  324. padding: 16,
  325. alignItems: 'center',
  326. flexDirection: 'row',
  327. },
  328. tipsText: {
  329. color: '#333',
  330. fontSize: 12,
  331. padding: 16,
  332. },
  333. buttonView: {
  334. padding: 16,
  335. marginBottom: 16
  336. }
  337. })