Application Android et IOS pour l'amicale des élèves https://play.google.com/store/apps/details?id=fr.amicaleinsat.application
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ProximoMainScreen.js 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // @flow
  2. import * as React from 'react';
  3. import {Platform, View} from 'react-native'
  4. import {Body, Left, ListItem, Right, Text} from 'native-base';
  5. import i18n from "i18n-js";
  6. import {MaterialCommunityIcons} from "@expo/vector-icons";
  7. import ThemeManager from "../../utils/ThemeManager";
  8. import Touchable from "react-native-platform-touchable";
  9. import WebSectionList from "../../components/WebSectionList";
  10. const DATA_URL = "https://etud.insa-toulouse.fr/~proximo/data/stock-v2.json";
  11. type Props = {
  12. navigation: Object,
  13. }
  14. type State = {
  15. fetchedData: Object,
  16. }
  17. /**
  18. * Class defining the main proximo screen. This screen shows the different categories of articles
  19. * offered by proximo.
  20. */
  21. export default class ProximoMainScreen extends React.Component<Props, State> {
  22. articles: Object;
  23. onPressSearchBtn: Function;
  24. onPressAboutBtn: Function;
  25. getRenderItem: Function;
  26. createDataset: Function;
  27. constructor() {
  28. super();
  29. this.onPressSearchBtn = this.onPressSearchBtn.bind(this);
  30. this.onPressAboutBtn = this.onPressAboutBtn.bind(this);
  31. this.getRenderItem = this.getRenderItem.bind(this);
  32. this.createDataset = this.createDataset.bind(this);
  33. }
  34. static sortFinalData(a: Object, b: Object) {
  35. let str1 = a.type.name.toLowerCase();
  36. let str2 = b.type.name.toLowerCase();
  37. // Make 'All' category with id -1 stick to the top
  38. if (a.type.id === -1)
  39. return -1;
  40. if (b.type.id === -1)
  41. return 1;
  42. // Sort others by name ascending
  43. if (str1 < str2)
  44. return -1;
  45. if (str1 > str2)
  46. return 1;
  47. return 0;
  48. }
  49. componentDidMount() {
  50. const rightButton = this.getRightButton.bind(this);
  51. this.props.navigation.setOptions({
  52. headerRight: rightButton,
  53. });
  54. }
  55. getKeyExtractor(item: Object) {
  56. return item !== undefined ? item.type['id'] : undefined;
  57. }
  58. createDataset(fetchedData: Object) {
  59. return [
  60. {
  61. title: '',
  62. data: this.generateData(fetchedData),
  63. extraData: this.state,
  64. keyExtractor: this.getKeyExtractor
  65. }
  66. ];
  67. }
  68. /**
  69. * Generate the data using types and FetchedData.
  70. * This will group items under the same type.
  71. *
  72. * @param fetchedData The array of articles represented by objects
  73. * @returns {Array} The formatted dataset
  74. */
  75. generateData(fetchedData: Object) {
  76. let finalData = [];
  77. this.articles = undefined;
  78. if (fetchedData.types !== undefined && fetchedData.articles !== undefined) {
  79. let types = fetchedData.types;
  80. this.articles = fetchedData.articles;
  81. finalData.push({
  82. type: {
  83. id: -1,
  84. name: i18n.t('proximoScreen.all'),
  85. icon: 'star'
  86. },
  87. data: this.getAvailableArticles(this.articles, undefined)
  88. });
  89. for (let i = 0; i < types.length; i++) {
  90. finalData.push({
  91. type: types[i],
  92. data: this.getAvailableArticles(this.articles, types[i])
  93. });
  94. }
  95. }
  96. finalData.sort(ProximoMainScreen.sortFinalData);
  97. return finalData;
  98. }
  99. /**
  100. * Get an array of available articles (in stock) of the given type
  101. *
  102. * @param articles The list of all articles
  103. * @param type The type of articles to find (undefined for any type)
  104. * @return {Array} The array of available articles
  105. */
  106. getAvailableArticles(articles: Array<Object>, type: ?Object) {
  107. let availableArticles = [];
  108. for (let k = 0; k < articles.length; k++) {
  109. if ((type !== undefined && type !== null && articles[k]['type'].includes(type['id'])
  110. || type === undefined)
  111. && parseInt(articles[k]['quantity']) > 0) {
  112. availableArticles.push(articles[k]);
  113. }
  114. }
  115. return availableArticles;
  116. }
  117. onPressSearchBtn() {
  118. let searchScreenData = {
  119. shouldFocusSearchBar: true,
  120. data: {
  121. type: {
  122. id: "0",
  123. name: i18n.t('proximoScreen.all'),
  124. icon: 'star'
  125. },
  126. data: this.articles !== undefined ?
  127. this.getAvailableArticles(this.articles, undefined) : []
  128. },
  129. };
  130. this.props.navigation.navigate('ProximoListScreen', searchScreenData);
  131. }
  132. onPressAboutBtn() {
  133. this.props.navigation.navigate('ProximoAboutScreen');
  134. }
  135. getRightButton() {
  136. return (
  137. <View
  138. style={{
  139. flexDirection: 'row',
  140. marginRight: 10,
  141. }}>
  142. <Touchable
  143. style={{padding: 6}}
  144. onPress={this.onPressSearchBtn}>
  145. <MaterialCommunityIcons
  146. name="magnify"
  147. size={26}
  148. color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}/>
  149. </Touchable>
  150. <Touchable
  151. style={{padding: 6}}
  152. onPress={this.onPressAboutBtn}>
  153. <MaterialCommunityIcons
  154. name="information"
  155. size={26}
  156. color={Platform.OS === 'ios' ? ThemeManager.getCurrentThemeVariables().brandPrimary : "#fff"}/>
  157. </Touchable>
  158. </View>
  159. );
  160. }
  161. getRenderItem({item}: Object) {
  162. let dataToSend = {
  163. shouldFocusSearchBar: false,
  164. data: item,
  165. };
  166. const onPress = this.props.navigation.navigate.bind(this, 'ProximoListScreen', dataToSend);
  167. if (item.data.length > 0) {
  168. return (
  169. <ListItem
  170. button
  171. thumbnail
  172. onPress={onPress}
  173. >
  174. <Left>
  175. <MaterialCommunityIcons
  176. name={item.type.icon}
  177. size={30}
  178. color={ThemeManager.getCurrentThemeVariables().brandPrimary}
  179. />
  180. </Left>
  181. <Body>
  182. <Text>
  183. {item.type.name}
  184. </Text>
  185. <Text note>
  186. {item.data.length} {item.data.length > 1 ? i18n.t('proximoScreen.articles') : i18n.t('proximoScreen.article')}
  187. </Text>
  188. </Body>
  189. <Right>
  190. <MaterialCommunityIcons
  191. icon="chevron-right"
  192. size={26}
  193. color={ThemeManager.getCurrentThemeVariables().customMaterialIconColor}/>
  194. </Right>
  195. </ListItem>
  196. );
  197. } else
  198. return <View/>;
  199. }
  200. render() {
  201. const nav = this.props.navigation;
  202. return (
  203. <WebSectionList
  204. createDataset={this.createDataset}
  205. navigation={nav}
  206. refreshTime={0}
  207. fetchUrl={DATA_URL}
  208. renderItem={this.getRenderItem}
  209. updateErrorText={i18n.t("homeScreen.listUpdateFail")}/>
  210. );
  211. }
  212. }