Browse Source

Added mascot to vote screen

Arnaud Vergnet 1 year ago
parent
commit
9a379ffb3d

+ 5
- 5
locales/en.json View File

@@ -230,6 +230,7 @@
230 230
     },
231 231
     "vote": {
232 232
       "title": "Elections",
233
+      "noVote": "No vote available",
233 234
       "select": {
234 235
         "title": "Elections open",
235 236
         "subtitle": "Vote now!",
@@ -258,11 +259,10 @@
258 259
         "totalVotes": "Total votes:",
259 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 268
     "equipment": {

+ 5
- 5
locales/fr.json View File

@@ -229,6 +229,7 @@
229 229
     },
230 230
     "vote": {
231 231
       "title": "Élections",
232
+      "noVote": "Pas de vote en cours",
232 233
       "select": {
233 234
         "title": "Élections ouvertes",
234 235
         "subtitle": "Vote maintenant !",
@@ -257,11 +258,10 @@
257 258
         "totalVotes": "Nombre total de votes :",
258 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 267
     "equipment": {

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

@@ -0,0 +1,37 @@
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,48 +0,0 @@
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,6 +89,11 @@ export default class AsyncStorageManager {
89 89
             default: '1',
90 90
             current: '',
91 91
         },
92
+        voteShowBanner: {
93
+            key: 'voteShowBanner',
94
+            default: '1',
95
+            current: '',
96
+        },
92 97
         proxiwashWatchedMachines: {
93 98
             key: 'proxiwashWatchedMachines',
94 99
             default: '[]',

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

@@ -4,12 +4,17 @@ import * as React from 'react';
4 4
 import {FlatList, RefreshControl, View} from "react-native";
5 5
 import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
6 6
 import {getTimeOnlyString, stringToDate} from "../../utils/Planning";
7
-import VoteTitle from "../../components/Amicale/Vote/VoteTitle";
8 7
 import VoteTease from "../../components/Amicale/Vote/VoteTease";
9 8
 import VoteSelect from "../../components/Amicale/Vote/VoteSelect";
10 9
 import VoteResults from "../../components/Amicale/Vote/VoteResults";
11 10
 import VoteWait from "../../components/Amicale/Vote/VoteWait";
12 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 19
 export type team = {
15 20
     id: number,
@@ -37,10 +42,10 @@ type objectVoteDates = {
37 42
 }
38 43
 
39 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 51
 // const FAKE_DATE2 = {
@@ -92,6 +97,7 @@ type Props = {
92 97
 
93 98
 type State = {
94 99
     hasVoted: boolean,
100
+    mascotDialogVisible: boolean,
95 101
 }
96 102
 
97 103
 /**
@@ -101,6 +107,7 @@ export default class VoteScreen extends React.Component<Props, State> {
101 107
 
102 108
     state = {
103 109
         hasVoted: false,
110
+        mascotDialogVisible: AsyncStorageManager.getInstance().preferences.voteShowBanner.current === "1",
104 111
     };
105 112
 
106 113
     teams: Array<team>;
@@ -200,11 +207,23 @@ export default class VoteScreen extends React.Component<Props, State> {
200 207
 
201 208
     mainRenderItem = ({item}: { item: { key: string } }) => {
202 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 225
         else
207
-            return null;
226
+            return this.getContent();
208 227
     };
209 228
 
210 229
     getScreen = (data: Array<{ [key: string]: any } | null>) => {
@@ -254,7 +273,7 @@ export default class VoteScreen extends React.Component<Props, State> {
254 273
         else if (this.isResultRunning())
255 274
             return this.getVoteResultCard();
256 275
         else
257
-            return null;
276
+            return <VoteNotAvailable/>;
258 277
     }
259 278
 
260 279
     onVoteSuccess = () => this.setState({hasVoted: true});
@@ -278,7 +297,7 @@ export default class VoteScreen extends React.Component<Props, State> {
278 297
                     this.datesString.date_result_end)}
279 298
             />;
280 299
         else
281
-            return null;
300
+            return <VoteNotAvailable/>;
282 301
     }
283 302
 
284 303
     /**
@@ -289,7 +308,7 @@ export default class VoteScreen extends React.Component<Props, State> {
289 308
             return <VoteTease
290 309
                 startDate={this.getDateString(this.dates.date_begin, this.datesString.date_begin)}/>;
291 310
         else
292
-            return null;
311
+            return <VoteNotAvailable/>;
293 312
     }
294 313
 
295 314
     /**
@@ -304,6 +323,18 @@ export default class VoteScreen extends React.Component<Props, State> {
304 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 339
      * Renders the authenticated screen.
309 340
      *
@@ -313,23 +344,40 @@ export default class VoteScreen extends React.Component<Props, State> {
313 344
      */
314 345
     render() {
315 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