SearchV2.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /**
  2. * 新版搜索页
  3. * @邠心vbe on 2023/02/03
  4. */
  5. import React, { Component } from 'react';
  6. import { View, Text, StyleSheet, TextInput, FlatList, Image } from 'react-native';
  7. import apiStation from '../../api/apiStation';
  8. import utils from '../../utils/utils';
  9. import { PageList } from '../Router';
  10. import ListViewV2 from './ListViewV2';
  11. export default class SearchV2 extends Component {
  12. constructor(props) {
  13. super(props);
  14. this.state = {
  15. isSearch: false,
  16. searchResult: [{id:0}],
  17. latlng: {
  18. lat: 0.00001,
  19. lng: 0.00001
  20. }
  21. };
  22. }
  23. componentDidMount() {
  24. this.getGeoLocation();
  25. }
  26. getGeoLocation() {
  27. navigator.geolocation.getCurrentPosition(location => {
  28. let latlng = {
  29. lat: location.coords.latitude,
  30. lng: location.coords.longitude
  31. }
  32. this.setState({
  33. latlng: latlng
  34. })
  35. this.searchStation(latlng);
  36. }, error => {
  37. console.warn("getGeoLocation", error);
  38. this.searchStation(this.state.latlng);
  39. });
  40. }
  41. searchStation(latlng, time=1500) {
  42. this.setState({
  43. isSearch: true
  44. });
  45. latlng.siteName = this.searchWorld
  46. apiStation.searchStation(latlng).then(res => {
  47. if (res.data.sites) {
  48. const list = [];
  49. res.data.sites.forEach(item => {
  50. list.push({
  51. id: item.sitePk,
  52. name: item.siteName,
  53. address: item.siteAddress,
  54. latitude: item.locationLatitude,
  55. longitude: item.locationLongitude,
  56. acConnector: item.acConnector,
  57. allConnector: item.allConnector,
  58. dcConnector: item.dcConnector,
  59. siteType: item.siteType,
  60. distance: utils.getDistance(item.distance),
  61. serviceProvider: item.serviceProvider
  62. });
  63. });
  64. setTimeout(() => {
  65. this.setState({
  66. isSearch: false,
  67. searchResult: list
  68. });
  69. }, time);
  70. }
  71. }).catch(err => {
  72. console.log('err', err);
  73. this.setState({
  74. isSearch: false,
  75. searchResult: []
  76. });
  77. });
  78. }
  79. intoStation(info) {
  80. startPage(PageList.chargeDetailPage, {stationInfo: info, action: 'search', from: PageList.search});
  81. }
  82. listItem = (props) => {
  83. return <ListViewV2 {...props} onPress={() => this.intoStation(props.item)}/>
  84. }
  85. render() {
  86. return (
  87. <View style={styles.container}>
  88. <View style={styles.searchView}>
  89. <Feather
  90. name={'search'}
  91. size={20}
  92. color={'#999'}/>
  93. <TextInput
  94. style={styles.searchInput}
  95. autoFocus={true}
  96. maxLength={50}
  97. numberOfLines={1}
  98. returnKeyType={'search'}
  99. clearButtonMode={'while-editing'}
  100. placeholder='Search using site name or service provider'
  101. placeholderTextColor={textPlacehoder}
  102. onChangeText={text => {
  103. this.searchWorld = text;
  104. }}
  105. onSubmitEditing={() => {
  106. this.searchStation(this.state.latlng, 1000);
  107. }}/>
  108. </View>
  109. { this.state.isSearch
  110. ? <View style={styles.searchingView}>
  111. <Image
  112. style={styles.seachingIcon}
  113. source={require('../../images/icon/search-loading.gif')}/>
  114. </View>
  115. : <FlatList
  116. style={styles.listView}
  117. data={this.state.searchResult}
  118. renderItem={this.listItem}
  119. keyExtractor={item => item.id}
  120. keyboardShouldPersistTaps="always"
  121. ListEmptyComponent={<Text style={styles.noResult}>No search result</Text>}
  122. />
  123. }
  124. </View>
  125. );
  126. }
  127. }
  128. const styles = StyleSheet.create({
  129. container: {
  130. flex: 1,
  131. backgroundColor: colorLight //pageBackground
  132. },
  133. searchView: {
  134. marginTop: 16,
  135. marginLeft: 16,
  136. marginRight: 16,
  137. marginBottom: 8,
  138. paddingLeft: 16,
  139. paddingRight: 16,
  140. borderRadius: 60,
  141. borderWidth: 1,
  142. borderColor: '#E5E5E5',
  143. alignItems: 'center',
  144. flexDirection: 'row',
  145. backgroundColor: '#F5F5F5'
  146. },
  147. searchInput: {
  148. flex: 1,
  149. color: textPrimary,
  150. ...$padding(6, 8),
  151. fontSize: 15,
  152. marginLeft: 4,
  153. lineHeight: 20
  154. },
  155. searchingView: {
  156. padding: 0,
  157. alignItems: 'center'
  158. },
  159. seachingIcon: {
  160. width: 120,
  161. height: 120
  162. },
  163. noResult: {
  164. color: '#999',
  165. fontSize: 14,
  166. padding: 20,
  167. textAlign: 'center',
  168. },
  169. listView: {
  170. flex: 1
  171. },
  172. itemView: {
  173. alignItems: 'center',
  174. flexDirection: 'row',
  175. borderBottomWidth: 1,
  176. borderBottomColor: '#eee'
  177. },
  178. stationInfo: {
  179. flex: 1,
  180. padding: 16
  181. },
  182. nameView: {
  183. paddingTop: 3,
  184. alignItems: 'center',
  185. flexDirection: 'row'
  186. },
  187. stationName: {
  188. color: textPrimary,
  189. fontSize: 18,
  190. fontWeight: 'bold'
  191. },
  192. stationAddress: {
  193. color: '#666',
  194. fontSize: 14,
  195. paddingBottom: 8
  196. },
  197. infoStatus: {
  198. fontSize: 10,
  199. paddingTop: 3,
  200. paddingLeft: 8,
  201. paddingRight: 8,
  202. paddingBottom: 3,
  203. borderRadius: 5,
  204. marginLeft: 12,
  205. },
  206. selected: {
  207. color: textPrimary,
  208. backgroundColor: colorAccent
  209. },
  210. available: {
  211. color: textLight,
  212. backgroundColor: '#90DB0A'
  213. },
  214. unavailable: {
  215. color: '#999',
  216. fontSize: 10.5,
  217. paddingTop: 7,
  218. paddingLeft: 9,
  219. paddingRight: 9,
  220. paddingBottom: 7,
  221. backgroundColor: '#CCC'
  222. },
  223. connectView: {
  224. paddingTop: 4,
  225. paddingBottom: 4,
  226. alignItems: 'center',
  227. flexDirection: 'row'
  228. },
  229. directView: {
  230. zIndex: 1,
  231. paddingTop: 4,
  232. paddingRight: 16,
  233. alignItems: 'center'
  234. },
  235. distanceText: {
  236. color: textPrimary,
  237. fontSize: 12,
  238. paddingTop: 2
  239. },
  240. });