Browse Source

Update prettier and eslint config

Arnaud Vergnet 2 months ago
parent
commit
02f9241d28
100 changed files with 4235 additions and 3968 deletions
  1. 0
    6
      .eslintrc.js
  2. 0
    6
      .prettierrc.js
  3. 4
    0
      .vscode/settings.json
  4. 26
    23
      App.tsx
  5. 5
    5
      __mocks__/react-native-keychain/index.js
  6. 16
    18
      __tests__/managers/ConnectionManager.test.js
  7. 55
    58
      __tests__/utils/EquipmentBooking.test.js
  8. 26
    29
      __tests__/utils/PlanningEventManager.test.js
  9. 17
    20
      __tests__/utils/Proxiwash.test.js
  10. 4
    6
      __tests__/utils/WebData.test.js
  11. 0
    18
      clear-node-cache.sh
  12. 2
    3
      index.js
  13. 1
    2
      metro.config.js
  14. 2266
    2432
      package-lock.json
  15. 103
    68
      package.json
  16. 11
    11
      src/components/Amicale/AuthenticatedScreen.tsx
  17. 2
    2
      src/components/Amicale/LogoutDialog.tsx
  18. 17
    10
      src/components/Amicale/Vote/VoteNotAvailable.tsx
  19. 16
    11
      src/components/Amicale/Vote/VoteResults.tsx
  20. 19
    17
      src/components/Amicale/Vote/VoteSelect.tsx
  21. 2
    5
      src/components/Amicale/Vote/VoteTease.tsx
  22. 5
    8
      src/components/Amicale/Vote/VoteWait.tsx
  23. 10
    10
      src/components/Animations/AnimatedAccordion.tsx
  24. 24
    17
      src/components/Animations/AnimatedBottomBar.tsx
  25. 5
    4
      src/components/Animations/AnimatedFAB.tsx
  26. 21
    10
      src/components/Collapsible/CollapsibleComponent.tsx
  27. 2
    2
      src/components/Collapsible/CollapsibleFlatList.tsx
  28. 2
    2
      src/components/Collapsible/CollapsibleScrollView.tsx
  29. 2
    2
      src/components/Collapsible/CollapsibleSectionList.tsx
  30. 1
    1
      src/components/Dialogs/AlertDialog.tsx
  31. 1
    1
      src/components/Dialogs/ErrorDialog.tsx
  32. 13
    6
      src/components/Dialogs/LoadingConfirmDialog.tsx
  33. 3
    3
      src/components/Dialogs/OptionsDialog.tsx
  34. 13
    9
      src/components/Home/ActionsDashboardItem.tsx
  35. 9
    5
      src/components/Home/EventDashboardItem.tsx
  36. 31
    24
      src/components/Home/FeedItem.tsx
  37. 15
    7
      src/components/Home/PreviewEventDashboardItem.tsx
  38. 33
    21
      src/components/Home/SmallDashboardItem.tsx
  39. 3
    2
      src/components/Intro/IconIntro.tsx
  40. 6
    8
      src/components/Intro/MascotIntroEnd.tsx
  41. 29
    28
      src/components/Intro/MascotIntroWelcome.tsx
  42. 5
    5
      src/components/Lists/CardList/CardList.tsx
  43. 21
    14
      src/components/Lists/CardList/CardListItem.tsx
  44. 22
    18
      src/components/Lists/CardList/ImageListItem.tsx
  45. 16
    9
      src/components/Lists/Clubs/ClubListHeader.tsx
  46. 35
    22
      src/components/Lists/Clubs/ClubListItem.tsx
  47. 16
    14
      src/components/Lists/DashboardEdit/DashboardEditAccordion.tsx
  48. 23
    15
      src/components/Lists/DashboardEdit/DashboardEditItem.tsx
  49. 27
    16
      src/components/Lists/DashboardEdit/DashboardEditPreviewItem.tsx
  50. 21
    19
      src/components/Lists/Equipment/EquipmentListItem.tsx
  51. 20
    15
      src/components/Lists/PlanexGroups/GroupListAccordion.tsx
  52. 29
    18
      src/components/Lists/PlanexGroups/GroupListItem.tsx
  53. 21
    10
      src/components/Lists/Proximo/ProximoListItem.tsx
  54. 36
    22
      src/components/Lists/Proxiwash/ProxiwashListItem.tsx
  55. 9
    6
      src/components/Lists/Proxiwash/ProxiwashSectionHeader.tsx
  56. 55
    42
      src/components/Mascot/Mascot.tsx
  57. 81
    64
      src/components/Mascot/MascotPopup.tsx
  58. 14
    8
      src/components/Mascot/SpeechArrow.tsx
  59. 15
    11
      src/components/Media/ImageGalleryButton.tsx
  60. 5
    4
      src/components/Overrides/CustomAgenda.tsx
  61. 3
    3
      src/components/Overrides/CustomHTML.tsx
  62. 3
    3
      src/components/Overrides/CustomHeaderButton.tsx
  63. 64
    62
      src/components/Overrides/CustomIntroSlider.tsx
  64. 9
    7
      src/components/Overrides/CustomModal.tsx
  65. 19
    13
      src/components/Overrides/CustomSlider.tsx
  66. 18
    12
      src/components/Screens/BasicLoadingScreen.tsx
  67. 18
    14
      src/components/Screens/ErrorView.tsx
  68. 36
    28
      src/components/Screens/WebSectionList.tsx
  69. 29
    18
      src/components/Screens/WebViewScreen.tsx
  70. 30
    23
      src/components/Tabbar/CustomTabBar.tsx
  71. 30
    22
      src/components/Tabbar/TabHomeIcon.tsx
  72. 27
    19
      src/components/Tabbar/TabIcon.tsx
  73. 0
    2
      src/constants/NewsSourcesConstants.ts
  74. 23
    0
      src/constants/Styles.tsx
  75. 1
    1
      src/constants/Update.tsx
  76. 11
    11
      src/managers/AprilFoolsManager.ts
  77. 6
    6
      src/managers/AsyncStorageManager.ts
  78. 6
    8
      src/managers/ConnectionManager.ts
  79. 3
    5
      src/managers/DashboardManager.ts
  80. 1
    1
      src/managers/DateManager.ts
  81. 3
    3
      src/managers/ServicesManager.ts
  82. 6
    6
      src/managers/ThemeManager.ts
  83. 35
    31
      src/navigation/MainNavigator.tsx
  84. 63
    47
      src/navigation/TabNavigator.tsx
  85. 7
    7
      src/screens/About/AboutDependenciesScreen.tsx
  86. 37
    23
      src/screens/About/AboutScreen.tsx
  87. 25
    20
      src/screens/About/DebugScreen.tsx
  88. 25
    15
      src/screens/Amicale/AmicaleContactScreen.tsx
  89. 27
    14
      src/screens/Amicale/Clubs/ClubAboutScreen.tsx
  90. 54
    25
      src/screens/Amicale/Clubs/ClubDisplayScreen.tsx
  91. 20
    17
      src/screens/Amicale/Clubs/ClubListScreen.tsx
  92. 39
    23
      src/screens/Amicale/Equipment/EquipmentConfirmScreen.tsx
  93. 31
    27
      src/screens/Amicale/Equipment/EquipmentListScreen.tsx
  94. 104
    86
      src/screens/Amicale/Equipment/EquipmentRentScreen.tsx
  95. 57
    51
      src/screens/Amicale/LoginScreen.tsx
  96. 37
    30
      src/screens/Amicale/ProfileScreen.tsx
  97. 34
    28
      src/screens/Amicale/VoteScreen.tsx
  98. 2
    4
      src/screens/Game/Shapes/BaseShape.ts
  99. 1
    1
      src/screens/Game/Shapes/ShapeI.ts
  100. 0
    0
      src/screens/Game/Shapes/ShapeJ.ts

+ 0
- 6
.eslintrc.js View File

@@ -1,6 +0,0 @@
1
-module.exports = {
2
-  root: true,
3
-  extends: '@react-native-community',
4
-  parser: '@typescript-eslint/parser',
5
-  plugins: ['@typescript-eslint'],
6
-};

+ 0
- 6
.prettierrc.js View File

@@ -1,6 +0,0 @@
1
-module.exports = {
2
-  bracketSpacing: false,
3
-  jsxBracketSameLine: true,
4
-  singleQuote: true,
5
-  trailingComma: 'all',
6
-};

+ 4
- 0
.vscode/settings.json View File

@@ -0,0 +1,4 @@
1
+{
2
+    "i18n-ally.localesPaths": "locales",
3
+    "i18n-ally.keystyle": "nested"
4
+}

+ 26
- 23
App.tsx View File

@@ -17,13 +17,13 @@
17 17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18 18
  */
19 19
 
20
-import * as React from 'react';
21
-import {LogBox, Platform, SafeAreaView, View} from 'react-native';
22
-import {NavigationContainer} from '@react-navigation/native';
23
-import {Provider as PaperProvider} from 'react-native-paper';
24
-import {setSafeBounceHeight} from 'react-navigation-collapsible';
20
+import React from 'react';
21
+import { LogBox, Platform, SafeAreaView, View } from 'react-native';
22
+import { NavigationContainer } from '@react-navigation/native';
23
+import { Provider as PaperProvider } from 'react-native-paper';
24
+import { setSafeBounceHeight } from 'react-navigation-collapsible';
25 25
 import SplashScreen from 'react-native-splash-screen';
26
-import {OverflowMenuProvider} from 'react-navigation-header-buttons';
26
+import { OverflowMenuProvider } from 'react-navigation-header-buttons';
27 27
 import AsyncStorageManager from './src/managers/AsyncStorageManager';
28 28
 import CustomIntroSlider from './src/components/Overrides/CustomIntroSlider';
29 29
 import ThemeManager from './src/managers/ThemeManager';
@@ -31,11 +31,12 @@ import MainNavigator from './src/navigation/MainNavigator';
31 31
 import AprilFoolsManager from './src/managers/AprilFoolsManager';
32 32
 import Update from './src/constants/Update';
33 33
 import ConnectionManager from './src/managers/ConnectionManager';
34
-import type {ParsedUrlDataType} from './src/utils/URLHandler';
34
+import type { ParsedUrlDataType } from './src/utils/URLHandler';
35 35
 import URLHandler from './src/utils/URLHandler';
36
-import {setupStatusBar} from './src/utils/Utils';
36
+import { setupStatusBar } from './src/utils/Utils';
37 37
 import initLocales from './src/utils/Locales';
38
-import {NavigationContainerRef} from '@react-navigation/core';
38
+import { NavigationContainerRef } from '@react-navigation/core';
39
+import GENERAL_STYLES from './src/constants/Styles';
39 40
 
40 41
 // Native optimizations https://reactnavigation.org/docs/react-native-screens
41 42
 // Crashes app when navigating away from webview on android 9+
@@ -56,11 +57,11 @@ type StateType = {
56 57
 };
57 58
 
58 59
 export default class App extends React.Component<{}, StateType> {
59
-  navigatorRef: {current: null | NavigationContainerRef};
60
+  navigatorRef: { current: null | NavigationContainerRef };
60 61
 
61 62
   defaultHomeRoute: string | null;
62 63
 
63
-  defaultHomeData: {[key: string]: string};
64
+  defaultHomeData: { [key: string]: string };
64 65
 
65 66
   urlHandler: URLHandler;
66 67
 
@@ -106,7 +107,7 @@ export default class App extends React.Component<{}, StateType> {
106 107
     if (nav != null) {
107 108
       nav.navigate('home', {
108 109
         screen: 'index',
109
-        params: {nextScreen: parsedData.route, data: parsedData.data},
110
+        params: { nextScreen: parsedData.route, data: parsedData.data },
110 111
       });
111 112
     }
112 113
   };
@@ -132,15 +133,15 @@ export default class App extends React.Component<{}, StateType> {
132 133
     });
133 134
     AsyncStorageManager.set(
134 135
       AsyncStorageManager.PREFERENCES.showIntro.key,
135
-      false,
136
+      false
136 137
     );
137 138
     AsyncStorageManager.set(
138 139
       AsyncStorageManager.PREFERENCES.updateNumber.key,
139
-      Update.number,
140
+      Update.number
140 141
     );
141 142
     AsyncStorageManager.set(
142 143
       AsyncStorageManager.PREFERENCES.showAprilFoolsStart.key,
143
-      false,
144
+      false
144 145
     );
145 146
   };
146 147
 
@@ -161,16 +162,16 @@ export default class App extends React.Component<{}, StateType> {
161 162
       isLoading: false,
162 163
       currentTheme: ThemeManager.getCurrentTheme(),
163 164
       showIntro: AsyncStorageManager.getBool(
164
-        AsyncStorageManager.PREFERENCES.showIntro.key,
165
+        AsyncStorageManager.PREFERENCES.showIntro.key
165 166
       ),
166 167
       showUpdate:
167 168
         AsyncStorageManager.getNumber(
168
-          AsyncStorageManager.PREFERENCES.updateNumber.key,
169
+          AsyncStorageManager.PREFERENCES.updateNumber.key
169 170
         ) !== Update.number,
170 171
       showAprilFools:
171 172
         AprilFoolsManager.getInstance().isAprilFoolsEnabled() &&
172 173
         AsyncStorageManager.getBool(
173
-          AsyncStorageManager.PREFERENCES.showAprilFoolsStart.key,
174
+          AsyncStorageManager.PREFERENCES.showAprilFoolsStart.key
174 175
         ),
175 176
     });
176 177
     SplashScreen.hide();
