Browse Source

Update Proximo screens to use TypeScript

Arnaud Vergnet 3 years ago
parent
commit
2eb4a3e0c1

+ 0
- 83
src/screens/Services/Proximo/ProximoAboutScreen.js View File

@@ -1,83 +0,0 @@
1
-/*
2
- * Copyright (c) 2019 - 2020 Arnaud Vergnet.
3
- *
4
- * This file is part of Campus INSAT.
5
- *
6
- * Campus INSAT is free software: you can redistribute it and/or modify
7
- *  it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation, either version 3 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * Campus INSAT is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18
- */
19
-
20
-// @flow
21
-
22
-import * as React from 'react';
23
-import {Image, View} from 'react-native';
24
-import i18n from 'i18n-js';
25
-import {Card, Avatar, Paragraph, Text} from 'react-native-paper';
26
-import CustomTabBar from '../../../components/Tabbar/CustomTabBar';
27
-import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
28
-import type {CardTitleIconPropsType} from '../../../constants/PaperStyles';
29
-
30
-const LOGO = 'https://etud.insa-toulouse.fr/~amicale_app/images/Proximo.png';
31
-
32
-/**
33
- * Class defining the proximo about screen.
34
- */
35
-// eslint-disable-next-line react/prefer-stateless-function
36
-export default class ProximoAboutScreen extends React.Component<null> {
37
-  render(): React.Node {
38
-    return (
39
-      <CollapsibleScrollView style={{padding: 5}}>
40
-        <View
41
-          style={{
42
-            width: '100%',
43
-            height: 100,
44
-            marginTop: 20,
45
-            marginBottom: 20,
46
-            justifyContent: 'center',
47
-            alignItems: 'center',
48
-          }}>
49
-          <Image
50
-            source={{uri: LOGO}}
51
-            style={{height: '100%', width: '100%', resizeMode: 'contain'}}
52
-          />
53
-        </View>
54
-        <Text>{i18n.t('screens.proximo.description')}</Text>
55
-        <Card style={{margin: 5}}>
56
-          <Card.Title
57
-            title={i18n.t('screens.proximo.openingHours')}
58
-            left={(iconProps: CardTitleIconPropsType): React.Node => (
59
-              <Avatar.Icon size={iconProps.size} icon="clock-outline" />
60
-            )}
61
-          />
62
-          <Card.Content>
63
-            <Paragraph>18h30 - 19h30</Paragraph>
64
-          </Card.Content>
65
-        </Card>
66
-        <Card
67
-          style={{margin: 5, marginBottom: CustomTabBar.TAB_BAR_HEIGHT + 20}}>
68
-          <Card.Title
69
-            title={i18n.t('screens.proximo.paymentMethods')}
70
-            left={(iconProps: CardTitleIconPropsType): React.Node => (
71
-              <Avatar.Icon size={iconProps.size} icon="cash" />
72
-            )}
73
-          />
74
-          <Card.Content>
75
-            <Paragraph>
76
-              {i18n.t('screens.proximo.paymentMethodsDescription')}
77
-            </Paragraph>
78
-          </Card.Content>
79
-        </Card>
80
-      </CollapsibleScrollView>
81
-    );
82
-  }
83
-}

+ 78
- 0
src/screens/Services/Proximo/ProximoAboutScreen.tsx View File

