StepCharging.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /**
  2. * 新充电流程:正在充电模块
  3. * @邠心vbe on 2023/06/20
  4. */
  5. import React, { useEffect, useRef, useState } from 'react';
  6. import { Animated, Easing, Image, ScrollView, StyleSheet, View } from 'react-native';
  7. import app from '../../../app.json';
  8. import Button, { ElevationObject } from '../../components/Button';
  9. import TextView from '../../components/TextView';
  10. import utils from '../../utils/utils';
  11. import { PaymentList } from '../chargeV2/Payment';
  12. import DiscountView from './DiscountView';
  13. import PaymentListV2 from '../chargeV2/PaymentListV2';
  14. import DialogIdleFee from './DialogIdleFee';
  15. const StepCharging = ({
  16. idleFeeConfig,
  17. connectorInfo={},
  18. currentPayment,
  19. onStopCharge,
  20. selectedVoucher={}
  21. }) => {
  22. const [isCharging, setCharging] = useState(false);
  23. const [loadingEmps, setEmps] = useState("");
  24. const [skipAnim, setAnimSkip] = useState(false);
  25. const topAnim = useRef(new Animated.Value($vw(16)*-2)).current;
  26. const fadeAnim = useRef(new Animated.Value(0)).current;
  27. const moveTop = () => {
  28. fadeAnim.setValue(0);
  29. Animated.timing(topAnim, {
  30. toValue: ($vh(50) * -1 - $vw(16) - 32),
  31. duration: 1000,
  32. easing: Easing.linear,
  33. useNativeDriver: false
  34. }).start();
  35. setTimeout(() => {
  36. setCharging(true);
  37. showFade();
  38. }, 1100);
  39. }
  40. const showFade = () => {
  41. Animated.timing(fadeAnim, {
  42. toValue: 1,
  43. duration: 1000,
  44. useNativeDriver: false
  45. }).start();
  46. setTimeout(() => {
  47. setAnimSkip(true);
  48. }, 1100);
  49. }
  50. useEffect(() => {
  51. const isCharge = (connectorInfo.status == "Charging");
  52. //console.log("[useEffect]:start", isCharge, fadeAnim);
  53. setCharging(isCharge);
  54. setAnimSkip(isCharge);
  55. if (!isCharge) {
  56. changeEmps();
  57. }
  58. }, [])
  59. useEffect(() => {
  60. //console.log("[useEffect]:connectorInfo", connectorInfo.status);
  61. if (connectorInfo.status == "Charging") {
  62. if (!isCharging) {
  63. moveTop();
  64. }
  65. } else {
  66. setCharging(false)
  67. }
  68. }, [connectorInfo])
  69. useEffect(() => {
  70. //console.log("[useEffect]:loadingEmps", loadingEmps);
  71. if (connectorInfo.status == "Charging") {
  72. moveTop();
  73. } else {
  74. setTimeout(() => {
  75. changeEmps();
  76. }, 500);
  77. }
  78. }, [loadingEmps])
  79. const changeEmps = () => {
  80. let emp = loadingEmps;
  81. if (loadingEmps.length == 3) {
  82. emp = "";
  83. } else {
  84. emp += ".";
  85. }
  86. setEmps(emp);
  87. }
  88. return (
  89. isCharging
  90. ? <ScrollView
  91. style={ui.flex1}
  92. contentContainerStyle={$padding(16)}>
  93. <Animated.View style={{opacity: skipAnim ? 1 : fadeAnim}}>
  94. <View style={ui.center}>
  95. <Image
  96. style={styles.stepImage}
  97. resizeMode="contain"
  98. source={require('../../images/site/charging-status-charge.png')}/>
  99. <TextView style={styles.stepTitle}>{$t('charging.statusCharging')}</TextView>
  100. <TextView style={styles.stepDesc}>{$t('charging.stepChargingDesc')}</TextView>
  101. { connectorInfo.batteryPercent >= 0 &&
  102. <TextView
  103. style={styles.socText}
  104. numberOfLines={1}>{connectorInfo.batteryPercent || "0"}%</TextView>
  105. }
  106. </View>
  107. <View style={styles.infoRow}>
  108. <View style={skipAnim ? styles.infoCarded : styles.infoCard}>
  109. <TextView style={styles.infoTitle}>{$t('charging.labelTimeElapsed')}</TextView>
  110. <TextView
  111. numberOfLines={1}
  112. ellipsizeMode="tail"
  113. style={styles.infoText}>{utils.minutes2HHMM(connectorInfo?.timeElapsed ?? 0)}</TextView>
  114. <TextView style={styles.infoDesc}></TextView>
  115. </View>
  116. <View style={skipAnim ? styles.infoCarded : styles.infoCard}>
  117. <TextView style={styles.infoTitle}>{$t('charging.labelTotalkWh')}</TextView>
  118. <TextView
  119. numberOfLines={1}
  120. ellipsizeMode="tail"
  121. style={styles.infoText}>{connectorInfo.totalKWhDelivered || "0"} kWh</TextView>
  122. <TextView style={styles.infoDesc}></TextView>
  123. </View>
  124. </View>
  125. <View style={styles.infoRow}>
  126. <View style={skipAnim ? styles.infoCarded : styles.infoCard}>
  127. <DiscountView visible={connectorInfo.hasDiscount}/>
  128. <TextView style={styles.infoTitle}>{$t('charging.labelRate')}</TextView>
  129. <TextView
  130. numberOfLines={2}
  131. ellipsizeMode="tail"
  132. style={styles.infoText}>{connectorInfo.rates || "S$0.00/kWh"}</TextView>
  133. {(app.modules.nationally && connectorInfo.rates != connectorInfo.userRates) && (
  134. <TextView
  135. numberOfLines={1}
  136. ellipsizeMode="tail"
  137. style={styles.infoDesc}>({connectorInfo.userRates || "S$0.00/kWh"})</TextView>)
  138. }
  139. </View>
  140. <View style={skipAnim ? styles.infoCarded : styles.infoCard}>
  141. <TextView style={styles.infoTitle}>{$t('charging.labelTotalCharges')}</TextView>
  142. <TextView
  143. numberOfLines={2}
  144. ellipsizeMode="tail"
  145. style={styles.infoText}>{connectorInfo.totalCharges || "S$ 0.0"}</TextView>
  146. {(app.modules.nationally && connectorInfo.totalCharges != connectorInfo.userTotalCharges) && (
  147. <TextView
  148. numberOfLines={1}
  149. ellipsizeMode="tail"
  150. style={styles.infoDesc}>({connectorInfo.userTotalCharges || "S$ 0.0"})</TextView>)
  151. }
  152. </View>
  153. </View>
  154. </Animated.View>
  155. <EndView/>
  156. { (idleFeeConfig && idleFeeConfig.idleFee) &&
  157. <DialogIdleFee idleFeeConfig={idleFeeConfig}/>
  158. }
  159. <View style={ui.flexc}>
  160. <TextView style={[styles.label, ui.flex1]}>{$t('charging.paymentMethod')}</TextView>
  161. { utils.isNotEmpty(selectedVoucher.userVoucherId) &&
  162. <TextView style={[styles.label, {flex: 1, paddingLeft: 16}]}>{$t('voucher.vouchers')}</TextView>
  163. }
  164. </View>
  165. <View style={ui.flexc}>
  166. <View style={ui.flex1}>
  167. { app.charge.paymentMethod
  168. ? <PaymentListV2
  169. isSelect={false}
  170. payType={currentPayment}
  171. chargeBoxId={connectorInfo.chargeBoxId}/>
  172. : <PaymentList
  173. isSelect={false}
  174. payType={currentPayment}/>
  175. }
  176. </View>
  177. { utils.isNotEmpty(selectedVoucher.userVoucherId) &&
  178. <View style={styles.voucherLayout}>
  179. <MaterialCommunityIcons
  180. name="ticket-percent"
  181. size={35}
  182. color={colorAccent}/>
  183. <View style={styles.vouchersView}>
  184. <TextView
  185. style={styles.voucherName}
  186. numberOfLines={1}>
  187. {selectedVoucher.voucherName}
  188. </TextView>
  189. <TextView
  190. style={styles.voucherDesc}
  191. numberOfLines={1}>
  192. {selectedVoucher.voucherDesc}
  193. </TextView>
  194. </View>
  195. </View>
  196. }
  197. </View>
  198. <Button
  199. style={styles.buttonView}
  200. text={$t('charging.btnStopCharging')}
  201. elevation={1.5}
  202. borderRadius={6}
  203. onClick={onStopCharge}/>
  204. </ScrollView>
  205. : <View style={ui.flex1}>
  206. <Animated.View style={[
  207. styles.content, {
  208. marginTop: topAnim
  209. }
  210. ]}>
  211. <Image
  212. style={styles.stepImage}
  213. resizeMode="contain"
  214. source={require('../../images/site/charging-status-ready.png')}/>
  215. <View style={ui.flexcc}>
  216. <TextView style={styles.stepTitle}>{$t('charging.stepInitializing')}</TextView>
  217. <TextView style={[styles.stepTitle, {width: 30, marginRight: -10}]}>{loadingEmps}</TextView>
  218. </View>
  219. <TextView style={styles.stepDesc}>{$t('charging.stepInitializingDesc')}</TextView>
  220. </Animated.View>
  221. {/* <View style={styles.bottomView}>
  222. <TextView style={styles.label}>{$t('charging.paymentMethod')}</TextView>
  223. { app.charge.paymentMethod
  224. ? <PaymentListV2
  225. isSelect={false}
  226. payType={currentPayment}
  227. chargeBoxId={connectorInfo.chargeBoxId}/>
  228. : <PaymentList
  229. isSelect={false}
  230. payType={currentPayment}/>
  231. }
  232. <View style={styles.buttonView}></View>
  233. </View> */}
  234. </View>
  235. );
  236. }
  237. export default StepCharging;
  238. const styles = StyleSheet.create({
  239. content: {
  240. flex: 1,
  241. alignItems: 'center',
  242. justifyContent: 'center'
  243. },
  244. stepImage: {
  245. width: $vw(70),
  246. height: $vw(16),
  247. margin: 16
  248. },
  249. stepTitle: {
  250. fontSize: 24,
  251. fontWeight: 'bold',
  252. color: colorAccent
  253. },
  254. stepDesc: {
  255. color: textPrimary,
  256. fontSize: 16,
  257. textAlign: 'center',
  258. ...$padding(0, 32, 48)
  259. },
  260. socText: {
  261. right: $vw(15),
  262. color: colorAccent,
  263. width: 60,
  264. marginRight: -8,
  265. fontSize: 24,
  266. fontWeight: 'bold',
  267. position: 'absolute',
  268. textAlign: 'center',
  269. },
  270. infoRow: {
  271. marginLeft: 16,
  272. marginBottom: 16,
  273. flexDirection: 'row'
  274. },
  275. infoCard: {
  276. flex: 1,
  277. paddingTop: 12,
  278. paddingBottom: 12,
  279. borderRadius: 10,
  280. marginRight: 16,
  281. overflow: 'hidden',
  282. alignItems: 'center',
  283. //...ElevationObject(5),
  284. backgroundColor: colorLight
  285. },
  286. infoCarded: {
  287. flex: 1,
  288. paddingTop: 12,
  289. paddingBottom: 12,
  290. borderRadius: 10,
  291. marginRight: 16,
  292. overflow: 'hidden',
  293. alignItems: 'center',
  294. ...ElevationObject(5),
  295. backgroundColor: colorLight
  296. },
  297. infoTitle: {
  298. color: textPrimary,
  299. fontSize: 12
  300. },
  301. infoText: {
  302. color: textPrimary,
  303. fontSize: 15,
  304. fontWeight: 'bold',
  305. textAlign: 'center',
  306. ...$padding(12, 6)
  307. },
  308. infoDesc: {
  309. color: textPrimary,
  310. fontSize: 12,
  311. marginTop: -12,
  312. paddingBottom: 8
  313. },
  314. infoStatus: {
  315. fontSize: 16,
  316. fontWeight: 'bold',
  317. ...$padding(16, 8)
  318. },label: {
  319. color: '#000',
  320. fontSize: 14,
  321. fontWeight: 'bold',
  322. paddingTop: 16,
  323. paddingBottom: 8
  324. },
  325. bottomView: {
  326. left: 0,
  327. right: 0,
  328. bottom: 32,
  329. padding: 16,
  330. position: 'absolute'
  331. },
  332. buttonView: {
  333. marginTop: 16,
  334. marginBottom: 16
  335. },
  336. voucherLayout: {
  337. flex: 1,
  338. padding: 12,
  339. maxWidth: $vw(50) - 24,
  340. borderRadius: 10,
  341. marginLeft: 16,
  342. marginBottom: 12,
  343. alignItems: 'center',
  344. flexDirection: 'row',
  345. ...ElevationObject(5),
  346. backgroundColor: colorLight,
  347. },
  348. vouchersView: {
  349. flex: 1,
  350. paddingLeft: 8,
  351. flexWrap: 'wrap',
  352. alignItems: 'center',
  353. flexDirection: 'row'
  354. },
  355. selectText: {
  356. flex: 1,
  357. color: textSecondary,
  358. fontSize: 15,
  359. fontWeight: 'bold'
  360. },
  361. voucherName: {
  362. color: textPrimary,
  363. fontSize: 15,
  364. paddingLeft: 8,
  365. fontWeight: 'bold'
  366. },
  367. voucherDesc: {
  368. color: textSecondary,
  369. fontSize: 12,
  370. paddingLeft: 8,
  371. paddingRight: 16
  372. }
  373. })