@@ -194,7 +195,7 @@ export default class App extends React.Component<{}, StateType> {
194 195
    * Renders the app based on loading state
195 196
    */
196 197
   render() {
197
-    const {state} = this;
198
+    const { state } = this;
198 199
     if (state.isLoading) {
199 200
       return null;
200 201
     }
@@ -213,12 +214,14 @@ export default class App extends React.Component<{}, StateType> {
213 214
           <View
214 215
             style={{
215 216
               backgroundColor: ThemeManager.getCurrentTheme().colors.background,
216
-              flex: 1,
217
-            }}>
218
-            <SafeAreaView style={{flex: 1}}>
217
+              ...GENERAL_STYLES.flex,
218
+            }}
219
+          >
220
+            <SafeAreaView style={GENERAL_STYLES.flex}>
219 221
               <NavigationContainer
220 222
                 theme={state.currentTheme}
221
-                ref={this.navigatorRef}>
223
+                ref={this.navigatorRef}
224
+              >
222 225
                 <MainNavigator
223 226
                   defaultHomeRoute={this.defaultHomeRoute}
224 227
                   defaultHomeData={this.defaultHomeData}

+ 5
- 5
__mocks__/react-native-keychain/index.js View File

@@ -1,7 +1,7 @@
1 1
 const keychainMock = {
2
-    SECURITY_LEVEL_ANY: "MOCK_SECURITY_LEVEL_ANY",
3
-    SECURITY_LEVEL_SECURE_SOFTWARE: "MOCK_SECURITY_LEVEL_SECURE_SOFTWARE",
4
-    SECURITY_LEVEL_SECURE_HARDWARE: "MOCK_SECURITY_LEVEL_SECURE_HARDWARE",
5
-}
2
+  SECURITY_LEVEL_ANY: 'MOCK_SECURITY_LEVEL_ANY',
3
+  SECURITY_LEVEL_SECURE_SOFTWARE: 'MOCK_SECURITY_LEVEL_SECURE_SOFTWARE',
4
+  SECURITY_LEVEL_SECURE_HARDWARE: 'MOCK_SECURITY_LEVEL_SECURE_HARDWARE',
5
+};
6 6
 
7
-export default keychainMock;
7
+export default keychainMock;

+ 16
- 18
__tests__/managers/ConnectionManager.test.js View File

@@ -1,11 +1,9 @@
1
-/* eslint-disable */
2
-
3
-import React from 'react';
4 1
 import ConnectionManager from '../../src/managers/ConnectionManager';
5
-import {ERROR_TYPE} from '../../src/utils/WebData';
2
+import { ERROR_TYPE } from '../../src/utils/WebData';
6 3
 
7 4
 jest.mock('react-native-keychain');
8 5
 
6
+// eslint-disable-next-line no-unused-vars
9 7
 const fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS but in react-native
10 8
 
11 9
 const c = ConnectionManager.getInstance();
@@ -44,7 +42,7 @@ test('connect bad credentials', () => {
44 42
     });
45 43
   });
46 44
   return expect(c.connect('email', 'password')).rejects.toBe(
47
-    ERROR_TYPE.BAD_CREDENTIALS,
45
+    ERROR_TYPE.BAD_CREDENTIALS
48 46
   );
49 47
 });
50 48
 
@@ -54,7 +52,7 @@ test('connect good credentials', () => {
54 52
       json: () => {
55 53
         return {
56 54
           error: ERROR_TYPE.SUCCESS,
57
-          data: {token: 'token'},
55
+          data: { token: 'token' },
58 56
         };
59 57
       },
60 58
     });
@@ -79,7 +77,7 @@ test('connect good credentials no consent', () => {
79 77
     });
80 78
   });
81 79
   return expect(c.connect('email', 'password')).rejects.toBe(
82
-    ERROR_TYPE.NO_CONSENT,
80
+    ERROR_TYPE.NO_CONSENT
83 81
   );
84 82
 });
85 83
 
@@ -89,7 +87,7 @@ test('connect good credentials, fail save token', () => {
89 87
       json: () => {
90 88
         return {
91 89
           error: ERROR_TYPE.SUCCESS,
92
-          data: {token: 'token'},
90
+          data: { token: 'token' },
93 91
         };
94 92
       },
95 93
     });
@@ -100,7 +98,7 @@ test('connect good credentials, fail save token', () => {
100 98
       return Promise.reject(false);
101 99
     });
102 100
   return expect(c.connect('email', 'password')).rejects.toBe(
103
-    ERROR_TYPE.TOKEN_SAVE,
101
+    ERROR_TYPE.TOKEN_SAVE
104 102
   );
105 103
 });
106 104
 
@@ -109,7 +107,7 @@ test('connect connection error', () => {
109 107
     return Promise.reject();
110 108
   });
111 109
   return expect(c.connect('email', 'password')).rejects.toBe(
112
-    ERROR_TYPE.CONNECTION_ERROR,
110
+    ERROR_TYPE.CONNECTION_ERROR
113 111
   );
114 112
 });
115 113
 
@@ -125,7 +123,7 @@ test('connect bogus response 1', () => {
125 123
     });
126 124
   });
127 125
   return expect(c.connect('email', 'password')).rejects.toBe(
128
-    ERROR_TYPE.SERVER_ERROR,
126
+    ERROR_TYPE.SERVER_ERROR
129 127
   );
130 128
 });
131 129
 
@@ -140,14 +138,14 @@ test('authenticatedRequest success', () => {
140 138
       json: () => {
141 139
         return {
142 140
           error: ERROR_TYPE.SUCCESS,
143
-          data: {coucou: 'toi'},
141
+          data: { coucou: 'toi' },
144 142
         };
145 143
       },
146 144
     });
147 145
   });
148 146
   return expect(
149
-    c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'),
150
-  ).resolves.toStrictEqual({coucou: 'toi'});
147
+    c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check')
148
+  ).resolves.toStrictEqual({ coucou: 'toi' });
151 149
 });
152 150
 
153 151
 test('authenticatedRequest error wrong token', () => {
@@ -167,7 +165,7 @@ test('authenticatedRequest error wrong token', () => {
167 165
     });
168 166
   });
169 167
   return expect(
170
-    c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'),
168
+    c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check')
171 169
   ).rejects.toBe(ERROR_TYPE.BAD_TOKEN);
172 170
 });
173 171
 
@@ -187,7 +185,7 @@ test('authenticatedRequest error bogus response', () => {
187 185
     });
188 186
   });
189 187
   return expect(
190
-    c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'),
188
+    c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check')
191 189
   ).rejects.toBe(ERROR_TYPE.SERVER_ERROR);
192 190
 });
193 191
 
@@ -201,7 +199,7 @@ test('authenticatedRequest connection error', () => {
201 199
     return Promise.reject();
202 200
   });
203 201
   return expect(
204
-    c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'),
202
+    c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check')
205 203
   ).rejects.toBe(ERROR_TYPE.CONNECTION_ERROR);
206 204
 });
207 205
 
@@ -212,6 +210,6 @@ test('authenticatedRequest error no token', () => {
212 210
       return null;
213 211
     });
214 212
   return expect(
215
-    c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check'),
213
+    c.authenticatedRequest('https://www.amicale-insat.fr/api/token/check')
216 214
   ).rejects.toBe(ERROR_TYPE.TOKEN_RETRIEVE);
217 215
 });

+ 55
- 58
__tests__/utils/EquipmentBooking.test.js View File

@@ -1,6 +1,3 @@
1
-/* eslint-disable */
2
-
3
-import React from 'react';
4 1
 import * as EquipmentBooking from '../../src/utils/EquipmentBooking';
5 2
 import i18n from 'i18n-js';
6 3
 
@@ -18,7 +15,7 @@ test('getCurrentDay', () => {
18 15
     .spyOn(Date, 'now')
19 16
     .mockImplementation(() => new Date('2020-01-14 14:50:35').getTime());
20 17
   expect(EquipmentBooking.getCurrentDay().getTime()).toBe(
21
-    new Date('2020-01-14').getTime(),
18
+    new Date('2020-01-14').getTime()
22 19
   );
23 20
 });
24 21
 
@@ -30,19 +27,19 @@ test('isEquipmentAvailable', () => {
30 27
     id: 1,
31 28
     name: 'Petit barbecue',
32 29
     caution: 100,
33
-    booked_at: [{begin: '2020-07-07', end: '2020-07-10'}],
30
+    booked_at: [{ begin: '2020-07-07', end: '2020-07-10' }],
34 31
   };
35 32
   expect(EquipmentBooking.isEquipmentAvailable(testDevice)).toBeFalse();
36 33
 
37
-  testDevice.booked_at = [{begin: '2020-07-07', end: '2020-07-09'}];
34
+  testDevice.booked_at = [{ begin: '2020-07-07', end: '2020-07-09' }];
38 35
   expect(EquipmentBooking.isEquipmentAvailable(testDevice)).toBeFalse();
39 36
 
40
-  testDevice.booked_at = [{begin: '2020-07-09', end: '2020-07-10'}];
37
+  testDevice.booked_at = [{ begin: '2020-07-09', end: '2020-07-10' }];
41 38
   expect(EquipmentBooking.isEquipmentAvailable(testDevice)).toBeFalse();
42 39
 
43 40
   testDevice.booked_at = [
44
-    {begin: '2020-07-07', end: '2020-07-8'},
45
-    {begin: '2020-07-10', end: '2020-07-12'},
41
+    { begin: '2020-07-07', end: '2020-07-8' },
42
+    { begin: '2020-07-10', end: '2020-07-12' },
46 43
   ];
47 44
   expect(EquipmentBooking.isEquipmentAvailable(testDevice)).toBeTrue();
48 45
 });
@@ -55,29 +52,29 @@ test('getFirstEquipmentAvailability', () => {
55 52
     id: 1,
56 53
     name: 'Petit barbecue',
57 54
     caution: 100,
58
-    booked_at: [{begin: '2020-07-07', end: '2020-07-10'}],
55
+    booked_at: [{ begin: '2020-07-07', end: '2020-07-10' }],
59 56
   };
60 57
   expect(
61
-    EquipmentBooking.getFirstEquipmentAvailability(testDevice).getTime(),
58
+    EquipmentBooking.getFirstEquipmentAvailability(testDevice).getTime()
62 59
   ).toBe(new Date('2020-07-11').getTime());
63
-  testDevice.booked_at = [{begin: '2020-07-07', end: '2020-07-09'}];
60
+  testDevice.booked_at = [{ begin: '2020-07-07', end: '2020-07-09' }];
64 61
   expect(
65
-    EquipmentBooking.getFirstEquipmentAvailability(testDevice).getTime(),
62
+    EquipmentBooking.getFirstEquipmentAvailability(testDevice).getTime()
66 63
   ).toBe(new Date('2020-07-10').getTime());
67 64
   testDevice.booked_at = [
68
-    {begin: '2020-07-07', end: '2020-07-09'},
69
-    {begin: '2020-07-10', end: '2020-07-16'},
65
+    { begin: '2020-07-07', end: '2020-07-09' },
66
+    { begin: '2020-07-10', end: '2020-07-16' },
70 67
   ];
71 68
   expect(
72
-    EquipmentBooking.getFirstEquipmentAvailability(testDevice).getTime(),
69
+    EquipmentBooking.getFirstEquipmentAvailability(testDevice).getTime()
73 70
   ).toBe(new Date('2020-07-17').getTime());
74 71
   testDevice.booked_at = [
75
-    {begin: '2020-07-07', end: '2020-07-09'},
76
-    {begin: '2020-07-10', end: '2020-07-12'},
77
-    {begin: '2020-07-14', end: '2020-07-16'},
72
+    { begin: '2020-07-07', end: '2020-07-09' },
73
+    { begin: '2020-07-10', end: '2020-07-12' },
74
+    { begin: '2020-07-14', end: '2020-07-16' },
78 75
   ];
79 76
   expect(
80
-    EquipmentBooking.getFirstEquipmentAvailability(testDevice).getTime(),
77
+    EquipmentBooking.getFirstEquipmentAvailability(testDevice).getTime()
81 78
   ).toBe(new Date('2020-07-13').getTime());
82 79
 });
83 80
 