@@ -0,0 +1,78 @@
1
+/*
2
+ * Copyright (c) 2019 - 2020 Arnaud Vergnet.
3
+ *
4
+ * This file is part of Campus INSAT.
5
+ *
6
+ * Campus INSAT is free software: you can redistribute it and/or modify
7
+ *  it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * Campus INSAT is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18
+ */
19
+
20
+// @flow
21
+
22
+import * as React from 'react';
23
+import {Image, View} from 'react-native';
24
+import i18n from 'i18n-js';
25
+import {Card, Avatar, Paragraph, Text} from 'react-native-paper';
26
+import CustomTabBar from '../../../components/Tabbar/CustomTabBar';
27
+import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
28
+
29
+const LOGO = 'https://etud.insa-toulouse.fr/~amicale_app/images/Proximo.png';
30
+
31
+/**
32
+ * Class defining the proximo about screen.
33
+ */
34
+export default function ProximoAboutScreen() {
35
+  return (
36
+    <CollapsibleScrollView style={{padding: 5}}>
37
+      <View
38
+        style={{
39
+          width: '100%',
40
+          height: 100,
41
+          marginTop: 20,
42
+          marginBottom: 20,
43
+          justifyContent: 'center',
44
+          alignItems: 'center',
45
+        }}>
46
+        <Image
47
+          source={{uri: LOGO}}
48
+          style={{height: '100%', width: '100%', resizeMode: 'contain'}}
49
+        />
50
+      </View>
51
+      <Text>{i18n.t('screens.proximo.description')}</Text>
52
+      <Card style={{margin: 5}}>
53
+        <Card.Title
54
+          title={i18n.t('screens.proximo.openingHours')}
55
+          left={(iconProps) => (
56
+            <Avatar.Icon size={iconProps.size} icon="clock-outline" />
57
+          )}
58
+        />
59
+        <Card.Content>
60
+          <Paragraph>18h30 - 19h30</Paragraph>
61
+        </Card.Content>
62
+      </Card>
63
+      <Card style={{margin: 5, marginBottom: CustomTabBar.TAB_BAR_HEIGHT + 20}}>
64
+        <Card.Title
65
+          title={i18n.t('screens.proximo.paymentMethods')}
66
+          left={(iconProps) => (
67
+            <Avatar.Icon size={iconProps.size} icon="cash" />
68
+          )}
69
+        />
70
+        <Card.Content>
71
+          <Paragraph>
72
+            {i18n.t('screens.proximo.paymentMethodsDescription')}
73
+          </Paragraph>
74
+        </Card.Content>
75
+      </Card>
76
+    </CollapsibleScrollView>
77
+  );
78
+}

src/screens/Services/Proximo/ProximoListScreen.js → src/screens/Services/Proximo/ProximoListScreen.tsx View File

@@ -17,8 +17,6 @@
17 17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18 18
  */
19 19
 
20
-// @flow
21
-
22 20
 import * as React from 'react';
23 21
 import {Image, Platform, ScrollView, View} from 'react-native';
24 22
 import i18n from 'i18n-js';
@@ -38,7 +36,6 @@ import ProximoListItem from '../../../components/Lists/Proximo/ProximoListItem';
38 36
 import MaterialHeaderButtons, {
39 37
   Item,
40 38
 } from '../../../components/Overrides/CustomHeaderButton';
41
-import type {CustomThemeType} from '../../../managers/ThemeManager';
42 39
 import CollapsibleFlatList from '../../../components/Collapsible/CollapsibleFlatList';
43 40
 import type {ProximoArticleType} from './ProximoMainScreen';
44 41
 
@@ -54,34 +51,42 @@ function sortPriceReverse(
54 51
 }
55 52
 
56 53
 function sortName(a: ProximoArticleType, b: ProximoArticleType): number {
57
-  if (a.name.toLowerCase() < b.name.toLowerCase()) return -1;
58
-  if (a.name.toLowerCase() > b.name.toLowerCase()) return 1;
54
+  if (a.name.toLowerCase() < b.name.toLowerCase()) {
55
+    return -1;
56
+  }
57
+  if (a.name.toLowerCase() > b.name.toLowerCase()) {
58
+    return 1;
59
+  }
59 60
   return 0;
60 61
 }
61 62
 
62 63
 function sortNameReverse(a: ProximoArticleType, b: ProximoArticleType): number {
63
-  if (a.name.toLowerCase() < b.name.toLowerCase()) return 1;
64
-  if (a.name.toLowerCase() > b.name.toLowerCase()) return -1;
64
+  if (a.name.toLowerCase() < b.name.toLowerCase()) {
65
+    return 1;
66
+  }
67
+  if (a.name.toLowerCase() > b.name.toLowerCase()) {
68
+    return -1;
69
+  }
65 70
   return 0;
66 71
 }
67 72
 
68 73
 const LIST_ITEM_HEIGHT = 84;
69 74
 
