Browse Source

Implemented base vote screen and updated ConnectionManager.js to match new protocol

Arnaud Vergnet 4 years ago
parent
commit
e1a57487a2

+ 56
- 82
__tests__/managers/ConnectionManager.test.js View File

@@ -65,84 +65,64 @@ test('recoverLogin success saved', () => {
65 65
 
66 66
 test('isRequestResponseValid', () => {
67 67
     let json = {
68
-        state: true,
68
+        error: 0,
69 69
         data: {}
70 70
     };
71
-    expect(c.isRequestResponseValid(json)).toBeTrue();
71
+    expect(c.isResponseValid(json)).toBeTrue();
72 72
     json = {
73
-        state: false,
73
+        error: 1,
74 74
         data: {}
75 75
     };
76
-    expect(c.isRequestResponseValid(json)).toBeTrue();
76
+    expect(c.isResponseValid(json)).toBeTrue();
77 77
     json = {
78
-        state: false,
79
-        message: 'coucou',
78
+        error: 50,
79
+        data: {}
80
+    };
81
+    expect(c.isResponseValid(json)).toBeTrue();
82
+    json = {
83
+        error: 50,
80 84
         data: {truc: 'machin'}
81 85
     };
82
-    expect(c.isRequestResponseValid(json)).toBeTrue();
86
+    expect(c.isResponseValid(json)).toBeTrue();
83 87
     json = {
84 88
         message: 'coucou'
85 89
     };
86
-    expect(c.isRequestResponseValid(json)).toBeFalse();
90
+    expect(c.isResponseValid(json)).toBeFalse();
87 91
     json = {
88
-        state: 'coucou'
92
+        error: 'coucou',
93
+        data: {truc: 'machin'}
89 94
     };
90
-    expect(c.isRequestResponseValid(json)).toBeFalse();
95
+    expect(c.isResponseValid(json)).toBeFalse();
91 96
     json = {
92
-        state: true,
97
+        error: 0,
98
+        data: 'coucou'
93 99
     };
94
-    expect(c.isRequestResponseValid(json)).toBeFalse();
100
+    expect(c.isResponseValid(json)).toBeFalse();
101
+    json = {
102
+        error: 0,
103
+    };
104
+    expect(c.isResponseValid(json)).toBeFalse();
95 105
 });
96 106
 
97 107
 test("isConnectionResponseValid", () => {
98 108
     let json = {
99
-        state: true,
100
-        message: 'Connexion confirmée',
101
-        token: 'token'
102
-    };
103
-    expect(c.isConnectionResponseValid(json)).toBeTrue();
104
-    json = {
105
-        state: true,
106
-        token: 'token'
109
+        error: 0,
110
+        data: {token: 'token'}
107 111
     };
108 112
     expect(c.isConnectionResponseValid(json)).toBeTrue();
109 113
     json = {
110
-        state: false,
111
-    };
112
-    expect(c.isConnectionResponseValid(json)).toBeTrue();
113
-    json = {
114
-        state: false,
115
-        message: 'Adresse mail ou mot de passe incorrect',
116
-        token: ''
114
+        error: 2,
115
+        data: {}
117 116
     };
118 117
     expect(c.isConnectionResponseValid(json)).toBeTrue();
119 118
     json = {
120
-        state: true,
121
-        message: 'Connexion confirmée',
122
-        token: ''
123
-    };
124
-    expect(c.isConnectionResponseValid(json)).toBeFalse();
125
-    json = {
126
-        state: true,
127
-        message: 'Connexion confirmée',
128
-    };
129
-    expect(c.isConnectionResponseValid(json)).toBeFalse();
130
-    json = {
131
-        state: 'coucou',
132
-        message: 'Connexion confirmée',
133
-        token: 'token'
119
+        error: 0,
120
+        data: {token: ''}
134 121
     };
135 122
     expect(c.isConnectionResponseValid(json)).toBeFalse();
136 123
     json = {
137
-        state: true,
138
-        message: 'Connexion confirmée',
139
-        token: 2
140
-    };
141
-    expect(c.isConnectionResponseValid(json)).toBeFalse();
142
-    json = {
143
-        coucou: 'coucou',
144
-        message: 'Connexion confirmée',
145
-        token: 'token'
124
+        error: 'prout',
125
+        data: {token: ''}
146 126
     };
147 127
     expect(c.isConnectionResponseValid(json)).toBeFalse();
148 128
 });
@@ -152,10 +132,9 @@ test("connect bad credentials", () => {
152 132
         return Promise.resolve({
153 133
             json: () => {
154 134
                 return {
155
-                    state: false,
156
-                    message: 'Adresse mail ou mot de passe incorrect',
157
-                    token: ''
158
-                }
135
+                    error: ERROR_TYPE.BAD_CREDENTIALS,
136
+                    data: {}
137
+                };
159 138
             },
160 139
         })
161 140
     });
@@ -168,10 +147,9 @@ test("connect good credentials", () => {
168 147
         return Promise.resolve({
169 148
             json: () => {
170 149
                 return {
171
-                    state: true,
172
-                    message: 'Connexion confirmée',
173
-                    token: 'token'
174
-                }
150
+                    error: ERROR_TYPE.SUCCESS,
151
+                    data: {token: 'token'}
152
+                };
175 153
             },
176 154
         })
177 155
     });
