Browse Source

add app/pages/signLumi/RegisterVL.js

wudebin 5 months ago
parent
commit
d3be425485
1 changed files with 532 additions and 0 deletions
  1. 532 0
      Strides-SPAPP/app/pages/signLumi/RegisterVL.js

+ 532 - 0
Strides-SPAPP/app/pages/signLumi/RegisterVL.js

@@ -0,0 +1,532 @@
+/**
+ * LUMI版本Register页面
+ * @邠心vbe on 2024/05/31
+ */
+import React, { Component } from 'react';
+import { View, ScrollView, StyleSheet, TextInput, Pressable } from 'react-native';
+import apiUser from '../../api/apiUser';
+import Button from '../../components/Button';
+import { PageList } from '../Router';
+import Dialog from '../../components/Dialog';
+import Dropdown from '../../components/Dropdown';
+import { CountryDropNum, GetCountryList } from '../../components/CountryIcon';
+import CheckBox from '../../components/CheckBox';
+import TextView from '../../components/TextView';
+import utils from '../../utils/utils';
+
+export default class RegisterVL extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      agree: true,
+      countryNum: '65',
+      countryCode: "SG",
+      userInfo: {
+        email: "",
+        phone: "",
+        vehicle: {},
+        password: "",
+        verificationCode: ""
+      },
+      countryList: [],
+      params: {...this.props.route.params},
+      email: '',
+      password: '',
+      sendMinutes: 0,
+      strengthCheck: {
+        minLength: false,
+        wordCase: false,
+        oneNumber: false,
+        allCheck: false
+      },
+      showPassword: false
+    };
+  }
+
+  componentDidMount() {
+    this.getCountryList();
+  }
+
+  togglePassword() {
+    this.setState({
+      showPassword: !this.state.showPassword
+    })
+  }
+
+  applyStrength(text) {
+    const strength = this.state.strengthCheck;
+    strength.allCheck = true;
+    if (text.length >= 8) {
+      strength.minLength = true;
+    } else {
+      strength.minLength = false;
+      strength.allCheck = false;
+    }
+    if (/\d{1,}/.test(text)) {
+      strength.oneNumber = true;
+    } else {
+      strength.oneNumber = false;
+      strength.allCheck = false;
+    }
+    if (/[a-z]{1,}/.test(text) && /[A-Z]{1,}/.test(text)) {
+      strength.wordCase = true;
+    } else {
+      strength.wordCase = false;
+      strength.allCheck = false;
+    }
+    this.setState({
+      password: text,
+      strengthCheck: strength
+    });
+  }
+
+  changeInfo(key, value) {
+    var info = this.state.userInfo;
+    info[key] = value;
+    this.setState({
+      'userInfo': info
+    });
+  }
+
+  changeAgree(ag) {
+    this.setState({
+      agree: ag
+    })
+  }
+
+  changeCountry(value, index) {
+    this.setState({
+      countryCode: value
+    })
+    if (this.canChangeCalling) {
+      const country = this.state.countryList[index]
+      this.changeCalling(country.countryNum, -1);
+    }
+  }
+
+  changeCalling(value, index) {
+    this.setState({
+      countryNum: value
+    })
+    if (index >= 0) {
+      this.canChangeCalling = false;
+    }
+  }
+
+  getCountryList() {
+    GetCountryList(list => {
+      this.setState({
+        countryList: list
+      })
+    })
+  }
+
+  sendVerification() {
+    var info = this.state.userInfo;
+    if (!info.email) {
+      toastShort($t('sign.plsInputEmail'));
+      return;
+    }
+    if (!utils.isValidEmail(info.email)) {
+      toastShort($t('sign.errEmailFormat'));
+      return;
+    }
+    Dialog.showProgressDialog()
+    apiUser.sendVerificationCodeV2({email: info.email, type: "register"}).then(res => {
+      Dialog.dismissLoading()
+      //this.state.sendMinutes = 60;
+      this.state.sendMinutes = res.data?.resendTime ?? 60;
+      toastShort($t('sign.sendOTPSuccess'));
+      this.contdownTime();
+    }).catch(err => {
+      Dialog.dismissLoading()
+      toastShort(err);
+    });
+  }
+
+  contdownTime() {
+    if (this.state.sendMinutes > 0) {
+      this.setState({
+        sendMinutes: this.state.sendMinutes - 1
+      })
+      setTimeout(() => {
+        this.contdownTime();
+      }, 1000);
+    }
+  }
+
+  onRegister() {
+    //console.log('sign up', this.state);
+    var info = this.state.userInfo;
+    if (!info.nickName) {
+      toastShort($t('sign.plsInputDiaplayName'));
+      return;
+    }
+    if (!info.email) {
+      toastShort($t('sign.plsInputEmail'));
+      return;
+    }
+    if (!utils.isValidEmail(info.email)) {
+      toastShort($t('sign.errEmailFormat'));
+      return;
+    }
+    /*if (!info.verificationCode) {
+      toastShort($t('sign.plsInputOTP'));
+      return;
+    }*/
+    if (!info.phone) {
+      toastShort($t('sign.plsInputContactNo'));
+      return;
+    }
+    if (!/^\d{6,15}$/.test(info.phone)) {
+      toastShort($t('sign.errContactNoFormat'));
+      return;
+    }
+    if (!this.state.password) {
+      toastShort($t('sign.plsInputPassword'));
+      return;
+    }
+    if (!this.state.strengthCheck.allCheck) {
+      toastShort($t('sign.errPasswordStrong'));
+      return;
+    }
+    if (!info.password) {
+      toastShort($t('sign.plsInputPassword2'));
+      return;
+    }
+    if (info.password != this.state.password) {
+      toastShort($t('sign.errPasswordConfirm'));
+      return;
+    }
+    if (this.state.isFleetDriver) {
+      if (!info.pdvLicence) {
+        toastShort($t('sign.plsInputPDVLicence'));
+        return;
+      }
+      if (this.state.pdvImages[0] == '' || this.state.pdvImages[1] == '') {
+        toastShort($t('sign.plsUploadLicencePhotos'));
+        return;
+      }
+    }
+    let param = Object.assign({}, info);
+    //param.phone = this.state.countryNum + info.phone
+    param.callingCode = this.state.countryNum;
+    param.countryCode = this.state.countryCode;
+    if (this.state.isFleetDriver) {
+      param.userType = 'Driver';
+      param.pdvLicencePictures = this.state.pdvImages;
+      param.fleetCompanyId = this.state.fleetCompanyId;
+    } else {
+      param.userType = 'Public';
+    }
+    param.otp = param.verificationCode;
+    param.vehicle = this.state.vehicleInfo;
+    console.log('params', param);
+    Dialog.showProgressDialog();
+    apiUser.register(param).then(res => {
+      Dialog.dismissLoading();
+      //toastShort('Sign up successfully!');
+      if (isIOS) {
+        setTimeout(() => {
+          this.showSuccessDialog();
+        }, 600);
+      } else {
+        this.showSuccessDialog();
+      }
+    }).catch(err => {
+      toastShort(err);
+      Dialog.dismissLoading();
+    });
+  }
+
+  render() {
+    return (
+      <ScrollView
+        style={styles.container}
+        contentContainerStyle={$padding(16)}
+        keyboardShouldPersistTaps={isIOS ? 'never' : 'handled'}>
+        {/* <TextView style={styles.textTitle}>Registration details</TextView>
+        <TextView style={styles.textSubTitle}>Please input relevant info as stated</TextView> */}
+        <View style={styles.signInput}>
+          <TextInput
+            style={styles.inputView} 
+            placeholder={$t('sign.labelDisplayName')}
+            placeholderTextColor={textPlacehoder}
+            maxLength={50}
+            onChangeText={v => this.changeInfo('nickName', v)}
+          />
+        </View>
+        <View style={styles.signInput}>
+          <TextInput
+            style={styles.inputView}
+            placeholder={$t('sign.labelEmail')}
+            placeholderTextColor={textPlacehoder}
+            maxLength={50}
+            keyboardType="email-address"
+            textContentType='emailAddress'
+            onChangeText={v => this.changeInfo('email', v)}
+          />
+        </View>
+        {/* <View style={ui.flexc}>
+          <View style={[styles.signInput, ui.flex2]}>
+            <TextInput
+              style={[styles.inputView, {flex: 2.2, marginLeft: 2}]}
+              placeholder={"Validate OTP"}
+              placeholderTextColor={textPlacehoder}
+              maxLength={6}
+              keyboardType="number-pad"
+              textContentType="telephoneNumber"
+              onChangeText={v => this.changeInfo('verificationCode', v)}
+            />
+          </View>
+          <Button
+            text={this.state.sendMinutes > 0 ? (this.state.sendMinutes + " s") : $t('sign.btnSendOTP')}
+            style={styles.sendBtn}
+            disabled={this.state.sendMinutes > 0}
+            viewStyle={styles.sendBtnView}
+            textStyle={styles.sendBtnText}
+            onClick={() => this.sendVerification()}
+          />
+        </View> */}
+        <View style={ui.flexc}>
+          <View style={[styles.signInput, styles.dropView]}>
+            <TextInput style={styles.dropInput} editable={false}/>
+            <TextView style={styles.countryText}>{"+" + this.state.countryNum}</TextView>
+            <MaterialIcons name={'keyboard-arrow-down'} size={24} color={colorDark}/>
+            <Dropdown
+              style={styles.dropLayer}
+              prefixText="+"
+              list={this.state.countryList}
+              value={this.state.countryNum}
+              nameKey='countryNum'
+              valueKey='countryNum'
+              onChange={(value, index)=> this.changeCalling(value, index)}
+              customerItemView={
+                (item, index, onClick) => 
+                <CountryDropNum
+                  key={index} 
+                  country={item}
+                  value={this.state.countryNum}
+                  onClick={onClick}/>
+              }/>
+          </View>
+          <View style={[styles.signInput, ui.flex2]}>
+            <TextInput
+              style={styles.inputView}
+              placeholder={$t('sign.labelMobileNumber')}
+              placeholderTextColor={textPlacehoder}
+              keyboardType='phone-pad'
+              maxLength={15}
+              onChangeText={v => this.changeInfo('phone', v)}
+            />
+          </View>
+        </View>
+        <View style={styles.signInput}>
+          <TextInput
+            secureTextEntry={!this.state.showPassword}
+            style={styles.inputView}
+            placeholder={$t('sign.labelPassword')}
+            placeholderTextColor={textPlacehoder}
+            maxLength={20}
+            onChangeText={(value) => this.applyStrength(value)}/>
+          <MaterialCommunityIcons
+            name={this.state.showPassword ? "eye" : "eye-off"}
+            size={16}
+            color={"#DADADA"}
+            onPress={() => this.togglePassword()}/>
+        </View>
+        <View style={styles.passwordTipView}>
+          {/* <TextView style={styles.passwordTipText}>Your password must have:</TextView> */}
+          <View style={ui.flexc}>
+            <MaterialIcons
+              name="check-circle-outline"
+              color={this.state.strengthCheck.minLength ? colorAccent : colorCancel}
+              size={18}/>
+            <TextView style={styles.passwordTipText}>8 or more characters</TextView>
+          </View>
+          <View style={ui.flexc}>
+            <MaterialIcons
+              name="check-circle-outline"
+              color={this.state.strengthCheck.wordCase ? colorAccent : colorCancel}
+              size={18}/>
+            <TextView style={styles.passwordTipText}>Upper and Lower case letters</TextView>
+          </View>
+          <View style={ui.flexc}>
+            <MaterialIcons
+              name="check-circle-outline"
+              color={this.state.strengthCheck.oneNumber ? colorAccent : colorCancel}
+              size={18}/>
+            <TextView style={styles.passwordTipText}>At least one number</TextView>
+          </View>
+        </View>
+        <View style={styles.signInput}>
+          <TextInput
+            secureTextEntry={!this.state.showPassword}
+            style={styles.inputView}
+            placeholder={$t('sign.labelConfirmPassword')}
+            placeholderTextColor={textPlacehoder}
+            maxLength={20}
+            onChangeText={v => this.changeInfo('password', v)}/>
+          <MaterialCommunityIcons
+            name={this.state.showPassword ? "eye" : "eye-off"}
+            size={16}
+            color={"#DADADA"}
+            onPress={() => this.togglePassword()}/>
+        </View>
+        <EndView/><EndView half/>
+        {/* <TextView style={styles.textTitle}>Got A Referral Code?</TextView>
+        <TextView style={styles.textSubTitle}>Please input the code from your referrer</TextView>
+        <View style={styles.signInput}>
+          <TextInput
+            style={styles.inputView}
+            placeholder={"Referral Code"}
+            placeholderTextColor={textPlacehoder}
+            maxLength={6}
+            onChangeText={v => this.changeInfo('referralCode', v)}/>
+        </View> */}
+        <View style={styles.agreeView}>
+          <CheckBox
+            value={this.state.agree}
+            onValueChange={v => this.changeAgree(v)}
+          />
+          <View style={styles.agreeTextRow}>
+            <TextView style={styles.agreeText} onPress={() => this.changeAgree(!this.state.agree)}>
+              {$t('sign.iHaveReadAndAgree')}
+            </TextView>
+            <TextView style={styles.agreeLink} onPress={() => startPage(PageList.condition)}>{$t('drawer.termsOfUse')}</TextView>
+            <TextView style={styles.agreeText}>{' '}</TextView>
+            <TextView style={styles.agreeText}>{$t('sign.linkAndLink')}</TextView>
+            <TextView style={styles.agreeLink} onPress={() => startPage(PageList.privacy)}>{$t('drawer.privacyPolicy')}</TextView>
+            <TextView style={styles.agreeText}>{$t('sign.linkAndLinkEnd')}</TextView>
+          </View>
+        </View>
+        <Button
+          style={styles.signButton}
+          elevation={0}
+          disabled={!this.state.agree}
+          text={$t('sign.btnRegister')}
+          fontSize={14}
+          onClick={() => this.onRegister()}/>
+      </ScrollView>
+    );
+  }
+}
+
+const styles = StyleSheet.create({
+  container: {
+    flex: 1,
+    backgroundColor: colorLight
+  },
+  textTitle: {
+    color: textPrimary,
+    fontSize: 16,
+    fontWeight: "bold"
+  },
+  textSubTitle: {
+    color: textSecondary,
+    fontSize: 12
+  },
+  signInput: {
+    marginTop: 16,
+    borderRadius: 0,
+    paddingLeft: 16,
+    paddingRight: 16,
+    alignItems: 'center',
+    flexDirection: 'row',
+    borderWidth: 1,
+    borderRadius: 4,
+    borderColor: "#DADADA"
+  },
+  inputView: {
+    flex: 1,
+    height: 48,
+    color: textPrimary,
+    fontSize: 12
+  },
+  sendBtn: {
+    flex: 1.2,
+    marginLeft: 16,
+    marginRight: 0,
+    marginTop: 16,
+    borderRadius: 6,
+    backgroundColor: colorPrimary
+  },
+  sendBtnView: {
+    flex: 1,
+    height: 48,
+    paddingLeft: 4,
+    paddingRight: 4,
+    alignItems: 'center',
+    justifyContent: 'center'
+  },
+  sendBtnText: {
+    color: textButton,
+    fontSize: 13,
+    fontWeight: 'bold'
+  },
+  dropView: {
+    flex: 1,
+    marginRight: 16,
+    paddingRight: 8,
+    alignItems: "center",
+    flexDirection: "row"
+  },
+  dropLayer: {
+    left: 0,
+    right: 0,
+    opacity: 0,
+    position: 'absolute'
+  },
+  dropInput: {
+    width: 8,
+    color: textPrimary,
+    height: 48
+  },
+  countryText: {
+    flex: 1,
+    color: "#9D9D9D",
+    fontSize: 14,
+    paddingRight: 4
+  },
+  passwordTipView: {
+    paddingTop: 8
+  },
+  passwordTipText: {
+    color: "#666",
+    fontSize: 14,
+    paddingTop: 2,
+    paddingLeft: 8,
+    paddingBottom: 2
+  },
+  agreeView: {
+    marginTop: 48,
+    marginBottom: 16,
+    alignItems: 'center',
+    flexDirection: 'row'
+  },
+  agreeTextRow: {
+    flex: 1,
+    paddingTop: 4,
+    paddingLeft: 8,
+    flexWrap: 'wrap',
+    flexDirection: 'row'
+  },
+  agreeText: {
+    color: textPrimary,
+    fontSize: 14,
+    paddingTop: 2,
+    paddingBottom: 2
+  },
+  agreeLink: {
+    ...ui.link,
+    fontSize: 14,
+    paddingTop: 2,
+    paddingBottom: 2,
+    textDecorationLine: 'underline'
+  },
+  signButton: {
+    marginBottom: 24,
+    borderRadius: 4,
+    backgroundColor: colorPrimary
+  }
+})