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.

ClubDisplayScreen.js 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // @flow
  2. import * as React from 'react';
  3. import {ScrollView, View} from 'react-native';
  4. import HTML from "react-native-render-html";
  5. import {Linking} from "expo";
  6. import {Avatar, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
  7. import ImageModal from 'react-native-image-modal';
  8. import i18n from "i18n-js";
  9. import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
  10. type Props = {
  11. navigation: Object,
  12. route: Object
  13. };
  14. type State = {
  15. imageModalVisible: boolean,
  16. };
  17. function openWebLink(event, link) {
  18. Linking.openURL(link).catch((err) => console.error('Error opening link', err));
  19. }
  20. /**
  21. * Class defining a club event information page.
  22. * If called with data and categories navigation parameters, will use those to display the data.
  23. * If called with clubId parameter, will fetch the information on the server
  24. */
  25. class ClubDisplayScreen extends React.Component<Props, State> {
  26. displayData: Object;
  27. categories: Object | null;
  28. clubId: number;
  29. shouldFetchData: boolean;
  30. colors: Object;
  31. state = {
  32. imageModalVisible: false,
  33. };
  34. constructor(props) {
  35. super(props);
  36. this.colors = props.theme.colors;
  37. if (this.props.route.params.data !== undefined && this.props.route.params.categories !== undefined) {
  38. this.displayData = this.props.route.params.data;
  39. this.categories = this.props.route.params.categories;
  40. this.clubId = this.props.route.params.data.id;
  41. this.shouldFetchData = false;
  42. } else {
  43. this.displayData = null;
  44. this.categories = null;
  45. this.clubId = this.props.route.params.clubId;
  46. this.shouldFetchData = true;
  47. }
  48. }
  49. getCategoryName(id: number) {
  50. if (this.categories !== null) {
  51. for (let i = 0; i < this.categories.length; i++) {
  52. if (id === this.categories[i].id)
  53. return this.categories[i].name;
  54. }
  55. }
  56. return "";
  57. }
  58. getCategoriesRender(categories: Array<number | null>) {
  59. if (this.categories === null)
  60. return null;
  61. let final = [];
  62. for (let i = 0; i < categories.length; i++) {
  63. let cat = categories[i];
  64. if (cat !== null) {
  65. final.push(
  66. <Chip
  67. style={{marginRight: 5}}
  68. key={i.toString()}>
  69. {this.getCategoryName(cat)}
  70. </Chip>
  71. );
  72. }
  73. }
  74. return <View style={{flexDirection: 'row', marginTop: 5}}>{final}</View>;
  75. }
  76. getManagersRender(resp: Array<string>) {
  77. let final = [];
  78. for (let i = 0; i < resp.length; i++) {
  79. final.push(<Paragraph key={i.toString()}>{resp[i]}</Paragraph>)
  80. }
  81. const hasManagers = resp.length > 0;
  82. return (
  83. <Card style={{marginTop: 10, marginBottom: 10}}>
  84. <Card.Title
  85. title={i18n.t('clubs.managers')}
  86. subtitle={hasManagers ? i18n.t('clubs.managersSubtitle') : i18n.t('clubs.managersUnavailable')}
  87. left={(props) => <Avatar.Icon
  88. {...props}
  89. style={{backgroundColor: 'transparent'}}
  90. color={hasManagers ? this.colors.success : this.colors.primary}
  91. icon="account-tie"/>}
  92. />
  93. <Card.Content>
  94. {final}
  95. </Card.Content>
  96. </Card>
  97. );
  98. }
  99. updateHeaderTitle(data: Object) {
  100. this.props.navigation.setOptions({title: data.name})
  101. }
  102. getScreen = (response: Array<Object>) => {
  103. let data = response[0];
  104. this.updateHeaderTitle(data);
  105. return (
  106. <ScrollView style={{paddingLeft: 5, paddingRight: 5}}>
  107. {this.getCategoriesRender(data.category)}
  108. {data.logo !== null ?
  109. <View style={{
  110. marginLeft: 'auto',
  111. marginRight: 'auto',
  112. marginTop: 10,
  113. marginBottom: 10,
  114. }}>
  115. <ImageModal
  116. resizeMode="contain"
  117. imageBackgroundColor={this.colors.background}
  118. style={{
  119. width: 300,
  120. height: 300,
  121. }}
  122. source={{
  123. uri: data.logo,
  124. }}
  125. /></View>
  126. : <View/>}
  127. {data.description !== null ?
  128. // Surround description with div to allow text styling if the description is not html
  129. <Card.Content>
  130. <HTML html={"<div>" + data.description + "</div>"}
  131. tagsStyles={{
  132. p: {color: this.colors.text,},
  133. div: {color: this.colors.text}
  134. }}
  135. onLinkPress={openWebLink}/>
  136. </Card.Content>
  137. : <View/>}
  138. {this.getManagersRender(data.responsibles)}
  139. </ScrollView>
  140. );
  141. };
  142. render() {
  143. if (this.shouldFetchData)
  144. return <AuthenticatedScreen
  145. {...this.props}
  146. requests={[
  147. {
  148. link: 'clubs/info',
  149. params: {'id': this.clubId},
  150. mandatory: true
  151. }
  152. ]}
  153. renderFunction={this.getScreen}
  154. />;
  155. else
  156. return this.getScreen([this.displayData]);
  157. }
  158. }
  159. export default withTheme(ClubDisplayScreen);