RegisterV4.js 25 KB

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