@@ -186,13 +164,9 @@ test("connect good credentials no consent", () => {
186 164
         return Promise.resolve({
187 165
             json: () => {
188 166
                 return {
189
-                    state: false,
190
-                    message: 'pas de consent',
191
-                    token: '',
192
-                    data: {
193
-                        consent: false,
194
-                    }
195
-                }
167
+                    error: ERROR_TYPE.NO_CONSENT,
168
+                    data: {}
169
+                };
196 170
             },
197 171
         })
198 172
     });
@@ -205,17 +179,16 @@ test("connect good credentials, fail save token", () => {
205 179
         return Promise.resolve({
206 180
             json: () => {
207 181
                 return {
208
-                    state: true,
209
-                    message: 'Connexion confirmée',
210
-                    token: 'token'
211
-                }
182
+                    error: ERROR_TYPE.SUCCESS,
183
+                    data: {token: 'token'}
184
+                };
212 185
             },
213 186
         })
214 187
     });
215 188
     jest.spyOn(ConnectionManager.prototype, 'saveLogin').mockImplementationOnce(() => {
216 189
         return Promise.reject(false);
217 190
     });
218
-    return expect(c.connect('email', 'password')).rejects.toBe(ERROR_TYPE.SAVE_TOKEN);
191
+    return expect(c.connect('email', 'password')).rejects.toBe(ERROR_TYPE.UNKNOWN);
219 192
 });
220 193
 
221 194
 test("connect connection error", () => {
@@ -249,7 +222,10 @@ test("authenticatedRequest success", () => {
249 222
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
250 223
         return Promise.resolve({
251 224
             json: () => {
252
-                return {state: true, message: 'Connexion vérifiée', data: {coucou: 'toi'}}
225
+                return {
226
+                    error: ERROR_TYPE.SUCCESS,
227
+                    data: {coucou: 'toi'}
228
+                };
253 229
             },
254 230
         })
255 231
     });
@@ -264,12 +240,15 @@ test("authenticatedRequest error wrong token", () => {
264 240
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
265 241
         return Promise.resolve({
266 242
             json: () => {
267
-                return {state: false, message: 'Le champ token sélectionné est invalide.'}
243
+                return {
244
+                    error: ERROR_TYPE.BAD_TOKEN,
245
+                    data: {}
246
+                };
268 247
             },
269 248
         })
270 249
     });
271 250
     return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'))
272
-        .rejects.toBe(ERROR_TYPE.BAD_CREDENTIALS);
251
+        .rejects.toBe(ERROR_TYPE.BAD_TOKEN);
273 252
 });
274 253
 
