Forráskód Böngészése

Develop Points history page
https://dev.wormwood.com.sg/zentao/task-view-204.html

vbea 2 éve
szülő
commit
9a5c5869f0

+ 13 - 0
Strides-APP/app/api/apiVoucher.js

@@ -50,7 +50,20 @@ export default apiVoucher = {
   getSelectionVoucher(data) {
     return get(prefix + "charge-can-use-vouchers", data)
   },
+  /**
+   * 获取优惠券详情
+   * @param {String|Number} voucherId 优惠券ID
+   * @returns Promise
+   */
   getVoucherInfo(voucherId) {
     return get(prefix + "vouchers/" + voucherId)
+  },
+  /**
+   * 分页获取积分历史列表
+   * @param {String} lastId 上一页最后一项的pointsHistoryId
+   * @returns Promise
+   */
+  getPointsHistory(lastId) {
+    return get(prefix + "points-history", {lastPointsHistoryId: lastId})
   }
 }

+ 3 - 1
Strides-APP/app/i18n/locales/en.js

@@ -77,6 +77,7 @@ export default {
     topUpWithCard: "Top Up with Card",
     vouchers: "VOUCHERS",
     voucherDetails: "Voucher Details",
+    pointsHistory: "Points History",
     wallet: "Transactions",
     applyMember: "Apply Membership",
     yourMembers: "Your Membership",
@@ -580,6 +581,7 @@ export default {
     conditionMinSpend: "Minimum Spend of"
   },
   points: {
-    points: "Points"
+    points: "Points",
+    noData: "No Data"
   }
 }

+ 3 - 1
Strides-APP/app/i18n/locales/zh-TW.js

@@ -77,6 +77,7 @@ export default {
     topUpWithCard: "使用信用卡充值",
     vouchers: "優惠券",
     voucherDetails: "優惠券詳情",
+    pointsHistory: "積點記錄",
     wallet: "我的餘額",
     applyMember: "申請會員",
     yourMembers: "我的會員",
@@ -580,6 +581,7 @@ export default {
     conditionMinSpend: "最低消費金額"
   },
   points: {
-    points: "積點"
+    points: "積點",
+    noData: "沒有積點記錄"
   }
 }

+ 3 - 1
Strides-APP/app/i18n/locales/zh.js

@@ -77,6 +77,7 @@ export default {
     topUpWithCard: "使用信用卡充值",
     vouchers: "代金券",
     voucherDetails: "代金券信息",
+    pointsHistory: "积分记录",
     wallet: "我的余额",
     applyMember: "申请会员",
     yourMembers: "我的会员",
@@ -580,6 +581,7 @@ export default {
     conditionMinSpend: "最低消费金额为"
   },
   points: {
-    points: "积分"
+    points: "积分",
+    noData: "没有积分记录"
   }
 }

+ 6 - 0
Strides-APP/app/pages/Router.js

@@ -69,6 +69,7 @@ import HistoryList from './wallet/HistoryList';
 import VoucherPage from './vouchers/VoucherPage';
 import VoucherSelect from './vouchers/VoucherSelect';
 import VoucherDetails from './vouchers/VoucherDetails';
