StepCharging.js 10 KB

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