Browse Source

Update equipment screens to use TypeScript

Arnaud Vergnet 3 years ago
parent
commit
67cb96dd03

+ 2
- 2
src/components/Lists/Equipment/EquipmentListItem.tsx View File

30
 
30
 
31
 type PropsType = {
31
 type PropsType = {
32
   navigation: StackNavigationProp<any>;
32
   navigation: StackNavigationProp<any>;
33
-  userDeviceRentDates: [string, string];
33
+  userDeviceRentDates: [string, string] | null;
34
   item: DeviceType;
34
   item: DeviceType;
35
   height: number;
35
   height: number;
36
 };
36
 };
57
   }
57
   }
58
 
58
 
59
   let description;
59
   let description;
60
-  if (isRented) {
60
+  if (isRented && userDeviceRentDates) {
61
     const start = new Date(userDeviceRentDates[0]);
61
     const start = new Date(userDeviceRentDates[0]);
62
     const end = new Date(userDeviceRentDates[1]);
62
     const end = new Date(userDeviceRentDates[1]);
63
     if (start.getTime() !== end.getTime()) {
63
     if (start.getTime() !== end.getTime()) {

+ 0
- 121
src/screens/Amicale/Equipment/EquipmentConfirmScreen.js View File

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 {
24
-  Button,
25
-  Caption,
26
-  Card,
27
-  Headline,
28
-  Paragraph,
29
-  withTheme,
30
-} from 'react-native-paper';
31
-import {View} from 'react-native';
32
-import i18n from 'i18n-js';
33
-import type {CustomThemeType} from '../../../managers/ThemeManager';
34
-import type {DeviceType} from './EquipmentListScreen';
35
-import {getRelativeDateString} from '../../../utils/EquipmentBooking';
36
-import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
37
-
38
-type PropsType = {
39
-  route: {
40
-    params?: {
41
-      item?: DeviceType,
42
-      dates: [string, string],
43
-    },
44
-  },
45
-  theme: CustomThemeType,
46
-};
47
-
48
-class EquipmentConfirmScreen extends React.Component<PropsType> {
49
-  item: DeviceType | null;
50
-
51
-  dates: [string, string] | null;
52
-
53
-  constructor(props: PropsType) {
54
-    super(props);
55
-    if (props.route.params != null) {
56
-      if (props.route.params.item != null) this.item = props.route.params.item;
57
-      else this.item = null;
58
-      if (props.route.params.dates != null)
59
-        this.dates = props.route.params.dates;
60
-      else this.dates = null;
61
-    }
62
-  }
63
-
64
-  render(): React.Node {
65
-    const {item, dates, props} = this;
66
-    if (item != null && dates != null) {
67
-      const start = new Date(dates[0]);
68
-      const end = new Date(dates[1]);
69
-      let buttonText;
70
-      if (start == null) buttonText = i18n.t('screens.equipment.booking');
71
-      else if (end != null && start.getTime() !== end.getTime())
72
-        buttonText = i18n.t('screens.equipment.bookingPeriod', {
73
-          begin: getRelativeDateString(start),
74
-          end: getRelativeDateString(end),
75
-        });
76
-      else
77
-        buttonText = i18n.t('screens.equipment.bookingDay', {
78
-          date: getRelativeDateString(start),
79
-        });
80
-      return (
81
-        <CollapsibleScrollView>
82
-          <Card style={{margin: 5}}>
83
-            <Card.Content>
84
-              <View style={{flex: 1}}>
85
-                <View
86
-                  style={{
87
-                    marginLeft: 'auto',
88
-                    marginRight: 'auto',
89
-                    flexDirection: 'row',
90
-                    flexWrap: 'wrap',
91
-                  }}>
92
-                  <Headline style={{textAlign: 'center'}}>{item.name}</Headline>
93
-                  <Caption
94
-                    style={{
95
-                      textAlign: 'center',
96
-                      lineHeight: 35,
97
-                      marginLeft: 10,
98
-                    }}>
99
-                    ({i18n.t('screens.equipment.bail', {cost: item.caution})})
100
-                  </Caption>
101
-                </View>
102
-              </View>
103
-              <Button
104
-                icon="check-circle-outline"
105
-                color={props.theme.colors.success}
106
-                mode="text">
107
-                {buttonText}
108
-              </Button>
109
-              <Paragraph style={{textAlign: 'center'}}>
110
-                {i18n.t('screens.equipment.bookingConfirmedMessage')}
111
-              </Paragraph>
112
-            </Card.Content>
113
-          </Card>
114
-        </CollapsibleScrollView>
115
-      );
116
-    }
117
-    return null;
118
-  }
119
-}
120
-
121
-export default withTheme(EquipmentConfirmScreen);

+ 104
- 0
src/screens/Amicale/Equipment/EquipmentConfirmScreen.tsx View File

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
+import * as React from 'react';
21
+import {
22
+  Button,
23
+  Caption,
24
+  Card,
25
+  Headline,
26
+  Paragraph,
27
+  useTheme,
28
+} from 'react-native-paper';
29
+import {View} from 'react-native';
30
+import i18n from 'i18n-js';
31
+import {getRelativeDateString} from '../../../utils/EquipmentBooking';
32
+import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
33
+import {StackScreenProps} from '@react-navigation/stack';
34
+import {MainStackParamsList} from '../../../navigation/MainNavigator';
35
+
36
+type EquipmentConfirmScreenNavigationProp = StackScreenProps<
37
+  MainStackParamsList,
38
+  'equipment-confirm'
39
+>;
40
+
41
+type Props = EquipmentConfirmScreenNavigationProp;
42
+
43
+function EquipmentConfirmScreen(props: Props) {
44
+  const theme = useTheme();
45
+  const item = props.route.params?.item;
46
+  const dates = props.route.params?.dates;
47
+
48
+  if (item != null && dates != null) {
49
+    const start = new Date(dates[0]);
50
+    const end = new Date(dates[1]);
51
+    let buttonText;
52
+    if (start == null) {
53
+      buttonText = i18n.t('screens.equipment.booking');
54
+    } else if (end != null && start.getTime() !== end.getTime()) {
55
+      buttonText = i18n.t('screens.equipment.bookingPeriod', {
56
+        begin: getRelativeDateString(start),
57
+        end: getRelativeDateString(end),
58
+      });
59
+    } else {
60
+      buttonText = i18n.t('screens.equipment.bookingDay', {
61
+        date: getRelativeDateString(start),
62
+      });
63
+    }
64
+    return (
65
+      <CollapsibleScrollView>
66
+        <Card style={{margin: 5}}>
67
+          <Card.Content>
68
+            <View style={{flex: 1}}>
69
+              <View
70
+                style={{
71
+                  marginLeft: 'auto',
72
+                  marginRight: 'auto',
73
+                  flexDirection: 'row',
74
+                  flexWrap: 'wrap',
75
+                }}>
76
+                <Headline style={{textAlign: 'center'}}>{item.name}</Headline>
77
+                <Caption
78
+                  style={{
79
+                    textAlign: 'center',
80
+                    lineHeight: 35,
81
+                    marginLeft: 10,
82
+                  }}>
83
+                  ({i18n.t('screens.equipment.bail', {cost: item.caution})})
84
+                </Caption>
85
+              </View>
86
+            </View>
87
+            <Button
88
+              icon="check-circle-outline"
89
+              color={theme.colors.success}
90
+              mode="text">
91
+              {buttonText}
92
+            </Button>
93
+            <Paragraph style={{textAlign: 'center'}}>
94
+              {i18n.t('screens.equipment.bookingConfirmedMessage')}
95
+            </Paragraph>
96
+          </Card.Content>
97
+        </Card>
98
+      </CollapsibleScrollView>
99
+    );
100
+  }
101
+  return null;
102
+}
103
+
104
+export default EquipmentConfirmScreen;

src/screens/Amicale/Equipment/EquipmentListScreen.js → src/screens/Amicale/Equipment/EquipmentListScreen.tsx View File

17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18
  */
18
  */
19
 
19
 
20
-// @flow
21
-
22
 import * as React from 'react';
20
 import * as React from 'react';
23
 import {View} from 'react-native';
21
 import {View} from 'react-native';
24
-import {Button, withTheme} from 'react-native-paper';
22
+import {Button} from 'react-native-paper';
25
 import {StackNavigationProp} from '@react-navigation/stack';
23
 import {StackNavigationProp} from '@react-navigation/stack';
26
 import i18n from 'i18n-js';
24
 import i18n from 'i18n-js';
27
 import AuthenticatedScreen from '../../../components/Amicale/AuthenticatedScreen';
25
 import AuthenticatedScreen from '../../../components/Amicale/AuthenticatedScreen';
28
-import type {ClubType} from '../Clubs/ClubListScreen';
29
 import EquipmentListItem from '../../../components/Lists/Equipment/EquipmentListItem';
26
 import EquipmentListItem from '../../../components/Lists/Equipment/EquipmentListItem';
30
 import MascotPopup from '../../../components/Mascot/MascotPopup';
27
 import MascotPopup from '../../../components/Mascot/MascotPopup';
31
 import {MASCOT_STYLE} from '../../../components/Mascot/Mascot';
28
 import {MASCOT_STYLE} from '../../../components/Mascot/Mascot';
32
 import AsyncStorageManager from '../../../managers/AsyncStorageManager';
29
 import AsyncStorageManager from '../../../managers/AsyncStorageManager';
33
 import CollapsibleFlatList from '../../../components/Collapsible/CollapsibleFlatList';
30
 import CollapsibleFlatList from '../../../components/Collapsible/CollapsibleFlatList';
34
-import type {ApiGenericDataType} from '../../../utils/WebData';
35
 
31
 
36
 type PropsType = {
32
 type PropsType = {
37
-  navigation: StackNavigationProp,
33
+  navigation: StackNavigationProp<any>;
38
 };
34
 };
39
 
35
 
40
 type StateType = {
36
 type StateType = {
41
-  mascotDialogVisible: boolean,
37
+  mascotDialogVisible: boolean;
42
 };
38
 };
43
 
39
 
44
 export type DeviceType = {
40
 export type DeviceType = {
45
-  id: number,
46
-  name: string,
47
-  caution: number,
48
-  booked_at: Array<{begin: string, end: string}>,
41
+  id: number;
42
+  name: string;
43
+  caution: number;
44
+  booked_at: Array<{begin: string; end: string}>;
49
 };
45
 };
50
 
46
 
51
 export type RentedDeviceType = {
47
 export type RentedDeviceType = {
52
-  device_id: number,
53
-  device_name: string,
54
-  begin: string,
55
-  end: string,
48
+  device_id: number;
49
+  device_name: string;
50
+  begin: string;
51
+  end: string;
56
 };
52
 };
57
 
53
 
58
 const LIST_ITEM_HEIGHT = 64;
54
 const LIST_ITEM_HEIGHT = 64;
60
 class EquipmentListScreen extends React.Component<PropsType, StateType> {
56
 class EquipmentListScreen extends React.Component<PropsType, StateType> {
61
   userRents: null | Array<RentedDeviceType>;
57
   userRents: null | Array<RentedDeviceType>;
62
 
58
 
63
-  authRef: {current: null | AuthenticatedScreen};
59
+  authRef: {current: null | AuthenticatedScreen<any>};
64
 
60
 
65
   canRefresh: boolean;
61
   canRefresh: boolean;
66
 
62
 
67
   constructor(props: PropsType) {
63
   constructor(props: PropsType) {
68
     super(props);
64
     super(props);
65
+    this.userRents = null;
69
     this.state = {
66
     this.state = {
70
       mascotDialogVisible: AsyncStorageManager.getBool(
67
       mascotDialogVisible: AsyncStorageManager.getBool(
71
         AsyncStorageManager.PREFERENCES.equipmentShowMascot.key,
68
         AsyncStorageManager.PREFERENCES.equipmentShowMascot.key,
77
   }
74
   }
78
 
75
 
79
   onScreenFocus = () => {
76
   onScreenFocus = () => {
80
-    if (this.canRefresh && this.authRef.current != null)
77
+    if (
78
+      this.canRefresh &&
79
+      this.authRef.current &&
80
+      this.authRef.current.reload
81
+    ) {
81
       this.authRef.current.reload();
82
       this.authRef.current.reload();
83
+    }
82
     this.canRefresh = true;
84
     this.canRefresh = true;
83
   };
85
   };
84
 
86
 
85
-  getRenderItem = ({item}: {item: DeviceType}): React.Node => {
87
+  getRenderItem = ({item}: {item: DeviceType}) => {
86
     const {navigation} = this.props;
88
     const {navigation} = this.props;
87
     return (
89
     return (
88
       <EquipmentListItem
90
       <EquipmentListItem
94
     );
96
     );
95
   };
97
   };
96
 
98
 
97
-  getUserDeviceRentDates(item: DeviceType): [number, number] | null {
99
+  getUserDeviceRentDates(item: DeviceType): [string, string] | null {
98
     let dates = null;
100
     let dates = null;
99
     if (this.userRents != null) {
101
     if (this.userRents != null) {
100
       this.userRents.forEach((device: RentedDeviceType) => {
102
       this.userRents.forEach((device: RentedDeviceType) => {
111
    *
113
    *
112
    * @returns {*}
114
    * @returns {*}
113
    */
115
    */
114
-  getListHeader(): React.Node {
116
+  getListHeader() {
115
     return (
117
     return (
116
       <View
118
       <View
117
         style={{
119
         style={{
133
     );
135
     );
134
   }
136
   }
135
 
137
 
136
-  keyExtractor = (item: ClubType): string => item.id.toString();
138
+  keyExtractor = (item: DeviceType): string => item.id.toString();
137
 
139
 
138
   /**
140
   /**
139
    * Gets the main screen component with the fetched data
141
    * Gets the main screen component with the fetched data
141
    * @param data The data fetched from the server
143
    * @param data The data fetched from the server
142
    * @returns {*}
144
    * @returns {*}
143
    */
145
    */
144
-  getScreen = (data: Array<ApiGenericDataType | null>): React.Node => {
146
+  getScreen = (
147
+    data: Array<
148
+      {devices: Array<DeviceType>} | {locations: Array<RentedDeviceType>} | null
149
+    >,
150
+  ) => {
145
     const [allDevices, userRents] = data;
151
     const [allDevices, userRents] = data;
146
-    if (userRents != null) this.userRents = userRents.locations;
152
+    if (userRents) {
153
+      this.userRents = (userRents as {
154
+        locations: Array<RentedDeviceType>;
155
+      }).locations;
156
+    }
147
     return (
157
     return (
148
       <CollapsibleFlatList
158
       <CollapsibleFlatList
149
         keyExtractor={this.keyExtractor}
159
         keyExtractor={this.keyExtractor}
150
         renderItem={this.getRenderItem}
160
         renderItem={this.getRenderItem}
151
         ListHeaderComponent={this.getListHeader()}
161
         ListHeaderComponent={this.getListHeader()}
152
-        data={allDevices != null ? allDevices.devices : null}
162
+        data={
163
+          allDevices
164
+            ? (allDevices as {devices: Array<DeviceType>}).devices
165
+            : null
166
+        }
153
       />
167
       />
154
     );
168
     );
155
   };
169
   };
166
     this.setState({mascotDialogVisible: false});
180
     this.setState({mascotDialogVisible: false});
167
   };
181
   };
168
 
182
 
169
-  render(): React.Node {
183
+  render() {
170
     const {props, state} = this;
184
     const {props, state} = this;
171
     return (
185
     return (
172
       <View style={{flex: 1}}>
186
       <View style={{flex: 1}}>
193
           message={i18n.t('screens.equipment.mascotDialog.message')}
207
           message={i18n.t('screens.equipment.mascotDialog.message')}
194
           icon="vote"
208
           icon="vote"
195
           buttons={{
209
           buttons={{
196
-            action: null,
197
             cancel: {
210
             cancel: {
198
               message: i18n.t('screens.equipment.mascotDialog.button'),
211
               message: i18n.t('screens.equipment.mascotDialog.button'),
199
               icon: 'check',
212
               icon: 'check',
207
   }
220
   }
208
 }
221
 }
209
 
222
 
210
-export default withTheme(EquipmentListScreen);
223
+export default EquipmentListScreen;

src/screens/Amicale/Equipment/EquipmentRentScreen.js → src/screens/Amicale/Equipment/EquipmentRentScreen.tsx View File

17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18
  */
18
  */
19
 
19
 
20
-// @flow
21
-
22
 import * as React from 'react';
20
 import * as React from 'react';
23
 import {
21
 import {
24
   Button,
22
   Button,
28
   Subheading,
26
   Subheading,
29
   withTheme,
27
   withTheme,
30
 } from 'react-native-paper';
28
 } from 'react-native-paper';
31
-import {StackNavigationProp} from '@react-navigation/stack';
29
+import {StackNavigationProp, StackScreenProps} from '@react-navigation/stack';
32
 import {BackHandler, View} from 'react-native';
30
 import {BackHandler, View} from 'react-native';
33
 import * as Animatable from 'react-native-animatable';
31
 import * as Animatable from 'react-native-animatable';
34
 import i18n from 'i18n-js';
32
 import i18n from 'i18n-js';
35
-import {CalendarList} from 'react-native-calendars';
33
+import {CalendarList, PeriodMarking} from 'react-native-calendars';
36
 import type {DeviceType} from './EquipmentListScreen';
34
 import type {DeviceType} from './EquipmentListScreen';
37
-import type {CustomThemeType} from '../../../managers/ThemeManager';
38
 import LoadingConfirmDialog from '../../../components/Dialogs/LoadingConfirmDialog';
35
 import LoadingConfirmDialog from '../../../components/Dialogs/LoadingConfirmDialog';
39
 import ErrorDialog from '../../../components/Dialogs/ErrorDialog';
36
 import ErrorDialog from '../../../components/Dialogs/ErrorDialog';
40
 import {
37
 import {
47
 } from '../../../utils/EquipmentBooking';
44
 } from '../../../utils/EquipmentBooking';
48
 import ConnectionManager from '../../../managers/ConnectionManager';
45
 import ConnectionManager from '../../../managers/ConnectionManager';
49
 import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
46
 import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
47
+import {MainStackParamsList} from '../../../navigation/MainNavigator';
48
+
49
+type EquipmentRentScreenNavigationProp = StackScreenProps<
50
+  MainStackParamsList,
51
+  'equipment-rent'
52
+>;
50
 
53
 
51
-type PropsType = {
52
-  navigation: StackNavigationProp,
53
-  route: {
54
-    params?: {
55
-      item?: DeviceType,
56
-    },
57
-  },
58
-  theme: CustomThemeType,
54
+type Props = EquipmentRentScreenNavigationProp & {
55
+  navigation: StackNavigationProp<any>;
56
+  theme: ReactNativePaper.Theme;
59
 };
57
 };
60
 
58
 
61
 export type MarkedDatesObjectType = {
59
 export type MarkedDatesObjectType = {
62
-  [key: string]: {startingDay: boolean, endingDay: boolean, color: string},
60
+  [key: string]: PeriodMarking;
63
 };
61
 };
64
 
62
 
65
 type StateType = {
63
 type StateType = {
66
-  dialogVisible: boolean,
67
-  errorDialogVisible: boolean,
68
-  markedDates: MarkedDatesObjectType,
69
-  currentError: number,
64
+  dialogVisible: boolean;
65
+  errorDialogVisible: boolean;
66
+  markedDates: MarkedDatesObjectType;
67
+  currentError: number;
70
 };
68
 };
71
 
69
 
72
-class EquipmentRentScreen extends React.Component<PropsType, StateType> {
70
+class EquipmentRentScreen extends React.Component<Props, StateType> {
73
   item: DeviceType | null;
71
   item: DeviceType | null;
74
 
72
 
75
   bookedDates: Array<string>;
73
   bookedDates: Array<string>;
76
 
74
 
77
-  bookRef: {current: null | Animatable.View};
75
+  bookRef: {current: null | (Animatable.View & View)};
78
 
76
 
79
   canBookEquipment: boolean;
77
   canBookEquipment: boolean;
80
 
78
 
81
   lockedDates: {
79
   lockedDates: {
82
-    [key: string]: {startingDay: boolean, endingDay: boolean, color: string},
80
+    [key: string]: PeriodMarking;
83
   };
81
   };
84
 
82
 
85
-  constructor(props: PropsType) {
83
+  constructor(props: Props) {
86
     super(props);
84
     super(props);
85
+    this.item = null;
86
+    this.lockedDates = {};
87
     this.state = {
87
     this.state = {
88
       dialogVisible: false,
88
       dialogVisible: false,
89
       errorDialogVisible: false,
89
       errorDialogVisible: false,
95
     this.canBookEquipment = false;
95
     this.canBookEquipment = false;
96
     this.bookedDates = [];
96
     this.bookedDates = [];
97
     if (props.route.params != null) {
97
     if (props.route.params != null) {
98
-      if (props.route.params.item != null) this.item = props.route.params.item;
99
-      else this.item = null;
98
+      if (props.route.params.item != null) {
99
+        this.item = props.route.params.item;
100
+      } else {
101
+        this.item = null;
102
+      }
100
     }
103
     }
101
     const {item} = this;
104
     const {item} = this;
102
     if (item != null) {
105
     if (item != null) {
103
       this.lockedDates = {};
106
       this.lockedDates = {};
104
-      item.booked_at.forEach((date: {begin: string, end: string}) => {
107
+      item.booked_at.forEach((date: {begin: string; end: string}) => {
105
         const range = getValidRange(
108
         const range = getValidRange(
106
           new Date(date.begin),
109
           new Date(date.begin),
107
           new Date(date.end),
110
           new Date(date.end),
211
    * @param day The day selected
214
    * @param day The day selected
212
    */
215
    */
213
   selectNewDate = (day: {
216
   selectNewDate = (day: {
214
-    dateString: string,
215
-    day: number,
216
-    month: number,
217
-    timestamp: number,
218
-    year: number,
217
+    dateString: string;
218
+    day: number;
219
+    month: number;
220
+    timestamp: number;
221
+    year: number;
219
   }) => {
222
   }) => {
220
     const selected = new Date(day.dateString);
223
     const selected = new Date(day.dateString);
221
     const start = this.getBookStartDate();
224
     const start = this.getBookStartDate();
229
       } else if (this.bookedDates.length === 1) {
232
       } else if (this.bookedDates.length === 1) {
230
         this.updateSelectionRange(start, selected);
233
         this.updateSelectionRange(start, selected);
231
         this.enableBooking();
234
         this.enableBooking();
232
-      } else this.resetSelection();
235
+      } else {
236
+        this.resetSelection();
237
+      }
233
       this.updateMarkedSelection();
238
       this.updateMarkedSelection();
234
     }
239
     }
235
   };
240
   };
249
    * Shows the book button by plying a fade animation
254
    * Shows the book button by plying a fade animation
250
    */
255
    */
251
   showBookButton() {
256
   showBookButton() {
252
-    if (this.bookRef.current != null) {
257
+    if (this.bookRef.current && this.bookRef.current.fadeInUp) {
253
       this.bookRef.current.fadeInUp(500);
258
       this.bookRef.current.fadeInUp(500);
254
     }
259
     }
255
   }
260
   }
258
    * Hides the book button by plying a fade animation
263
    * Hides the book button by plying a fade animation
259
    */
264
    */
260
   hideBookButton() {
265
   hideBookButton() {
261
-    if (this.bookRef.current != null) {
266
+    if (this.bookRef.current && this.bookRef.current.fadeOutDown) {
262
       this.bookRef.current.fadeOutDown(500);
267
       this.bookRef.current.fadeOutDown(500);
263
     }
268
     }
264
   }
269
   }
271
   }
276
   }
272
 
277
 
273
   resetSelection() {
278
   resetSelection() {
274
-    if (this.canBookEquipment) this.hideBookButton();
279
+    if (this.canBookEquipment) {
280
+      this.hideBookButton();
281
+    }
275
     this.canBookEquipment = false;
282
     this.canBookEquipment = false;
276
     this.bookedDates = [];
283
     this.bookedDates = [];
277
   }
284
   }
287
     });
294
     });
288
   }
295
   }
289
 
296
 
290
-  render(): React.Node {
297
+  render() {
291
     const {item, props, state} = this;
298
     const {item, props, state} = this;
292
     const start = this.getBookStartDate();
299
     const start = this.getBookStartDate();
293
     const end = this.getBookEndDate();
300
     const end = this.getBookEndDate();
294
     let subHeadingText;
301
     let subHeadingText;
295
-    if (start == null) subHeadingText = i18n.t('screens.equipment.booking');
296
-    else if (end != null && start.getTime() !== end.getTime())
302
+    if (start == null) {
303
+      subHeadingText = i18n.t('screens.equipment.booking');
304
+    } else if (end != null && start.getTime() !== end.getTime()) {
297
       subHeadingText = i18n.t('screens.equipment.bookingPeriod', {
305
       subHeadingText = i18n.t('screens.equipment.bookingPeriod', {
298
         begin: getRelativeDateString(start),
306
         begin: getRelativeDateString(start),
299
         end: getRelativeDateString(end),
307
         end: getRelativeDateString(end),
300
       });
308
       });
301
-    else
309
+    } else {
302
       subHeadingText = i18n.t('screens.equipment.bookingDay', {
310
       subHeadingText = i18n.t('screens.equipment.bookingDay', {
303
         date: getRelativeDateString(start),
311
         date: getRelativeDateString(start),
304
       });
312
       });
313
+    }
305
     if (item != null) {
314
     if (item != null) {
306
       const isAvailable = isEquipmentAvailable(item);
315
       const isAvailable = isEquipmentAvailable(item);
307
       const firstAvailability = getFirstEquipmentAvailability(item);
316
       const firstAvailability = getFirstEquipmentAvailability(item);
369
               onDayPress={this.selectNewDate}
378
               onDayPress={this.selectNewDate}
370
               // If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday.
379
               // If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday.
371
               firstDay={1}
380
               firstDay={1}
372
-              // Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates
373
-              disableAllTouchEventsForDisabledDays
374
               // Hide month navigation arrows.
381
               // Hide month navigation arrows.
375
               hideArrows={false}
382
               hideArrows={false}
376
               // Date marking style [simple/period/multi-dot/custom]. Default = 'simple'
383
               // Date marking style [simple/period/multi-dot/custom]. Default = 'simple'
377
-              markingType="period"
384
+              markingType={'period'}
378
               markedDates={{...this.lockedDates, ...state.markedDates}}
385
               markedDates={{...this.lockedDates, ...state.markedDates}}
379
               theme={{
386
               theme={{
380
                 backgroundColor: props.theme.colors.agendaBackgroundColor,
387
                 backgroundColor: props.theme.colors.agendaBackgroundColor,

+ 2
- 5
src/utils/EquipmentBooking.ts View File

21
 import type {DeviceType} from '../screens/Amicale/Equipment/EquipmentListScreen';
21
 import type {DeviceType} from '../screens/Amicale/Equipment/EquipmentListScreen';
22
 import DateManager from '../managers/DateManager';
22
 import DateManager from '../managers/DateManager';
23
 import type {MarkedDatesObjectType} from '../screens/Amicale/Equipment/EquipmentRentScreen';
23
 import type {MarkedDatesObjectType} from '../screens/Amicale/Equipment/EquipmentRentScreen';
24
+import {PeriodMarking} from 'react-native-calendars';
24
 
25
 
25
 /**
26
 /**
26
  * Gets the current day at midnight
27
  * Gets the current day at midnight
189
   range: Array<string>,
190
   range: Array<string>,
190
 ): MarkedDatesObjectType {
191
 ): MarkedDatesObjectType {
191
   const markedDates: {
192
   const markedDates: {
192
-    [key: string]: {
193
-      startingDay: boolean;
194
-      endingDay: boolean;
195
-      color: string;
196
-    };
193
+    [key: string]: PeriodMarking;
197
   } = {};
194
   } = {};
198
   for (let i = 0; i < range.length; i += 1) {
195
   for (let i = 0; i < range.length; i += 1) {
199
     const isStart = i === 0;
196
     const isStart = i === 0;

Loading…
Cancel
Save