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.

ServicesScreen.tsx 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright (c) 2019 - 2020 Arnaud Vergnet.
  3. *
  4. * This file is part of Campus INSAT.
  5. *
  6. * Campus INSAT is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Campus INSAT is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. import * as React from 'react';
  20. import {Image, View} from 'react-native';
  21. import {
  22. Avatar,
  23. Card,
  24. Divider,
  25. List,
  26. TouchableRipple,
  27. withTheme,
  28. } from 'react-native-paper';
  29. import i18n from 'i18n-js';
  30. import {StackNavigationProp} from '@react-navigation/stack';
  31. import CardList from '../../components/Lists/CardList/CardList';
  32. import MaterialHeaderButtons, {
  33. Item,
  34. } from '../../components/Overrides/CustomHeaderButton';
  35. import {MASCOT_STYLE} from '../../components/Mascot/Mascot';
  36. import MascotPopup from '../../components/Mascot/MascotPopup';
  37. import AsyncStorageManager from '../../managers/AsyncStorageManager';
  38. import ServicesManager, {
  39. SERVICES_CATEGORIES_KEY,
  40. } from '../../managers/ServicesManager';
  41. import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList';
  42. import type {ServiceCategoryType} from '../../managers/ServicesManager';
  43. type PropsType = {
  44. navigation: StackNavigationProp<any>;
  45. theme: ReactNativePaper.Theme;
  46. };
  47. class ServicesScreen extends React.Component<PropsType> {
  48. finalDataset: Array<ServiceCategoryType>;
  49. constructor(props: PropsType) {
  50. super(props);
  51. const services = new ServicesManager(props.navigation);
  52. this.finalDataset = services.getCategories([
  53. SERVICES_CATEGORIES_KEY.SPECIAL,
  54. ]);
  55. }
  56. componentDidMount() {
  57. const {props} = this;
  58. props.navigation.setOptions({
  59. headerRight: this.getAboutButton,
  60. });
  61. }
  62. getAboutButton = () => (
  63. <MaterialHeaderButtons>
  64. <Item
  65. title="information"
  66. iconName="information"
  67. onPress={this.onAboutPress}
  68. />
  69. </MaterialHeaderButtons>
  70. );
  71. onAboutPress = () => {
  72. const {props} = this;
  73. props.navigation.navigate('amicale-contact');
  74. };
  75. /**
  76. * Gets the list title image for the list.
  77. *
  78. * If the source is a string, we are using an icon.
  79. * If the source is a number, we are using an internal image.
  80. *
  81. * @param source The source image to display. Can be a string for icons or a number for local images
  82. * @returns {*}
  83. */
  84. getListTitleImage(source: string | number) {
  85. const {props} = this;
  86. if (typeof source === 'number') {
  87. return (
  88. <Image
  89. source={source}
  90. style={{
  91. width: 48,
  92. height: 48,
  93. }}
  94. />
  95. );
  96. }
  97. return (
  98. <Avatar.Icon
  99. size={48}
  100. icon={source}
  101. color={props.theme.colors.primary}
  102. style={{backgroundColor: 'transparent'}}
  103. />
  104. );
  105. }
  106. /**
  107. * A list item showing a list of available services for the current category
  108. *
  109. * @param item
  110. * @returns {*}
  111. */
  112. getRenderItem = ({item}: {item: ServiceCategoryType}) => {
  113. const {props} = this;
  114. return (
  115. <TouchableRipple
  116. style={{
  117. margin: 5,
  118. marginBottom: 20,
  119. }}
  120. onPress={() => {
  121. props.navigation.navigate('services-section', {data: item});
  122. }}>
  123. <View>
  124. <Card.Title
  125. title={item.title}
  126. subtitle={item.subtitle}
  127. left={() => this.getListTitleImage(item.image)}
  128. right={() => <List.Icon icon="chevron-right" />}
  129. />
  130. <CardList dataset={item.content} isHorizontal />
  131. </View>
  132. </TouchableRipple>
  133. );
  134. };
  135. keyExtractor = (item: ServiceCategoryType): string => item.title;
  136. render() {
  137. return (
  138. <View>
  139. <CollapsibleFlatList
  140. data={this.finalDataset}
  141. renderItem={this.getRenderItem}
  142. keyExtractor={this.keyExtractor}
  143. ItemSeparatorComponent={() => <Divider />}
  144. hasTab
  145. />
  146. <MascotPopup
  147. prefKey={AsyncStorageManager.PREFERENCES.servicesShowMascot.key}
  148. title={i18n.t('screens.services.mascotDialog.title')}
  149. message={i18n.t('screens.services.mascotDialog.message')}
  150. icon="cloud-question"
  151. buttons={{
  152. cancel: {
  153. message: i18n.t('screens.services.mascotDialog.button'),
  154. icon: 'check',
  155. },
  156. }}
  157. emotion={MASCOT_STYLE.WINK}
  158. />
  159. </View>
  160. );
  161. }
  162. }
  163. export default withTheme(ServicesScreen);