Browse Source

Added mascot to vote screen

Arnaud Vergnet 3 years ago
parent
commit
9a379ffb3d

+ 5
- 5
locales/en.json View File

230
     },
230
     },
231
     "vote": {
231
     "vote": {
232
       "title": "Elections",
232
       "title": "Elections",
233
+      "noVote": "No vote available",
233
       "select": {
234
       "select": {
234
         "title": "Elections open",
235
         "title": "Elections open",
235
         "subtitle": "Vote now!",
236
         "subtitle": "Vote now!",
258
         "totalVotes": "Total votes:",
259
         "totalVotes": "Total votes:",
259
         "votes": "votes"
260
         "votes": "votes"
260
       },
261
       },
261
-      "main": {
262
-        "title": "The Elections",
263
-        "subtitle": "Why your vote is important",
264
-        "paragraph1": "The Amicale's elections is the right moment for you to choose the next team, which will handle different projects on the campus, help organizing your favorite events, animate the campus life during the whole year, and relay your ideas to the administration, so that your campus life is the most enjoyable possible!\nYour turn to make a change!\uD83D\uDE09",
265
-        "paragraph2": "Note: If there is only one list, it is still important to vote to show your support, so that the administration knows the current list is supported by students. It is always a plus when taking difficult decisions! \uD83D\uDE09"
262
+      "mascotDialog": {
263
+        "title": "Why vote?",
264
+        "message": "The Amicale's elections is the right moment for you to choose the next team, which will handle different projects on the campus, help organizing your favorite events, animate the campus life during the whole year, and relay your ideas to the administration, so that your campus life is the most enjoyable possible!\nYour turn to make a change!\uD83D\uDE09\n\nNote: If there is only one list, it is still important to vote to show your support, so that the administration knows the current list is supported by students. It is always a plus when taking difficult decisions! \uD83D\uDE09",
265
+        "button": "Ok"
266
       }
266
       }
267
     },
267
     },
268
     "equipment": {
268
     "equipment": {

+ 5
- 5
locales/fr.json View File

229
     },
229
     },
230
     "vote": {
230
     "vote": {
231
       "title": "Élections",
231
       "title": "Élections",
232
+      "noVote": "Pas de vote en cours",
232
       "select": {
233
       "select": {
233
         "title": "Élections ouvertes",
234
         "title": "Élections ouvertes",
234
         "subtitle": "Vote maintenant !",
235
         "subtitle": "Vote maintenant !",
257
         "totalVotes": "Nombre total de votes :",
258
         "totalVotes": "Nombre total de votes :",
258
         "votes": "votes"
259
         "votes": "votes"
259
       },
260
       },
260
-      "main": {
261
-        "title": "Les Élections",
262
-        "subtitle": "Pourquoi ton vote est important",
263
-        "paragraph1": "Les élections de l'amicale, c'est le moment pour toi de choisir la prochaine équipe qui portera les différents projets du campus, qui soutiendra les organisations de tes événements favoris, qui te proposera des animations tout au long de l'année, et qui poussera tes idées à l’administration pour que la vie de campus soit des plus riches !\nAlors à toi de jouer ! \uD83D\uDE09",
264
-        "paragraph2": "NB : Si par cas il n'y a qu'une liste qui se présente, il est important que tout le monde vote, afin qui la liste puisse montrer à l’administration que les INSAiens la soutiennent ! Ça compte toujours pour les décisions difficiles ! \uD83D\uDE09"
261
+      "mascotDialog": {
262
+        "title": "Pourquoi voter ?",
263
+        "message": "Les élections de l'amicale, c'est le moment pour toi de choisir la prochaine équipe qui portera les différents projets du campus, qui soutiendra les organisations de tes événements favoris, qui te proposera des animations tout au long de l'année, et qui poussera tes idées à l’administration pour que la vie de campus soit des plus riches !\nAlors à toi de jouer ! \uD83D\uDE09\n\nNB : Si par cas il n'y a qu'une liste qui se présente, il est important que tout le monde vote, afin qui la liste puisse montrer à l’administration que les INSAiens la soutiennent ! Ça compte toujours pour les décisions difficiles ! \uD83D\uDE09",
264
+        "button": "Oké"
265
       }
265
       }
266
     },
266
     },
