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.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. // @flow
  2. import * as React from 'react';
  3. import type {cardList} from "../../components/Lists/CardList/CardList";
  4. import CardList from "../../components/Lists/CardList/CardList";
  5. import CustomTabBar from "../../components/Tabbar/CustomTabBar";
  6. import {withCollapsible} from "../../utils/withCollapsible";
  7. import {Collapsible} from "react-navigation-collapsible";
  8. import {Animated, View} from "react-native";
  9. import {Avatar, Card, Divider, List, TouchableRipple, withTheme} from "react-native-paper";
  10. import type {CustomTheme} from "../../managers/ThemeManager";
  11. import i18n from 'i18n-js';
  12. import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
  13. import ConnectionManager from "../../managers/ConnectionManager";
  14. import {StackNavigationProp} from "@react-navigation/stack";
  15. import AvailableWebsites from "../../constants/AvailableWebsites";
  16. type Props = {
  17. navigation: StackNavigationProp,
  18. collapsibleStack: Collapsible,
  19. theme: CustomTheme,
  20. }
  21. export type listItem = {
  22. title: string,
  23. description: string,
  24. image: string | number,
  25. shouldLogin: boolean,
  26. content: cardList,
  27. }
  28. const AMICALE_LOGO = require("../../../assets/amicale.png");
  29. const CLUBS_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Clubs.png";
  30. const PROFILE_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/ProfilAmicaliste.png";
  31. const VOTE_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Vote.png";
  32. const AMICALE_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/WebsiteAmicale.png";
  33. const PROXIMO_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Proximo.png"
  34. const WIKETUD_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Wiketud.png";
  35. const EE_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/EEC.png";
  36. const TUTORINSA_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/TutorINSA.png";
  37. const BIB_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Bib.png";
  38. const RU_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/RU.png";
  39. const ROOM_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Salles.png";
  40. const EMAIL_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Bluemind.png";
  41. const ENT_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/ENT.png";
  42. const ACCOUNT_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Account.png";
  43. class ServicesScreen extends React.Component<Props> {
  44. amicaleDataset: cardList;
  45. studentsDataset: cardList;
  46. insaDataset: cardList;
  47. finalDataset: Array<listItem>
  48. constructor(props) {
  49. super(props);
  50. const nav = props.navigation;
  51. this.amicaleDataset = [
  52. {
  53. title: i18n.t('screens.clubsAbout'),
  54. subtitle: i18n.t('servicesScreen.descriptions.clubs'),
  55. image: CLUBS_IMAGE,
  56. onPress: () => this.onAmicaleServicePress("club-list"),
  57. },
  58. {
  59. title: i18n.t('screens.profile'),
  60. subtitle: i18n.t('servicesScreen.descriptions.profile'),
  61. image: PROFILE_IMAGE,
  62. onPress: () => this.onAmicaleServicePress("profile"),
  63. },
  64. {
  65. title: i18n.t('screens.amicaleWebsite'),
  66. subtitle: i18n.t('servicesScreen.descriptions.amicaleWebsite'),
  67. image: AMICALE_IMAGE,
  68. onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.AMICALE, title: i18n.t('screens.amicaleWebsite')}),
  69. },
  70. {
  71. title: i18n.t('screens.vote'),
  72. subtitle: i18n.t('servicesScreen.descriptions.vote'),
  73. image: VOTE_IMAGE,
  74. onPress: () => this.onAmicaleServicePress("vote"),
  75. },
  76. ];
  77. this.studentsDataset = [
  78. {
  79. title: i18n.t('screens.proximo'),
  80. subtitle: i18n.t('servicesScreen.descriptions.proximo'),
  81. image: PROXIMO_IMAGE,
  82. onPress: () => nav.navigate("proximo"),
  83. },
  84. {
  85. title: "Wiketud",
  86. subtitle: i18n.t('servicesScreen.descriptions.wiketud'),
  87. image: WIKETUD_IMAGE,
  88. onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.WIKETUD, title: "Wiketud"}),
  89. },
  90. {
  91. title: "Élus Étudiants",
  92. subtitle: i18n.t('servicesScreen.descriptions.elusEtudiants'),
  93. image: EE_IMAGE,
  94. onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.ELUS_ETUDIANTS, title: "Élus Étudiants"}),
  95. },
  96. {
  97. title: "Tutor'INSA",
  98. subtitle: i18n.t('servicesScreen.descriptions.tutorInsa'),
  99. image: TUTORINSA_IMAGE,
  100. onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.TUTOR_INSA, title: "Tutor'INSA"})
  101. },
  102. ];
  103. this.insaDataset = [
  104. {
  105. title: i18n.t('screens.menuSelf'),
  106. subtitle: i18n.t('servicesScreen.descriptions.self'),
  107. image: RU_IMAGE,
  108. onPress: () => nav.navigate("self-menu"),
  109. },
  110. {
  111. title: i18n.t('screens.availableRooms'),
  112. subtitle: i18n.t('servicesScreen.descriptions.availableRooms'),
  113. image: ROOM_IMAGE,
  114. onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.AVAILABLE_ROOMS, title: i18n.t('screens.availableRooms')}),
  115. },
  116. {
  117. title: i18n.t('screens.bib'),
  118. subtitle: i18n.t('servicesScreen.descriptions.bib'),
  119. image: BIB_IMAGE,
  120. onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.BIB, title: i18n.t('screens.bib')}),
  121. },
  122. {
  123. title: i18n.t('screens.bluemind'),
  124. subtitle: i18n.t('servicesScreen.descriptions.mails'),
  125. image: EMAIL_IMAGE,
  126. onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.BLUEMIND, title: i18n.t('screens.bluemind')}),
  127. },
  128. {
  129. title: i18n.t('screens.ent'),
  130. subtitle: i18n.t('servicesScreen.descriptions.ent'),
  131. image: ENT_IMAGE,
  132. onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.ENT, title: i18n.t('screens.ent')}),
  133. },
  134. {
  135. title: i18n.t('screens.insaAccount'),
  136. subtitle: i18n.t('servicesScreen.descriptions.insaAccount'),
  137. image: ACCOUNT_IMAGE,
  138. onPress: () => nav.navigate("website", {host: AvailableWebsites.websites.INSA_ACCOUNT, title: i18n.t('screens.insaAccount')}),
  139. },
  140. ];
  141. this.finalDataset = [
  142. {
  143. title: i18n.t("servicesScreen.amicale"),
  144. description: "LOGIN",
  145. image: AMICALE_LOGO,
  146. shouldLogin: true,
  147. content: this.amicaleDataset
  148. },
  149. {
  150. title: i18n.t("servicesScreen.students"),
  151. description: "SERVICES OFFERED BY STUDENTS",
  152. image: 'account-group',
  153. shouldLogin: false,
  154. content: this.studentsDataset
  155. },
  156. {
  157. title: i18n.t("servicesScreen.insa"),
  158. description: "SERVICES OFFERED BY INSA",
  159. image: 'school',
  160. shouldLogin: false,
  161. content: this.insaDataset
  162. },
  163. ];
  164. }
  165. componentDidMount() {
  166. this.props.navigation.setOptions({
  167. headerRight: this.getAboutButton,
  168. });
  169. }
  170. getAboutButton = () =>
  171. <MaterialHeaderButtons>
  172. <Item title="information" iconName="information" onPress={this.onAboutPress}/>
  173. </MaterialHeaderButtons>;
  174. onAboutPress = () => this.props.navigation.navigate('amicale-contact');
  175. /**
  176. * Gets the list title image for the list.
  177. *
  178. * If the source is a string, we are using an icon.
  179. * If the source is a number, we are using an internal image.
  180. *
  181. * @param props Props to pass to the component
  182. * @param source The source image to display. Can be a string for icons or a number for local images
  183. * @returns {*}
  184. */
  185. getListTitleImage(props, source: string | number) {
  186. if (typeof source === "number")
  187. return <Avatar.Image
  188. {...props}
  189. size={48}
  190. source={source}
  191. style={{backgroundColor: 'transparent'}}
  192. />
  193. else
  194. return <Avatar.Icon
  195. {...props}
  196. size={48}
  197. icon={source}
  198. color={this.props.theme.colors.primary}
  199. style={{backgroundColor: 'transparent'}}
  200. />
  201. }
  202. /**
  203. * Redirects to the given route or to the login screen if user is not logged in.
  204. *
  205. * @param route The route to navigate to
  206. */
  207. onAmicaleServicePress(route: string) {
  208. if (ConnectionManager.getInstance().isLoggedIn())
  209. this.props.navigation.navigate(route);
  210. else
  211. this.props.navigation.navigate("login", {nextScreen: route});
  212. }
  213. /**
  214. * A list item showing a list of available services for the current category
  215. *
  216. * @param item
  217. * @returns {*}
  218. */
  219. renderItem = ({item}: { item: listItem }) => {
  220. return (
  221. <TouchableRipple
  222. style={{
  223. margin: 5,
  224. marginBottom: 20,
  225. }}
  226. onPress={() => this.props.navigation.navigate("services-section", {data: item})}
  227. >
  228. <View>
  229. <Card.Title
  230. title={item.title}
  231. left={(props) => this.getListTitleImage(props, item.image)}
  232. right={(props) => <List.Icon {...props} icon="chevron-right"/>}
  233. />
  234. <CardList
  235. dataset={item.content}
  236. isHorizontal={true}
  237. />
  238. </View>
  239. </TouchableRipple>
  240. );
  241. };
  242. keyExtractor = (item: listItem) => {
  243. return item.title;
  244. }
  245. render() {
  246. const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
  247. return <Animated.FlatList
  248. data={this.finalDataset}
  249. renderItem={this.renderItem}
  250. keyExtractor={this.keyExtractor}
  251. onScroll={onScroll}
  252. contentContainerStyle={{
  253. paddingTop: containerPaddingTop,
  254. paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20
  255. }}
  256. scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
  257. ItemSeparatorComponent={() => <Divider/>}
  258. />
  259. }
  260. }
  261. export default withCollapsible(withTheme(ServicesScreen));