Ver Fonte

add app/pages/member/ApplyMember.js

wudebin há 5 meses atrás
pai
commit
18d487b3df

+ 292 - 0
Strides-SPAPP/app/pages/member/ApplyMember.js

@@ -0,0 +1,292 @@
+/**
+ * 申请会员页面
+ * @邠心vbe on 2023/07/14
+ */
+import React, { Component } from 'react';
+import { View, Text, StyleSheet, TextInput, ScrollView } from 'react-native';
+import apiMember from '../../api/apiMember';
+import apiUpload from '../../api/apiUpload';
+import { GetCountryList } from '../../components/CountryIcon';
+import Dropdown from '../../components/Dropdown';
+import { UploadThemes } from '../../components/ThemesConfig';
+import { UploadView } from '../sign/RegisterDriver';
+import ImagePicker from 'react-native-image-crop-picker';
+import CheckBoxText from '../../components/CheckBoxText';
+import Button from '../../components/Button';
+import TextView from '../../components/TextView';
+
+const options = {
+  width: 300,
+  height: 200,
+  cropping: true,
+  multiple: false,
+  mediaType: 'photo',
+  writeTempFile: false,
+  compressImageQuality: 0.8,
+  compressImageMaxWidth: 720,
+  compressImageMaxHeight: 1280,
+  ...UploadThemes
+}
+
+export default class ApplyMember extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      agree: true,
+      groupList: [],
+      memberForm: {
+        groupPk: "",
+        membershipNo: "",
+        cardFront: ""
+      },
+      isFleet: false
+    };
+  }
+
+  componentDidMount() {
+    //console.log(this.state.params);
+    //this.getCountryList();
+    this.getGroupList();
+  }
+
+  changeForm(key, value) {
+    const form = {...this.state.memberForm};
+    form[key] = value;
+    this.setState({
+      memberForm: form
+    })
+  }
+
+  changeGroup(value, index) {
+    const group = this.state.groupList[index];
+    this.setState({
+      isFleet: group?.groupType == "FLEET"
+    })
+    this.changeForm("groupPk", value);
+  }
+
+  getCountryList() {
+    GetCountryList(list => {
+      this.setState({
+        countryNums: list
+      })
+    })
+  }
+
+  getGroupList() {
+    apiMember.getMembersOption().then(res => {
+      if (res.data) {
+        this.setState({
+          groupList: res.data
+        })
+      }
+    }).catch(err => [
+      toastShort(err)
+    ])
+  }
+
+  uploadImage() {
+    ImagePicker.openPicker({
+      ...options,
+      cropperToolbarTitle: $t('common.cropperTitle')
+    }).then(image => {
+      if (image.path) {
+        apiUpload.uploadImage(image.path, image.mime, 'MEMBERSHIP').then(res => {
+          if (res.success && res.data.picturePath) {
+            this.changeForm("cardFront", res.data.picturePath)
+            toastShort($t('common.uploadSuccess'));
+          } else {
+            toastShort($t('common.uploadFailed'));
+          }
+        }).catch(err => {
+          toastShort(err);
+        });
+      }
+    }).catch(err1 => {
+      //console.log(err1);
+    });
+  }
+
+  changeAgree(ag) {
+    this.setState({
+      agree: ag
+    })
+  }
+
+  onApplyMember() {
+    if (!this.state.memberForm.membershipNo) {
+      toastShort($t('members.errMembershipNo'));
+      return;
+    }
+    if (!this.state.memberForm.cardFront) {
+      toastShort($t('members.errUploadCard'));
+      return;
+    }
+    console.log('params', this.state.memberForm);
+    Dialog.showProgressDialog();
+    apiMember.applyMembers(this.state.memberForm).then(res => {
+      Dialog.dismissLoading();
+      toastLong(res.msg ?? $t('common.submitSuccess'));
+      goBack();
+    }).catch(err => {
+      toastLong(err);
+      Dialog.dismissLoading();
+    })
+  }
+
+  render() {
+    return (
+      <View style={styles.container}>
+        <ScrollView style={styles.applyForm}>
+          <View style={styles.formItem}>
+            <TextView style={styles.inputLabel}>{$t('members.membership')}</TextView>
+            <Dropdown
+              style={styles.selectView}
+              textStyle={styles.selectText}
+              title={$t('members.membership')}
+              list={this.state.groupList}
+              value={this.state.memberForm.groupPk}
+              valueKey='groupPk'
+              nameKey='groupName'
+              onChange={(value, index)=> this.changeGroup(value, index)}/>
+          </View>
+          <View style={styles.formItem}>
+            <TextView style={styles.inputLabel}>{$t("members.labelMemberLicenceNo")}
+              {/*this.state.isFleet ? $t('members.labelPHVNo') : $t('members.membershipNo')*/}
+            </TextView>
+            <TextInput
+              style={styles.inputView}
+              allowFontScaling={false}
+              placeholder={$t('members.placeLast4Digits')}
+              placeholderTextColor={textPlacehoder}
+              maxLength={4}
+              //keyboardType='phone-pad'
+              onChangeText={v => this.changeForm('membershipNo', v)}
+            />
+          </View>
+          <View style={styles.formItem}>
+            <TextView style={styles.inputLabel}>
+              {this.state.isFleet ? $t('members.labelPDVPhotos') : $t('members.labelUpload')}
+            </TextView>
+            <View style={styles.uploadGroup}>
+              <UploadView
+                style={styles.uploadView}
+                imageStyle={styles.uploadImage}
+                onPress={() => this.uploadImage()}
+                url={this.state.memberForm.cardFront}/>
+            </View>
+          </View>
+          <View style={styles.formItem}>
+            <TextView style={styles.inputLabel}>{$t('members.labelRequirement')}</TextView>
+            <TextView style={styles.contentView}>{$t('members.contentRequirement')}</TextView>
+          </View>
+        </ScrollView>
+        <View style={styles.agreeView}>
+          <View style={ui.flex}>
+            <CheckBoxText
+              value={this.state.agree}
+              text={$t('sign.agreePDVInfoAccurate')}
+              textStyle={styles.agreeText}
+              onValueChange={v => this.changeAgree(v)}
+            />
+          </View>
+          <Button
+            style={styles.submitButton}
+            elevation={1.5}
+            disabled={!this.state.agree}
+            text={$t('nav.submit')}
+            fontSize={14}
+            onClick={() => {
+              this.onApplyMember();
+            }}
+          />
+        </View>
+      </View>
+    );
+  }
+}
+
+const styles = StyleSheet.create({
+  container: {
+    flex: 1,
+    backgroundColor: colorLight
+  },
+  applyForm: {
+    flex: 1,
+    paddingLeft: 16,
+    paddingRight: 16
+  },
+  formItem: {
+    marginTop: 16,
+    alignItems: 'center',
+    flexDirection: 'row'
+  },
+  inputLabel: {
+    flex: 1,
+    color: textPrimary,
+    fontSize: 14,
+    marginRight: 4
+  },
+  inputView: {
+    flex: 2,
+    color: textPrimary,
+    fontSize: 14,
+    borderRadius: 5,
+    minHeight: 40,
+    paddingTop: 6,
+    paddingLeft: 12,
+    paddingRight: 12,
+    paddingBottom: 6,
+    backgroundColor: '#F5F5F5'
+  },
+  selectView: {
+    flex: 2,
+    borderRadius: 5,
+    minHeight: 40,
+    paddingLeft: 12,
+    paddingRight: 12,
+    alignItems: 'center',
+    flexDirection: 'row',
+    backgroundColor: '#F5F5F5'
+  },
+  contentView: {
+    flex: 2,
+    color: textPrimary,
+    fontSize: 14
+  },
+  selectText: {
+    flex: 1,
+    color: textPrimary,
+    fontSize: 14
+  },
+  uploadGroup: {
+    flex: 2,
+    marginLeft: -16,
+    alignItems: 'center',
+    flexDirection: 'row'
+  },
+  uploadView: {
+    //flex: 1,
+    alignItems: 'center'
+  },
+  uploadImage: {
+    width: $vw(28),
+    height: $vw(18.7),
+    borderRadius: 6
+  },
+  agreeView: {
+    padding: 16,
+  },
+  agreeText: {
+    flex: 1,
+    color: textPrimary,
+    fontSize: 14,
+    paddingTop: 2,
+    paddingLeft: 4,
+    paddingBottom: 2
+  },
+  submitButton: {
+    marginTop: 16,
+    marginBottom: 8
+  }
+})