70 75
 type PropsType = {
71
-  navigation: StackNavigationProp,
76
+  navigation: StackNavigationProp<any>;
72 77
   route: {
73 78
     params: {
74
-      data: {data: Array<ProximoArticleType>},
75
-      shouldFocusSearchBar: boolean,
76
-    },
77
-  },
78
-  theme: CustomThemeType,
79
+      data: {data: Array<ProximoArticleType>};
80
+      shouldFocusSearchBar: boolean;
81
+    };
82
+  };
83
+  theme: ReactNativePaper.Theme;
79 84
 };
80 85
 
81 86
 type StateType = {
82
-  currentSortMode: number,
83
-  modalCurrentDisplayItem: React.Node,
84
-  currentSearchString: string,
87
+  currentSortMode: number;
88
+  modalCurrentDisplayItem: React.ReactNode;
89
+  currentSearchString: string;
85 90
 };
86 91
 
87 92
 /**
@@ -96,6 +101,7 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
96 101
 
97 102
   constructor(props: PropsType) {
98 103
     super(props);
104
+    this.modalRef = null;
99 105
     this.listData = props.route.params.data.data.sort(sortName);
100 106
     this.shouldFocusSearchBar = props.route.params.shouldFocusSearchBar;
101 107
     this.state = {
@@ -186,7 +192,9 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
186 192
         this.listData.sort(sortName);
187 193
         break;
188 194
     }
189
-    if (this.modalRef && currentMode !== currentSortMode) this.modalRef.close();
195
+    if (this.modalRef && currentMode !== currentSortMode) {
196
+      this.modalRef.close();
197
+    }
190 198
   }
191 199
 
192 200
   /**
@@ -198,9 +206,13 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
198 206
   getStockColor(availableStock: number): string {
199 207
     const {theme} = this.props;
200 208
     let color: string;
201
-    if (availableStock > 3) color = theme.colors.success;
202
-    else if (availableStock > 0) color = theme.colors.warning;
203
-    else color = theme.colors.danger;
209
+    if (availableStock > 3) {
210
+      color = theme.colors.success;
211
+    } else if (availableStock > 0) {
212
+      color = theme.colors.warning;
213
+    } else {
214
+      color = theme.colors.danger;
215
+    }
204 216
     return color;
205 217
   }
206 218
 
@@ -209,7 +221,7 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
209 221
    *
210 222
    * @return {*}
211 223
    */
