RegisterV4.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. /**
  2. * 带OTP的注册页面
  3. * @邠心vbe on 2023/02/06
  4. */
  5. import React from 'react';
  6. import { View, ScrollView, StyleSheet, TextInput, Pressable, Image, Linking } from 'react-native';
  7. import apiUser from '../../api/apiUser';
  8. import Button from '../../components/Button';
  9. import { PageList } from '../Router';
  10. import Dialog from '../../components/Dialog';
  11. import app from '../../../app.json';
  12. import Dropdown from '../../components/Dropdown';
  13. import ImagePicker from 'react-native-image-crop-picker';
  14. import apiUpload from '../../api/apiUpload';
  15. import { CountryDropCode, CountryDropNum, GetCountryList } from '../../components/CountryIcon';
  16. import StrengthView from './StrengthView';
  17. import CheckBox from '../../components/CheckBox';
  18. import { UploadThemes } from '../../components/ThemesConfig';
  19. import TextView from '../../components/TextView';
  20. import utils from '../../utils/utils';
  21. const options = {
  22. width: 300,
  23. height: 200,
  24. cropping: true,
  25. multiple: false,
  26. mediaType: 'photo',
  27. writeTempFile: false,
  28. compressImageQuality: 0.8,
  29. compressImageMaxWidth: 720,
  30. compressImageMaxHeight: 1280,
  31. ...UploadThemes
  32. }
  33. export default class RegisterV4 extends React.Component {
  34. constructor(props) {
  35. super(props);
  36. this.StrengthView = StrengthView.V4
  37. this.state = {
  38. agree: false,
  39. agree2: false,
  40. strength: 0,
  41. countryNum: '65',
  42. countryCode: "SG",
  43. userInfo: {
  44. email: "",
  45. verificationCode: ""
  46. },
  47. countryList: [],
  48. wrongCount: 0,
  49. params: {...this.props.route.params},
  50. email: '',
  51. password: '',
  52. fleetCompanyId: '',
  53. sendMinutes: 0,
  54. isFleetDriver: false,
  55. pdvImages: ['', ''],
  56. companyList: []
  57. };
  58. this.canChangeCalling = true;
  59. }
  60. componentDidMount() {
  61. //console.log(this.state.params);
  62. if (this.state.params.isFleetUser) {
  63. this.setState({
  64. isFleetDriver: true
  65. })
  66. this.props.navigation.setOptions({
  67. headerTitle: $t('route.driverRegister')
  68. })
  69. }
  70. this.getCountryList();
  71. this.getCompanyList();
  72. }
  73. applyStrength(text) {
  74. this.StrengthView.apply(text, strength => {
  75. if (this.state.strength != strength) {
  76. this.setState({
  77. password: text,
  78. strength: strength
  79. });
  80. } else {
  81. this.setState({
  82. password: text
  83. });
  84. }
  85. });
  86. }
  87. changeInfo(key, value) {
  88. var info = this.state.userInfo;
  89. info[key] = value;
  90. this.setState({
  91. 'userInfo': info
  92. });
  93. }
  94. getCountryList() {
  95. GetCountryList(list => {
  96. this.setState({
  97. countryList: list
  98. })
  99. })
  100. }
  101. getCompanyList() {
  102. apiUser.getConmpany().then(res => {
  103. if (res.data) {
  104. this.setState({
  105. companyList: res.data
  106. })
  107. }
  108. }).catch(err => [
  109. toastShort(err)
  110. ])
  111. }
  112. sendVerification() {
  113. var info = this.state.userInfo;
  114. if (!info.email) {
  115. toastShort($t('sign.plsInputEmail'));
  116. return;
  117. }
  118. if (!utils.isValidEmail(info.email)) {
  119. toastShort($t('sign.errEmailFormat'));
  120. return;
  121. }
  122. Dialog.showProgressDialog()
  123. apiUser.sendVerificationCodeV2({email: info.email, type: "register"}).then(res => {
  124. Dialog.dismissLoading()
  125. //this.state.sendMinutes = 60;
  126. this.state.sendMinutes = res.data?.resendTime ?? 60;
  127. toastShort($t('sign.sendOTPSuccess'));
  128. this.contdownTime();
  129. }).catch(err => {
  130. Dialog.dismissLoading()
  131. toastShort(err);
  132. });
  133. }
  134. contdownTime() {
  135. if (this.state.sendMinutes > 0) {
  136. this.setState({
  137. sendMinutes: this.state.sendMinutes - 1
  138. })
  139. setTimeout(() => {
  140. this.contdownTime();
  141. }, 1000);
  142. }
  143. }
  144. onRegister() {
  145. //console.log('sign up', this.state);
  146. var info = this.state.userInfo;
  147. if (!info.nickName) {
  148. toastShort($t('sign.plsInputDiaplayName'));
  149. return;
  150. }
  151. if (!info.email) {
  152. toastShort($t('sign.plsInputEmail'));
  153. return;
  154. }
  155. if (!utils.isValidEmail(info.email)) {
  156. toastShort($t('sign.errEmailFormat'));
  157. return;
  158. }
  159. if (!info.verificationCode) {
  160. toastShort($t('sign.plsInputOTP'));
  161. return;
  162. }
  163. if (!info.phone) {
  164. toastShort($t('sign.plsInputContactNo'));
  165. return;
  166. }
  167. if (!/^\d{6,15}$/.test(info.phone)) {
  168. toastShort($t('sign.errContactNoFormat'));
  169. return;
  170. }
  171. if (!this.state.password) {
  172. toastShort($t('sign.plsInputPassword'));
  173. return;
  174. }
  175. if (this.state.strength < this.StrengthView.maxStrength) {
  176. toastShort($t('sign.errPasswordStrong'));
  177. return;
  178. }
  179. if (!info.password) {
  180. toastShort($t('sign.plsInputPassword2'));
  181. return;
  182. }
  183. if (info.password != this.state.password) {
  184. toastShort($t('sign.errPasswordConfirm'));
  185. if (this.state.wrongCount < 3) {
  186. this.setState({
  187. wrongCount: this.state.wrongCount + 1
  188. })
  189. }
  190. return;
  191. }
  192. if (this.state.isFleetDriver) {
  193. if (!info.pdvLicence) {
  194. toastShort($t('sign.plsInputPDVLicence'));
  195. return;
  196. }
  197. if (this.state.pdvImages[0] == '' || this.state.pdvImages[1] == '') {
  198. toastShort($t('sign.plsUploadLicencePhotos'));
  199. return;
  200. }
  201. }
  202. let param = Object.assign({}, info);
  203. //param.phone = this.state.countryNum + info.phone
  204. param.callingCode = this.state.countryNum;
  205. param.countryCode = this.state.countryCode;
  206. if (this.state.isFleetDriver) {
  207. param.userType = 'Driver';
  208. param.pdvLicencePictures = this.state.pdvImages;
  209. param.fleetCompanyId = this.state.fleetCompanyId;
  210. } else {
  211. param.userType = 'Public';
  212. }
  213. param.otp = param.verificationCode;
  214. console.log('params', param);
  215. Dialog.showProgressDialog();
  216. apiUser.register(param).then(res => {
  217. Dialog.dismissLoading();
  218. //toastShort('Sign up successfully!');
  219. if (isIOS) {
  220. setTimeout(() => {
  221. this.showSuccessDialog();
  222. }, 600);
  223. } else {
  224. this.showSuccessDialog();
  225. }
  226. }).catch(err => {
  227. toastShort(err);
  228. Dialog.dismissLoading();
  229. });
  230. }
  231. showSuccessDialog() {
  232. Dialog.showResultDialog($t('sign.signUpSuccess'), $t('nav.ok'),
  233. () => {
  234. this.backToLogin();
  235. }
  236. )
  237. }
  238. getBackTopPosition() {
  239. return isIOS ? statusHeight - 16 : 8;
  240. }
  241. backToLogin() {
  242. if (this.state.params.actionLogin) {
  243. goBack()
  244. startPage(PageList.login);
  245. } else {
  246. goBack();
  247. }
  248. }
  249. uploadImage(index) {
  250. ImagePicker.openPicker({
  251. ...options,
  252. cropperToolbarTitle: $t('common.cropperTitle')
  253. }).then(image => {
  254. if (image.path) {
  255. apiUpload.uploadImage(image.path, image.mime, 'PDVL').then(res => {
  256. if (res.success && res.data.picturePath) {
  257. let imageUrl = this.state.pdvImages;
  258. imageUrl[index] = res.data.picturePath;
  259. this.setState({
  260. pdvImages: imageUrl
  261. });
  262. toastShort($t('common.uploadSuccess'));
  263. } else {
  264. toastShort($t('common.updateFailed'));
  265. }
  266. }).catch(err => {
  267. toastShort(err);
  268. });
  269. }
  270. }).catch(err1 => {
  271. //console.log(err1);
  272. });
  273. }
  274. changeAgree(ag) {
  275. this.setState({
  276. agree: ag
  277. })
  278. }
  279. changeAgree2(ag) {
  280. this.setState({
  281. agree2: ag
  282. })
  283. }
  284. changeCountry(value, index) {
  285. this.setState({
  286. countryCode: value
  287. })
  288. if (this.canChangeCalling) {
  289. const country = this.state.countryList[index]
  290. this.changeCalling(country.countryNum, -1);
  291. }
  292. }
  293. changeCalling(value, index) {
  294. this.setState({
  295. countryNum: value
  296. })
  297. if (index >= 0) {
  298. this.canChangeCalling = false;
  299. }
  300. }
  301. toPrivayPolicy() {
  302. Linking.openURL(app.storeUrl.privacyPolicyUrl)
  303. }
  304. toUserTerms() {
  305. Linking.openURL(app.storeUrl.termsUseUrl)
  306. }
  307. render() {
  308. return (
  309. <View style={styles.container}>
  310. <ScrollView
  311. style={styles.scollView}
  312. keyboardShouldPersistTaps={isIOS ? 'never' : 'handled'}>
  313. <View style={styles.signView}>
  314. {/* <View style={styles.tabView}>
  315. <Text
  316. style={[
  317. styles.tabText,
  318. this.state.isFleetDriver ? {} : styles.tabActive
  319. ]}
  320. onPress={() => this.changeTab(false)}
  321. >Public Users</Text>
  322. <Text
  323. style={[
  324. styles.tabText,
  325. this.state.isFleetDriver ? styles.tabActive: {}
  326. ]}
  327. onPress={() => this.changeTab(true)}
  328. >Fleet/PH Drivers</Text>
  329. </View> */}
  330. <View style={styles.signInput}>
  331. <TextView style={styles.inputLabel}>{$t('sign.labelDisplayName')}</TextView>
  332. <TextInput
  333. style={styles.inputView}
  334. placeholder={$t('sign.labelDisplayName')}
  335. placeholderTextColor={textPlacehoder}
  336. maxLength={50}
  337. onChangeText={v => this.changeInfo('nickName', v)}
  338. />
  339. </View>
  340. <View style={styles.signInput}>
  341. <TextView style={styles.inputLabel}>{$t('sign.labelEmail')}</TextView>
  342. <TextInput
  343. style={styles.inputView}
  344. placeholder={$t('sign.labelEmail')}
  345. placeholderTextColor={textPlacehoder}
  346. maxLength={50}
  347. keyboardType="email-address"
  348. textContentType='emailAddress'
  349. onChangeText={v => this.changeInfo('email', v)}
  350. />
  351. </View>
  352. <View style={styles.signInput}>
  353. <TextView style={[styles.inputLabel, {flex: 2}]}>{$t('sign.labelValidateEmail')}</TextView>
  354. <TextInput
  355. style={[styles.inputView, {flex: 2.2, marginLeft: 2}]}
  356. placeholder={$t('sign.labelOtp')}
  357. placeholderTextColor={textPlacehoder}
  358. maxLength={6}
  359. keyboardType="number-pad"
  360. textContentType="telephoneNumber"
  361. onChangeText={v => this.changeInfo('verificationCode', v)}
  362. />
  363. <Button
  364. text={this.state.sendMinutes > 0 ? (this.state.sendMinutes + " s") : $t('sign.btnSendOTP')}
  365. style={styles.sendBtn}
  366. disabled={this.state.sendMinutes > 0}
  367. viewStyle={styles.sendBtnView}
  368. textStyle={styles.sendBtnText}
  369. onClick={() => this.sendVerification()}
  370. />
  371. </View>
  372. <View style={styles.signInput}>
  373. <TextView style={styles.inputLabel}>{$t('sign.labelCountry')}</TextView>
  374. <Dropdown
  375. style={styles.selectView}
  376. title={$t('sign.labelCountry')}
  377. list={this.state.countryList}
  378. value={this.state.countryCode}
  379. nameKey='countryName'
  380. valueKey='countryCode'
  381. iconColor={colorDark}
  382. onChange={(value, index)=> this.changeCountry(value, index)}
  383. customerItemView={
  384. (item, index, onClick) =>
  385. <CountryDropCode
  386. key={index}
  387. country={item}
  388. value={this.state.countryCode}
  389. onClick={onClick}/>
  390. }/>
  391. </View>
  392. <View style={styles.signInput}>
  393. <TextView style={styles.inputLabel}>{$t('sign.labelPhoneNumber')}</TextView>
  394. <View style={styles.mobileView}>
  395. <View style={styles.dropView}>
  396. <TextInput style={styles.dropInput} editable={false}/>
  397. <TextView style={styles.countryText}>{"+" + this.state.countryNum}</TextView>
  398. <MaterialIcons name={'arrow-drop-down'} size={24} color={colorDark}/>
  399. <Dropdown
  400. style={styles.dropLayer}
  401. prefixText="+"
  402. list={this.state.countryList}
  403. value={this.state.countryNum}
  404. nameKey='countryNum'
  405. valueKey='countryNum'
  406. onChange={(value, index)=> this.changeCalling(value, index)}
  407. customerItemView={
  408. (item, index, onClick) =>
  409. <CountryDropNum
  410. key={index}
  411. country={item}
  412. value={this.state.countryNum}
  413. onClick={onClick}/>
  414. }/>
  415. </View>
  416. <TextInput
  417. style={styles.contactView}
  418. placeholder={$t('sign.labelMobileNumber')}
  419. placeholderTextColor={textPlacehoder}
  420. keyboardType='phone-pad'
  421. maxLength={15}
  422. onChangeText={v => this.changeInfo('phone', v)}
  423. />
  424. </View>
  425. </View>
  426. <View style={styles.signInput}>
  427. <TextView style={styles.inputLabel}>{$t('sign.labelCreatePassword')}</TextView>
  428. <TextInput
  429. secureTextEntry={this.state.wrongCount < 3}
  430. style={styles.inputView}
  431. placeholder={$t('sign.labelPassword')}
  432. placeholderTextColor={textPlacehoder}
  433. maxLength={20}
  434. onChangeText={(value) => {
  435. this.applyStrength(value);
  436. }}
  437. />
  438. </View>
  439. <View style={styles.signInput}>
  440. <TextView style={styles.inputLabel}></TextView>
  441. <View style={styles.passwordView}>
  442. <this.StrengthView.VIEW strength={this.state.strength}/>
  443. </View>
  444. </View>
  445. <View style={styles.signInput}>
  446. <TextView style={styles.inputLabel}>{$t('sign.labelConfirmPassword')}</TextView>
  447. <TextInput
  448. secureTextEntry={this.state.wrongCount < 3}
  449. style={styles.inputView}
  450. placeholder={$t('sign.labelPassword')}
  451. placeholderTextColor={textPlacehoder}
  452. maxLength={20}
  453. onChangeText={v => this.changeInfo('password', v)}
  454. />
  455. </View>
  456. { this.state.isFleetDriver &&
  457. <>
  458. <View style={styles.signInput}>
  459. <TextView style={styles.inputLabel}>{$t('sign.labelYourCompany')}</TextView>
  460. <Dropdown
  461. style={[styles.inputView, ui.flexc]}
  462. title={$t('sign.labelCompany')}
  463. list={this.state.companyList}
  464. value={this.state.fleetCompanyId}
  465. valueKey='fleetCompanyId'
  466. nameKey='fleetCompanyName'
  467. onChange={(value, index)=> {
  468. this.setState({
  469. fleetCompanyId: value
  470. })
  471. }}/>
  472. </View>
  473. <View style={styles.signInput}>
  474. <TextView style={styles.inputLabel}>{$t('sign.labelPDVLicence')}</TextView>
  475. <TextInput
  476. style={styles.inputView}
  477. placeholder={$t('sign.hintPDVLicence')}
  478. placeholderTextColor={textPlacehoder}
  479. maxLength={20}
  480. onChangeText={v => this.changeInfo('pdvLicence', v)}
  481. />
  482. </View>
  483. <View style={styles.signInput}>
  484. <TextView style={styles.inputLabel}>{$t('sign.labelPDVPhotos')}</TextView>
  485. <View style={styles.uploadGroup}>
  486. { this.state.pdvImages.map((item, index) => (
  487. <UploadView
  488. key={index}
  489. onPress={() => this.uploadImage(index)}
  490. url={item}/>
  491. ))
  492. }
  493. </View>
  494. </View>
  495. </>
  496. }
  497. {/* <View style={styles.referView}>
  498. <Text style={styles.referTitle}>Have a referral code?</Text>
  499. <View style={styles.referText}>
  500. <Text>You'll get</Text>
  501. <Text style={styles.weight}>$5</Text>
  502. <Text>Credit as registration bonus!</Text>
  503. </View>
  504. <View style={styles.codeView}>
  505. <Text style={{ color: textPrimary, fontSize: 16 }}>Referral Code</Text>
  506. <TextInput
  507. style={styles.codeText}
  508. maxLength={6}
  509. placeholder='Referral Code'
  510. placeholderTextColor={textPlacehoder}
  511. onChangeText={v => this.changeInfo('referralCode', v)}
  512. />
  513. </View>
  514. </View> */}
  515. <View style={styles.consentView}>
  516. <TextView style={styles.consentTitle}>Consent and purpose notification</TextView>
  517. <TextView style={styles.agreeText}>
  518. We collect, use and disclose your personal data for the purpose of providing Electric Vehicle (EV) charging services to you.
  519. </TextView>
  520. </View>
  521. <View style={styles.agreeView}>
  522. <CheckBox
  523. value={this.state.agree2}
  524. onValueChange={v => this.changeAgree2(v)}
  525. />
  526. <View style={styles.agreeTextRow}>
  527. <TextView style={styles.agreeText} onPress={() => this.changeAgree2(!this.state.agree2)}>
  528. I consent to Strides YTL Pte. Ltd. to collect, use and disclose my personal data for the above purposes and in accordance with the SMRT Corporation’s Privacy Statement and Personal Data Protection Act 2012.
  529. </TextView>
  530. </View>
  531. </View>
  532. <View style={styles.agreeView2}>
  533. <CheckBox
  534. value={this.state.agree}
  535. onValueChange={v => this.changeAgree(v)}
  536. />
  537. <View style={styles.agreeTextRow}>
  538. <TextView style={styles.agreeText} onPress={() => this.changeAgree(!this.state.agree)}>
  539. {$t('sign.iHaveReadAndAgree')}
  540. </TextView>
  541. <TextView style={styles.agreeLink} onPress={() => this.toUserTerms()}>{$t('drawer.termsOfUse')}</TextView>
  542. <TextView style={styles.agreeText}>{' '}</TextView>
  543. <TextView style={styles.agreeText}>{$t('sign.linkAndLink')}</TextView>
  544. <TextView style={styles.agreeLink} onPress={() => this.toPrivayPolicy()}>{$t('drawer.privacyPolicy')}</TextView>
  545. <TextView style={styles.agreeText}>{$t('sign.linkAndLinkEnd')}</TextView>
  546. </View>
  547. </View>
  548. <Button
  549. style={styles.signButton}
  550. elevation={1.5}
  551. disabled={!this.state.agree || !this.state.agree2}
  552. text={$t('sign.btnSignUp')}
  553. fontSize={14}
  554. onClick={() => {
  555. this.onRegister();
  556. }}
  557. />
  558. </View>
  559. </ScrollView>
  560. </View>
  561. );
  562. }
  563. }
  564. const UploadView = ({url, onPress}) => (
  565. <Pressable
  566. style={styles.uploadView}
  567. onPress={onPress}>
  568. { url == ''
  569. ? <Image
  570. style={styles.uploadIcon}
  571. source={require('../../images/icon/ic-add-photo.png')}/>
  572. : <Image
  573. style={styles.uploadIcon}
  574. defaultSource={require('../../images/icon/icon-upload-default.png')}
  575. source={{uri: utils.getImageUrl(url)}}/>
  576. }
  577. </Pressable>
  578. )
  579. const styles = StyleSheet.create({
  580. container: {
  581. flex: 1,
  582. backgroundColor: colorLight
  583. },
  584. header: {
  585. paddingTop: 56,
  586. backgroundColor: colorAccent
  587. },
  588. backView: {
  589. top: 12,
  590. zIndex: 5,
  591. padding: 16,
  592. position: 'absolute',
  593. flexDirection: 'row'
  594. },
  595. backButton: {
  596. borderRadius: 60,
  597. backgroundColor: colorLight
  598. },
  599. backButtonView: {
  600. height: 43,
  601. paddingLeft: 16,
  602. paddingRight: 16,
  603. alignItems: 'center',
  604. flexDirection: 'row'
  605. },
  606. scollView: {
  607. flex: 1
  608. },
  609. logoView: {
  610. paddingTop: 32,
  611. paddingBottom: 56,
  612. alignItems: 'center'
  613. },
  614. logoImg: {
  615. width:165.09,
  616. height: 51.94,
  617. },
  618. signView: {
  619. flex: 1,
  620. padding: 16,
  621. //marginTop: -30,
  622. borderTopLeftRadius: 20,
  623. borderTopRightRadius: 20,
  624. backgroundColor: colorLight
  625. },
  626. tabView: {
  627. marginBottom: 4,
  628. borderWidth: 1,
  629. borderRadius: 6,
  630. overflow: 'hidden',
  631. alignItems: 'center',
  632. flexDirection: 'row',
  633. borderColor: colorAccent,
  634. },
  635. tabText: {
  636. flex: 1,
  637. color: textPrimary,
  638. fontSize: 15,
  639. textAlign: 'center',
  640. ...$padding(10, 0),
  641. },
  642. tabActive: {
  643. fontWeight: 'bold',
  644. backgroundColor: colorAccent
  645. },
  646. title: {
  647. color: textPrimary,
  648. fontSize: 18,
  649. fontWeight: '700',
  650. paddingTop: 4,
  651. paddingBottom: 6,
  652. },
  653. signInput: {
  654. marginTop: 16,
  655. alignItems: 'center',
  656. flexDirection: 'row'
  657. },
  658. inputLabel: {
  659. flex: 1,
  660. color: textPrimary,
  661. fontSize: 14,
  662. marginRight: 4
  663. },
  664. inputView: {
  665. flex: 2,
  666. color: textPrimary,
  667. fontSize: 14,
  668. borderRadius: 5,
  669. minHeight: 40,
  670. paddingTop: 6,
  671. paddingLeft: 12,
  672. paddingRight: 12,
  673. paddingBottom: 6,
  674. backgroundColor: '#F5F5F5'
  675. },
  676. selectView: {
  677. flex: 2,
  678. fontSize: 14,
  679. borderRadius: 5,
  680. minHeight: 40,
  681. paddingTop: 6,
  682. paddingLeft: 12,
  683. paddingRight: 6,
  684. paddingBottom: 6,
  685. alignItems: 'center',
  686. flexDirection: 'row',
  687. backgroundColor: '#F5F5F5'
  688. },
  689. mobileView: {
  690. flex: 2,
  691. marginLeft: -12,
  692. alignItems: 'center',
  693. flexDirection: 'row'
  694. },
  695. dropView: {
  696. fontSize: 16,
  697. borderRadius: 4,
  698. paddingRight: 4,
  699. flexDirection: 'row',
  700. alignItems: 'center',
  701. backgroundColor: '#F5F5F5'
  702. },
  703. dropInput: {
  704. width: 12,
  705. padding: 6,
  706. color: textPrimary,
  707. minHeight: 40,
  708. },
  709. countryText: {
  710. color: textPrimary,
  711. fontSize: 14,
  712. paddingRight: 4
  713. },
  714. dropLayer: {
  715. left: 0,
  716. right: 0,
  717. opacity: 0,
  718. position: 'absolute'
  719. },
  720. contactView: {
  721. flex: 1,
  722. color: textPrimary,
  723. fontSize: 15,
  724. borderRadius: 4,
  725. minHeight: 40,
  726. paddingTop: 6,
  727. paddingLeft: 12,
  728. paddingRight: 12,
  729. paddingBottom: 6,
  730. marginLeft: 10,
  731. backgroundColor: '#F5F5F5'
  732. },
  733. passwordView: {
  734. flex: 2,
  735. marginTop: -8,
  736. },
  737. referView: {
  738. padding: 16,
  739. marginTop: 24,
  740. borderRadius: 6,
  741. alignItems: 'center',
  742. backgroundColor: '#F5F5F5'
  743. },
  744. referTitle: {
  745. color: textPrimary,
  746. fontSize: 18,
  747. fontWeight: 'bold'
  748. },
  749. referText: {
  750. color: textPrimary,
  751. paddingTop: 4,
  752. alignItems: 'flex-end',
  753. flexDirection: 'row'
  754. },
  755. weight: {
  756. fontSize: 18,
  757. paddingLeft: 4,
  758. paddingRight: 4,
  759. color: colorAccent,
  760. fontWeight: 'bold'
  761. },
  762. codeView: {
  763. paddingTop: 16,
  764. alignItems: 'center',
  765. flexDirection: 'row'
  766. },
  767. codeText: {
  768. color: textPrimary,
  769. fontSize: 16,
  770. paddingTop: 6,
  771. paddingLeft: 12,
  772. paddingRight: 12,
  773. paddingBottom: 6,
  774. minHeight: 40,
  775. marginLeft: 16,
  776. borderRadius: 6,
  777. textAlign: 'center',
  778. backgroundColor: colorLight
  779. },
  780. signButton: {
  781. marginTop: 24,
  782. marginBottom: 8,
  783. },
  784. uploadGroup: {
  785. flex: 2,
  786. alignItems: 'center',
  787. flexDirection: 'row',
  788. justifyContent: 'center'
  789. },
  790. uploadView: {
  791. flex: 1,
  792. alignItems: 'center'
  793. },
  794. uploadIcon: {
  795. width: $vw(28),
  796. height: $vw(28),
  797. borderRadius: 6
  798. },
  799. consentView: {
  800. paddingTop: 32
  801. },
  802. consentTitle: {
  803. color: textPrimary,
  804. fontSize: 15,
  805. paddingTop: 2,
  806. paddingBottom: 8,
  807. fontWeight: 'bold',
  808. textDecorationLine: 'underline'
  809. },
  810. agreeView: {
  811. paddingTop: 16,
  812. marginBottom: 8,
  813. flexDirection: 'row',
  814. alignItems: 'flex-start',
  815. },
  816. agreeView2: {
  817. marginTop: 8,
  818. marginBottom: 16,
  819. flexDirection: 'row',
  820. alignItems: 'flex-start',
  821. },
  822. agreeTextRow: {
  823. flex: 1,
  824. paddingTop: 4,
  825. paddingLeft: 8,
  826. flexWrap: 'wrap',
  827. flexDirection: 'row'
  828. },
  829. agreeText: {
  830. color: textPrimary,
  831. fontSize: 14,
  832. paddingTop: 2,
  833. paddingBottom: 2
  834. },
  835. agreeLink: {
  836. ...ui.link,
  837. fontSize: 14,
  838. paddingTop: 2,
  839. paddingBottom: 2,
  840. textDecorationLine: 'underline'
  841. },
  842. sendBtn: {
  843. flex: 1.8,
  844. marginLeft: 6,
  845. marginRight: 0,
  846. borderRadius: 6
  847. },
  848. sendBtnView: {
  849. flex: 1,
  850. height: 40,
  851. paddingLeft: 4,
  852. paddingRight: 4,
  853. alignItems: 'center',
  854. justifyContent: 'center'
  855. },
  856. sendBtnText: {
  857. color: colorLight,
  858. fontSize: 13,
  859. fontWeight: 'bold'
  860. },
  861. });