Browse Source

Added contact link

Arnaud Vergnet 3 years ago
parent
commit
c4337b13cb

+ 91
- 55
src/screens/Amicale/Clubs/ClubDisplayScreen.js View File

2
 
2
 
3
 import * as React from 'react';
3
 import * as React from 'react';
4
 import {ScrollView, View} from 'react-native';
4
 import {ScrollView, View} from 'react-native';
5
-import {Avatar, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
5
+import {Avatar, Button, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
6
 import ImageModal from 'react-native-image-modal';
6
 import ImageModal from 'react-native-image-modal';
7
 import i18n from "i18n-js";
7
 import i18n from "i18n-js";
8
 import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
8
 import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
9
 import CustomHTML from "../../../components/Overrides/CustomHTML";
9
 import CustomHTML from "../../../components/Overrides/CustomHTML";
10
 import CustomTabBar from "../../../components/Tabbar/CustomTabBar";
10
 import CustomTabBar from "../../../components/Tabbar/CustomTabBar";
11
+import type {category, club} from "./ClubListScreen";
12
+import type {CustomTheme} from "../../../managers/ThemeManager";
13
+import {StackNavigationProp} from "@react-navigation/stack";
14
+import {Linking} from "expo";
11
 
15
 
12
 type Props = {
16
 type Props = {
13
-    navigation: Object,
14
-    route: Object
17
+    navigation: StackNavigationProp,
18
+    route: {
19
+        params?: {
20
+            data?: club,
21
+            categories?: Array<category>,
22
+            clubId?: number,
23
+        }, ...
24
+    },
25
+    theme: CustomTheme
15
 };
26
 };
16
 
27
 
17
 type State = {
28
 type State = {
18
     imageModalVisible: boolean,
29
     imageModalVisible: boolean,
19
 };
30
 };
20
 
31
 
32
+const AMICALE_MAIL = "clubs@amicale-insat.fr";
33
+
21
 /**
34
 /**
22
  * Class defining a club event information page.
35
  * Class defining a club event information page.
23
  * If called with data and categories navigation parameters, will use those to display the data.
36
  * If called with data and categories navigation parameters, will use those to display the data.
25
  */
38
  */
26
 class ClubDisplayScreen extends React.Component<Props, State> {
39
 class ClubDisplayScreen extends React.Component<Props, State> {
27
 
40
 
28
-    displayData: Object;
29
-    categories: Object | null;
41
+    displayData: club | null;
42
+    categories: Array<category> | null;
30
     clubId: number;
43
     clubId: number;
31
 
44
 
32
     shouldFetchData: boolean;
45
     shouldFetchData: boolean;
33
 
46
 
34
-    colors: Object;
35
-
36
     state = {
47
     state = {
37
         imageModalVisible: false,
48
         imageModalVisible: false,
38
     };
49
     };
39
 
50
 
40
     constructor(props) {
51
     constructor(props) {
41
         super(props);
52
         super(props);
42
-        this.colors = props.theme.colors;
43
-
44
-        if (this.props.route.params.data !== undefined && this.props.route.params.categories !== undefined) {
45
-            this.displayData = this.props.route.params.data;
46
-            this.categories = this.props.route.params.categories;
47
-            this.clubId = this.props.route.params.data.id;
48
-            this.shouldFetchData = false;
49
-        } else {
50
-            this.displayData = null;
51
-            this.categories = null;
52
-            this.clubId = this.props.route.params.clubId;
53
-            this.shouldFetchData = true;
53
+        if (this.props.route.params != null) {
54
+            if (this.props.route.params.data != null && this.props.route.params.categories != null) {
55
+                this.displayData = this.props.route.params.data;
56
+                this.categories = this.props.route.params.categories;
57
+                this.clubId = this.props.route.params.data.id;
58
+                this.shouldFetchData = false;
59
+            } else if (this.props.route.params.clubId != null) {
60
+                this.displayData = null;
61
+                this.categories = null;
62
+                this.clubId = this.props.route.params.clubId;
63
+                this.shouldFetchData = true;
64
+            }
54
         }
65
         }
55
     }
66
     }
56
 
67
 
64
         return "";
75
         return "";
65
     }
76
     }
66
 
77
 
67
-    getCategoriesRender(categories: Array<number | null>) {
78
+    getCategoriesRender(categories: [number, number]) {
68
         if (this.categories === null)
79
         if (this.categories === null)
69
             return null;
80
             return null;
70
 
81
 
84
         return <View style={{flexDirection: 'row', marginTop: 5}}>{final}</View>;
95
         return <View style={{flexDirection: 'row', marginTop: 5}}>{final}</View>;
85
     }
96
     }
86
 
97
 
87
-    getManagersRender(resp: Array<string>) {
98
+    getManagersRender(resp: Array<string>, email: string | null) {
88
         let final = [];
99
         let final = [];
89
         for (let i = 0; i < resp.length; i++) {
100
         for (let i = 0; i < resp.length; i++) {
90
             final.push(<Paragraph key={i.toString()}>{resp[i]}</Paragraph>)
101
             final.push(<Paragraph key={i.toString()}>{resp[i]}</Paragraph>)
98
                     left={(props) => <Avatar.Icon
109
                     left={(props) => <Avatar.Icon
99
                         {...props}
110
                         {...props}
100
                         style={{backgroundColor: 'transparent'}}
111
                         style={{backgroundColor: 'transparent'}}
101
-                        color={hasManagers ? this.colors.success : this.colors.primary}
112
+                        color={hasManagers ? this.props.theme.colors.success : this.props.theme.colors.primary}
102
                         icon="account-tie"/>}
113
                         icon="account-tie"/>}
103
                 />
114
                 />
104
                 <Card.Content>
115
                 <Card.Content>
105
                     {final}
116
                     {final}
117
+                    {this.getEmailButton(email, hasManagers)}
106
                 </Card.Content>
118
                 </Card.Content>
107
             </Card>
119
             </Card>
108
         );
120
         );
109
     }
121
     }
110
 
122
 
123
+    getEmailButton(email: string | null, hasManagers: boolean) {
124
+        const destinationEmail = email != null && hasManagers
125
+            ? email
126
+            : AMICALE_MAIL;
127
+        const text = email != null && hasManagers
128
+            ? i18n.t("clubs.clubContact")
129
+            : i18n.t("clubs.amicaleContact");
130
+        return (
131
+            <Card.Actions>
132
+                <Button
133
+                    icon="email"
134
+                    mode="contained"
135
+                    onPress={() => Linking.openURL('mailto:' + destinationEmail)}
136
+                    style={{marginLeft: 'auto'}}
137
+                >
138
+                    {text}
139
+                </Button>
140
+            </Card.Actions>
141
+        );
142
+    }
143
+
111
     updateHeaderTitle(data: Object) {
144
     updateHeaderTitle(data: Object) {
112
         this.props.navigation.setOptions({title: data.name})
145
         this.props.navigation.setOptions({title: data.name})
113
     }
146
     }
114
 
147
 
115
     getScreen = (response: Array<Object>) => {
148
     getScreen = (response: Array<Object>) => {
116
-        let data = response[0];
149
+        let data: club = response[0];
117
         this.updateHeaderTitle(data);
150
         this.updateHeaderTitle(data);
151
+        if (data != null) {
152
+            return (
153
+                <ScrollView style={{paddingLeft: 5, paddingRight: 5}}>
154
+                    {this.getCategoriesRender(data.category)}
155
+                    {data.logo !== null ?
156
+                        <View style={{
157
+                            marginLeft: 'auto',
158
+                            marginRight: 'auto',
159
+                            marginTop: 10,
160
+                            marginBottom: 10,
161
+                        }}>
162
+                            <ImageModal
163
+                                resizeMode="contain"
164
+                                imageBackgroundColor={this.props.theme.colors.background}
165
+                                style={{
166
+                                    width: 300,
167
+                                    height: 300,
168
+                                }}
169
+                                source={{
170
+                                    uri: data.logo,
171
+                                }}
172
+                            /></View>
173
+                        : <View/>}
174
+
175
+                    {data.description !== null ?
176
+                        // Surround description with div to allow text styling if the description is not html
177
+                        <Card.Content>
178
+                            <CustomHTML html={data.description}/>
179
+                        </Card.Content>
180
+                        : <View/>}
181
+                    {this.getManagersRender(data.responsibles, data.email)}
182
+                </ScrollView>
183
+            );
184
+        } else
185
+            return null;
118
 
186
 
119
-        return (
120
-            <ScrollView style={{paddingLeft: 5, paddingRight: 5}}>
121
-                {this.getCategoriesRender(data.category)}
122
-                {data.logo !== null ?
123
-                    <View style={{
124
-                        marginLeft: 'auto',
125
-                        marginRight: 'auto',
126
-                        marginTop: 10,
127
-                        marginBottom: 10,
128
-                    }}>
129
-                        <ImageModal
130
-                            resizeMode="contain"
131
-                            imageBackgroundColor={this.colors.background}
132
-                            style={{
133
-                                width: 300,
134
-                                height: 300,
135
-                            }}
136
-                            source={{
137
-                                uri: data.logo,
138
-                            }}
139
-                        /></View>
140
-                    : <View/>}
141
-
142
-                {data.description !== null ?
143
-                    // Surround description with div to allow text styling if the description is not html
144
-                    <Card.Content>
145
-                        <CustomHTML html={data.description}/>
146
-                    </Card.Content>
147
-                    : <View/>}
148
-                {this.getManagersRender(data.responsibles)}
149
-            </ScrollView>
150
-        );
151
     };
187
     };
152
 
188
 
153
     render() {
189
     render() {

+ 1
- 1
src/screens/Amicale/Clubs/ClubListScreen.js View File

24
     name: string,
24
     name: string,
25
     description: string,
25
     description: string,
26
     logo: string,
26
     logo: string,
27
-    email:string,
27
+    email: string | null,
28
     category: [number, number],
28
     category: [number, number],
29
     responsibles: Array<string>,
29
     responsibles: Array<string>,
30
 };
30
 };

+ 2
- 0
translations/en.json View File

261
     "managersUnavailable": "This club has no one :(",
261
     "managersUnavailable": "This club has no one :(",
262
     "categories": "Categories",
262
     "categories": "Categories",
263
     "categoriesFilterMessage": "Click on a category to filter the list",
263
     "categoriesFilterMessage": "Click on a category to filter the list",
264
+    "clubContact": "Contact the club",
265
+    "amicaleContact": "Contact the Amicale",
264
     "about": {
266
     "about": {
265
       "text": "The clubs, making the campus live, with more than sixty clubs offering various activities! From the philosophy club to the PABI (Production Artisanale de Bière Insaienne), without forgetting the multiple music and dance clubs, you will surely find an activity that suits you!",
267
       "text": "The clubs, making the campus live, with more than sixty clubs offering various activities! From the philosophy club to the PABI (Production Artisanale de Bière Insaienne), without forgetting the multiple music and dance clubs, you will surely find an activity that suits you!",
266
       "title": "A question ?",
268
       "title": "A question ?",

+ 2
- 0
translations/fr.json View File

261
     "managersUnavailable": "Ce club est tout seul :(",
261
     "managersUnavailable": "Ce club est tout seul :(",
262
     "categories": "Catégories",
262
     "categories": "Catégories",
263
     "categoriesFilterMessage": "Cliquez sur une catégorie pour filtrer la liste",
263
     "categoriesFilterMessage": "Cliquez sur une catégorie pour filtrer la liste",
264
+    "clubContact": "Contacter le club",
265
+    "amicaleContact": "Contacter l'Amicale",
264
     "about": {
266
     "about": {
265
       "text": "Les clubs, c'est ce qui fait vivre le campus au quotidien, plus d'une soixantaine de clubs qui proposent des activités diverses et variées ! Du club Philosophie au PABI (Production Artisanale de Bière Insaienne), en passant par les multiples clubs de musique et de danse, vous trouverez forcément une activité qui vous permettra de vous épanouir sur le campus !",
267
       "text": "Les clubs, c'est ce qui fait vivre le campus au quotidien, plus d'une soixantaine de clubs qui proposent des activités diverses et variées ! Du club Philosophie au PABI (Production Artisanale de Bière Insaienne), en passant par les multiples clubs de musique et de danse, vous trouverez forcément une activité qui vous permettra de vous épanouir sur le campus !",
266
       "title": "Une question ?",
268
       "title": "Une question ?",

Loading…
Cancel
Save