+import PointsHistory from './vouchers/PointsHistory';
 
 export var PageList = {
   'splash': {
@@ -377,6 +378,11 @@ export var PageList = {
     titleScope: 'route.vouchers',
     component: VoucherSelect
   },
+  'pointsHistory': {
+    title: app.isWhitelabel ? "Points History" : undefined,
+    titleScope: app.isWhitelabel ? 'route.pointsHistory' : undefined,
+    component: PointsHistory
+  },
   'settings': {
     title: 'Settings',
     titleScope: 'route.settings',

+ 1 - 1
Strides-APP/app/pages/charging/StepChargeView.js

@@ -77,7 +77,7 @@ export default StepChargeView = ({
         <TextView style={styles.title}>{$t('voucher.selectVoucher')}</TextView>
         <Pressable
           style={styles.voucherLayout}
-          onPress={() => (!isPending && !isCharging) && PagerUtil.toSelectVoucher()}>
+          onPress={() => (!isPending && !isCharging) && PagerUtil.toSelectVoucher(connectorInfo.chargeBoxId, connectorInfo.connectorId)}>
           <MaterialCommunityIcons
             name="ticket-percent"
             size={35}

+ 206 - 0
Strides-APP/app/pages/vouchers/PointsHistory.js

@@ -0,0 +1,206 @@
+/**
+ * 积分历史列表页面
+ * @邠心vbe on 2024/05/07
+ */
+import React, { Component } from 'react';
+import { View, Text, RefreshControl, FlatList, StyleSheet } from 'react-native';
+import { MyRefreshProps } from '../../components/ThemesConfig';
+import TextView from '../../components/TextView';
+import Dialog from '../../components/Dialog';
+import apiVoucher from '../../api/apiVoucher';
+import ToolbarUgly from '../../components/ToolbarUgly';
+import app from '../../../app.json';
+
+export default class PointsHistory extends Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      dataList: [],
+      hasMore: true,
+      refreshing: false
+    };
+  }
+
+  componentDidMount() {
+    Dialog.showProgressDialog();
+    this.getHistoryList();
+  }
+
+  onRefresh() {
+    this.setState({
+      refreshing: true
+    })
+    this.getHistoryList();
+  }
+
+  getNextPage() {
+    if (this.state.dataList.length > 0 && this.state.hasMore) {
+      console.log("[Points History]", "getNextPage");
+      const last = this.state.dataList[this.state.dataList.length-1]
+      this.getHistoryList(last.pointsHistoryId);
+    }
+  }
+
+  getHistoryList(lastPk="") {
+    apiVoucher.getPointsHistory(lastPk).then(res => {
+      if (res.data) {
+        if (lastPk) {
+          if (res.data.length > 0) {
+            const list = this.state.dataList;
+            this.setState({
+              dataList: list.concat(res.data)
+            });
+          } else {
+            this.setState({
+              hasMore: false
+            })
+          }
+        } else {
+          this.setState({
+            dataList: res.data,
+            hasMore: true
+          });
+        }
+      } else {
+        this.setState({
+          dataList: []
+        });
+      }
+    }).catch(err => {
+      toastShort(err)
+    }).finally(() => {
+      this.setState({
+        refreshing: false
+      });
+      Dialog.dismissLoading();
+    });
+  }
+
+  listItem = ({item, index, separators}) => {
+    return (
+      <View style={styles.itemView}>
+        <MaterialCommunityIcons
+          style={styles.iconType}
+          name={item.action = "Increase" ? "ev-station" : "ticket-percent-outline"}
+          size={20}
+          color={textPrimary}/>
+        <View style={styles.itemContent}>
+          <View style={ui.flex1}>
+            <TextView style={styles.issueName}>{item.remarks}</TextView>
+            <TextView style={styles.issueDesc}>{item.siteName + ", " + item.chargeBoxId + ", " + item.refId}</TextView>
+          </View>
+          { item.action = "Increase"
+            ? <TextView style={styles.amountText}>+ {item.points}</TextView>
+            : <TextView style={styles.amountDuct}>- {item.points}</TextView>
+          }
+        </View>
+      </View>
+    )
+  }
+
+  divideView = (props) => {
+    return (<View style={styles.divide}></View>)
+  }
+
+  bottomView = () => {
+    if (!this.state.hasMore) {
+      return (<Text style={styles.noMore}>{$t('wallet.noMore')}</Text>)
+    } else {
+      return null
+    }
+  }
+
+  render() {
+    return (
+      <View style={ui.flex1}>
+        { !app.isWhitelabel &&
+          <ToolbarUgly
+            title={$t("route.pointsHistory")}/>
+        }
+        <FlatList
+          style={styles.listView}
+          data={this.state.dataList}
+          renderItem={this.listItem}
+          ItemSeparatorComponent={this.divideView}
+          ListFooterComponent={this.bottomView}
+          keyExtractor={item => item.pointsHistoryId}
+          onEndReached={() => this.getNextPage()}
+          onEndReachedThreshold={0.3}
+          refreshControl={
+            <RefreshControl
+              {...MyRefreshProps()}
+              refreshing={this.state.refreshing}
+              onRefresh={() => this.onRefresh()}
+            />
+          }
+          ListEmptyComponent={<Text style={styles.noData}>{$t('points.noData')}</Text>}
+        />
+      </View>
+    );
+  }
+}
+
+const styles = StyleSheet.create({
+  listView: {
+    flex: 1
+  },
+  itemView: {
+    paddingLeft: 16,
+    paddingRight: 16,
+    alignItems: 'center',
+    flexDirection: 'row'
+  },
+  itemContent: {
+    flex: 1,
+    marginLeft: 8,
+    ...$padding(16, 4),
+    alignItems: 'center',
+    flexDirection: 'row'
+  },
+  divide: {
+    marginLeft: 52,
+    marginRight: 16,
+    borderTopWidth: 1,
+    borderTopColor: '#eee',
+  },
+  iconType: {
+    width: 28,
+    height: 28,
+    textAlign: 'center',
+    lineHeight: 26,
+    borderWidth: 1,
+    borderRadius: 30,
+    borderColor: textPrimary
+  },
+  issueName: {
+    color: textPrimary,
+    fontSize: 12,
+    paddingBottom: 2
+  },
+  issueDesc: {
+    color: '#999',
+    fontSize: 8
+  },
+  amountDuct: {
+    color: '#FF2E00',
+    fontSize: 12,
+    paddingLeft: 8
+  },
+  amountText: {
+    color: colorAccent,
+    fontSize: 12,
+    paddingLeft: 8
+  },
+  noData: {
+    color: textPlacehoder,
+    fontSize: 8,
+    padding: 20,
+    textAlign: 'center'
+  },
+  noMore: {
+    color: textPlacehoder,
+    fontSize: 8,
+    padding: 16,
+    textAlign: 'center'
+  }
+})

+ 16 - 9
Strides-APP/app/pages/vouchers/ViewRedeem.js

@@ -6,6 +6,7 @@ import Modal from "react-native-modal";
 import { ModalProps } from "../../components/BottomModal";
 import Dialog from '../../components/Dialog';
 import apiVoucher from '../../api/apiVoucher';
+import { PageList } from '../Router';
 
 export default ViewRedeem = ({
   userInfo={},
@@ -63,22 +64,27 @@ export default ViewRedeem = ({
             size={24}
             color={textPrimary}/>
           <TextView
-            style={styles.buttonText}>
+            style={styles.buttonText}
+            numberOfLines={1}>
             {$t("voucher.inputPromoCode")}
           </TextView>
         </Button>
         <Text style={styles.btnDivide}></Text>
-        <View
-          style={styles.buttonRight}>
+        <Button
+          style={styles.buttonRight}
+          viewStyle={styles.buttonView}
+          onClick={() => startPage(PageList.pointsHistory)}>
           <TextView
-            style={styles.buttonText}>
+            style={styles.buttonText}
+            numberOfLines={1}>
             {$t("voucher.availablePoints")}
           </TextView>
           <TextView
-            style={styles.valueText}>
+            style={styles.valueText}
+            numberOfLines={1}>
             {userInfo?.points || '0'}
           </TextView>
-        </View>
+        </Button>
       </View>
       <Modal
         isVisible={visible}
@@ -150,9 +156,10 @@ const styles = StyleSheet.create({
   },
   buttonRight: {
     flex: 1,
-    alignItems: 'center',
-    flexDirection: 'row',
-    justifyContent: 'center',
+    borderTopLeftRadius: 0,
+    borderTopRightRadius: 3,
+    borderBottomLeftRadius: 0,
+    borderBottomRightRadius: 3,
     backgroundColor: 'transparent'
   },
   buttonView: {

+ 1 - 1
Strides-APP/app/pages/wallet/HistoryList.js

@@ -3,7 +3,7 @@
  * @邠心vbe on 2024/03/29
  */
 import React, { Component } from 'react';
-import { View, Text, RefreshControl, FlatList, StyleSheet, Pressable, Image, PixelRatio } from 'react-native';
+import { View, Text, RefreshControl, FlatList, StyleSheet, Pressable, Image } from 'react-native';
 import { MyRefreshProps } from '../../components/ThemesConfig';
 import apiWallet from '../../api/apiWallet';
 import TextView from '../../components/TextView';