@@ -85,7 +82,7 @@ test('getRelativeDateString', () => {
85 82
   jest
86 83
     .spyOn(Date, 'now')
87 84
     .mockImplementation(() => new Date('2020-07-09').getTime());
88
-  jest.spyOn(i18n, 't').mockImplementation((translationString: string) => {
85
+  jest.spyOn(i18n, 't').mockImplementation((translationString) => {
89 86
     const prefix = 'screens.equipment.';
90 87
     if (translationString === prefix + 'otherYear') return '0';
91 88
     else if (translationString === prefix + 'otherMonth') return '1';
@@ -95,25 +92,25 @@ test('getRelativeDateString', () => {
95 92
     else return null;
96 93
   });
97 94
   expect(EquipmentBooking.getRelativeDateString(new Date('2020-07-09'))).toBe(
98
-    '4',
95
+    '4'
99 96
   );
100 97
   expect(EquipmentBooking.getRelativeDateString(new Date('2020-07-10'))).toBe(
101
-    '3',
98
+    '3'
102 99
   );
103 100
   expect(EquipmentBooking.getRelativeDateString(new Date('2020-07-11'))).toBe(
104
-    '2',
101
+    '2'
105 102
   );
106 103
   expect(EquipmentBooking.getRelativeDateString(new Date('2020-07-30'))).toBe(
107
-    '2',
104
+    '2'
108 105
   );
109 106
   expect(EquipmentBooking.getRelativeDateString(new Date('2020-08-30'))).toBe(
110
-    '1',
107
+    '1'
111 108
   );
112 109
   expect(EquipmentBooking.getRelativeDateString(new Date('2020-11-10'))).toBe(
113
-    '1',
110
+    '1'
114 111
   );
115 112
   expect(EquipmentBooking.getRelativeDateString(new Date('2021-11-10'))).toBe(
116
-    '0',
113
+    '0'
117 114
   );
118 115
 });
119 116
 
@@ -122,7 +119,7 @@ test('getValidRange', () => {
122 119
     id: 1,
123 120
     name: 'Petit barbecue',
124 121
     caution: 100,
125
-    booked_at: [{begin: '2020-07-07', end: '2020-07-10'}],
122
+    booked_at: [{ begin: '2020-07-07', end: '2020-07-10' }],
126 123
   };
127 124
   let start = new Date('2020-07-11');
128 125
   let end = new Date('2020-07-15');
@@ -134,62 +131,62 @@ test('getValidRange', () => {
134 131
     '2020-07-15',
135 132
   ];
136 133
   expect(EquipmentBooking.getValidRange(start, end, testDevice)).toStrictEqual(
137
-    result,
134
+    result
138 135
   );
139 136
   testDevice.booked_at = [
140
-    {begin: '2020-07-07', end: '2020-07-10'},
141
-    {begin: '2020-07-13', end: '2020-07-15'},
137
+    { begin: '2020-07-07', end: '2020-07-10' },
138
+    { begin: '2020-07-13', end: '2020-07-15' },
142 139
   ];
143 140
   result = ['2020-07-11', '2020-07-12'];
144 141
   expect(EquipmentBooking.getValidRange(start, end, testDevice)).toStrictEqual(
145
-    result,
142
+    result
146 143
   );
147 144
 
148
-  testDevice.booked_at = [{begin: '2020-07-12', end: '2020-07-13'}];
145
+  testDevice.booked_at = [{ begin: '2020-07-12', end: '2020-07-13' }];
149 146
   result = ['2020-07-11'];
150 147
   expect(EquipmentBooking.getValidRange(start, end, testDevice)).toStrictEqual(
151
-    result,
148
+    result
152 149
   );
153
-  testDevice.booked_at = [{begin: '2020-07-07', end: '2020-07-12'}];
150
+  testDevice.booked_at = [{ begin: '2020-07-07', end: '2020-07-12' }];
154 151
   result = ['2020-07-13', '2020-07-14', '2020-07-15'];
155 152
   expect(EquipmentBooking.getValidRange(end, start, testDevice)).toStrictEqual(
156
-    result,
153
+    result
157 154
   );
158 155
   start = new Date('2020-07-14');
159 156
   end = new Date('2020-07-14');
160 157
   result = ['2020-07-14'];
161 158
   expect(
162
-    EquipmentBooking.getValidRange(start, start, testDevice),
159
+    EquipmentBooking.getValidRange(start, start, testDevice)
163 160
   ).toStrictEqual(result);
164 161
   expect(EquipmentBooking.getValidRange(end, start, testDevice)).toStrictEqual(
165
-    result,
162
+    result
166 163
   );
167 164
   expect(EquipmentBooking.getValidRange(start, end, null)).toStrictEqual(
168
-    result,
165
+    result
169 166
   );
170 167
 
171 168
   start = new Date('2020-07-14');
172 169
   end = new Date('2020-07-17');
173 170
   result = ['2020-07-14', '2020-07-15', '2020-07-16', '2020-07-17'];
174 171
   expect(EquipmentBooking.getValidRange(start, end, null)).toStrictEqual(
175
-    result,
172
+    result
176 173
   );
177 174
 
178
-  testDevice.booked_at = [{begin: '2020-07-17', end: '2020-07-17'}];
175
+  testDevice.booked_at = [{ begin: '2020-07-17', end: '2020-07-17' }];
179 176
   result = ['2020-07-14', '2020-07-15', '2020-07-16'];
180 177
   expect(EquipmentBooking.getValidRange(start, end, testDevice)).toStrictEqual(
181
-    result,
178
+    result
182 179
   );
183 180
 
184 181
   testDevice.booked_at = [
185
-    {begin: '2020-07-12', end: '2020-07-13'},
186
-    {begin: '2020-07-15', end: '2020-07-20'},
182
+    { begin: '2020-07-12', end: '2020-07-13' },
183
+    { begin: '2020-07-15', end: '2020-07-20' },
187 184
   ];
188 185
   start = new Date('2020-07-11');
189 186
   end = new Date('2020-07-23');
190 187
   result = ['2020-07-21', '2020-07-22', '2020-07-23'];
191 188
   expect(EquipmentBooking.getValidRange(end, start, testDevice)).toStrictEqual(
192
-    result,
189
+    result
193 190
   );
194 191
 });
195 192
 
@@ -205,7 +202,7 @@ test('generateMarkedDates', () => {
205 202
     id: 1,
206 203
     name: 'Petit barbecue',
207 204
     caution: 100,
208
-    booked_at: [{begin: '2020-07-07', end: '2020-07-10'}],
205
+    booked_at: [{ begin: '2020-07-07', end: '2020-07-10' }],
209 206
   };
210 207
   let start = new Date('2020-07-11');
211 208
   let end = new Date('2020-07-13');
@@ -228,7 +225,7 @@ test('generateMarkedDates', () => {
228 225
     },
229 226
   };
230 227
   expect(
231
-    EquipmentBooking.generateMarkedDates(true, theme, range),
228
+    EquipmentBooking.generateMarkedDates(true, theme, range)
232 229
   ).toStrictEqual(result);
233 230
   result = {
234 231
     '2020-07-11': {
@@ -248,7 +245,7 @@ test('generateMarkedDates', () => {
248 245
     },
249 246
   };
250 247
   expect(
251
-    EquipmentBooking.generateMarkedDates(false, theme, range),
248
+    EquipmentBooking.generateMarkedDates(false, theme, range)
252 249
   ).toStrictEqual(result);
253 250
   result = {
254 251
     '2020-07-11': {
@@ -269,10 +266,10 @@ test('generateMarkedDates', () => {
269 266
   };
270 267
   range = EquipmentBooking.getValidRange(end, start, testDevice);
271 268
   expect(
272
-    EquipmentBooking.generateMarkedDates(false, theme, range),
269
+    EquipmentBooking.generateMarkedDates(false, theme, range)
273 270
   ).toStrictEqual(result);
274 271
 
275
-  testDevice.booked_at = [{begin: '2020-07-13', end: '2020-07-15'}];
272
+  testDevice.booked_at = [{ begin: '2020-07-13', end: '2020-07-15' }];
276 273
   result = {
277 274
     '2020-07-11': {
278 275
       startingDay: true,
@@ -287,10 +284,10 @@ test('generateMarkedDates', () => {
287 284
   };
288 285
   range = EquipmentBooking.getValidRange(start, end, testDevice);
289 286
   expect(
290
-    EquipmentBooking.generateMarkedDates(true, theme, range),
287
+    EquipmentBooking.generateMarkedDates(true, theme, range)
291 288
   ).toStrictEqual(result);
292 289
 
293
-  testDevice.booked_at = [{begin: '2020-07-12', end: '2020-07-13'}];
290
+  testDevice.booked_at = [{ begin: '2020-07-12', end: '2020-07-13' }];
294 291
   result = {
295 292
     '2020-07-11': {
296 293
       startingDay: true,
@@ -300,12 +297,12 @@ test('generateMarkedDates', () => {
300 297
   };
301 298
   range = EquipmentBooking.getValidRange(start, end, testDevice);
302 299
   expect(
303
-    EquipmentBooking.generateMarkedDates(true, theme, range),
300
+    EquipmentBooking.generateMarkedDates(true, theme, range)
304 301
   ).toStrictEqual(result);
305 302
 
306 303
   testDevice.booked_at = [
307
-    {begin: '2020-07-12', end: '2020-07-13'},
308
-    {begin: '2020-07-15', end: '2020-07-20'},
304
+    { begin: '2020-07-12', end: '2020-07-13' },
305
+    { begin: '2020-07-15', end: '2020-07-20' },
309 306
   ];
310 307
   start = new Date('2020-07-11');
311 308
   end = new Date('2020-07-23');
@@ -318,7 +315,7 @@ test('generateMarkedDates', () => {
318 315
   };
319 316
   range = EquipmentBooking.getValidRange(start, end, testDevice);
320 317
   expect(
321
-    EquipmentBooking.generateMarkedDates(true, theme, range),
318
+    EquipmentBooking.generateMarkedDates(true, theme, range)
322 319
   ).toStrictEqual(result);
323 320
 
324 321
   result = {
@@ -340,6 +337,6 @@ test('generateMarkedDates', () => {
340 337
   };
341 338
   range = EquipmentBooking.getValidRange(end, start, testDevice);
342 339
   expect(
343
-    EquipmentBooking.generateMarkedDates(true, theme, range),
340
+    EquipmentBooking.generateMarkedDates(true, theme, range)
344 341
   ).toStrictEqual(result);
345 342
 });

+ 26
- 29
__tests__/utils/PlanningEventManager.test.js View File

@@ -1,6 +1,3 @@
1
-/* eslint-disable */
2
-
3
-import React from 'react';
4 1
 import * as Planning from '../../src/utils/Planning';
5 2
 
6 3
 test('isDescriptionEmpty', () => {
@@ -24,7 +21,7 @@ test('isEventDateStringFormatValid', () => {
24 21
   expect(Planning.isEventDateStringFormatValid('3214-64-12 01:16')).toBeTrue();
25 22
 
26 23
   expect(
27
-    Planning.isEventDateStringFormatValid('3214-64-12 01:16:00'),
24
+    Planning.isEventDateStringFormatValid('3214-64-12 01:16:00')
28 25
   ).toBeFalse();
29 26
   expect(Planning.isEventDateStringFormatValid('3214-64-12 1:16')).toBeFalse();
30 27
   expect(Planning.isEventDateStringFormatValid('3214-f4-12 01:16')).toBeFalse();
@@ -32,7 +29,7 @@ test('isEventDateStringFormatValid', () => {
32 29
   expect(Planning.isEventDateStringFormatValid('2020-03-21')).toBeFalse();
33 30
   expect(Planning.isEventDateStringFormatValid('2020-03-21 truc')).toBeFalse();
34 31
   expect(
35
-    Planning.isEventDateStringFormatValid('3214-64-12 1:16:65'),
32
+    Planning.isEventDateStringFormatValid('3214-64-12 1:16:65')
36 33
   ).toBeFalse();
37 34
   expect(Planning.isEventDateStringFormatValid('garbage')).toBeFalse();
38 35
   expect(Planning.isEventDateStringFormatValid('')).toBeFalse();
@@ -65,17 +62,17 @@ test('getFormattedEventTime', () => {
65 62
   expect(Planning.getFormattedEventTime(undefined, undefined)).toBe('/ - /');
66 63
   expect(Planning.getFormattedEventTime('20:30', '23:00')).toBe('/ - /');
67 64
   expect(Planning.getFormattedEventTime('2020-03-30', '2020-03-31')).toBe(
68
-    '/ - /',
65
+    '/ - /'
69 66
   );
70 67
 
71 68
   expect(
72
-    Planning.getFormattedEventTime('2020-03-21 09:00', '2020-03-21 09:00'),
69
+    Planning.getFormattedEventTime('2020-03-21 09:00', '2020-03-21 09:00')
73 70
   ).toBe('09:00');
74 71
   expect(
75
-    Planning.getFormattedEventTime('2020-03-21 09:00', '2020-03-22 17:00'),
72
+    Planning.getFormattedEventTime('2020-03-21 09:00', '2020-03-22 17:00')
76 73
   ).toBe('09:00 - 23:59');
77 74
   expect(
78
-    Planning.getFormattedEventTime('2020-03-30 20:30', '2020-03-30 23:00'),
75
+    Planning.getFormattedEventTime('2020-03-30 20:30', '2020-03-30 23:00')
79 76
   ).toBe('20:30 - 23:00');
80 77
 });
81 78
 
@@ -90,38 +87,38 @@ test('getDateOnlyString', () => {
90 87
 
91 88
 test('isEventBefore', () => {
92 89
   expect(
93
-    Planning.isEventBefore('2020-03-21 09:00', '2020-03-21 10:00'),
90
+    Planning.isEventBefore('2020-03-21 09:00', '2020-03-21 10:00')
94 91
   ).toBeTrue();
95 92
   expect(
96
-    Planning.isEventBefore('2020-03-21 10:00', '2020-03-21 10:15'),
93
+    Planning.isEventBefore('2020-03-21 10:00', '2020-03-21 10:15')
97 94
   ).toBeTrue();
98 95
   expect(
99
-    Planning.isEventBefore('2020-03-21 10:15', '2021-03-21 10:15'),
96
+    Planning.isEventBefore('2020-03-21 10:15', '2021-03-21 10:15')
100 97
   ).toBeTrue();
101 98
   expect(
102
-    Planning.isEventBefore('2020-03-21 10:15', '2020-05-21 10:15'),
99
+    Planning.isEventBefore('2020-03-21 10:15', '2020-05-21 10:15')
103 100
   ).toBeTrue();
104 101
   expect(
105
-    Planning.isEventBefore('2020-03-21 10:15', '2020-03-30 10:15'),
102
+    Planning.isEventBefore('2020-03-21 10:15', '2020-03-30 10:15')
106 103
   ).toBeTrue();
107 104
 
108 105
   expect(
109
-    Planning.isEventBefore('2020-03-21 10:00', '2020-03-21 10:00'),
106
+    Planning.isEventBefore('2020-03-21 10:00', '2020-03-21 10:00')
110 107
   ).toBeFalse();
111 108
   expect(
112
-    Planning.isEventBefore('2020-03-21 10:00', '2020-03-21 09:00'),
109
+    Planning.isEventBefore('2020-03-21 10:00', '2020-03-21 09:00')
113 110
   ).toBeFalse();
114 111
   expect(
115
-    Planning.isEventBefore('2020-03-21 10:15', '2020-03-21 10:00'),
112
+    Planning.isEventBefore('2020-03-21 10:15', '2020-03-21 10:00')
116 113
   ).toBeFalse();
117 114
   expect(
118
-    Planning.isEventBefore('2021-03-21 10:15', '2020-03-21 10:15'),
115
+    Planning.isEventBefore('2021-03-21 10:15', '2020-03-21 10:15')
119 116
   ).toBeFalse();
120 117
   expect(
121
-    Planning.isEventBefore('2020-05-21 10:15', '2020-03-21 10:15'),
118
+    Planning.isEventBefore('2020-05-21 10:15', '2020-03-21 10:15')
122 119
   ).toBeFalse();
123 120
   expect(
124
-    Planning.isEventBefore('2020-03-30 10:15', '2020-03-21 10:15'),
121
+    Planning.isEventBefore('2020-03-30 10:15', '2020-03-21 10:15')
125 122
   ).toBeFalse();
126 123
 
127 124
   expect(Planning.isEventBefore('garbage', '2020-03-21 10:15')).toBeFalse();
@@ -162,25 +159,25 @@ test('generateEmptyCalendar', () => {
162 159
 
163 160
 test('pushEventInOrder', () => {
164 161
   let eventArray = [];
165
-  let event1 = {date_begin: '2020-01-14 09:15'};
162
+  let event1 = { date_begin: '2020-01-14 09:15' };
166 163
   Planning.pushEventInOrder(eventArray, event1);
167 164
   expect(eventArray.length).toBe(1);
168 165
   expect(eventArray[0]).toBe(event1);
169 166
 
170
-  let event2 = {date_begin: '2020-01-14 10:15'};
167
+  let event2 = { date_begin: '2020-01-14 10:15' };
171 168
   Planning.pushEventInOrder(eventArray, event2);
172 169
   expect(eventArray.length).toBe(2);
173 170
   expect(eventArray[0]).toBe(event1);
174 171
   expect(eventArray[1]).toBe(event2);
175 172
 
176
-  let event3 = {date_begin: '2020-01-14 10:15', title: 'garbage'};
173
+  let event3 = { date_begin: '2020-01-14 10:15', title: 'garbage' };
177 174
   Planning.pushEventInOrder(eventArray, event3);
178 175
   expect(eventArray.length).toBe(3);
179 176
   expect(eventArray[0]).toBe(event1);
180 177
   expect(eventArray[1]).toBe(event2);
181 178
   expect(eventArray[2]).toBe(event3);
182 179
 
183
-  let event4 = {date_begin: '2020-01-13 09:00'};
180
+  let event4 = { date_begin: '2020-01-13 09:00' };
184 181
   Planning.pushEventInOrder(eventArray, event4);
185 182
   expect(eventArray.length).toBe(4);
186 183
   expect(eventArray[0]).toBe(event4);
@@ -194,11 +191,11 @@ test('generateEventAgenda', () => {
194 191
     .spyOn(Date, 'now')
195 192
     .mockImplementation(() => new Date('2020-01-14T00:00:00.000Z').getTime());
196 193
   let eventList = [
197
-    {date_begin: '2020-01-14 09:15'},
198
-    {date_begin: '2020-02-01 09:15'},
199
-    {date_begin: '2020-01-15 09:15'},
200
-    {date_begin: '2020-02-01 09:30'},
201
-    {date_begin: '2020-02-01 08:30'},
194
+    { date_begin: '2020-01-14 09:15' },
195
+    { date_begin: '2020-02-01 09:15' },
196
+    { date_begin: '2020-01-15 09:15' },
197
+    { date_begin: '2020-02-01 09:30' },
198
+    { date_begin: '2020-02-01 08:30' },
202 199
   ];
203 200
   const calendar = Planning.generateEventAgenda(eventList, 2);
204 201
   expect(calendar['2020-01-14'].length).toBe(1);

+ 17
- 20
__tests__/utils/Proxiwash.test.js View File

@@ -1,6 +1,3 @@
1
-/* eslint-disable */
2
-
3
-import React from 'react';
4 1
 import {
5 2
   getCleanedMachineWatched,
6 3
   getMachineEndDate,
@@ -15,19 +12,19 @@ test('getMachineEndDate', () => {
15 12
   let expectDate = new Date('2020-01-14T15:00:00.000Z');
16 13
   expectDate.setHours(23);
17 14
   expectDate.setMinutes(10);
18
-  expect(getMachineEndDate({endTime: '23:10'}).getTime()).toBe(
19
-    expectDate.getTime(),
15
+  expect(getMachineEndDate({ endTime: '23:10' }).getTime()).toBe(
16
+    expectDate.getTime()
20 17
   );
21 18
 
22 19
   expectDate.setHours(16);
23 20
   expectDate.setMinutes(30);
24
-  expect(getMachineEndDate({endTime: '16:30'}).getTime()).toBe(
25
-    expectDate.getTime(),
21
+  expect(getMachineEndDate({ endTime: '16:30' }).getTime()).toBe(
22
+    expectDate.getTime()
26 23
   );
27 24
 
28
-  expect(getMachineEndDate({endTime: '15:30'})).toBeNull();
25
+  expect(getMachineEndDate({ endTime: '15:30' })).toBeNull();
29 26
 
30
-  expect(getMachineEndDate({endTime: '13:10'})).toBeNull();
27
+  expect(getMachineEndDate({ endTime: '13:10' })).toBeNull();
31 28
 
32 29
   jest
33 30
     .spyOn(Date, 'now')
@@ -35,8 +32,8 @@ test('getMachineEndDate', () => {
35 32
   expectDate = new Date('2020-01-14T23:00:00.000Z');
36 33
   expectDate.setHours(0);
37 34
   expectDate.setMinutes(30);
38
-  expect(getMachineEndDate({endTime: '00:30'}).getTime()).toBe(
39
-    expectDate.getTime(),
35
+  expect(getMachineEndDate({ endTime: '00:30' }).getTime()).toBe(
36
+    expectDate.getTime()
40 37
   );
41 38
 });
42 39
 
@@ -52,16 +49,16 @@ test('isMachineWatched', () => {
52 49
     },
53 50
   ];
54 51
   expect(
55
-    isMachineWatched({number: '0', endTime: '23:30'}, machineList),
52
+    isMachineWatched({ number: '0', endTime: '23:30' }, machineList)
56 53
   ).toBeTrue();
57 54
   expect(
58
-    isMachineWatched({number: '1', endTime: '20:30'}, machineList),
55
+    isMachineWatched({ number: '1', endTime: '20:30' }, machineList)
59 56
   ).toBeTrue();
60 57
   expect(
61
-    isMachineWatched({number: '3', endTime: '20:30'}, machineList),
58
+    isMachineWatched({ number: '3', endTime: '20:30' }, machineList)
62 59
   ).toBeFalse();
63 60
   expect(
64
-    isMachineWatched({number: '1', endTime: '23:30'}, machineList),
61
+    isMachineWatched({ number: '1', endTime: '23:30' }, machineList)
65 62
   ).toBeFalse();
66 63
 });
67 64
 
@@ -74,8 +71,8 @@ test('getMachineOfId', () => {
74 71
       number: '1',
75 72
     },
76 73
   ];
77
-  expect(getMachineOfId('0', machineList)).toStrictEqual({number: '0'});
78
-  expect(getMachineOfId('1', machineList)).toStrictEqual({number: '1'});
74
+  expect(getMachineOfId('0', machineList)).toStrictEqual({ number: '0' });
75
+  expect(getMachineOfId('1', machineList)).toStrictEqual({ number: '1' });
79 76
   expect(getMachineOfId('3', machineList)).toBeNull();
80 77
 });
81 78
 
@@ -110,7 +107,7 @@ test('getCleanedMachineWatched', () => {
110 107
   ];
111 108
   let cleanedList = watchList;
112 109
   expect(getCleanedMachineWatched(watchList, machineList)).toStrictEqual(
113
-    cleanedList,
110
+    cleanedList
114 111
   );
115 112
 
116 113
   watchList = [
@@ -138,7 +135,7 @@ test('getCleanedMachineWatched', () => {
138 135
     },
139 136
   ];
140 137
   expect(getCleanedMachineWatched(watchList, machineList)).toStrictEqual(
141
-    cleanedList,
138
+    cleanedList
142 139
   );
143 140
 
144 141
   watchList = [
@@ -162,6 +159,6 @@ test('getCleanedMachineWatched', () => {
162 159
     },
163 160
   ];
164 161
   expect(getCleanedMachineWatched(watchList, machineList)).toStrictEqual(
165
-    cleanedList,
162
+    cleanedList
166 163
   );
167 164
 });

+ 4
- 6
__tests__/utils/WebData.test.js View File

@@ -1,8 +1,6 @@
1
-/* eslint-disable */
2
-
3
-import React from 'react';
4
-import {isApiResponseValid} from '../../src/utils/WebData';
1
+import { isApiResponseValid } from '../../src/utils/WebData';
5 2
 
3
+// eslint-disable-next-line no-unused-vars
6 4
 const fetch = require('isomorphic-fetch'); // fetch is not implemented in nodeJS but in react-native
7 5
 
8 6
 test('isRequestResponseValid', () => {
@@ -23,7 +21,7 @@ test('isRequestResponseValid', () => {
23 21
   expect(isApiResponseValid(json)).toBeTrue();
24 22
   json = {
25 23
     error: 50,
26
-    data: {truc: 'machin'},
24
+    data: { truc: 'machin' },
27 25
   };
28 26
   expect(isApiResponseValid(json)).toBeTrue();
29 27
   json = {
@@ -32,7 +30,7 @@ test('isRequestResponseValid', () => {
32 30
   expect(isApiResponseValid(json)).toBeFalse();
33 31
   json = {
34 32
     error: 'coucou',
35
-    data: {truc: 'machin'},
33
+    data: { truc: 'machin' },
36 34
   };
37 35
   expect(isApiResponseValid(json)).toBeFalse();
38 36
   json = {

+ 0
- 18
clear-node-cache.sh View File

@@ -1,18 +0,0 @@
1
-#!/bin/bash
2
-
3
-echo "Removing node_modules..."
4
-rm -rf node_modules/
5
-echo -e "Done\n"
6
-
7
-echo "Removing locks..."
8
-rm -f package-lock.json && rm -f yarn.lock
9
-echo -e "Done\n"
10
-
11
-#echo "Verifying npm cache..."
12
-#npm cache verify
13
-#echo -e "Done\n"
14
-
15
-echo "Installing dependencies..."
16
-npm install
17
-echo -e "Done\n"
18
-

+ 2
- 3
index.js View File

@@ -21,9 +21,8 @@
21 21
  * @format
22 22
  */
23 23
 
24
-import {AppRegistry} from 'react-native';
24
+import { AppRegistry } from 'react-native';
25 25
 import App from './App';
26
-import {name as appName} from './app.json';
26
+import { name as appName } from './app.json';
27 27
 
28
-// eslint-disable-next-line flowtype/require-return-type
29 28
 AppRegistry.registerComponent(appName, () => App);

+ 1
- 2
metro.config.js View File

@@ -7,11 +7,10 @@
7 7
 
8 8
 module.exports = {
9 9
   transformer: {
10
-    // eslint-disable-next-line flowtype/require-return-type
11 10
     getTransformOptions: async () => ({
12 11
       transform: {
13 12
         experimentalImportSupport: false,
14
-        inlineRequires: false,
13
+        inlineRequires: true,
15 14
       },
16 15
     }),
17 16
   },

+ 2266
- 2432
package-lock.json
File diff suppressed because it is too large
View File


+ 103
- 68
package.json View File

@@ -3,12 +3,113 @@
3 3
   "version": "4.1.0",
4 4
   "private": true,
5 5
   "scripts": {
6
-    "start": "react-native start",
7 6
     "android": "react-native run-android",
8 7
     "android-release": "react-native run-android --variant=release",
9 8
     "ios": "react-native run-ios",
9
+    "start": "react-native start",
10
+    "start-no-cache": "react-native start --reset-cache",
10 11
     "test": "jest",
11
-    "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
12
+    "typescript": "tsc --noEmit",
13
+    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
14
+    "lint-fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
15
+    "full-check": "npm run typescript && npm run lint && npm run test",
16
+    "pod": "cd ios && pod install && cd ..",
17
+    "bundle": "npm run full-check && cd android && ./gradlew bundleRelease",
18
+    "postversion": "react-native-version"
19
+  },
20
+  "dependencies": {
21
+    "@nartc/react-native-barcode-mask": "1.2.0",
22
+    "@react-native-community/async-storage": "1.12.0",
23
+    "@react-native-community/masked-view": "0.1.10",
24
+    "@react-native-community/push-notification-ios": "1.5.0",
25
+    "@react-native-community/slider": "3.0.3",
26
+    "@react-navigation/bottom-tabs": "5.8.0",
27
+    "@react-navigation/native": "5.7.3",
28
+    "@react-navigation/stack": "5.9.0",
29
+    "i18n-js": "3.7.1",
30
+    "react": "16.13.1",
31
+    "react-native": "0.63.2",
32
+    "react-native-animatable": "1.3.3",
33
+    "react-native-app-intro-slider": "4.0.4",
34
+    "react-native-appearance": "0.3.4",
35
+    "react-native-autolink": "3.0.0",
36
+    "react-native-calendars": "1.403.0",
37
+    "react-native-camera": "3.40.0",
38
+    "react-native-collapsible": "1.5.3",
39
+    "react-native-gesture-handler": "1.8.0",
40
+    "react-native-image-zoom-viewer": "3.0.1",
41
+    "react-native-keychain": "4.0.5",
42
+    "react-native-linear-gradient": "2.5.6",
43
+    "react-native-localize": "1.4.1",
44
+    "react-native-modalize": "2.0.6",
45
+    "react-native-paper": "4.2.0",
46
+    "react-native-permissions": "2.2.1",
47
+    "react-native-push-notification": "5.1.1",
48
+    "react-native-reanimated": "1.13.0",
49
+    "react-native-render-html": "4.2.3",
50
+    "react-native-safe-area-context": "3.1.8",
51
+    "react-native-screens": "2.11.0",
52
+    "react-native-splash-screen": "3.2.0",
53
+    "react-native-vector-icons": "7.1.0",
54
+    "react-native-webview": "10.9.0",
55
+    "react-navigation-collapsible": "5.6.4",
56
+    "react-navigation-header-buttons": "5.0.2"
57
+  },
58
+  "devDependencies": {
59
+    "@babel/core": "7.11.0",
60
+    "@babel/runtime": "7.11.0",
61
+    "@react-native-community/eslint-config": "1.1.0",
62
+    "@types/i18n-js": "3.0.3",
63
+    "@types/jest": "25.2.3",
64
+    "@types/react-native": "0.63.2",
65
+    "@types/react-native-calendars": "1.20.10",
66
+    "@types/react-native-vector-icons": "6.4.6",
67
+    "@types/react-test-renderer": "16.9.2",
68
+    "@typescript-eslint/eslint-plugin": "2.27.0",
69
+    "@typescript-eslint/parser": "2.27.0",
70
+    "babel-jest": "25.1.0",
71
+    "eslint": "7.2.0",
72
+    "jest": "25.1.0",
73
+    "jest-extended": "0.11.5",
74
+    "jest-fetch-mock": "3.0.3",
75
+    "metro-react-native-babel-preset": "0.59.0",
76
+    "prettier": "2.0.5",
77
+    "react-native-version": "4.0.0",
78
+    "react-test-renderer": "16.13.1",
79
+    "typescript": "3.8.3"
80
+  },
81
+  "eslintConfig": {
82
+    "root": true,
83
+    "parser": "@typescript-eslint/parser",
84
+    "plugins": [
85
+      "@typescript-eslint"
86
+    ],
87
+    "extends": [
88
+      "@react-native-community",
89
+      "prettier"
90
+    ],
91
+    "rules": {
92
+      "prettier/prettier": [
93
+        "error",
94
+        {
95
+          "quoteProps": "consistent",
96
+          "singleQuote": true,
97
+          "tabWidth": 2,
98
+          "trailingComma": "es5",
99
+          "useTabs": false
100
+        }
101
+      ]
102
+    }
103
+  },
104
+  "eslintIgnore": [
105
+    "node_modules/"
106
+  ],
107
+  "prettier": {
108
+    "quoteProps": "consistent",
109
+    "singleQuote": true,
110
+    "tabWidth": 2,
111
+    "trailingComma": "es5",
112
+    "useTabs": false
12 113
   },
13 114
   "jest": {
14 115
     "preset": "react-native",
@@ -23,71 +124,5 @@
23 124
     "setupFilesAfterEnv": [
24 125
       "jest-extended"
25 126
     ]
26
-  },
27
-  "dependencies": {
28
-    "@nartc/react-native-barcode-mask": "^1.2.0",
29
-    "@react-native-community/async-storage": "^1.12.0",
30
-    "@react-native-community/masked-view": "^0.1.10",
31
-    "@react-native-community/push-notification-ios": "^1.5.0",
32
-    "@react-native-community/slider": "^3.0.3",
33
-    "@react-navigation/bottom-tabs": "^5.8.0",
34
-    "@react-navigation/native": "^5.7.3",
35
-    "@react-navigation/stack": "^5.9.0",
36
-    "i18n-js": "^3.7.1",
37
-    "react": "16.13.1",
38
-    "react-native": "0.63.2",
39
-    "react-native-animatable": "^1.3.3",
40
-    "react-native-app-intro-slider": "^4.0.4",
41
-    "react-native-appearance": "^0.3.4",
42
-    "react-native-autolink": "^3.0.0",
43
-    "react-native-calendars": "^1.403.0",
44
-    "react-native-camera": "^3.40.0",
45
-    "react-native-collapsible": "^1.5.3",
46
-    "react-native-gesture-handler": "^1.8.0",
47
-    "react-native-image-zoom-viewer": "^3.0.1",
48
-    "react-native-keychain": "4.0.5",
49
-    "react-native-linear-gradient": "^2.5.6",
50
-    "react-native-localize": "^1.4.1",
51
-    "react-native-modalize": "^2.0.6",
52
-    "react-native-paper": "^4.2.0",
53
-    "react-native-permissions": "^2.2.1",
54
-    "react-native-push-notification": "^5.1.1",
55
-    "react-native-reanimated": "^1.13.0",
56
-    "react-native-render-html": "^4.2.3",
57
-    "react-native-safe-area-context": "^3.1.8",
58
-    "react-native-screens": "^2.11.0",
59
-    "react-native-splash-screen": "^3.2.0",
60
-    "react-native-vector-icons": "^7.1.0",
61
-    "react-native-webview": "^10.9.0",
62
-    "react-navigation-collapsible": "^5.6.4",
63
-    "react-navigation-header-buttons": "^5.0.2"
64
-  },
65
-  "devDependencies": {
66
-    "@babel/core": "^7.11.0",
67
-    "@babel/runtime": "^7.11.0",
68
-    "@react-native-community/eslint-config": "^1.1.0",
69
-    "@types/i18n-js": "^3.0.3",
70
-    "@types/jest": "^25.2.3",
71
-    "@types/react-native": "^0.63.2",
72
-    "@types/react-native-calendars": "^1.20.10",
73
-    "@types/react-native-vector-icons": "^6.4.6",
74
-    "@types/react-test-renderer": "^16.9.2",
75
-    "@typescript-eslint/eslint-plugin": "^2.27.0",
76
-    "@typescript-eslint/parser": "^2.27.0",
77
-    "babel-jest": "^25.1.0",
78
-    "eslint": "^7.2.0",
79
-    "eslint-config-airbnb": "^18.2.0",
80
-    "eslint-config-prettier": "^6.11.0",
81
-    "eslint-plugin-flowtype": "^5.2.0",
82
-    "eslint-plugin-import": "^2.22.0",
83
-    "eslint-plugin-jsx-a11y": "^6.3.1",
84
-    "eslint-plugin-react": "^7.20.5",
85
-    "eslint-plugin-react-hooks": "^4.0.0",
86
-    "jest": "^25.1.0",
87
-    "jest-extended": "^0.11.5",
88
-    "metro-react-native-babel-preset": "^0.59.0",
89
-    "prettier": "2.0.5",
90
-    "react-test-renderer": "16.13.1",
91
-    "typescript": "^3.8.3"
92 127
   }
93 128
 }

+ 11
- 11
src/components/Amicale/AuthenticatedScreen.tsx View File

@@ -18,9 +18,9 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {StackNavigationProp} from '@react-navigation/stack';
21
+import { StackNavigationProp } from '@react-navigation/stack';
22 22
 import ConnectionManager from '../../managers/ConnectionManager';
23
-import {ERROR_TYPE} from '../../utils/WebData';
23
+import { ERROR_TYPE } from '../../utils/WebData';
24 24
 import ErrorView from '../Screens/ErrorView';
25 25
 import BasicLoadingScreen from '../Screens/BasicLoadingScreen';
26 26
 
@@ -90,7 +90,7 @@ class AuthenticatedScreen<T> extends React.Component<PropsType<T>, StateType> {
90 90
    * @param error The error code received
91 91
    */
92 92
   onRequestFinished(data: T | null, index: number, error?: number) {
93
-    const {props} = this;
93
+    const { props } = this;
94 94
     if (index >= 0 && index < props.requests.length) {
95 95
       this.fetchedData[index] = data;
96 96
       this.errors[index] = error != null ? error : ERROR_TYPE.SUCCESS;
@@ -101,7 +101,7 @@ class AuthenticatedScreen<T> extends React.Component<PropsType<T>, StateType> {
101 101
     }
102 102
 
103 103
     if (this.allRequestsFinished()) {
104
-      this.setState({loading: false});
104
+      this.setState({ loading: false });
105 105
     }
106 106
   }
107 107
 
@@ -113,7 +113,7 @@ class AuthenticatedScreen<T> extends React.Component<PropsType<T>, StateType> {
113 113
    * @return {number} The error code or ERROR_TYPE.SUCCESS if no error was found
114 114
    */
115 115
   getError(): number {
116
-    const {props} = this;
116
+    const { props } = this;
117 117
     for (let i = 0; i < this.errors.length; i += 1) {
118 118
       if (
119 119
         this.errors[i] !== ERROR_TYPE.SUCCESS &&
@@ -131,7 +131,7 @@ class AuthenticatedScreen<T> extends React.Component<PropsType<T>, StateType> {
131 131
    * @return {*}
132 132
    */
133 133
   getErrorRender() {
134
-    const {props} = this;
134
+    const { props } = this;
135 135
     const errorCode = this.getError();
136 136
     let shouldOverride = false;
137 137
     let override = null;
@@ -166,9 +166,9 @@ class AuthenticatedScreen<T> extends React.Component<PropsType<T>, StateType> {
166 166
    * If the user is logged in, send all requests.
167 167
    */
168 168
   fetchData = () => {
169
-    const {state, props} = this;
169
+    const { state, props } = this;
170 170
     if (!state.loading) {
171
-      this.setState({loading: true});
171
+      this.setState({ loading: true });
172 172
     }
173 173
 
174 174
     if (this.connectionManager.isLoggedIn()) {
@@ -176,11 +176,11 @@ class AuthenticatedScreen<T> extends React.Component<PropsType<T>, StateType> {
176 176
         this.connectionManager
177 177
           .authenticatedRequest<T>(
178 178
             props.requests[i].link,
179
-            props.requests[i].params,
179
+            props.requests[i].params
180 180
           )
181 181
           .then((response: T): void => this.onRequestFinished(response, i))
182 182
           .catch((error: number): void =>
183
-            this.onRequestFinished(null, i, error),
183
+            this.onRequestFinished(null, i, error)
184 184
           );
185 185
       }
186 186
     } else {
@@ -213,7 +213,7 @@ class AuthenticatedScreen<T> extends React.Component<PropsType<T>, StateType> {
213 213
   }
214 214
 
215 215
   render() {
216
-    const {state, props} = this;
216
+    const { state, props } = this;
217 217
     if (state.loading) {
218 218
       return <BasicLoadingScreen />;
219 219
     }

+ 2
- 2
src/components/Amicale/LogoutDialog.tsx View File

@@ -21,7 +21,7 @@ import * as React from 'react';
21 21
 import i18n from 'i18n-js';
22 22
 import LoadingConfirmDialog from '../Dialogs/LoadingConfirmDialog';
23 23
 import ConnectionManager from '../../managers/ConnectionManager';
24
-import {useNavigation} from '@react-navigation/native';
24
+import { useNavigation } from '@react-navigation/native';
25 25
 
26 26
 type PropsType = {
27 27
   visible: boolean;
@@ -37,7 +37,7 @@ function LogoutDialog(props: PropsType) {
37 37
         .then(() => {
38 38
           navigation.reset({
39 39
             index: 0,
40
-            routes: [{name: 'main'}],
40
+            routes: [{ name: 'main' }],
41 41
           });
42 42
           props.onDismiss();
43 43
           resolve();

+ 17
- 10
src/components/Amicale/Vote/VoteNotAvailable.tsx View File

@@ -18,24 +18,31 @@
18 18
  */
19 19
 
20 20
 import React from 'react';
21
-import {View} from 'react-native';
22
-import {Headline, useTheme} from 'react-native-paper';
21
+import { StyleSheet, View } from 'react-native';
22
+import { Headline, useTheme } from 'react-native-paper';
23 23
 import i18n from 'i18n-js';
24 24
 
25
+const styles = StyleSheet.create({
26
+  container: {
27
+    width: '100%',
28
+    marginTop: 10,
29
+    marginBottom: 10,
30
+  },
31
+  headline: {
32
+    textAlign: 'center',
33
+  },
34
+});
35
+
25 36
 function VoteNotAvailable() {
26 37
   const theme = useTheme();
27 38
   return (
28
-    <View
29
-      style={{
30
-        width: '100%',
31
-        marginTop: 10,
32
-        marginBottom: 10,
33
-      }}>
39
+    <View style={styles.container}>
34 40
       <Headline
35 41
         style={{
36 42
           color: theme.colors.textDisabled,
37
-          textAlign: 'center',
38
-        }}>
43
+          ...styles.headline,
44
+        }}
45
+      >
39 46
         {i18n.t('screens.vote.noVote')}
40 47
       </Headline>
41 48
     </View>

+ 16
- 11
src/components/Amicale/Vote/VoteResults.tsx View File

@@ -26,9 +26,9 @@ import {
26 26
   Subheading,
27 27
   withTheme,
28 28
 } from 'react-native-paper';
29
-import {FlatList, StyleSheet} from 'react-native';
29
+import { FlatList, StyleSheet } from 'react-native';
30 30
 import i18n from 'i18n-js';
31
-import type {VoteTeamType} from '../../../screens/Amicale/VoteScreen';
31
+import type { VoteTeamType } from '../../../screens/Amicale/VoteScreen';
32 32
 
33 33
 type PropsType = {
34 34
   teams: Array<VoteTeamType>;
@@ -40,8 +40,11 @@ const styles = StyleSheet.create({
40 40
   card: {
41 41
     margin: 10,
42 42
   },
43
-  icon: {
44
-    backgroundColor: 'transparent',
43
+  itemCard: {
44
+    marginTop: 10,
45
+  },
46
+  item: {
47
+    padding: 0,
45 48
   },
46 49
 });
47 50
 
@@ -86,16 +89,18 @@ class VoteResults extends React.Component<PropsType> {
86 89
 
87 90
   voteKeyExtractor = (item: VoteTeamType): string => item.id.toString();
88 91
 
89
-  resultRenderItem = ({item}: {item: VoteTeamType}) => {
92
+  resultRenderItem = ({ item }: { item: VoteTeamType }) => {
90 93
     const isWinner = this.winnerIds.indexOf(item.id) !== -1;
91 94
     const isDraw = this.winnerIds.length > 1;
92
-    const {props} = this;
95
+    const { props } = this;
96
+    const elevation = isWinner ? 5 : 3;
93 97
     return (
94 98
       <Card
95 99
         style={{
96
-          marginTop: 10,
97
-          elevation: isWinner ? 5 : 3,
98
-        }}>
100
+          ...styles.itemCard,
101
+          elevation: elevation,
102
+        }}
103
+      >
99 104
         <List.Item
100 105
           title={item.name}
101 106
           description={`${item.votes} ${i18n.t('screens.vote.results.votes')}`}
@@ -113,7 +118,7 @@ class VoteResults extends React.Component<PropsType> {
113 118
               ? props.theme.colors.primary
114 119
               : props.theme.colors.text,
115 120
           }}
116
-          style={{padding: 0}}
121
+          style={styles.item}
117 122
         />
118 123
         <ProgressBar
119 124
           progress={item.votes / this.totalVotes}
@@ -124,7 +129,7 @@ class VoteResults extends React.Component<PropsType> {
124 129
   };
125 130
 
126 131
   render() {
127
-    const {props} = this;
132
+    const { props } = this;
128 133
     return (
129 134
       <Card style={styles.card}>
130 135
         <Card.Title

+ 19
- 17
src/components/Amicale/Vote/VoteSelect.tsx View File

@@ -18,13 +18,13 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {Avatar, Button, Card, RadioButton} from 'react-native-paper';
22
-import {FlatList, StyleSheet, View} from 'react-native';
21
+import { Avatar, Button, Card, RadioButton } from 'react-native-paper';
22
+import { FlatList, StyleSheet, View } from 'react-native';
23 23
 import i18n from 'i18n-js';
24 24
 import ConnectionManager from '../../../managers/ConnectionManager';
25 25
 import LoadingConfirmDialog from '../../Dialogs/LoadingConfirmDialog';
26 26
 import ErrorDialog from '../../Dialogs/ErrorDialog';
27
-import type {VoteTeamType} from '../../../screens/Amicale/VoteScreen';
27
+import type { VoteTeamType } from '../../../screens/Amicale/VoteScreen';
28 28
 
29 29
 type PropsType = {
30 30
   teams: Array<VoteTeamType>;
@@ -43,8 +43,8 @@ const styles = StyleSheet.create({
43 43
   card: {
44 44
     margin: 10,
45 45
   },
46
-  icon: {
47
-    backgroundColor: 'transparent',
46
+  button: {
47
+    marginLeft: 'auto',
48 48
   },
49 49
 });
50 50
 
@@ -63,28 +63,28 @@ export default class VoteSelect extends React.PureComponent<
63 63
   }
64 64
 
65 65
   onVoteSelectionChange = (teamName: string): void =>
66
-    this.setState({selectedTeam: teamName});
66
+    this.setState({ selectedTeam: teamName });
67 67
 
68 68
   voteKeyExtractor = (item: VoteTeamType): string => item.id.toString();
69 69
 
70
-  voteRenderItem = ({item}: {item: VoteTeamType}) => (
70
+  voteRenderItem = ({ item }: { item: VoteTeamType }) => (
71 71
     <RadioButton.Item label={item.name} value={item.id.toString()} />
72 72
   );
73 73
 
74
-  showVoteDialog = (): void => this.setState({voteDialogVisible: true});
74
+  showVoteDialog = (): void => this.setState({ voteDialogVisible: true });
75 75
 
76
-  onVoteDialogDismiss = (): void => this.setState({voteDialogVisible: false});
76
+  onVoteDialogDismiss = (): void => this.setState({ voteDialogVisible: false });
77 77
 
78 78
   onVoteDialogAccept = async (): Promise<void> => {
79 79
     return new Promise((resolve: () => void) => {
80
-      const {state} = this;
80
+      const { state } = this;
81 81
       ConnectionManager.getInstance()
82 82
         .authenticatedRequest('elections/vote', {
83 83
           team: parseInt(state.selectedTeam, 10),
84 84
         })
85 85
         .then(() => {
86 86
           this.onVoteDialogDismiss();
87
-          const {props} = this;
87
+          const { props } = this;
88 88
           props.onVoteSuccess();
89 89
           resolve();
90 90
         })
@@ -103,13 +103,13 @@ export default class VoteSelect extends React.PureComponent<
103 103
     });
104 104
 
105 105
   onErrorDialogDismiss = () => {
106
-    this.setState({errorDialogVisible: false});
107
-    const {props} = this;
106
+    this.setState({ errorDialogVisible: false });
107
+    const { props } = this;
108 108
     props.onVoteError();
109 109
   };
110 110
 
111 111
   render() {
112
-    const {state, props} = this;
112
+    const { state, props } = this;
113 113
     return (
114 114
       <View>
115 115
         <Card style={styles.card}>
@@ -123,7 +123,8 @@ export default class VoteSelect extends React.PureComponent<
123 123
           <Card.Content>
124 124
             <RadioButton.Group
125 125
               onValueChange={this.onVoteSelectionChange}
126
-              value={state.selectedTeam}>
126
+              value={state.selectedTeam}
127
+            >
127 128
               <FlatList
128 129
                 data={props.teams}
129 130
                 keyExtractor={this.voteKeyExtractor}
@@ -137,8 +138,9 @@ export default class VoteSelect extends React.PureComponent<
137 138
               icon="send"
138 139
               mode="contained"
139 140
               onPress={this.showVoteDialog}
140
-              style={{marginLeft: 'auto'}}
141
-              disabled={state.selectedTeam === 'none'}>
141
+              style={styles.button}
142
+              disabled={state.selectedTeam === 'none'}
143
+            >
142 144
               {i18n.t('screens.vote.select.sendButton')}
143 145
             </Button>
144 146
           </Card.Actions>

+ 2
- 5
src/components/Amicale/Vote/VoteTease.tsx View File

@@ -18,8 +18,8 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {Avatar, Card, Paragraph} from 'react-native-paper';
22
-import {StyleSheet} from 'react-native';
21
+import { Avatar, Card, Paragraph } from 'react-native-paper';
22
+import { StyleSheet } from 'react-native';
23 23
 import i18n from 'i18n-js';
24 24
 
25 25
 type PropsType = {
@@ -30,9 +30,6 @@ const styles = StyleSheet.create({
30 30
   card: {
31 31
     margin: 10,
32 32
   },
33
-  icon: {
34
-    backgroundColor: 'transparent',
35
-  },
36 33
 });
37 34
 
38 35
 export default function VoteTease(props: PropsType) {

+ 5
- 8
src/components/Amicale/Vote/VoteWait.tsx View File

@@ -18,8 +18,8 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {Avatar, Card, Paragraph, useTheme} from 'react-native-paper';
22
-import {StyleSheet} from 'react-native';
21
+import { Avatar, Card, Paragraph, useTheme } from 'react-native-paper';
22
+import { StyleSheet } from 'react-native';
23 23
 import i18n from 'i18n-js';
24 24
 
25 25
 type PropsType = {
@@ -33,14 +33,11 @@ const styles = StyleSheet.create({
33 33
   card: {
34 34
     margin: 10,
35 35
   },
36
-  icon: {
37
-    backgroundColor: 'transparent',
38
-  },
39 36
 });
40 37
 
41 38
 export default function VoteWait(props: PropsType) {
42 39
   const theme = useTheme();
43
-  const {startDate} = props;
40
+  const { startDate } = props;
44 41
   return (
45 42
     <Card style={styles.card}>
46 43
       <Card.Title
@@ -56,12 +53,12 @@ export default function VoteWait(props: PropsType) {
56 53
       />
57 54
       <Card.Content>
58 55
         {props.justVoted ? (
59
-          <Paragraph style={{color: theme.colors.success}}>
56
+          <Paragraph style={{ color: theme.colors.success }}>
60 57
             {i18n.t('screens.vote.wait.messageSubmitted')}
61 58
           </Paragraph>
62 59
         ) : null}
63 60
         {props.hasVoted ? (
64
-          <Paragraph style={{color: theme.colors.success}}>
61
+          <Paragraph style={{ color: theme.colors.success }}>
65 62
             {i18n.t('screens.vote.wait.messageVoted')}
66 63
           </Paragraph>
67 64
         ) : null}

+ 10
- 10
src/components/Animations/AnimatedAccordion.tsx View File

@@ -18,8 +18,8 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {View, ViewStyle} from 'react-native';
22
-import {List, withTheme} from 'react-native-paper';
21
+import { View, ViewStyle } from 'react-native';
22
+import { List, withTheme } from 'react-native-paper';
23 23
 import Collapsible from 'react-native-collapsible';
24 24
 import * as Animatable from 'react-native-animatable';
25 25
 
@@ -47,7 +47,7 @@ type StateType = {
47 47
 const AnimatedListIcon = Animatable.createAnimatableComponent(List.Icon);
48 48
 
49 49
 class AnimatedAccordion extends React.Component<PropsType, StateType> {
50
-  chevronRef: {current: null | (typeof AnimatedListIcon & List.Icon)};
50
+  chevronRef: { current: null | (typeof AnimatedListIcon & List.Icon) };
51 51
 
52 52
   chevronIcon: string;
53 53
 
@@ -68,7 +68,7 @@ class AnimatedAccordion extends React.Component<PropsType, StateType> {
68 68
   }
69 69
 
70 70
   shouldComponentUpdate(nextProps: PropsType): boolean {
71
-    const {state, props} = this;
71
+    const { state, props } = this;
72 72
     if (nextProps.opened != null && nextProps.opened !== props.opened) {
73 73
       state.expanded = nextProps.opened;
74 74
     }
@@ -76,7 +76,7 @@ class AnimatedAccordion extends React.Component<PropsType, StateType> {
76 76
   }
77 77
 
78 78
   setupChevron() {
79
-    const {expanded} = this.state;
79
+    const { expanded } = this.state;
80 80
     if (expanded) {
81 81
       this.chevronIcon = 'chevron-up';
82 82
       this.animStart = '180deg';
@@ -89,26 +89,26 @@ class AnimatedAccordion extends React.Component<PropsType, StateType> {
89 89
   }
90 90
 
91 91
   toggleAccordion = () => {
92
-    const {expanded} = this.state;
92
+    const { expanded } = this.state;
93 93
     if (this.chevronRef.current != null) {
94 94
       this.chevronRef.current.transitionTo({
95 95
         rotate: expanded ? this.animStart : this.animEnd,
96 96
       });
97
-      this.setState((prevState: StateType): {expanded: boolean} => ({
97
+      this.setState((prevState: StateType): { expanded: boolean } => ({
98 98
         expanded: !prevState.expanded,
99 99
       }));
100 100
     }
101 101
   };
102 102
 
103 103
   render() {
104
-    const {props, state} = this;
105
-    const {colors} = props.theme;
104
+    const { props, state } = this;
105
+    const { colors } = props.theme;
106 106
     return (
107 107
       <View style={props.style}>
108 108
         <List.Item
109 109
           title={props.title}
110 110
           description={props.subtitle}
111
-          titleStyle={state.expanded ? {color: colors.primary} : null}
111
+          titleStyle={state.expanded ? { color: colors.primary } : null}
112 112
           onPress={this.toggleAccordion}
113 113
           right={(iconProps) => (
114 114
             <AnimatedListIcon

+ 24
- 17
src/components/Animations/AnimatedBottomBar.tsx View File

@@ -24,9 +24,9 @@ import {
24 24
   StyleSheet,
25 25
   View,
26 26
 } from 'react-native';
27
-import {FAB, IconButton, Surface, withTheme} from 'react-native-paper';
27
+import { FAB, IconButton, Surface, withTheme } from 'react-native-paper';
28 28
 import * as Animatable from 'react-native-animatable';
29
-import {StackNavigationProp} from '@react-navigation/stack';
29
+import { StackNavigationProp } from '@react-navigation/stack';
30 30
 import AutoHideHandler from '../../utils/AutoHideHandler';
31 31
 import CustomTabBar from '../Tabbar/CustomTabBar';
32 32
 
@@ -76,14 +76,20 @@ const styles = StyleSheet.create({
76 76
     alignSelf: 'center',
77 77
     top: '-25%',
78 78
   },
79
+  side: {
80
+    flexDirection: 'row',
81
+  },
82
+  icon: {
83
+    marginLeft: 5,
84
+  },
79 85
 });
80 86
 
81 87
 class AnimatedBottomBar extends React.Component<PropsType, StateType> {
82
-  ref: {current: null | (Animatable.View & View)};
88
+  ref: { current: null | (Animatable.View & View) };
83 89
 
84 90
   hideHandler: AutoHideHandler;
85 91
 
86
-  displayModeIcons: {[key: string]: string};
92
+  displayModeIcons: { [key: string]: string };
87 93
 
88 94
   constructor(props: PropsType) {
89 95
     super(props);
@@ -101,7 +107,7 @@ class AnimatedBottomBar extends React.Component<PropsType, StateType> {
101 107
   }
102 108
 
103 109
   shouldComponentUpdate(nextProps: PropsType, nextState: StateType): boolean {
104
-    const {props, state} = this;
110
+    const { props, state } = this;
105 111
     return (
106 112
       nextProps.seekAttention !== props.seekAttention ||
107 113
       nextState.currentMode !== state.currentMode
@@ -124,7 +130,7 @@ class AnimatedBottomBar extends React.Component<PropsType, StateType> {
124 130
   };
125 131
 
126 132
   changeDisplayMode = () => {
127
-    const {props, state} = this;
133
+    const { props, state } = this;
128 134
     let newMode;
129 135
     switch (state.currentMode) {
130 136
       case DISPLAY_MODES.DAY:
@@ -140,12 +146,12 @@ class AnimatedBottomBar extends React.Component<PropsType, StateType> {
140 146
         newMode = DISPLAY_MODES.WEEK;
141 147
         break;
142 148
     }
143
-    this.setState({currentMode: newMode});
149
+    this.setState({ currentMode: newMode });
144 150
     props.onPress('changeView', newMode);
145 151
   };
146 152
 
147 153
   render() {
148
-    const {props, state} = this;
154
+    const { props, state } = this;
149 155
     const buttonColor = props.theme.colors.primary;
150 156
     return (
151 157
       <Animatable.View
@@ -154,7 +160,8 @@ class AnimatedBottomBar extends React.Component<PropsType, StateType> {
154 160
         style={{
155 161
           ...styles.container,
156 162
           bottom: 10 + CustomTabBar.TAB_BAR_HEIGHT,
157
-        }}>
163
+        }}
164
+      >
158 165
         <Surface style={styles.surface}>
159 166
           <View style={styles.fabContainer}>
160 167
             <AnimatedFAB
@@ -165,10 +172,10 @@ class AnimatedBottomBar extends React.Component<PropsType, StateType> {
165 172
               useNativeDriver
166 173
               style={styles.fab}
167 174
               icon="account-clock"
168
-              onPress={(): void => props.navigation.navigate('group-select')}
175
+              onPress={() => props.navigation.navigate('group-select')}
169 176
             />
170 177
           </View>
171
-          <View style={{flexDirection: 'row'}}>
178
+          <View style={styles.side}>
172 179
             <IconButton
173 180
               icon={this.displayModeIcons[state.currentMode]}
174 181
               color={buttonColor}
@@ -177,21 +184,21 @@ class AnimatedBottomBar extends React.Component<PropsType, StateType> {
177 184
             <IconButton
178 185
               icon="clock-in"
179 186
               color={buttonColor}
180
-              style={{marginLeft: 5}}
181
-              onPress={(): void => props.onPress('today')}
187
+              style={styles.icon}
188
+              onPress={() => props.onPress('today')}
182 189
             />
183 190
           </View>
184
-          <View style={{flexDirection: 'row'}}>
191
+          <View style={styles.side}>
185 192
             <IconButton
186 193
               icon="chevron-left"
187 194
               color={buttonColor}
188
-              onPress={(): void => props.onPress('prev')}
195
+              onPress={() => props.onPress('prev')}
189 196
             />
190 197
             <IconButton
191 198
               icon="chevron-right"
192 199
               color={buttonColor}
193
-              style={{marginLeft: 5}}
194
-              onPress={(): void => props.onPress('next')}
200
+              style={styles.icon}
201
+              onPress={() => props.onPress('next')}
195 202
             />
196 203
           </View>
197 204
         </Surface>

+ 5
- 4
src/components/Animations/AnimatedFAB.tsx View File

@@ -24,7 +24,7 @@ import {
24 24
   StyleSheet,
25 25
   View,
26 26
 } from 'react-native';
27
-import {FAB} from 'react-native-paper';
27
+import { FAB } from 'react-native-paper';
28 28
 import * as Animatable from 'react-native-animatable';
29 29
 import AutoHideHandler from '../../utils/AutoHideHandler';
30 30
 import CustomTabBar from '../Tabbar/CustomTabBar';
@@ -43,7 +43,7 @@ const styles = StyleSheet.create({
43 43
 });
44 44
 
45 45
 export default class AnimatedFAB extends React.Component<PropsType> {
46
-  ref: {current: null | (Animatable.View & View)};
46
+  ref: { current: null | (Animatable.View & View) };
47 47
 
48 48
   hideHandler: AutoHideHandler;
49 49
 
@@ -75,7 +75,7 @@ export default class AnimatedFAB extends React.Component<PropsType> {
75 75
   };
76 76
 
77 77
   render() {
78
-    const {props} = this;
78
+    const { props } = this;
79 79
     return (
80 80
       <Animatable.View
81 81
         ref={this.ref}
@@ -83,7 +83,8 @@ export default class AnimatedFAB extends React.Component<PropsType> {
83 83
         style={{
84 84
           ...styles.fab,
85 85
           bottom: CustomTabBar.TAB_BAR_HEIGHT,
86
-        }}>
86
+        }}
87
+      >
87 88
         <FAB icon={props.icon} onPress={props.onPress} />
88 89
       </Animatable.View>
89 90
     );

+ 21
- 10
src/components/Collapsible/CollapsibleComponent.tsx View File

@@ -18,19 +18,29 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {useCollapsibleStack} from 'react-navigation-collapsible';
21
+import { useCollapsibleStack } from 'react-navigation-collapsible';
22 22
 import CustomTabBar from '../Tabbar/CustomTabBar';
23
-import {NativeScrollEvent, NativeSyntheticEvent} from 'react-native';
23
+import {
24
+  NativeScrollEvent,
25
+  NativeSyntheticEvent,
26
+  StyleSheet,
27
+} from 'react-native';
24 28
 
25
-export interface CollapsibleComponentPropsType {
29
+export type CollapsibleComponentPropsType = {
26 30
   children?: React.ReactNode;
27 31
   hasTab?: boolean;
28 32
   onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
29
-}
33
+};
30 34
 
31
-interface PropsType extends CollapsibleComponentPropsType {
35
+type PropsType = CollapsibleComponentPropsType & {
32 36
   component: React.ComponentType<any>;
33
-}
37
+};
38
+
39
+const styles = StyleSheet.create({
40
+  main: {
41
+    minHeight: '100%',
42
+  },
43
+});
34 44
 
35 45
 function CollapsibleComponent(props: PropsType) {
36 46
   const onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
@@ -44,17 +54,18 @@ function CollapsibleComponent(props: PropsType) {
44 54
     scrollIndicatorInsetTop,
45 55
     onScrollWithListener,
46 56
   } = useCollapsibleStack();
47
-
57
+  const paddingBottom = props.hasTab ? CustomTabBar.TAB_BAR_HEIGHT : 0;
48 58
   return (
49 59
     <Comp
50 60
       {...props}
51 61
       onScroll={onScrollWithListener(onScroll)}
52 62
       contentContainerStyle={{
53 63
         paddingTop: containerPaddingTop,
54
-        paddingBottom: props.hasTab ? CustomTabBar.TAB_BAR_HEIGHT : 0,
55
-        minHeight: '100%',
64
+        paddingBottom: paddingBottom,
65
+        ...styles.main,
56 66
       }}
57
-      scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}>
67
+      scrollIndicatorInsets={{ top: scrollIndicatorInsetTop }}
68
+    >
58 69
       {props.children}
59 70
     </Comp>
60 71
   );

+ 2
- 2
src/components/Collapsible/CollapsibleFlatList.tsx View File

@@ -18,8 +18,8 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {Animated, FlatListProps} from 'react-native';
22
-import type {CollapsibleComponentPropsType} from './CollapsibleComponent';
21
+import { Animated, FlatListProps } from 'react-native';
22
+import type { CollapsibleComponentPropsType } from './CollapsibleComponent';
23 23
 import CollapsibleComponent from './CollapsibleComponent';
24 24
 
25 25
 type Props<T> = FlatListProps<T> & CollapsibleComponentPropsType;

+ 2
- 2
src/components/Collapsible/CollapsibleScrollView.tsx View File

@@ -18,8 +18,8 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {Animated, ScrollViewProps} from 'react-native';
22
-import type {CollapsibleComponentPropsType} from './CollapsibleComponent';
21
+import { Animated, ScrollViewProps } from 'react-native';
22
+import type { CollapsibleComponentPropsType } from './CollapsibleComponent';
23 23
 import CollapsibleComponent from './CollapsibleComponent';
24 24
 
25 25
 type Props = ScrollViewProps & CollapsibleComponentPropsType;

+ 2
- 2
src/components/Collapsible/CollapsibleSectionList.tsx View File

@@ -18,8 +18,8 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {Animated, SectionListProps} from 'react-native';
22
-import type {CollapsibleComponentPropsType} from './CollapsibleComponent';
21
+import { Animated, SectionListProps } from 'react-native';
22
+import type { CollapsibleComponentPropsType } from './CollapsibleComponent';
23 23
 import CollapsibleComponent from './CollapsibleComponent';
24 24
 
25 25
 type Props<T> = SectionListProps<T> & CollapsibleComponentPropsType;

+ 1
- 1
src/components/Dialogs/AlertDialog.tsx View File

@@ -18,7 +18,7 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {Button, Dialog, Paragraph, Portal} from 'react-native-paper';
21
+import { Button, Dialog, Paragraph, Portal } from 'react-native-paper';
22 22
 import i18n from 'i18n-js';
23 23
 
24 24
 type PropsType = {

+ 1
- 1
src/components/Dialogs/ErrorDialog.tsx View File

@@ -19,7 +19,7 @@
19 19
 
20 20
 import * as React from 'react';
21 21
 import i18n from 'i18n-js';
22
-import {ERROR_TYPE} from '../../utils/WebData';
22
+import { ERROR_TYPE } from '../../utils/WebData';
23 23
 import AlertDialog from './AlertDialog';
24 24
 
25 25
 type PropsType = {

+ 13
- 6
src/components/Dialogs/LoadingConfirmDialog.tsx View File

@@ -26,6 +26,7 @@ import {
26 26
   Portal,
27 27
 } from 'react-native-paper';
28 28
 import i18n from 'i18n-js';
29
+import { StyleSheet } from 'react-native';
29 30
 
30 31
 type PropsType = {
31 32
   visible: boolean;
@@ -41,6 +42,12 @@ type StateType = {
41 42
   loading: boolean;
42 43
 };
43 44
 
45
+const styles = StyleSheet.create({
46
+  button: {
47
+    marginRight: 10,
48
+  },
49
+});
50
+
44 51
 export default class LoadingConfirmDialog extends React.PureComponent<
45 52
   PropsType,
46 53
   StateType
@@ -70,8 +77,8 @@ export default class LoadingConfirmDialog extends React.PureComponent<
70 77
    * Set the dialog into loading state and closes it when operation finishes
71 78
    */
72 79
   onClickAccept = () => {
73
-    const {props} = this;
74
-    this.setState({loading: true});
80
+    const { props } = this;
81
+    this.setState({ loading: true });
75 82
     if (props.onAccept != null) {
76 83
       props.onAccept().then(this.hideLoading);
77 84
     }
@@ -83,21 +90,21 @@ export default class LoadingConfirmDialog extends React.PureComponent<
83 90
    */
84 91
   hideLoading = (): NodeJS.Timeout =>
85 92
     setTimeout(() => {
86
-      this.setState({loading: false});
93
+      this.setState({ loading: false });
87 94
     }, 200);
88 95
 
89 96
   /**
90 97
    * Hide the dialog if it is not loading
91 98
    */
92 99
   onDismiss = () => {
93
-    const {state, props} = this;
100
+    const { state, props } = this;
94 101
     if (!state.loading && props.onDismiss != null) {
95 102
       props.onDismiss();
96 103
     }
97 104
   };
98 105
 
99 106
   render() {
100
-    const {state, props} = this;
107
+    const { state, props } = this;
101 108
     return (
102 109
       <Portal>
103 110
         <Dialog visible={props.visible} onDismiss={this.onDismiss}>
@@ -113,7 +120,7 @@ export default class LoadingConfirmDialog extends React.PureComponent<
113 120
           </Dialog.Content>
114 121
           {state.loading ? null : (
115 122
             <Dialog.Actions>
116
-              <Button onPress={this.onDismiss} style={{marginRight: 10}}>
123
+              <Button onPress={this.onDismiss} style={styles.button}>
117 124
                 {i18n.t('dialog.cancel')}
118 125
               </Button>
119 126
               <Button onPress={this.onClickAccept}>

+ 3
- 3
src/components/Dialogs/OptionsDialog.tsx View File

@@ -18,8 +18,8 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {Button, Dialog, Paragraph, Portal} from 'react-native-paper';
22
-import {FlatList} from 'react-native';
21
+import { Button, Dialog, Paragraph, Portal } from 'react-native-paper';
22
+import { FlatList } from 'react-native';
23 23
 
24 24
 export type OptionsDialogButtonType = {
25 25
   title: string;
@@ -36,7 +36,7 @@ type PropsType = {
36 36
 };
37 37
 
38 38
 function OptionsDialog(props: PropsType) {
39
-  const getButtonRender = ({item}: {item: OptionsDialogButtonType}) => {
39
+  const getButtonRender = ({ item }: { item: OptionsDialogButtonType }) => {
40 40
     return (
41 41
       <Button onPress={item.onPress} icon={item.icon}>
42 42
         {item.title}

+ 13
- 9
src/components/Home/ActionsDashboardItem.tsx View File

@@ -18,10 +18,19 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {List} from 'react-native-paper';
22
-import {View} from 'react-native';
21
+import { List } from 'react-native-paper';
22
+import { StyleSheet, View } from 'react-native';
23 23
 import i18n from 'i18n-js';
24
-import {useNavigation} from '@react-navigation/native';
24
+import { useNavigation } from '@react-navigation/native';
25
+
26
+const styles = StyleSheet.create({
27
+  item: {
28
+    paddingTop: 0,
29
+    paddingBottom: 0,
30
+    marginLeft: 10,
31
+    marginRight: 10,
32
+  },
33
+});
25 34
 
26 35
 function ActionsDashBoardItem() {
27 36
   const navigation = useNavigation();
@@ -45,12 +54,7 @@ function ActionsDashBoardItem() {
45 54
           />
46 55
         )}
47 56
         onPress={(): void => navigation.navigate('feedback')}
48
-        style={{
49
-          paddingTop: 0,
50
-          paddingBottom: 0,
51
-          marginLeft: 10,
52
-          marginRight: 10,
53
-        }}
57
+        style={styles.item}
54 58
       />
55 59
     </View>
56 60
   );

+ 9
- 5
src/components/Home/EventDashboardItem.tsx View File

@@ -25,8 +25,9 @@ import {
25 25
   TouchableRipple,
26 26
   useTheme,
27 27
 } from 'react-native-paper';
28
-import {StyleSheet, View} from 'react-native';
28
+import { StyleSheet, View } from 'react-native';
29 29
 import i18n from 'i18n-js';
30
+import GENERAL_STYLES from '../../constants/Styles';
30 31
 
31 32
 type PropsType = {
32 33
   eventNumber: number;
@@ -45,6 +46,9 @@ const styles = StyleSheet.create({
45 46
   avatar: {
46 47
     backgroundColor: 'transparent',
47 48
   },
49
+  text: {
50
+    fontWeight: 'bold',
51
+  },
48 52
 });
49 53
 
50 54
 /**
@@ -61,7 +65,7 @@ function EventDashBoardItem(props: PropsType) {
61 65
   if (isAvailable) {
62 66
     subtitle = (
63 67
       <Text>
64
-        <Text style={{fontWeight: 'bold'}}>{props.eventNumber}</Text>
68
+        <Text style={styles.text}>{props.eventNumber}</Text>
65 69
         <Text>
66 70
           {props.eventNumber > 1
67 71
             ? i18n.t('screens.home.dashboard.todayEventsSubtitlePlural')
@@ -74,13 +78,13 @@ function EventDashBoardItem(props: PropsType) {
74 78
   }
75 79
   return (
76 80
     <Card style={styles.card}>
77
-      <TouchableRipple style={{flex: 1}} onPress={props.clickAction}>
81
+      <TouchableRipple style={GENERAL_STYLES.flex} onPress={props.clickAction}>
78 82
         <View>
79 83
           <Card.Title
80 84
             title={i18n.t('screens.home.dashboard.todayEventsTitle')}
81
-            titleStyle={{color: textColor}}
85
+            titleStyle={{ color: textColor }}
82 86
             subtitle={subtitle}
83
-            subtitleStyle={{color: textColor}}
87
+            subtitleStyle={{ color: textColor }}
84 88
             left={(iconProps) => (
85 89
               <Avatar.Icon
86 90
                 icon="calendar-range"

+ 31
- 24
src/components/Home/FeedItem.tsx View File

@@ -18,17 +18,18 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {Button, Card, Text, TouchableRipple} from 'react-native-paper';
22
-import {Image, View} from 'react-native';
21
+import { Button, Card, Text, TouchableRipple } from 'react-native-paper';
22
+import { Image, StyleSheet, View } from 'react-native';
23 23
 import Autolink from 'react-native-autolink';
24 24
 import i18n from 'i18n-js';
25
-import type {FeedItemType} from '../../screens/Home/HomeScreen';
25
+import type { FeedItemType } from '../../screens/Home/HomeScreen';
26 26
 import NewsSourcesConstants, {
27 27
   AvailablePages,
28 28
 } from '../../constants/NewsSourcesConstants';
29
-import type {NewsSourceType} from '../../constants/NewsSourcesConstants';
29
+import type { NewsSourceType } from '../../constants/NewsSourcesConstants';
30 30
 import ImageGalleryButton from '../Media/ImageGalleryButton';
31
-import {useNavigation} from '@react-navigation/native';
31
+import { useNavigation } from '@react-navigation/native';
32
+import GENERAL_STYLES from '../../constants/Styles';
32 33
 
33 34
 type PropsType = {
34 35
   item: FeedItemType;
@@ -46,6 +47,20 @@ function getFormattedDate(dateString: number): string {
46 47
   return date.toLocaleString();
47 48
 }
48 49
 
50
+const styles = StyleSheet.create({
51
+  image: {
52
+    width: 48,
53
+    height: 48,
54
+  },
55
+  button: {
56
+    marginLeft: 'auto',
57
+    marginRight: 'auto',
58
+  },
59
+  action: {
60
+    marginLeft: 'auto',
61
+  },
62
+});
63
+
49 64
 /**
50 65
  * Component used to display a feed item
51 66
  */
@@ -58,7 +73,7 @@ function FeedItem(props: PropsType) {
58 73
     });
59 74
   };
60 75
 
61
-  const {item, height} = props;
76
+  const { item, height } = props;
62 77
   const image = item.image !== '' && item.image != null ? item.image : null;
63 78
   const pageSource: NewsSourceType =
64 79
     NewsSourcesConstants[item.page_id as AvailablePages];
@@ -76,31 +91,23 @@ function FeedItem(props: PropsType) {
76 91
       style={{
77 92
         margin: cardMargin,
78 93
         height: cardHeight,
79
-      }}>
80
-      <TouchableRipple style={{flex: 1}} onPress={onPress}>
94
+      }}
95
+    >
96
+      <TouchableRipple style={GENERAL_STYLES.flex} onPress={onPress}>
81 97
         <View>
82 98
           <Card.Title
83 99
             title={pageSource.name}
84 100
             subtitle={getFormattedDate(item.time)}
85
-            left={() => (
86
-              <Image
87
-                source={pageSource.icon}
88
-                style={{
89
-                  width: 48,
90
-                  height: 48,
91
-                }}
92
-              />
93
-            )}
94
-            style={{height: titleHeight}}
101
+            left={() => <Image source={pageSource.icon} style={styles.image} />}
102
+            style={{ height: titleHeight }}
95 103
           />
96 104
           {image != null ? (
97 105
             <ImageGalleryButton
98
-              images={[{url: image}]}
106
+              images={[{ url: image }]}
99 107
               style={{
108
+                ...styles.button,
100 109
                 width: imageSize,
101 110
                 height: imageSize,
102
-                marginLeft: 'auto',
103
-                marginRight: 'auto',
104 111
               }}
105 112
             />
106 113
           ) : null}
@@ -110,12 +117,12 @@ function FeedItem(props: PropsType) {
110 117
                 text={item.message}
111 118
                 hashtag="facebook"
112 119
                 component={Text}
113
-                style={{height: textHeight}}
120
+                style={{ height: textHeight }}
114 121
               />
115 122
             ) : null}
116 123
           </Card.Content>
117
-          <Card.Actions style={{height: actionsHeight}}>
118
-            <Button onPress={onPress} icon="plus" style={{marginLeft: 'auto'}}>
124
+          <Card.Actions style={{ height: actionsHeight }}>
125
+            <Button onPress={onPress} icon="plus" style={styles.action}>
119 126
               {i18n.t('screens.home.dashboard.seeMore')}
120 127
             </Button>
121 128
           </Card.Actions>

+ 15
- 7
src/components/Home/PreviewEventDashboardItem.tsx View File

@@ -18,12 +18,13 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {StyleSheet, View} from 'react-native';
21
+import { StyleSheet, View } from 'react-native';
22 22
 import i18n from 'i18n-js';
23
-import {Avatar, Button, Card, TouchableRipple} from 'react-native-paper';
24
-import {getTimeOnlyString, isDescriptionEmpty} from '../../utils/Planning';
23
+import { Avatar, Button, Card, TouchableRipple } from 'react-native-paper';
24
+import { getTimeOnlyString, isDescriptionEmpty } from '../../utils/Planning';
25 25
 import CustomHTML from '../Overrides/CustomHTML';
26
-import type {PlanningEventType} from '../../utils/Planning';
26
+import type { PlanningEventType } from '../../utils/Planning';
27
+import GENERAL_STYLES from '../../constants/Styles';
27 28
 
28 29
 type PropsType = {
29 30
   event?: PlanningEventType | null;
@@ -52,19 +53,26 @@ const styles = StyleSheet.create({
52 53
  * Component used to display an event preview if an event is available
53 54
  */
54 55
 function PreviewEventDashboardItem(props: PropsType) {
55
-  const {event} = props;
56
+  const { event } = props;
56 57
   const isEmpty = event == null ? true : isDescriptionEmpty(event.description);
57 58
 
58 59
   if (event != null) {
59 60
     const logo = event.logo;
60 61
     const getImage = logo
61 62
       ? () => (
62
-          <Avatar.Image source={{uri: logo}} size={50} style={styles.avatar} />
63
+          <Avatar.Image
64
+            source={{ uri: logo }}
65
+            size={50}
66
+            style={styles.avatar}
67
+          />
63 68
         )
64 69
       : () => null;
65 70
     return (
66 71
       <Card style={styles.card} elevation={3}>
67
-        <TouchableRipple style={{flex: 1}} onPress={props.clickAction}>
72
+        <TouchableRipple
73
+          style={GENERAL_STYLES.flex}
74
+          onPress={props.clickAction}
75
+        >
68 76
           <View>
69 77
             <Card.Title
70 78
               title={event.title}

+ 33
- 21
src/components/Home/SmallDashboardItem.tsx View File

@@ -18,8 +18,8 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {Badge, TouchableRipple, useTheme} from 'react-native-paper';
22
-import {Dimensions, Image, View} from 'react-native';
21
+import { Badge, TouchableRipple, useTheme } from 'react-native-paper';
22
+import { Dimensions, Image, StyleSheet, View } from 'react-native';
23 23
 import * as Animatable from 'react-native-animatable';
24 24
 
25 25
 type PropsType = {
@@ -28,13 +28,32 @@ type PropsType = {
28 28
   badgeCount?: number;
29 29
 };
30 30
 
31
+const styles = StyleSheet.create({
32
+  image: {
33
+    width: '80%',
34
+    height: '80%',
35
+    marginLeft: 'auto',
36
+    marginRight: 'auto',
37
+    marginTop: 'auto',
38
+    marginBottom: 'auto',
39
+  },
40
+  badgeContainer: {
41
+    position: 'absolute',
42
+    top: 0,
43
+    right: 0,
44
+  },
45
+  badge: {
46
+    borderWidth: 2,
47
+  },
48
+});
49
+
31 50
 /**
32 51
  * Component used to render a small dashboard item
33 52
  */
34 53
 function SmallDashboardItem(props: PropsType) {
35 54
   const itemSize = Dimensions.get('window').width / 8;
36 55
   const theme = useTheme();
37
-  const {image} = props;
56
+  const { image } = props;
38 57
   return (
39 58
     <TouchableRipple
40 59
       onPress={props.onPress}
@@ -42,23 +61,18 @@ function SmallDashboardItem(props: PropsType) {
42 61
       style={{
43 62
         marginLeft: itemSize / 6,
44 63
         marginRight: itemSize / 6,
45
-      }}>
64
+      }}
65
+    >
46 66
       <View
47 67
         style={{
48 68
           width: itemSize,
49 69
           height: itemSize,
50
-        }}>
70
+        }}
71
+      >
51 72
         {image ? (
52 73
           <Image
53
-            source={typeof image === 'string' ? {uri: image} : image}
54
-            style={{
55
-              width: '80%',
56
-              height: '80%',
57
-              marginLeft: 'auto',
58
-              marginRight: 'auto',
59
-              marginTop: 'auto',
60
-              marginBottom: 'auto',
61
-            }}
74
+            source={typeof image === 'string' ? { uri: image } : image}
75
+            style={styles.image}
62 76
           />
63 77
         ) : null}
64 78
         {props.badgeCount != null && props.badgeCount > 0 ? (
@@ -66,18 +80,16 @@ function SmallDashboardItem(props: PropsType) {
66 80
             animation="zoomIn"
67 81
             duration={300}
68 82
             useNativeDriver
69
-            style={{
70
-              position: 'absolute',
71
-              top: 0,
72
-              right: 0,
73
-            }}>
83
+            style={styles.badgeContainer}
84
+          >
74 85
             <Badge
75 86
               visible={true}
76 87
               style={{
77 88
                 backgroundColor: theme.colors.primary,
78 89
                 borderColor: theme.colors.background,
79
-                borderWidth: 2,
80
-              }}>
90
+                ...styles.badge,
91
+              }}
92
+            >
81 93
               {props.badgeCount}
82 94
             </Badge>
83 95
           </Animatable.View>

+ 3
- 2
src/components/Intro/IconIntro.tsx View File

@@ -18,9 +18,10 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {StyleSheet, View} from 'react-native';
21
+import { StyleSheet, View } from 'react-native';
22 22
 import * as Animatable from 'react-native-animatable';
23 23
 import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
24
+import GENERAL_STYLES from '../../constants/Styles';
24 25
 
25 26
 type PropsType = {
26 27
   icon: string;
@@ -37,7 +38,7 @@ const styles = StyleSheet.create({
37 38
 
38 39
 function IntroIcon(props: PropsType) {
39 40
   return (
40
-    <View style={{flex: 1}}>
41
+    <View style={GENERAL_STYLES.flex}>
41 42
       <Animatable.View useNativeDriver style={styles.center} animation="fadeIn">
42 43
         <MaterialCommunityIcons name={props.icon} color="#fff" size={200} />
43 44
       </Animatable.View>

+ 6
- 8
src/components/Intro/MascotIntroEnd.tsx View File

@@ -18,25 +18,23 @@
18 18
  */
19 19
 
20 20
 import * as React from 'react';
21
-import {StyleSheet, View} from 'react-native';
22
-import Mascot, {MASCOT_STYLE} from '../Mascot/Mascot';
21
+import { StyleSheet, View } from 'react-native';
22
+import GENERAL_STYLES from '../../constants/Styles';
23
+import Mascot, { MASCOT_STYLE } from '../Mascot/Mascot';
23 24
 
24 25
 const styles = StyleSheet.create({
25 26
   center: {
26
-    marginTop: 'auto',
27
-    marginBottom: 'auto',
28
-    marginRight: 'auto',
29
-    marginLeft: 'auto',
27
+    ...GENERAL_STYLES.center,
28
+    width: '80%',
30 29
   },
31 30
 });
32 31