Profile.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /**
  2. * Profile Settings页面
  3. * @邠心vbe on 2021/04/27
  4. */
  5. import React, { Component } from 'react';
  6. import { View, Text, StyleSheet, Image, ScrollView, Switch, Pressable } from 'react-native';
  7. import apiUser from '../../api/apiUser';
  8. import { host } from '../../api/http';
  9. import Button, { ElevationObject } from '../../components/Button';
  10. import Dialog from '../../components/Dialog';
  11. import { StationBack } from '../../components/Toolbar';
  12. import utils from '../../utils/utils';
  13. import { PageList } from '../Router';
  14. import { CardList } from '../wallet/CardList';
  15. import VehicleList from './VehicleList';
  16. export default class Profile extends Component {
  17. constructor(props) {
  18. super(props);
  19. this.state = {
  20. userInfo: {
  21. notifyLowBalance: true,
  22. notifyChargingComplete: true,
  23. notifyPromotionsOffers: true
  24. },
  25. refreshId: 0,
  26. totalVehicle: 0
  27. };
  28. this.changed = false;
  29. }
  30. componentDidMount() {
  31. this.props.navigation.addListener('focus', () => {
  32. getUserInfo(info => {
  33. this.setState({
  34. userInfo: info,
  35. refreshId: this.state.refreshId + 1
  36. });
  37. }, true);
  38. });
  39. }
  40. componentWillUnmount() {
  41. if (this.changed) {
  42. this.setChangedSwitch();
  43. }
  44. }
  45. removeVehicle(id) {
  46. Dialog.showDialog({
  47. title: 'Remove Vehicle',
  48. message: 'Are you sure you want to remove this vehicle?',
  49. callback: btn => {
  50. if (btn == 'ok') {
  51. Dialog.dismissLoading();
  52. this.deleteVehicle(id);
  53. }
  54. }
  55. })
  56. }
  57. deleteVehicle(id) {
  58. Dialog.showProgressDialog();
  59. apiUser.deleteVehicle({
  60. vehiclePk: id
  61. }).then(res => {
  62. Dialog.dismissLoading();
  63. toastShort('Delete successfully');
  64. this.setState({
  65. refreshId: this.state.refreshId + 1
  66. })
  67. }).catch(err => {
  68. Dialog.dismissLoading();
  69. toastShort(err);
  70. });
  71. }
  72. changeSwitch(key, value) {
  73. userInfo[key] = value;
  74. this.setState({
  75. userInfo: userInfo
  76. });
  77. this.changed = true;
  78. }
  79. setChangedSwitch() {
  80. apiUser.setNotifySwitch(userInfo);
  81. }
  82. deleteAccount() {
  83. Dialog.showDialog({
  84. title: 'Delete My Account',
  85. message: 'Are you sure you want to delete your account? This operation cannot be revoke.',
  86. ok: 'CONFIRM',
  87. callback: button => {
  88. if (button == Dialog.BUTTON_OK) {
  89. this.deleteMyAccount();
  90. }
  91. }
  92. })
  93. }
  94. deleteMyAccount() {
  95. Dialog.showProgressDialog();
  96. apiUser.deleteAccount().then(res => {
  97. toastShort('Successfully deleted!')
  98. Dialog.dismissLoading();
  99. setTimeout(() => {
  100. startPage(PageList.login);
  101. }, 500);
  102. }).catch(err => {
  103. Dialog.dismissLoading();
  104. toastShort(err)
  105. })
  106. }
  107. render() {
  108. return (
  109. <ScrollView style={styles.container}>
  110. {/* Profile Info */}
  111. <View style={styles.headerView}>
  112. <Image
  113. style={styles.background}
  114. source={require('../../images/user/bg-profile.png')}/>
  115. <Pressable
  116. style={styles.profileView}
  117. onPress={() => {
  118. startPage(PageList.editProfile);
  119. }}>
  120. { userInfo.photoUrl
  121. ? <Image
  122. style={styles.avatar}
  123. source={{uri: host + userInfo.photoUrl}}/>
  124. : <Image
  125. style={styles.avatar}
  126. source={require('../../images/user/icon-default.jpg')}/>
  127. }
  128. <View style={styles.infoContent}>
  129. <Text
  130. style={styles.nickname}
  131. ellipsizeMode='tail'
  132. numberOfLines={1}>{userInfo.nickName}</Text>
  133. <Text style={styles.userText}>{userInfo.email}</Text>
  134. <Text style={styles.userText}>{(utils.isNotEmpty(userInfo.callingCode) && "+" + userInfo.callingCode) + userInfo.phone}</Text>
  135. </View>
  136. <FontAwesome
  137. size={34}
  138. color='#333'
  139. name='angle-right'/>
  140. </Pressable>
  141. <StationBack bottom={56}/>
  142. </View>
  143. {/* Summary Info */}
  144. <View style={styles.cardView}>
  145. <View style={styles.cardItem}>
  146. <Image
  147. style={styles.cardIcon}
  148. source={require('../../images/user/card-vehicle.png')}/>
  149. <View style={styles.cardInfo}>
  150. <Text style={styles.cardPrimary}>{this.state.totalVehicle}</Text>
  151. <Text style={styles.cardLabel}>My Vehicles</Text>
  152. </View>
  153. </View>
  154. <View style={[styles.cardItem, styles.cardDivide]}>
  155. <Image
  156. style={styles.cardIcon}
  157. source={require('../../images/user/card-wallet.png')}/>
  158. <Pressable
  159. style={styles.cardInfo}
  160. onPress={() => {
  161. startPage(PageList.wallet);
  162. }}>
  163. <Text style={styles.cardPrimary}>{currency}{userInfo.credit}</Text>
  164. <Text style={styles.cardLabel}>Credit Wallet</Text>
  165. </Pressable>
  166. </View>
  167. </View>
  168. {/* Vehicle List */}
  169. <View style={styles.titleView}>
  170. <Text style={styles.title}>My Vehicles</Text>
  171. <Button
  172. style={{backgroundColor: '#fff'}}
  173. borderRadius={3}
  174. viewStyle={styles.titleAdd}
  175. onClick={() => {
  176. startPage(PageList.addVehicle)
  177. }}>
  178. <Entypo name='plus' size={14} color='#333'/>
  179. <Text style={{fontSize: 12, paddingLeft: 1, color: '#333'}}>Add Vehicle</Text>
  180. </Button>
  181. </View>
  182. <View style={styles.verhicleList}>
  183. <VehicleList
  184. refreshId={this.state.refreshId}
  185. onResult={count => {
  186. this.setState({
  187. totalVehicle: count
  188. })
  189. }}
  190. onDelete={id => this.removeVehicle(id)}
  191. />
  192. </View>
  193. {/* Account List */}
  194. {/* <View style={styles.titleView}>
  195. <Text style={styles.title}>My Cards</Text>
  196. <Button
  197. textColor='#333'
  198. style={styles.titleAdd}
  199. onClick={() => {
  200. startPage(PageList.addCard)
  201. }}>
  202. <Entypo name='plus' size={14} color='#333'/>
  203. <Text style={{fontSize: 12, paddingLeft: 1}}>Add Card</Text>
  204. </Button>
  205. </View>
  206. <View style={styles.accountList}>
  207. <CardList refreshId={this.state.refreshId}/>
  208. </View> */}
  209. {/* Notifications */}
  210. <View style={styles.titleView}>
  211. <Text style={styles.title}>Notifications</Text>
  212. </View>
  213. <View style={styles.notificationView}>
  214. <Pressable
  215. style={styles.notificationItem}
  216. android_ripple={ripple}
  217. onPress={() => {
  218. this.changeSwitch("notifyChargingComplete", !userInfo.notifyChargingComplete);
  219. }}>
  220. <Text style={styles.notiLabel}>Notify me when charging complete</Text>
  221. <Switch
  222. value={this.state.userInfo.notifyChargingComplete}
  223. trackColor={isIOS ? { false: "#B2B2B2", true: colorAccent } : null}
  224. onValueChange={v => {
  225. this.changeSwitch("notifyChargingComplete", v);
  226. }}/>
  227. </Pressable>
  228. <Pressable
  229. style={[styles.notificationItem, styles.divide]}
  230. android_ripple={ripple}
  231. onPress={() => {
  232. this.changeSwitch("notifyLowBalance", !userInfo.notifyLowBalance);
  233. }}>
  234. <Text style={styles.notiLabel}>Notify me when wallet is low balance</Text>
  235. <Switch
  236. value={this.state.userInfo.notifyLowBalance}
  237. trackColor={isIOS ? { false: "#B2B2B2", true: colorAccent } : null}
  238. onValueChange={v => {
  239. this.changeSwitch("notifyLowBalance", v);
  240. }}/>
  241. </Pressable>
  242. <Pressable
  243. style={[styles.notificationItem, styles.divide]}
  244. android_ripple={ripple}
  245. onPress={() => {
  246. this.changeSwitch("notifyPromotionsOffers", !userInfo.notifyPromotionsOffers);
  247. }}>
  248. <Text style={styles.notiLabel}>Notify me for promotions and offers</Text>
  249. <Switch
  250. value={this.state.userInfo.notifyPromotionsOffers}
  251. trackColor={isIOS ? { false: "#B2B2B2", true: colorAccent } : null}
  252. onValueChange={v => {
  253. this.changeSwitch("notifyPromotionsOffers", v);
  254. }}/>
  255. </Pressable>
  256. </View>
  257. <Button
  258. style={styles.deleteButton}
  259. text="DELETE MY ACCOUNT"
  260. textColor="#fff"
  261. onClick={() => this.deleteAccount()}
  262. />
  263. </ScrollView>
  264. );
  265. }
  266. }
  267. const styles = StyleSheet.create({
  268. container: {
  269. flex: 1,
  270. backgroundColor: 'white'
  271. },
  272. headerView: {
  273. paddingBottom: 72
  274. },
  275. background: {
  276. left: 0,
  277. bottom: 0,
  278. width: $vw(100),
  279. height: $vw(62.4),
  280. resizeMode: "cover",
  281. position: 'absolute'
  282. },
  283. profileView: {
  284. padding: 16,
  285. zIndex: 10,
  286. alignItems: 'center',
  287. flexDirection: 'row'
  288. },
  289. avatar: {
  290. width: 66,
  291. height: 66,
  292. borderWidth: 2,
  293. borderRadius: 80,
  294. borderColor: '#fff'
  295. },
  296. infoContent: {
  297. flex: 1,
  298. paddingLeft: 16,
  299. },
  300. nickname: {
  301. color: '#000',
  302. fontSize: 16,
  303. paddingTop: 1,
  304. paddingBottom: 1.5,
  305. },
  306. userText: {
  307. color: '#333',
  308. fontSize: 13,
  309. paddingTop: 1.5
  310. },
  311. cardView: {
  312. padding: 16,
  313. marginTop: -56,
  314. marginLeft: 16,
  315. marginRight: 16,
  316. borderRadius: 10,
  317. ...ElevationObject(2),
  318. alignItems: 'center',
  319. flexDirection: 'row',
  320. backgroundColor: 'white',
  321. },
  322. cardItem: {
  323. flex: 1,
  324. alignItems: 'center',
  325. flexDirection: 'row',
  326. justifyContent: 'center'
  327. },
  328. cardDivide: {
  329. borderLeftWidth: 1,
  330. borderLeftColor: '#EEE'
  331. },
  332. cardIcon: {
  333. width: 32,
  334. height: 32
  335. },
  336. cardInfo: {
  337. paddingLeft: 16,
  338. alignItems: 'center'
  339. },
  340. cardPrimary: {
  341. color: '#333',
  342. fontSize: 18,
  343. paddingBottom: 2
  344. },
  345. cardLabel: {
  346. color: '#333',
  347. fontSize: 13,
  348. },
  349. titleView: {
  350. padding: 12,
  351. alignItems: 'center',
  352. flexDirection: 'row'
  353. },
  354. title: {
  355. flex: 1,
  356. padding: 8,
  357. color: '#000',
  358. fontSize: 16,
  359. },
  360. titleAdd: {
  361. padding: 8,
  362. color: '#333',
  363. alignItems: 'center',
  364. flexDirection: 'row'
  365. },
  366. verhicleList: {
  367. paddingLeft: 16,
  368. paddingRight: 16,
  369. marginBottom: -16
  370. },
  371. accountList: {
  372. paddingLeft: 16,
  373. paddingRight: 16,
  374. marginBottom: -16
  375. },
  376. notificationView: {
  377. marginLeft: 16,
  378. marginRight: 16,
  379. marginBottom: 20,
  380. borderRadius: 10,
  381. overflow: 'hidden',
  382. paddingLeft: 16,
  383. paddingRight: 16,
  384. borderColor: '#f5f5f5',
  385. borderWidth: 1,
  386. backgroundColor: 'white',
  387. ...ElevationObject(1.5)
  388. },
  389. notificationItem: {
  390. paddingTop: 16,
  391. paddingBottom: 16,
  392. alignItems: 'center',
  393. flexDirection: 'row'
  394. },
  395. notiLabel: {
  396. flex: 1,
  397. color: '#333',
  398. fontSize: 14
  399. },
  400. divide: {
  401. borderTopWidth: 1,
  402. borderTopColor: '#eee'
  403. },
  404. deleteButton: {
  405. ...$margin(32, 16, 16),
  406. backgroundColor: '#EA0A2A'
  407. }
  408. })