RegisterV4.js 23 KB

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