267
     "equipment": {
267
     "equipment": {

+ 37
- 0
src/components/Amicale/Vote/VoteNotAvailable.js View File

1
+// @flow
2
+
3
+import * as React from 'react';
4
+import {View} from 'react-native';
5
+import {Headline, withTheme} from "react-native-paper";
6
+import i18n from 'i18n-js';
7
+import type {CustomTheme} from "../../../managers/ThemeManager";
8
+
9
+type Props = {
10
+    theme: CustomTheme
11
+}
12
+
13
+class VoteNotAvailable extends React.Component<Props> {
14
+
15
+    shouldComponentUpdate() {
16
+        return false;
17
+    }
18
+
19
+    render() {
20
+        return (
21
+            <View style={{
22
+                width: "100%",
23
+                marginTop: 10,
24
+                marginBottom: 10,
25
+            }}>
26
+                <Headline
27
+                    style={{
28
+                        color: this.props.theme.colors.textDisabled,
29
+                        textAlign: "center",
30
+                    }}
31
+                >{i18n.t("screens.vote.noVote")}</Headline>
32
+            </View>
33
+        );
34
+    }
35
+}
36
+
37
+export default withTheme(VoteNotAvailable);

+ 0
- 48
src/components/Amicale/Vote/VoteTitle.js View File

1
-// @flow
2
-
3
-import * as React from 'react';
4
-import {Card, Paragraph} from "react-native-paper";
5
-import {Image, StyleSheet} from "react-native";
6
-import i18n from 'i18n-js';
7
-
8
-const ICON_AMICALE = require('../../../../assets/amicale.png');
9
-
10
-export default class VoteTitle extends React.Component<{}> {
11
-
12
-    shouldComponentUpdate() {
13
-        return false;
14
-    }
15
-
16
-    render() {
17
-        return (
18
-            <Card style={styles.card}>
19
-                <Card.Title
20
-                    title={i18n.t('screens.vote.main.title')}
21
-                    subtitle={i18n.t('screens.vote.main.subtitle')}
22
-                    left={(props) => <Image
23
-                        {...props}
24
-                        style={{
25
-                            width: props.size,
26
-                            height: props.size,
27
-                        }}
28
-                        source={ICON_AMICALE}
29
-                    />}
30
-                />
31
-                <Card.Content>
32
-                    <Paragraph>
33
-                        {i18n.t('screens.vote.main.paragraph1')}
34
-                    </Paragraph>
35
-                    <Paragraph>
36
-                        {i18n.t('screens.vote.main.paragraph2')}
37
-                    </Paragraph>
38
-                </Card.Content>
39
-            </Card>
40
-        );
41
-    }
42
-}
43
-
44
-const styles = StyleSheet.create({
45
-    card: {
46
-        margin: 10,
47
-    },
48
-});

+ 5
- 0
src/managers/AsyncStorageManager.js View File

89
             default: '1',
89
             default: '1',
90
             current: '',
90
             current: '',
91
         },
91
         },
