Profile.js 10 KB

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