+ 266 - 0
Strides-SPAPP/app/pages/member/MembersList.js

@@ -0,0 +1,266 @@
+/**
+ * 我的会员列表页面
+ * @邠心vbe on 2023/07/14
+ */
+import React, { Component } from 'react';
+import { View, Text, StyleSheet, Pressable, Image } from 'react-native';
+import apiMember from '../../api/apiMember';
+import { ElevationObject } from '../../components/Button';
+import Dialog from '../../components/Dialog';
+import TextView from '../../components/TextView';
+import utils from '../../utils/utils';
+import VbeSkeleton from '../../components/VbeSkeleton';
+
+export default class MembersList extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      loading: true,
+      memberList: [],
+      loadingList: ["", "", "", ""]
+    };
+  }
+
+  componentDidMount() {
+    this.props.navigation.addListener('focus', () => {
+      if (!this.state.loading) {
+        this.getMyMemberList();
+      }
+    })
+    setTimeout(() => {
+      this.getMyMemberList();
+    }, 500);
+  }
+
+  getMyMemberList() {
+    apiMember.getMyMemberList().then(res => {
+      if (res.data) {
+        this.setState({
+          memberList: res.data
+        });
+      } else {
+        this.setState({
+          memberList: []
+        });
+      }
+    }).catch(err => {
+      this.setState({
+        memberList: []
+      });
+      toastShort(err)
+    }).finally(() => {
+      this.setState({
+        loading: false
+      });
+    });
+  }
+
+  getMembershipStatus(status) {
+    switch (status) {
+      case "Pending":
+        return $t("members.statusPending");
+      case "Approved":
+        return $t("members.statusApproved");
+      case "Pass":
+        return $t("members.statusApproved");
+      case "Rejected":
+        return $t("members.statusRejected");
+      default:
+        return $t("charging.statusUnavailable");
+    }
+  }
+
+  onDeleteMember(item) {
+    Dialog.showDialog({
+      title: $t("members.deleteMember"),
+      message: $t("members.confirmDelete"),
+      ok: $t("nav.yes"),
+      cancel: $t("nav.no"),
+      callback: btn => {
+        if (btn == Dialog.BUTTON_OK) {
+          this.deleteMembers(item.membershipId)
+        }
+      }
+    })
+  }
+
+  deleteMembers(id) {
+    //Dialog.showProgressDialog();
+    apiMember.delMembers(id).then(res => {
+      toastShort($t("common.deleteSuccess"))
+      this.getMyMemberList();
+    }).catch(err => {
+      toastShort(err)
+    })
+  }
+
+  render() {
+    if (this.state.loading) {
+      return (
+        <View style={styles.container}>
+          { this.state.loadingList.map((item, index) =>
+            <View style={styles.loadingView} key={index}>
+              <VbeSkeleton
+                style={ui.flex1}
+                layout={[
+                  {width: '50%', height: 20},
+                  {width: '100%', height: 15, marginTop: 6},
+                  {width: '60%', height: 15, marginTop: 6}
+                ]}
+                animationDirection={"horizontalRight"}
+              />
+              <VbeSkeleton
+                style={styles.loadingIcon}
+                layout={[
+                  {width: 48, height: 48, borderRadius: 6}
+                ]}
+                animationDirection={"horizontalRight"}
+              />
+            </View>
+          )}
+        </View>
+      )
+    }
+    return (
+      <View style={styles.container}>
+        { this.state.memberList.length > 0
+        ? this.state.memberList.map((item, index) => (
+          <Pressable
+            key={index}
+            style={styles.memberView}
+            onPress={() => {
+              if (item.membershipStatus == "Rejected") {
+                this.onDeleteMember(item)
+              }
+              //startPage(PageList.editVehicle, {id: item.vehiclePk});
+            }}>
+            <View style={styles.itemBackground}>
+              { utils.isNotEmpty(item.groupLogo)
+              ? <Image
+                  source={{uri: utils.getImageUrl(item.groupLogo)}}
+                  resizeMode="contain"
+                  style={styles.groupLogo}/>
+              : <MaterialIcons
+                  name="card-membership"
+                  color={colorAccent}
+                  style={styles.groupIcon}
+                  size={52}/>
+              }
+            </View>
+            <View style={styles.memberItem}>
+              { utils.isEmpty(item.groupType)
+              ? <TextView style={styles.textLabel2}>{$t('members.membership')}:</TextView>
+              : <TextView style={styles.textType}>{item.groupType}</TextView>
+              }
+              <TextView
+                style={styles.textValue2}
+                numberOfLines={1}>{item.membership}</TextView>
+            </View>
+            <View style={styles.memberItem}>
+              <TextView style={styles.textLabel}>{$t('members.membershipNo')}:</TextView>
+              <TextView style={styles.textValue}>{item.membershipNo}</TextView>
+            </View>
+            <View style={styles.memberItem}>
+              <TextView style={styles.textLabel}>{$t('members.status')}:</TextView>
+              { item.membershipStatus == "Rejected"
+                ? <TextView style={[styles.textValue, styles.statusRed]}>{this.getMembershipStatus(item.membershipStatus)}</TextView>
+                : <TextView style={styles.textValue}>{this.getMembershipStatus(item.membershipStatus)}</TextView>
+              }
+              
+            </View>
+          </Pressable>
+        ))
+        : <Text style={ui.noData}>{$t('members.noData')}</Text>
+      }
+      </View>
+    );
+  }
+}
+
+const styles = StyleSheet.create({
+  container: {
+    flex: 1,
+    backgroundColor: pageBackground
+  },
+  loadingView: {
+    padding: 16,
+    borderRadius: 8,
+    borderColor: '#F0F0F0',
+    borderWidth: 1,
+    alignItems: 'flex-end',
+    backgroundColor: colorLight,
+    flexDirection: 'row',
+    ...$margin(16, 16, 0)
+  },
+  memberView: {
+    borderRadius: 8,
+    overflow: 'hidden',
+    ...ElevationObject(5),
+    ...$margin(16, 16, 0),
+    ...$padding(16),
+    backgroundColor: colorLight
+  },
+  memberItem: {
+    paddingTop: 1,
+    paddingBottom: 1,
+    alignItems: 'center',
+    flexDirection: 'row'
+  },
+  textLabel: {
+    color: textPrimary,
+    fontSize: 14,
+    paddingRight: 6,
+    fontWeight: 'bold'
+  },
+  textValue: {
+    flex: 1,
+    color: textPrimary,
+    fontSize: 14
+  },
+  textLabel2: {
+    color: textPrimary,
+    fontSize: 16,
+    paddingRight: 5,
+    marginBottom: 2,
+    fontWeight: 'bold'
+  },
+  textValue2: {
+    flex: 1,
+    color: textPrimary,
+    fontSize: 16,
+    fontWeight: 'bold',
+    marginBottom: 2
+  },
+  statusRed: {
+    color: "#FF2222"
+  },
+  textType: {
+    color: textLight,
+    fontSize: 10,
+    marginRight: 4,
+    borderRadius: 2,
+    ...$padding(1, 4),
+    backgroundColor: colorAccent
+  },
+  itemBackground: {
+    right: 0,
+    bottom: 0,
+    position: 'absolute'
+  },
+  groupIcon: {
+    margin: 4,
+    opacity: 0.08
+  },
+  groupLogo: {
+    width: 48,
+    height: 48,
+    margin: 8,
+    opacity: .8,
+    borderRadius: 6
+  },
+  loadingIcon: {
+    width: 48,
+    height: 48,
+    marginLeft: 16
+  }
+})