212
-  getSortMenuButton = (): React.Node => {
224
+  getSortMenuButton = () => {
213 225
     return (
214 226
       <MaterialHeaderButtons>
215 227
         <Item title="main" iconName="sort" onPress={this.onSortMenuPress} />
@@ -222,8 +234,9 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
222 234
    *
223 235
    * @return {*}
224 236
    */
225
-  getSearchBar = (): React.Node => {
237
+  getSearchBar = () => {
226 238
     return (
239
+      // @ts-ignore
227 240
       <Searchbar
228 241
         placeholder={i18n.t('screens.proximo.search')}
229 242
         onChangeText={this.onSearchStringChange}
@@ -237,7 +250,7 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
237 250
    * @param item The article to display
238 251
    * @return {*}
239 252
    */
240
-  getModalItemContent(item: ProximoArticleType): React.Node {
253
+  getModalItemContent(item: ProximoArticleType) {
241 254
     return (
242 255
       <View
243 256
         style={{
@@ -284,7 +297,7 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
284 297
    *
285 298
    * @return {*}
286 299
    */
287
-  getModalSortMenu(): React.Node {
300
+  getModalSortMenu() {
288 301
     const {currentSortMode} = this.state;
289 302
     return (
290 303
       <View
@@ -299,22 +312,22 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
299 312
           onValueChange={(value: string) => {
300 313
             this.setSortMode(value);
301 314
           }}
302
-          value={currentSortMode}>
315
+          value={currentSortMode.toString()}>
303 316
           <RadioButton.Item
304 317
             label={i18n.t('screens.proximo.sortPrice')}
305
-            value={1}
318
+            value={'1'}
306 319
           />
307 320
           <RadioButton.Item
308 321
             label={i18n.t('screens.proximo.sortPriceReverse')}
309
-            value={2}
322
+            value={'2'}
310 323
           />
311 324
           <RadioButton.Item
312 325
             label={i18n.t('screens.proximo.sortName')}
313
-            value={3}
326
+            value={'3'}
314 327
           />
315 328
           <RadioButton.Item
316 329
             label={i18n.t('screens.proximo.sortNameReverse')}
317
-            value={4}
330
+            value={'4'}
318 331
           />
319 332
         </RadioButton.Group>
320 333
       </View>
@@ -327,7 +340,7 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
327 340
    * @param item The article to render
328 341
    * @return {*}
329 342
    */
330
-  getRenderItem = ({item}: {item: ProximoArticleType}): React.Node => {
343
+  getRenderItem = ({item}: {item: ProximoArticleType}) => {
331 344
     const {currentSearchString} = this.state;
332 345
     if (stringMatchQuery(item.name, currentSearchString)) {
333 346
       const onPress = () => {
@@ -364,15 +377,15 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
364 377
   };
365 378
 
366 379
   itemLayout = (
367
-    data: ProximoArticleType,
380
+    data: Array<ProximoArticleType> | null | undefined,
368 381
     index: number,
369
-  ): {length: number, offset: number, index: number} => ({
382
+  ): {length: number; offset: number; index: number} => ({
370 383
     length: LIST_ITEM_HEIGHT,
371 384
     offset: LIST_ITEM_HEIGHT * index,
372 385
     index,
373 386
   });
374 387
 
375
-  render(): React.Node {
388
+  render() {
376 389
     const {state} = this;
377 390
     return (
378 391
       <View

src/screens/Services/Proximo/ProximoMainScreen.js → src/screens/Services/Proximo/ProximoMainScreen.tsx View File

@@ -27,43 +27,41 @@ import WebSectionList from '../../../components/Screens/WebSectionList';
27 27
 import MaterialHeaderButtons, {
28 28
   Item,
29 29
 } from '../../../components/Overrides/CustomHeaderButton';
30
-import type {CustomThemeType} from '../../../managers/ThemeManager';
31 30
 import type {SectionListDataType} from '../../../components/Screens/WebSectionList';
32
-import type {ListIconPropsType} from '../../../constants/PaperStyles';
33 31
 
34 32
 const DATA_URL = 'https://etud.insa-toulouse.fr/~proximo/data/stock-v2.json';
35 33
 const LIST_ITEM_HEIGHT = 84;
36 34
 
37 35
 export type ProximoCategoryType = {
38
-  name: string,
39
-  icon: string,
40
-  id: string,
36
+  name: string;
37
+  icon: string;
38
+  id: string;
41 39
 };
42 40
 
43 41
 export type ProximoArticleType = {
44
-  name: string,
45
-  description: string,
46
-  quantity: string,
47
-  price: string,
48
-  code: string,
49
-  id: string,
50
-  type: Array<string>,
51
-  image: string,
42
+  name: string;
43
+  description: string;
44
+  quantity: string;
45
+  price: string;
46
+  code: string;
47
+  id: string;
48
+  type: Array<string>;
49
+  image: string;
52 50
 };
53 51
 
54 52
 export type ProximoMainListItemType = {
55
-  type: ProximoCategoryType,
56
-  data: Array<ProximoArticleType>,
53
+  type: ProximoCategoryType;
54
+  data: Array<ProximoArticleType>;
57 55
 };
58 56
 
59 57
 export type ProximoDataType = {
60
-  types: Array<ProximoCategoryType>,
61
-  articles: Array<ProximoArticleType>,
58
+  types: Array<ProximoCategoryType>;
59
+  articles: Array<ProximoArticleType>;
62 60
 };
63 61
 
64 62
 type PropsType = {
65
-  navigation: StackNavigationProp,
66
-  theme: CustomThemeType,
63
+  navigation: StackNavigationProp<any>;
64
+  theme: ReactNativePaper.Theme;
67 65
 };
68 66
 
69 67
 /**
@@ -87,12 +85,20 @@ class ProximoMainScreen extends React.Component<PropsType> {
87 85
     const str2 = b.type.name.toLowerCase();
88 86
 
89 87
     // Make 'All' category with id -1 stick to the top
90
-    if (a.type.id === -1) return -1;
91
-    if (b.type.id === -1) return 1;
88
+    if (a.type.id === '-1') {
89
+      return -1;
90
+    }
91
+    if (b.type.id === '-1') {
92
+      return 1;
93
+    }
92 94
 
93 95
     // Sort others by name ascending
94
-    if (str1 < str2) return -1;
95
-    if (str1 > str2) return 1;
96
+    if (str1 < str2) {
97
+      return -1;
98
+    }
99
+    if (str1 > str2) {
100
+      return 1;
101
+    }
96 102
     return 0;
97 103
   }
98 104
 
@@ -105,16 +111,17 @@ class ProximoMainScreen extends React.Component<PropsType> {
105 111
    */
106 112
   static getAvailableArticles(
107 113
     articles: Array<ProximoArticleType> | null,
108
-    type: ?ProximoCategoryType,
114
+    type?: ProximoCategoryType,
109 115
   ): Array<ProximoArticleType> {
110
-    const availableArticles = [];
116
+    const availableArticles: Array<ProximoArticleType> = [];
111 117
     if (articles != null) {
112 118
       articles.forEach((article: ProximoArticleType) => {
113 119
         if (
114 120
           ((type != null && article.type.includes(type.id)) || type == null) &&
115 121
           parseInt(article.quantity, 10) > 0
116
-        )
122
+        ) {
117 123
           availableArticles.push(article);
124
+        }
118 125
       });
119 126
     }
120 127
     return availableArticles;
@@ -122,13 +129,18 @@ class ProximoMainScreen extends React.Component<PropsType> {
122 129
 
123 130
   articles: Array<ProximoArticleType> | null;
124 131
 
132
+  constructor(props: PropsType) {
133
+    super(props);
134
+    this.articles = null;
135
+  }
136
+
125 137
   /**
126 138
    * Creates header button
127 139
    */
128 140
   componentDidMount() {
129 141
     const {navigation} = this.props;
130 142
     navigation.setOptions({
131
-      headerRight: (): React.Node => this.getHeaderButtons(),
143
+      headerRight: () => this.getHeaderButtons(),
132 144
     });
133 145
   }
134 146
 
@@ -168,7 +180,7 @@ class ProximoMainScreen extends React.Component<PropsType> {
168 180
    * Gets the header buttons
169 181
    * @return {*}
170 182
    */
171
-  getHeaderButtons(): React.Node {
183
+  getHeaderButtons() {
172 184
     return (
173 185
       <MaterialHeaderButtons>
174 186
         <Item
@@ -199,7 +211,7 @@ class ProximoMainScreen extends React.Component<PropsType> {
199 211
    * @param item The category to render
200 212
    * @return {*}
201 213
    */
202
-  getRenderItem = ({item}: {item: ProximoMainListItemType}): React.Node => {
214
+  getRenderItem = ({item}: {item: ProximoMainListItemType}) => {
203 215
     const {navigation, theme} = this.props;
204 216
     const dataToSend = {
205 217
       shouldFocusSearchBar: false,
@@ -219,14 +231,14 @@ class ProximoMainScreen extends React.Component<PropsType> {
219 231
           title={item.type.name}
220 232
           description={subtitle}
221 233
           onPress={onPress}
222
-          left={(props: ListIconPropsType): React.Node => (
234
+          left={(props) => (
223 235
             <List.Icon
224 236
               style={props.style}
225 237
               icon={item.type.icon}
226 238
               color={theme.colors.primary}
227 239
             />
228 240
           )}
229
-          right={(props: ListIconPropsType): React.Node => (
241
+          right={(props) => (
230 242
             <List.Icon
231 243
               color={props.color}
232 244
               style={props.style}
@@ -295,7 +307,7 @@ class ProximoMainScreen extends React.Component<PropsType> {
295 307
     return finalData;
296 308
   }
297 309
 
298
-  render(): React.Node {
310
+  render() {
299 311
     const {navigation} = this.props;
300 312
     return (
301 313
       <WebSectionList

Loading…
Cancel
Save