Application Android et IOS pour l'amicale des élèves
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.

SelfMenuScreen.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // @flow
  2. import * as React from 'react';
  3. import {View} from 'react-native';
  4. import {Card, Text, withTheme} from 'react-native-paper';
  5. import {StackNavigationProp} from '@react-navigation/stack';
  6. import i18n from 'i18n-js';
  7. import DateManager from '../../managers/DateManager';
  8. import WebSectionList from '../../components/Screens/WebSectionList';
  9. import type {CustomThemeType} from '../../managers/ThemeManager';
  10. import type {SectionListDataType} from '../../components/Screens/WebSectionList';
  11. const DATA_URL =
  12. 'https://etud.insa-toulouse.fr/~amicale_app/menu/menu_data.json';
  13. type PropsType = {
  14. navigation: StackNavigationProp,
  15. theme: CustomThemeType,
  16. };
  17. export type RuFoodCategoryType = {
  18. name: string,
  19. dishes: Array<{name: string}>,
  20. };
  21. type RuMealType = {
  22. name: string,
  23. foodcategory: Array<RuFoodCategoryType>,
  24. };
  25. type RawRuMenuType = {
  26. restaurant_id: number,
  27. id: number,
  28. date: string,
  29. meal: Array<RuMealType>,
  30. };
  31. /**
  32. * Class defining the app's menu screen.
  33. */
  34. class SelfMenuScreen extends React.Component<PropsType> {
  35. /**
  36. * Formats the given string to make sure it starts with a capital letter
  37. *
  38. * @param name The string to format
  39. * @return {string} The formatted string
  40. */
  41. static formatName(name: string): string {
  42. return name.charAt(0) + name.substr(1).toLowerCase();
  43. }
  44. /**
  45. * Creates the dataset to be used in the FlatList
  46. *
  47. * @param fetchedData
  48. * @return {[]}
  49. */
  50. createDataset = (
  51. fetchedData: Array<RawRuMenuType>,
  52. ): SectionListDataType<RuFoodCategoryType> => {
  53. let result = [];
  54. if (fetchedData == null || fetchedData.length === 0) {
  55. result = [
  56. {
  57. title: i18n.t('general.notAvailable'),
  58. data: [],
  59. keyExtractor: this.getKeyExtractor,
  60. },
  61. ];
  62. } else {
  63. fetchedData.forEach((item: RawRuMenuType) => {
  64. result.push({
  65. title: DateManager.getInstance().getTranslatedDate(item.date),
  66. data: item.meal[0].foodcategory,
  67. keyExtractor: this.getKeyExtractor,
  68. });
  69. });
  70. }
  71. return result;
  72. };
  73. /**
  74. * Gets the render section header
  75. *
  76. * @param section The section to render the header from
  77. * @return {*}
  78. */
  79. getRenderSectionHeader = ({
  80. section,
  81. }: {
  82. section: {title: string},
  83. }): React.Node => {
  84. return (
  85. <Card
  86. style={{
  87. width: '95%',
  88. marginLeft: 'auto',
  89. marginRight: 'auto',
  90. marginTop: 5,
  91. marginBottom: 5,
  92. elevation: 4,
  93. }}>
  94. <Card.Title
  95. title={section.title}
  96. titleStyle={{
  97. textAlign: 'center',
  98. }}
  99. subtitleStyle={{
  100. textAlign: 'center',
  101. }}
  102. style={{
  103. paddingLeft: 0,
  104. }}
  105. />
  106. </Card>
  107. );
  108. };
  109. /**
  110. * Gets a FlatList render item
  111. *
  112. * @param item The item to render
  113. * @return {*}
  114. */
  115. getRenderItem = ({item}: {item: RuFoodCategoryType}): React.Node => {
  116. const {theme} = this.props;
  117. return (
  118. <Card
  119. style={{
  120. flex: 0,
  121. marginHorizontal: 10,
  122. marginVertical: 5,
  123. }}>
  124. <Card.Title style={{marginTop: 5}} title={item.name} />
  125. <View
  126. style={{
  127. width: '80%',
  128. marginLeft: 'auto',
  129. marginRight: 'auto',
  130. borderBottomWidth: 1,
  131. borderBottomColor: theme.colors.primary,
  132. marginTop: 5,
  133. marginBottom: 5,
  134. }}
  135. />
  136. <Card.Content>
  137. {item.dishes.map((object: {name: string}): React.Node =>
  138. object.name !== '' ? (
  139. <Text
  140. style={{
  141. marginTop: 5,
  142. marginBottom: 5,
  143. textAlign: 'center',
  144. }}>
  145. {SelfMenuScreen.formatName(object.name)}
  146. </Text>
  147. ) : null,
  148. )}
  149. </Card.Content>
  150. </Card>
  151. );
  152. };
  153. /**
  154. * Extract a key for the given item
  155. *
  156. * @param item The item to extract the key from
  157. * @return {*} The extracted key
  158. */
  159. getKeyExtractor = (item: RuFoodCategoryType): string => item.name;
  160. render(): React.Node {
  161. const {navigation} = this.props;
  162. return (
  163. <WebSectionList
  164. createDataset={this.createDataset}
  165. navigation={navigation}
  166. autoRefreshTime={0}
  167. refreshOnFocus={false}
  168. fetchUrl={DATA_URL}
  169. renderItem={this.getRenderItem}
  170. renderSectionHeader={this.getRenderSectionHeader}
  171. stickyHeader
  172. />
  173. );
  174. }
  175. }
  176. export default withTheme(SelfMenuScreen);