92
+        voteShowBanner: {
93
+            key: 'voteShowBanner',
94
+            default: '1',
95
+            current: '',
96
+        },
92
         proxiwashWatchedMachines: {
97
         proxiwashWatchedMachines: {
93
             key: 'proxiwashWatchedMachines',
98
             key: 'proxiwashWatchedMachines',
94
             default: '[]',
99
             default: '[]',

+ 77
- 29
src/screens/Amicale/VoteScreen.js View File

4
 import {FlatList, RefreshControl, View} from "react-native";
4
 import {FlatList, RefreshControl, View} from "react-native";
5
 import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
5
 import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
6
 import {getTimeOnlyString, stringToDate} from "../../utils/Planning";
6
 import {getTimeOnlyString, stringToDate} from "../../utils/Planning";
7
-import VoteTitle from "../../components/Amicale/Vote/VoteTitle";
8
 import VoteTease from "../../components/Amicale/Vote/VoteTease";
7
 import VoteTease from "../../components/Amicale/Vote/VoteTease";
9
 import VoteSelect from "../../components/Amicale/Vote/VoteSelect";
8
 import VoteSelect from "../../components/Amicale/Vote/VoteSelect";
10
 import VoteResults from "../../components/Amicale/Vote/VoteResults";
9
 import VoteResults from "../../components/Amicale/Vote/VoteResults";
11
 import VoteWait from "../../components/Amicale/Vote/VoteWait";
10
 import VoteWait from "../../components/Amicale/Vote/VoteWait";
12
 import {StackNavigationProp} from "@react-navigation/stack";
11
 import {StackNavigationProp} from "@react-navigation/stack";
12
+import i18n from "i18n-js";
13
+import {MASCOT_STYLE} from "../../components/Mascot/Mascot";
14
+import MascotPopup from "../../components/Mascot/MascotPopup";
15
+import AsyncStorageManager from "../../managers/AsyncStorageManager";
16
+import {Button} from "react-native-paper";
17
+import VoteNotAvailable from "../../components/Amicale/Vote/VoteNotAvailable";
13
 
18
 
14
 export type team = {
19
 export type team = {
15
     id: number,
20
     id: number,
37
 }
42
 }
38
 
43
 
39
 // const FAKE_DATE = {
44
 // const FAKE_DATE = {
40
-//     "date_begin": "2020-04-19 15:50",
41
-//     "date_end": "2020-04-19 15:50",
42
-//     "date_result_begin": "2020-04-19 19:50",
43
-//     "date_result_end": "2020-04-19 22:50",
45
+//     "date_begin": "2020-08-19 15:50",
46
+//     "date_end": "2020-08-19 15:50",
47
+//     "date_result_begin": "2020-08-19 19:50",
48
+//     "date_result_end": "2020-08-19 22:50",
44
 // };
49
 // };
45
 //
50
 //
46
 // const FAKE_DATE2 = {
51
 // const FAKE_DATE2 = {
92
 
97
 
93
 type State = {
98
 type State = {
94
     hasVoted: boolean,
99
     hasVoted: boolean,
100
+    mascotDialogVisible: boolean,
95
 }
101
 }
96
 
102
 
97
 /**
103
 /**
101
 
107
 
102
     state = {
108
     state = {
103
         hasVoted: false,
109
         hasVoted: false,
110
+        mascotDialogVisible: AsyncStorageManager.getInstance().preferences.voteShowBanner.current === "1",
104
     };
111
     };
105
 
112
 
106
     teams: Array<team>;
113
     teams: Array<team>;
200
 
207
 
201
     mainRenderItem = ({item}: { item: { key: string } }) => {
208
     mainRenderItem = ({item}: { item: { key: string } }) => {
202
         if (item.key === 'info')
209
         if (item.key === 'info')
203
-            return <VoteTitle/>;
204
-        else if (item.key === 'main' && this.dates != null)
205
-            return this.getContent();
210
+            return (
211
+                <View>
212
+                    <Button
213
+                        mode={"contained"}
214
+                        icon={"help-circle"}
215
+                        onPress={this.showMascotDialog}
216
+                        style={{
217
+                            marginLeft: "auto",
218
+                            marginRight: "auto",
219
+                            marginTop: 20
220
+                        }}>
221
+                        {i18n.t("screens.vote.mascotDialog.title")}
222
+                    </Button>
223
+                </View>
224
+            );
206
         else
225
         else
207
-            return null;
226
+            return this.getContent();
208
     };
227
     };
209
 
228
 
210
     getScreen = (data: Array<{ [key: string]: any } | null>) => {
229
     getScreen = (data: Array<{ [key: string]: any } | null>) => {
254
         else if (this.isResultRunning())
273
         else if (this.isResultRunning())
255
             return this.getVoteResultCard();
274
             return this.getVoteResultCard();
256
         else
275
         else
257
-            return null;
276
+            return <VoteNotAvailable/>;
258
     }
277
     }
259
 
278
 
260
     onVoteSuccess = () => this.setState({hasVoted: true});
279
     onVoteSuccess = () => this.setState({hasVoted: true});
278
                     this.datesString.date_result_end)}
297
                     this.datesString.date_result_end)}
279
             />;
298
             />;
280
         else
299
         else
281
-            return null;
300
+            return <VoteNotAvailable/>;
282
     }
301
     }
283
 
302
 
284
     /**
303
     /**
289
             return <VoteTease
308
             return <VoteTease
290
                 startDate={this.getDateString(this.dates.date_begin, this.datesString.date_begin)}/>;
309
                 startDate={this.getDateString(this.dates.date_begin, this.datesString.date_begin)}/>;
291
         else
310
         else
292
-            return null;
311
+            return <VoteNotAvailable/>;
293
     }
312
     }
294
 
313
 
295
     /**
314
     /**
304
                          isVoteRunning={this.isVoteRunning()}/>;
323
                          isVoteRunning={this.isVoteRunning()}/>;
305
     }
324
     }
306
 
325
 
326
+    showMascotDialog = () => {
327
+        this.setState({mascotDialogVisible: true})
328
+    };
329
+
330
+    hideMascotDialog = () => {
331
+        AsyncStorageManager.getInstance().savePref(
332
+            AsyncStorageManager.getInstance().preferences.voteShowBanner.key,
333
+            '0'
334
+        );
335
+        this.setState({mascotDialogVisible: false})
336
+    };
337
+
307
     /**
338
     /**
308
      * Renders the authenticated screen.
339
      * Renders the authenticated screen.
309
      *
340
      *
313
      */
344
      */
314
     render() {
345
     render() {
315
         return (
346
         return (
316
-            <AuthenticatedScreen
317
-                {...this.props}
318
-                ref={this.authRef}
319
-                requests={[
320
-                    {
321
-                        link: 'elections/teams',
322
-                        params: {},
323
-                        mandatory: false,
324
-                    },
325
-                    {
326
-                        link: 'elections/dates',
327
-                        params: {},
328
-                        mandatory: false,
329
-                    },
330
-                ]}
331
-                renderFunction={this.getScreen}
332
-            />
347
+            <View style={{flex: 1}}>
348
+                <AuthenticatedScreen
349
+                    {...this.props}
350
+                    ref={this.authRef}
351
+                    requests={[
352
+                        {
353
+                            link: 'elections/teams',
354
+                            params: {},
355
+                            mandatory: false,
356
+                        },
357
+                        {
358
+                            link: 'elections/dates',
359
+                            params: {},
360
+                            mandatory: false,
361
+                        },
362
+                    ]}
363
+                    renderFunction={this.getScreen}
364
+                />
365
+                <MascotPopup
366
+                    visible={this.state.mascotDialogVisible}
367
+                    title={i18n.t("screens.vote.mascotDialog.title")}
368
+                    message={i18n.t("screens.vote.mascotDialog.message")}
369
+                    icon={"vote"}
370
+                    buttons={{
371
+                        action: null,
372
+                        cancel: {
373
+                            message: i18n.t("screens.vote.mascotDialog.button"),
374
+                            icon: "check",
375
+                            onPress: this.hideMascotDialog,
376
+                        }
377
+                    }}
378
+                    emotion={MASCOT_STYLE.CUTE}
379
+                />
380
+            </View>
333
         );
381
         );
334
     }
382
     }
335
 }
383
 }

Loading…
Cancel
Save