275 254
 test("authenticatedRequest error bogus response", () => {
@@ -279,7 +258,9 @@ test("authenticatedRequest error bogus response", () => {
279 258
     jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
280 259
         return Promise.resolve({
281 260
             json: () => {
282
-                return {state: true, message: 'Connexion vérifiée'}
261
+                return {
262
+                    error: ERROR_TYPE.SUCCESS,
263
+                };
283 264
             },
284 265
         })
285 266
     });
@@ -302,13 +283,6 @@ test("authenticatedRequest error no token", () => {
302 283
     jest.spyOn(ConnectionManager.prototype, 'getToken').mockImplementationOnce(() => {
303 284
         return null;
304 285
     });
305
-    jest.spyOn(global, 'fetch').mockImplementationOnce(() => {
306
-        return Promise.resolve({
307
-            json: () => {
308
-                return {state: false, message: 'Le champ token sélectionné est invalide.'}
309
-            },
310
-        })
311
-    });
312 286
     return expect(c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'))
313
-        .rejects.toBe(ERROR_TYPE.NO_TOKEN);
287
+        .rejects.toBe(ERROR_TYPE.UNKNOWN);
314 288
 });

+ 47
- 14
src/components/Amicale/AuthenticatedScreen.js View File

@@ -10,7 +10,7 @@ import BasicLoadingScreen from "../Custom/BasicLoadingScreen";
10 10
 type Props = {
11 11
     navigation: Object,
12 12
     theme: Object,
13
-    link: string,
13
+    links: Array<{link: string, mandatory: boolean}>,
14 14
     renderFunction: Function,
15 15
 }
16 16
 
@@ -27,7 +27,7 @@ class AuthenticatedScreen extends React.Component<Props, State> {
27 27
     currentUserToken: string | null;
28 28
     connectionManager: ConnectionManager;
29 29
     errorCode: number;
30
-    data: Object;
30
+    data: Array<Object>;
31 31
     colors: Object;
32 32
 
33 33
     constructor(props) {
@@ -35,6 +35,7 @@ class AuthenticatedScreen extends React.Component<Props, State> {
35 35
         this.colors = props.theme.colors;
36 36
         this.connectionManager = ConnectionManager.getInstance();
37 37
         this.props.navigation.addListener('focus', this.onScreenFocus.bind(this));
38
+        this.data = new Array(this.props.links.length);
38 39
     }
39 40
 
40 41
     onScreenFocus() {
@@ -46,25 +47,53 @@ class AuthenticatedScreen extends React.Component<Props, State> {
46 47
         if (!this.state.loading)
47 48
             this.setState({loading: true});
48 49
         if (this.connectionManager.isLoggedIn()) {
49
-            this.connectionManager.authenticatedRequest(this.props.link)
50
-                .then((data) => {
51
-                    this.onFinishedLoading(data, -1);
52
-                })
53
-                .catch((error) => {
54
-                    this.onFinishedLoading(undefined, error);
55
-                });
50
+            for (let i = 0; i < this.props.links.length; i++) {
51
+                this.connectionManager.authenticatedRequest(this.props.links[i].link)
52
+                    .then((data) => {
53
+                        this.onFinishedLoading(data, i, -1);
54
+                    })
55
+                    .catch((error) => {
56
+                        this.onFinishedLoading(null, i, error);
57
+                    });
58
+            }
59
+
56 60
         } else {
57
-            this.onFinishedLoading(undefined, ERROR_TYPE.BAD_CREDENTIALS);
61
+            this.onFinishedLoading(null, -1, ERROR_TYPE.BAD_CREDENTIALS);
58 62
         }
59 63
     };
60 64
 
61
-    onFinishedLoading(data: Object, error: number) {
62
-        this.data = data;
65
+    onFinishedLoading(data: Object, index: number, error: number) {
66
+        if (index >= 0 && index < this.props.links.length)
67
+            this.data[index] = data;
63 68
         this.currentUserToken = data !== undefined
64 69
             ? this.connectionManager.getToken()
65 70
             : null;
66 71
         this.errorCode = error;
67
-        this.setState({loading: false});
72
+
73
+        if (this.allRequestsFinished())
74
+            this.setState({loading: false});
75
+    }
76
+
77
+    allRequestsFinished() {
78
+        let finished = true;
79
+        for (let i = 0; i < this.data.length; i++) {
80
+            if (this.data[i] === undefined) {
81
+                finished = false;
82
+                break;
83
+            }
84
+        }
85
+        return finished;
86
+    }
87
+
88
+    allRequestsValid() {
89
+        let valid = true;
90
+        for (let i = 0; i < this.data.length; i++) {
91
+            if (this.data[i] === null && this.props.links[i].mandatory) {
92
+                valid = false;
93
+                break;
94
+            }
95
+        }
96
+        return valid;
68 97
     }
69 98
 
70 99
     getErrorRender() {
@@ -75,6 +104,10 @@ class AuthenticatedScreen extends React.Component<Props, State> {
75 104
                 message = i18n.t("loginScreen.errors.credentials");
76 105
                 icon = "account-alert-outline";
77 106
                 break;
107
+            case ERROR_TYPE.BAD_TOKEN:
108
+                message = "BAD TOKEN"; // TODO translate
109
+                icon = "access-point-network-off";
110
+                break;
78 111
             case ERROR_TYPE.CONNECTION_ERROR:
79 112
                 message = i18n.t("loginScreen.errors.connection");
80 113
                 icon = "access-point-network-off";
@@ -99,7 +132,7 @@ class AuthenticatedScreen extends React.Component<Props, State> {
99 132
         return (
100 133
             this.state.loading
101 134
                 ? <BasicLoadingScreen/>
102
-                : (this.data !== undefined
135
+                : (this.allRequestsValid()
103 136
                 ? this.props.renderFunction(this.data)
104 137
                 : this.getErrorRender())
105 138
         );

+ 6
- 0
src/components/Sidebar/Sidebar.js View File

@@ -70,6 +70,12 @@ class SideBar extends React.Component<Props, State> {
70 70
                 onlyWhenLoggedIn: true,
71 71
             },
72 72
             {
73
+                name: "VOTE",
74
+                route: "VoteScreen",
75
+                icon: "vote",
76
+                onlyWhenLoggedIn: true,
77
+            },
78
+            {
73 79
                 name: i18n.t('screens.logout'),
74 80
                 route: 'disconnect',
75 81
                 action: this.showDisconnectDialog,

+ 56
- 41
src/managers/ConnectionManager.js View File

@@ -3,14 +3,35 @@
3 3
 import * as SecureStore from 'expo-secure-store';
4 4
 
5 5
 export const ERROR_TYPE = {
6
-    BAD_CREDENTIALS: 0,
7
-    CONNECTION_ERROR: 1,
8
-    SAVE_TOKEN: 2,
9
-    NO_TOKEN: 3,
10
-    NO_CONSENT: 4,
6
+    SUCCESS: 0,
7
+    BAD_CREDENTIALS: 1,
8
+    BAD_TOKEN: 2,
9
+    NO_CONSENT: 3,
10
+    BAD_INPUT: 400,
11
+    FORBIDDEN: 403,
12
+    CONNECTION_ERROR: 404,
13
+    SERVER_ERROR: 500,
14
+    UNKNOWN: 999,
11 15
 };
12 16
 
13
-const AUTH_URL = "https://www.amicale-insat.fr/api/password";
17
+type response_format = {
18
+    error: number,
19
+    data: Object,
20
+}
21
+
22
+/**
23
+ * champ: error
24
+ *
25
+ * 0 : SUCCESS -> pas d'erreurs
26
+ * 1 : BAD_CREDENTIALS -> email ou mdp invalide
27
+ * 2 : BAD_TOKEN -> session expirée
28
+ * 3 : NO_CONSENT
29
+ * 403 : FORBIDDEN -> accès a la ressource interdit
30
+ * 500 : SERVER_ERROR -> pb coté serveur
31
+ */
32
+
33
+const API_ENDPOINT = "https://www.amicale-insat.fr/api/";
34
+const AUTH_PATH = "password";
14 35
 
15 36
 export default class ConnectionManager {
16 37
     static instance: ConnectionManager | null = null;
@@ -110,7 +131,7 @@ export default class ConnectionManager {
110 131
             password: password,
111 132
         };
112 133
         return new Promise((resolve, reject) => {
113
-            fetch(AUTH_URL, {
134
+            fetch(API_ENDPOINT + AUTH_PATH, {
114 135
                 method: 'POST',
115 136
                 headers: new Headers({
116 137
                     'Accept': 'application/json',
@@ -118,22 +139,18 @@ export default class ConnectionManager {
118 139
                 }),
119 140
                 body: JSON.stringify(data)
120 141
             }).then(async (response) => response.json())
121
-                .then((data) => {
122
-                    if (this.isConnectionResponseValid(data)) {
123
-                        if (data.state) {
124
-                            this.saveLogin(email, data.token)
142
+                .then((response: response_format) => {
143
+                    if (this.isConnectionResponseValid(response)) {
144
+                        if (response.error === ERROR_TYPE.SUCCESS) {
145
+                            this.saveLogin(email, response.data.token)
125 146
                                 .then(() => {
126 147
                                     resolve(true);
127 148
                                 })
128 149
                                 .catch(() => {
129
-                                    reject(ERROR_TYPE.SAVE_TOKEN);
150
+                                    reject(ERROR_TYPE.UNKNOWN);
130 151
                                 });
131
-                        } else if (data.data !== undefined
132
-                            && data.data.consent !== undefined
133
-                            && !data.data.consent)
134
-                            reject(ERROR_TYPE.NO_CONSENT);
135
-                        else
136
-                            reject(ERROR_TYPE.BAD_CREDENTIALS);
152
+                        } else
153
+                            reject(response.error);
137 154
                     } else
138 155
                         reject(ERROR_TYPE.CONNECTION_ERROR);
139 156
                 })
@@ -143,35 +160,32 @@ export default class ConnectionManager {
143 160
         });
144 161
     }
145 162
 
146
-    isRequestResponseValid(response: Object) {
163
+    isResponseValid(response: response_format) {
147 164
         let valid = response !== undefined
148
-            && response.state !== undefined
149
-            && typeof response.state === "boolean";
165
+            && response.error !== undefined
166
+            && typeof response.error === "number";
150 167
 
151
-        if (valid && response.state)
152
-            valid = valid
153
-                && response.data !== undefined
154
-                && typeof response.data === "object";
168
+        valid = valid
169
+            && response.data !== undefined
170
+            && typeof response.data === "object";
155 171
         return valid;
156 172
     }
157 173
 
158
-    isConnectionResponseValid(response: Object) {
159
-        let valid = response !== undefined
160
-            && response.state !== undefined
161
-            && typeof response.state === "boolean";
174
+    isConnectionResponseValid(response: response_format) {
175
+        let valid = this.isResponseValid(response);
162 176
 
163
-        if (valid && response.state)
177
+        if (valid && response.error === ERROR_TYPE.SUCCESS)
164 178
             valid = valid
165
-                && response.token !== undefined
166
-                && response.token !== ''
167
-                && typeof response.token === "string";
179
+                && response.data.token !== undefined
180
+                && response.data.token !== ''
181
+                && typeof response.data.token === "string";
168 182
         return valid;
169 183
     }
170 184
 
171
-    async authenticatedRequest(url: string) {
185
+    async authenticatedRequest(path: string) {
172 186
         return new Promise((resolve, reject) => {
173 187
             if (this.getToken() !== null) {
174
-                fetch(url, {
188
+                fetch(API_ENDPOINT + path, {
175 189
                     method: 'POST',
176 190
                     headers: new Headers({
177 191
                         'Accept': 'application/json',
@@ -179,12 +193,13 @@ export default class ConnectionManager {
179 193
                     }),
180 194
                     body: JSON.stringify({token: this.getToken()})
181 195
                 }).then(async (response) => response.json())
182
-                    .then((data) => {
183
-                        if (this.isRequestResponseValid(data)) {
184
-                            if (data.state)
185
-                                resolve(data.data);
196
+                    .then((response: response_format) => {
197
+                        console.log(response);
198
+                        if (this.isResponseValid(response)) {
199
+                            if (response.error === ERROR_TYPE.SUCCESS)
200
+                                resolve(response.data);
186 201
                             else
187
-                                reject(ERROR_TYPE.BAD_CREDENTIALS);
202
+                                reject(response.error);
188 203
                         } else
189 204
                             reject(ERROR_TYPE.CONNECTION_ERROR);
190 205
                     })
@@ -192,7 +207,7 @@ export default class ConnectionManager {
192 207
                         reject(ERROR_TYPE.CONNECTION_ERROR);
193 208
                     });
194 209
             } else
195
-                reject(ERROR_TYPE.NO_TOKEN);
210
+                reject(ERROR_TYPE.UNKNOWN);
196 211
         });
197 212
     }
198 213
 }

+ 30
- 0
src/navigation/DrawerNavigator.js View File

@@ -20,6 +20,7 @@ import ProfileScreen from "../screens/Amicale/ProfileScreen";
20 20
 import ClubListScreen from "../screens/Amicale/Clubs/ClubListScreen";
21 21
 import ClubDisplayScreen from "../screens/Amicale/Clubs/ClubDisplayScreen";
22 22
 import ClubAboutScreen from "../screens/Amicale/Clubs/ClubAboutScreen";
23
+import VoteScreen from "../screens/Amicale/VoteScreen";
23 24
 
24 25
 const defaultScreenOptions = {
25 26
     gestureEnabled: true,
@@ -239,6 +240,31 @@ function ProfileStackComponent() {
239 240
     );
240 241
 }
241 242
 
243
+
244
+const VoteStack = createStackNavigator();
245
+
246
+function VoteStackComponent() {
247
+    return (
248
+        <VoteStack.Navigator
249
+            initialRouteName="VoteScreen"
250
+            headerMode="float"
251
+            screenOptions={defaultScreenOptions}
252
+        >
253
+            <VoteStack.Screen
254
+                name="VoteScreen"
255
+                component={VoteScreen}
256
+                options={({navigation}) => {
257
+                    const openDrawer = getDrawerButton.bind(this, navigation);
258
+                    return {
259
+                        title: "VoteScreen",
260
+                        headerLeft: openDrawer
261
+                    };
262
+                }}
263
+            />
264
+        </VoteStack.Navigator>
265
+    );
266
+}
267
+
242 268
 const ClubStack = createStackNavigator();
243 269
 
244 270
 function ClubStackComponent() {
@@ -341,6 +367,10 @@ export default function DrawerNavigator() {
341 367
                 name="ClubListScreen"
342 368
                 component={ClubStackComponent}
343 369
             />
370
+            <Drawer.Screen
371
+                name="VoteScreen"
372
+                component={VoteStackComponent}
373
+            />
344 374
         </Drawer.Navigator>
345 375
     );
346 376
 }

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

@@ -71,7 +71,7 @@ class ClubListScreen extends React.Component<Props, State> {
71 71
      * @return {*}
72 72
      */
73 73
     getHeaderButtons = () => {
74
-        const onPress = () => this.props.navigation.navigate( "ClubAboutScreen");
74
+        const onPress = () => this.props.navigation.navigate("ClubAboutScreen");
75 75
         return <HeaderButton icon={'information'} onPress={onPress}/>;
76 76
     };
77 77
 
@@ -91,11 +91,11 @@ class ClubListScreen extends React.Component<Props, State> {
91 91
     itemLayout = (data, index) => ({length: LIST_ITEM_HEIGHT, offset: LIST_ITEM_HEIGHT * index, index});
92 92
 
93 93
     getScreen = (data: Object) => {
94
-        this.categories = data.categories;
94
+        this.categories = data[0].categories;
95 95
         return (
96 96
             //$FlowFixMe
97 97
             <FlatList
98
-                data={data.clubs}
98
+                data={data[0].clubs}
99 99
                 keyExtractor={this.keyExtractor}
100 100
                 renderItem={this.getRenderItem}
101 101
                 ListHeaderComponent={this.getListHeader()}
@@ -193,7 +193,12 @@ class ClubListScreen extends React.Component<Props, State> {
193 193
         return (
194 194
             <AuthenticatedScreen
195 195
                 {...this.props}
196
-                link={'https://www.amicale-insat.fr/api/clubs/list'}
196
+                links={[
197
+                    {
198
+                        link: 'clubs/list',
199
+                        mandatory: true,
200
+                    }
201
+                ]}
197 202
                 renderFunction={this.getScreen}
198 203
             />
199 204
         );

+ 6
- 6
src/screens/Amicale/LoginScreen.js View File

@@ -149,18 +149,18 @@ class LoginScreen extends React.Component<Props, State> {
149 149
         const title = i18n.t("loginScreen.errors.title");
150 150
         let message;
151 151
         switch (error) {
152
-            case ERROR_TYPE.CONNECTION_ERROR:
153
-                message = i18n.t("loginScreen.errors.connection");
154
-                break;
155 152
             case ERROR_TYPE.BAD_CREDENTIALS:
156 153
                 message = i18n.t("loginScreen.errors.credentials");
157 154
                 break;
158
-            case ERROR_TYPE.SAVE_TOKEN:
159
-                message = i18n.t("loginScreen.errors.saveToken");
160
-                break;
161 155
             case ERROR_TYPE.NO_CONSENT:
162 156
                 message = i18n.t("loginScreen.errors.consent");
163 157
                 break;
158
+            case ERROR_TYPE.CONNECTION_ERROR:
159
+                message = i18n.t("loginScreen.errors.connection");
160
+                break;
161
+            case ERROR_TYPE.SERVER_ERROR:
162
+                message = "SERVER ERROR"; // TODO translate
163
+                break;
164 164
             default:
165 165
                 message = i18n.t("loginScreen.errors.unknown");
166 166
                 break;

+ 18
- 35
src/screens/Amicale/ProfileScreen.js View File

@@ -1,7 +1,7 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {FlatList, StyleSheet, View} from "react-native";
4
+import {FlatList, ScrollView, StyleSheet} from "react-native";
5 5
 import {Avatar, Button, Card, Divider, List, withTheme} from 'react-native-paper';
6 6
 import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
7 7
 import {openBrowser} from "../../utils/WebBrowser";
@@ -28,16 +28,9 @@ class ProfileScreen extends React.Component<Props, State> {
28 28
 
29 29
     data: Object;
30 30
 
31
-    flatListData: Array<Object>;
32
-
33 31
     constructor(props) {
34 32
         super(props);
35 33
         this.colors = props.theme.colors;
36
-        this.flatListData = [
37
-            {id: '0'},
38
-            {id: '1'},
39
-            {id: '2'},
40
-        ]
41 34
     }
42 35
 
43 36
     componentDidMount() {
@@ -47,44 +40,29 @@ class ProfileScreen extends React.Component<Props, State> {
47 40
         });
48 41
     }
49 42
 
50
-    showDisconnectDialog = () => this.setState({ dialogVisible: true });
43
+    showDisconnectDialog = () => this.setState({dialogVisible: true});
51 44
 
52
-    hideDisconnectDialog = () => this.setState({ dialogVisible: false });
45
+    hideDisconnectDialog = () => this.setState({dialogVisible: false});
53 46
 
54 47
     getHeaderButtons() {
55 48
         return <HeaderButton icon={'logout'} onPress={this.showDisconnectDialog}/>;
56 49
     }
57 50
 
58
-    getScreen(data: Object) {
59
-        this.data = data;
51
+    getScreen = (data: Object) => {
52
+        this.data = data[0];
60 53
         return (
61
-            <View>
62
-                <FlatList
63
-                    renderItem={item => this.getRenderItem(item)}
64
-                    keyExtractor={item => item.id}
65
-                    data={this.flatListData}
66
-                />
54
+            <ScrollView>
55
+                {this.getPersonalCard()}
56
+                {this.getClubCard()}
57
+                {this.getMembershipCar()}
67 58
                 <LogoutDialog
68 59
                     {...this.props}
69 60
                     visible={this.state.dialogVisible}
70 61
                     onDismiss={this.hideDisconnectDialog}
71 62
                 />
72
-            </View>
73
-
63
+            </ScrollView>
74 64
         )
75
-    }
76
-
77
-    getRenderItem({item}: Object): any {
78
-        switch (item.id) {
79
-            case '0':
80
-                return this.getPersonalCard();
81
-            case '1':
82
-                return this.getClubCard();
83
-            case '2':
84
-                return this.getMembershipCar();
85
-        }
86
-    }
87
-
65
+    };
88 66
 
89 67
     getPersonalCard() {
90 68
         return (
@@ -232,8 +210,13 @@ class ProfileScreen extends React.Component<Props, State> {
232 210
         return (
233 211
             <AuthenticatedScreen
234 212
                 {...this.props}
235
-                link={'https://www.amicale-insat.fr/api/user/profile'}
236
-                renderFunction={(data) => this.getScreen(data)}
213
+                links={[
214
+                    {
215
+                        link: 'user/profile',
216
+                        mandatory: true,
217
+                    }
218
+                ]}
219
+                renderFunction={this.getScreen}
237 220
             />
238 221
         );
239 222
     }

+ 130
- 0
src/screens/Amicale/VoteScreen.js View File

@@ -0,0 +1,130 @@
1
+// @flow
2
+
3
+import * as React from 'react';
4
+import {ScrollView, StyleSheet} from "react-native";
5
+import {Avatar, Card, Paragraph, withTheme} from 'react-native-paper';
6
+import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
7
+
8
+const ICON_AMICALE = require('../../../assets/amicale.png');
9
+
10
+type Props = {
11
+    navigation: Object,
12
+    theme: Object,
13
+}
14
+
15
+type State = {}
16
+
17
+class VoteScreen extends React.Component<Props, State> {
18
+
19
+    state = {};
20
+
21
+    colors: Object;
22
+
23
+    constructor(props) {
24
+        super(props);
25
+        this.colors = props.theme.colors;
26
+    }
27
+
28
+    getScreen = (data: Object) => {
29
+        console.log(data);
30
+        return (
31
+            <ScrollView>
32
+                {this.getTitleCard()}
33
+                {this.getVoteCard()}
34
+            </ScrollView>
35
+        );
36
+    };
37
+
38
+    getTitleCard() {
39
+        return (
40
+            <Card style={styles.card}>
41
+                <Card.Title
42
+                    title={"VOTE"}
43
+                    subtitle={"WHY"}
44
+                    left={(props) => <Avatar.Image
45
+                        {...props}
46
+                        source={ICON_AMICALE}
47
+                        style={styles.icon}
48
+                    />}
49
+                />
50
+                <Card.Content>
51
+                    <Paragraph>
52
+                        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus rhoncus porttitor
53
+                        suscipit. Quisque hendrerit, quam id vestibulum vestibulum, lorem nisi hendrerit nisi, a
54
+                        eleifend sapien diam ut elit. Curabitur sit amet vulputate lectus. Donec semper cursus sapien
55
+                        vel finibus.
56
+                    </Paragraph>
57
+                    <Paragraph>
58
+                        Sed et venenatis turpis. Fusce malesuada magna urna, sed vehicula sem luctus in. Vivamus
59
+                        faucibus vel eros a ultricies. In sed laoreet ante, luctus mattis tellus. Etiam vitae ipsum
60
+                        sagittis, consequat purus sed, blandit risus.
61
+                    </Paragraph>
62
+                </Card.Content>
63
+            </Card>
64
+        );
65
+    }
66
+
67
+    getVoteCard() {
68
+        return (
69
+            <Card style={styles.card}>
70
+                <Card.Title
71
+                    title={"VOTE OPEN"}
72
+                    subtitle={"VALID UNTIL DATE END"}
73
+                />
74
+                <Card.Content>
75
+                    <Paragraph>TEAM1</Paragraph>
76
+                    <Paragraph>TEAM2</Paragraph>
77
+                </Card.Content>
78
+            </Card>
79
+        );
80
+    }
81
+
82
+    getVoteResultCard() {
83
+        return (
84
+            <Card style={styles.card}>
85
+                <Card.Title
86
+                    title={"VOTE RESULTS"}
87
+                    subtitle={"DATE END RESULTS"}
88
+                />
89
+                <Card.Content>
90
+                    <Paragraph>TEAM1</Paragraph>
91
+                    <Paragraph>TEAM2</Paragraph>
92
+                </Card.Content>
93
+            </Card>
94
+        );
95
+    }
96
+
97
+    getEmptyVoteCard() {
98
+
99
+    }
100
+
101
+    render() {
102
+        return (
103
+            <AuthenticatedScreen
104
+                {...this.props}
105
+                links={[
106
+                    {
107
+                        link: 'elections/teams',
108
+                        mandatory: false,
109
+                    },
110
+                    {
111
+                        link: 'elections/dates',
112
+                        mandatory: true,
113
+                    },
114
+                ]}
115
+                renderFunction={this.getScreen}
116
+            />
117
+        );
118
+    }
119
+}
120
+
121
+const styles = StyleSheet.create({
122
+    card: {
123
+        margin: 10,
124
+    },
125
+    icon: {
126
+        backgroundColor: 'transparent'
127
+    },
128
+});
129
+
130
+export default withTheme(VoteScreen);

Loading…
Cancel
Save