ordering-ui-react-native 0.22.39 → 0.22.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.22.39",
3
+ "version": "0.22.41",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -29,6 +29,7 @@ import { OrderSummary } from './src/components/OrderSummary';
29
29
  import { PhoneInputNumber } from './src/components/PhoneInputNumber';
30
30
  import { PreviousMessages } from './src/components/PreviousMessages';
31
31
  import { PreviousOrders } from './src/components/PreviousOrders';
32
+ import { PrinterSettings } from './src/components/PrinterSettings';
32
33
  import { ProductItemAccordion } from './src/components/ProductItemAccordion';
33
34
  import { ReviewCustomer } from './src/components/ReviewCustomer'
34
35
  import { SearchBar } from './src/components/SearchBar';
@@ -103,6 +104,7 @@ export {
103
104
  PhoneInputNumber,
104
105
  PreviousMessages,
105
106
  PreviousOrders,
107
+ PrinterSettings,
106
108
  ProductItemAccordion,
107
109
  ReviewCustomer,
108
110
  SafeAreaContainerLayout,
@@ -69,11 +69,20 @@ export const DriverMap = (props: GoogleMapsParams) => {
69
69
  stopFollowUserLocation,
70
70
  } = useLocation();
71
71
 
72
- const origin = {
73
- latitude: initialPosition.latitude,
74
- longitude: initialPosition.longitude,
72
+ const destination = {
73
+ latitude: typeof location?.lat === 'string' ? parseFloat(location?.lat) || 0 : location?.lat || 0,
74
+ longitude: typeof location?.lng === 'string' ? parseFloat(location?.lng) || 0 : location?.lng || 0
75
75
  };
76
- const destination = { latitude: location.lat, longitude: location.lng };
76
+
77
+ const parsedInitialPosition = {
78
+ latitude: typeof initialPosition.latitude === 'string' ? parseFloat(initialPosition.latitude) || 0 : initialPosition.latitude || 0,
79
+ longitude: typeof initialPosition.longitude === 'string' ? parseFloat(initialPosition.longitude) || 0 : initialPosition.longitude || 0,
80
+ }
81
+
82
+ const parsedUserLocation = {
83
+ latitude: typeof userLocation?.latitude === 'string' ? parseFloat(userLocation?.latitude) || 0 : userLocation?.latitude || 0,
84
+ longitude: typeof userLocation?.longitude === 'string' ? parseFloat(userLocation?.longitude) || 0 : userLocation?.longitude || 0
85
+ }
77
86
 
78
87
  useEffect(() => {
79
88
  if (isToFollow) {
@@ -161,7 +170,7 @@ export const DriverMap = (props: GoogleMapsParams) => {
161
170
  if (driverUpdateLocation.error) return;
162
171
 
163
172
  calculateDistance(
164
- { lat: userLocation.latitude, lng: userLocation.longitude },
173
+ { lat: parsedUserLocation.latitude, lng: parsedUserLocation.longitude },
165
174
  destination,
166
175
  );
167
176
  // geocodePosition(userLocation);
@@ -169,13 +178,13 @@ export const DriverMap = (props: GoogleMapsParams) => {
169
178
  if (!following.current) return;
170
179
  fitCoordinates();
171
180
 
172
- const { latitude, longitude } = userLocation;
181
+ const { latitude, longitude } = parsedUserLocation;
173
182
 
174
183
  mapRef.current?.animateCamera({
175
184
  center: { latitude, longitude },
176
185
  });
177
186
 
178
- }, [userLocation]);
187
+ }, [parsedUserLocation]);
179
188
 
180
189
  const handleArrowBack: any = () => {
181
190
  setDriverUpdateLocation?.({
@@ -241,8 +250,8 @@ export const DriverMap = (props: GoogleMapsParams) => {
241
250
  [
242
251
  { latitude: location.lat, longitude: location.lng },
243
252
  {
244
- latitude: initialPosition.latitude,
245
- longitude: initialPosition.longitude,
253
+ latitude: parsedInitialPosition.latitude,
254
+ longitude: parsedInitialPosition.longitude,
246
255
  },
247
256
  ],
248
257
  {
@@ -255,7 +264,7 @@ export const DriverMap = (props: GoogleMapsParams) => {
255
264
 
256
265
  useEffect(() => {
257
266
  const interval = setInterval(() => {
258
- if (initialPosition.latitude !== 0 && autoFit.current) {
267
+ if (parsedInitialPosition.latitude !== 0 && autoFit.current) {
259
268
  if (mapRef.current) {
260
269
  fitCoordinates();
261
270
  autoFit.current = false;
@@ -263,7 +272,7 @@ export const DriverMap = (props: GoogleMapsParams) => {
263
272
  }
264
273
  }, 1000);
265
274
  return () => clearInterval(interval);
266
- }, [initialPosition]);
275
+ }, [parsedInitialPosition]);
267
276
 
268
277
  const fitCoordinatesZoom = () => {
269
278
  following.current = false;
@@ -346,8 +355,8 @@ export const DriverMap = (props: GoogleMapsParams) => {
346
355
  ref={mapRef}
347
356
  provider={PROVIDER_GOOGLE}
348
357
  initialRegion={{
349
- latitude: initialPosition.latitude,
350
- longitude: initialPosition.longitude,
358
+ latitude: parsedInitialPosition.latitude,
359
+ longitude: parsedInitialPosition.longitude,
351
360
  latitudeDelta: 0.001,
352
361
  longitudeDelta: 0.001 * ASPECT_RATIO,
353
362
  }}
@@ -369,8 +378,8 @@ export const DriverMap = (props: GoogleMapsParams) => {
369
378
  <>
370
379
  <Marker
371
380
  coordinate={{
372
- latitude: location.lat,
373
- longitude: location.lng,
381
+ latitude: destination.latitude,
382
+ longitude: destination.longitude
374
383
  }}
375
384
  title={location.title}>
376
385
  <Icon
@@ -387,7 +396,10 @@ export const DriverMap = (props: GoogleMapsParams) => {
387
396
  />
388
397
  </View>
389
398
  </Marker>
390
- <Marker coordinate={userLocation}>
399
+ <Marker coordinate={{
400
+ latitude: parsedUserLocation.latitude,
401
+ longitude: parsedUserLocation.longitude
402
+ }}>
391
403
  <View style={styles.driverIcon}>
392
404
  <OIcon
393
405
  style={styles.image}
@@ -401,8 +413,8 @@ export const DriverMap = (props: GoogleMapsParams) => {
401
413
  ) : (
402
414
  <Marker
403
415
  coordinate={{
404
- latitude: userLocation.latitude,
405
- longitude: userLocation.longitude,
416
+ latitude: parsedUserLocation.latitude,
417
+ longitude: parsedUserLocation.longitude
406
418
  }}
407
419
  title={markerTitle || t('YOUR_LOCATION', 'Your Location')}
408
420
  />
@@ -516,8 +528,8 @@ export const DriverMap = (props: GoogleMapsParams) => {
516
528
  options={{
517
529
  latitude: destination.latitude,
518
530
  longitude: destination.longitude,
519
- sourceLatitude: userLocation.latitude,
520
- sourceLongitude: userLocation.longitude,
531
+ sourceLatitude: parsedUserLocation.latitude,
532
+ sourceLongitude: parsedUserLocation.longitude,
521
533
  naverCallerName: 'com.deliveryapp',
522
534
  dialogTitle: t('SHOW_IN_OTHER_MAPS', 'Show in other maps'),
523
535
  dialogMessage: t('WHAT_APP_WOULD_YOU_USE', 'What app would you like to use?'),
@@ -539,7 +551,7 @@ export const DriverMap = (props: GoogleMapsParams) => {
539
551
  secondButton={true}
540
552
  firstColorCustom={theme.colors.red}
541
553
  secondColorCustom={theme.colors.green}
542
- widthButton={isHideRejectButtons ? '100%': '45%'}
554
+ widthButton={isHideRejectButtons ? '100%' : '45%'}
543
555
  isPadding
544
556
  isHideRejectButtons={isHideRejectButtons}
545
557
  />
@@ -50,12 +50,16 @@ export const GoogleMap = (props: GoogleMapsParams) => {
50
50
  const ASPECT_RATIO = width / height;
51
51
  const [isMapReady, setIsMapReady] = useState(false);
52
52
  const [markerPosition, setMarkerPosition] = useState({
53
- latitude: locations ? locations[locations.length - 1].lat : location.lat,
54
- longitude: locations ? locations[locations.length - 1].lng : location.lng,
53
+ latitude: locations
54
+ ? typeof locations[locations.length - 1].lat === 'string' ? parseFloat(locations[locations.length - 1].lat) || 0 : locations[locations.length - 1].lat || 0
55
+ : typeof location?.lat === 'string' ? parseFloat(location?.lat) || 0 : location?.lat || 0,
56
+ longitude: locations
57
+ ? typeof locations[locations.length - 1].lng === 'string' ? parseFloat(locations[locations.length - 1].lng) || 0 : locations[locations.length - 1].lng || 0
58
+ : typeof location?.lng === 'string' ? parseFloat(location?.lng) || 0 : location?.lng || 0,
55
59
  });
56
60
  const [region, setRegion] = useState({
57
- latitude: location.lat,
58
- longitude: location.lng,
61
+ latitude: typeof location?.lat === 'string' ? parseFloat(location?.lat) || 0 : location?.lat || 0,
62
+ longitude: typeof location?.lng === 'string' ? parseFloat(location?.lng) || 0 : location?.lng || 0,
59
63
  latitudeDelta: 0.001,
60
64
  longitudeDelta: 0.001 * ASPECT_RATIO,
61
65
  });
@@ -78,12 +82,15 @@ export const GoogleMap = (props: GoogleMapsParams) => {
78
82
  let MARKERS =
79
83
  locations &&
80
84
  locations.map((location: { lat: number; lng: number; level: number }) => {
81
- return location.level === 4 && driverLocation?.lat
85
+ return location.level === 4 && driverLocation?.lat && driverLocation?.lng
82
86
  ? {
83
- latitude: driverLocation?.lat,
84
- longitude: driverLocation?.lng,
87
+ latitude: typeof driverLocation?.lat === 'string' ? parseFloat(driverLocation?.lat) || 0 : driverLocation?.lat,
88
+ longitude: typeof driverLocation?.lng === 'string' ? parseFloat(driverLocation?.lng) || 0 : driverLocation?.lng,
85
89
  }
86
- : { latitude: location.lat, longitude: location.lng };
90
+ : {
91
+ latitude: typeof location?.lat === 'string' ? parseFloat(location?.lat) || 0 : location?.lat,
92
+ longitude: typeof location?.lng === 'string' ? parseFloat(location?.lng) || 0 : location?.lng
93
+ };
87
94
  });
88
95
 
89
96
  const handleArrowBack: any = () => {
@@ -309,24 +309,26 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
309
309
  setOpenModalForAccept(true);
310
310
  };
311
311
 
312
- const printAction = async (printerSettings: any, commands: any) => {
312
+ const printAction = async (printerSettings: any, commands: any, showAlert: boolean = true) => {
313
313
  try {
314
314
  var printResult = await StarPRNT.print(printerSettings?.emulation, commands, printerSettings?.portName);
315
- showToast(ToastType.Info, t('ORDER_PRINTED_SUCCESS', 'Order printed'), 1000)
315
+ showAlert && showToast(ToastType.Info, t('ORDER_PRINTED_SUCCESS', 'Order printed'), 1000)
316
316
  } catch (e) {
317
- showToast(ToastType.Error, t('ORDER_PRINTED_FAILED', 'Order not printed, connection failed'), 1000)
317
+ showAlert && showToast(ToastType.Error, t('ORDER_PRINTED_FAILED', 'Order not printed, connection failed'), 1000)
318
318
  }
319
319
  }
320
320
 
321
321
  const handleViewSummaryOrder = () => {
322
322
  if (printerSettings) {
323
- const commands: any = generateCommands({
324
- ...order,
325
- orderStatus: getOrderStatus(order?.status, t)?.value
326
- }, printerSettings?.printMode)
327
- commands.push({ appendCutPaper: StarPRNT.CutPaperAction.PartialCutWithFeed })
328
-
329
- printAction(printerSettings, commands)
323
+ printerSettings.map((printer: any, idx: number) => {
324
+ const commands: any = generateCommands({
325
+ ...order,
326
+ orderStatus: getOrderStatus(order?.status, t)?.value
327
+ }, printer?.printMode)
328
+ commands.push({ appendCutPaper: StarPRNT.CutPaperAction.PartialCutWithFeed })
329
+
330
+ printAction(printer, commands, idx === printerSettings.length - 1)
331
+ })
330
332
  return
331
333
  }
332
334
  navigation?.navigate &&
@@ -411,9 +413,9 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
411
413
 
412
414
  useEffect(() => {
413
415
  const getStorageData = async () => {
414
- const printer = await _retrieveStoreData('printer')
416
+ const printers = await _retrieveStoreData('printers')
415
417
  const autoPrint = await _retrieveStoreData('auto_print_after_accept_order')
416
- setPrinterSettings(printer)
418
+ setPrinterSettings(printers?.length && printers)
417
419
  setAutoPrintEnabled(!!autoPrint)
418
420
  }
419
421
 
@@ -0,0 +1,218 @@
1
+ import React, { useEffect, useState } from 'react'
2
+ import { Dimensions, StyleSheet, TouchableOpacity, View } from 'react-native';
3
+ import { useLanguage } from 'ordering-components/native'
4
+ import { useTheme } from 'styled-components/native'
5
+ import { useForm, Controller } from 'react-hook-form';
6
+ import FAIcons from 'react-native-vector-icons/FontAwesome'
7
+ import MCIcons from 'react-native-vector-icons/MaterialCommunityIcons'
8
+ import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons'
9
+ import FeatherIcon from 'react-native-vector-icons/Feather'
10
+ import {
11
+ ContainerEdition,
12
+ BackArrowWrapper,
13
+ BackArrow,
14
+ WrapperIcons,
15
+ WrapperHeader,
16
+ WrapperIcon
17
+ } from './styles'
18
+
19
+ import { Container } from '../../layouts/Container'
20
+ import { OText, OInput, OIcon } from '../shared'
21
+
22
+ export const PrinterEdition = (props: any) => {
23
+ const {
24
+ printer,
25
+ onClose
26
+ } = props
27
+
28
+ const WIDTH_SCREEN = Dimensions.get('window').width
29
+ const [, t] = useLanguage()
30
+ const theme = useTheme()
31
+ const { handleSubmit, control, setValue, watch } = useForm();
32
+
33
+ const watchIp = watch('ip')
34
+ const isErrorIp = !/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(watchIp)
35
+
36
+ const [currentPrinter, setCurrentPrinter] = useState(printer)
37
+
38
+ const styles = StyleSheet.create({
39
+ icons: {
40
+ maxWidth: 40,
41
+ height: 40,
42
+ padding: 10,
43
+ alignItems: 'flex-end'
44
+ },
45
+ optionIcons: {
46
+ paddingRight: 10
47
+ },
48
+ inputStyle: {
49
+ height: 40,
50
+ borderWidth: 1,
51
+ borderRadius: 8,
52
+ }
53
+ })
54
+
55
+ const handleChangePrinter = (values: any) => {
56
+ props.handleChangePrinter({
57
+ ...values,
58
+ item: currentPrinter,
59
+ })
60
+ }
61
+
62
+ const onSubmit = ({ ip }: any) => {
63
+ handleChangePrinter({ type: 2, ip, edit: true })
64
+ onClose && onClose()
65
+ }
66
+
67
+ useEffect(() => {
68
+ console.log(currentPrinter, isErrorIp)
69
+ currentPrinter?.ip && setValue('ip', currentPrinter?.ip)
70
+ }, [currentPrinter?.type])
71
+
72
+ useEffect(() => {
73
+ setCurrentPrinter(printer)
74
+ }, [printer])
75
+
76
+ return (
77
+ <Container>
78
+ <ContainerEdition>
79
+ <BackArrowWrapper>
80
+ <BackArrow activeOpacity={1} onPress={() => onClose()}>
81
+ <OIcon
82
+ src={theme.images.general.arrow_left}
83
+ color={theme.colors.textGray}
84
+ />
85
+ </BackArrow>
86
+ </BackArrowWrapper>
87
+ <WrapperHeader>
88
+ <SimpleLineIcons
89
+ name='printer'
90
+ color={theme.colors.textGray}
91
+ size={20}
92
+ style={{
93
+ ...styles.icons,
94
+ paddingLeft: 0,
95
+ color: theme.colors.primary
96
+ }}
97
+ />
98
+ <OText
99
+ size={22}
100
+ style={{ paddingTop: 0 }}
101
+ >
102
+ {printer.model}
103
+ </OText>
104
+ </WrapperHeader>
105
+
106
+ <WrapperIcons>
107
+ <OText
108
+ size={20}
109
+ style={{ paddingTop: 0, marginBottom: 10 }}
110
+ >
111
+ {`${t('CONNECTION_TYPE', 'Connection type')}:`}
112
+ </OText>
113
+ <WrapperIcon
114
+ activeOpacity={1}
115
+ style={{
116
+ borderColor: currentPrinter?.type === 1 ? theme.colors.primary : theme.colors.textGray
117
+ }}
118
+ onPress={() => {
119
+ setCurrentPrinter({ ...printer, type: 1 })
120
+ handleChangePrinter({ type: 1, ip: null, edit: true })
121
+ }}
122
+ >
123
+ <FAIcons
124
+ name='bluetooth'
125
+ size={22}
126
+ {...(currentPrinter?.type === 1 ? { color: theme.colors.primary } : {})}
127
+ style={styles.optionIcons}
128
+ />
129
+ <OText
130
+ size={18}
131
+ style={{ paddingTop: 0 }}
132
+ >
133
+ {t('CONNECTION_VIA_BLUETOOTH', 'Via Bluetooth')}
134
+ </OText>
135
+ </WrapperIcon>
136
+ <WrapperIcon
137
+ activeOpacity={1}
138
+ style={{
139
+ borderColor: currentPrinter?.type === 2 ? theme.colors.primary : theme.colors.textGray
140
+ }}
141
+ onPress={() => setCurrentPrinter({ ...printer, type: 2 })}
142
+ >
143
+ <MCIcons
144
+ name='access-point-network'
145
+ size={22}
146
+ {...(currentPrinter?.type === 2 ? { color: theme.colors.primary } : {})}
147
+ style={styles.optionIcons}
148
+ />
149
+ <OText
150
+ size={18}
151
+ style={{ paddingTop: 0 }}
152
+ >
153
+ {t('CONNECTION_VIA_LAN', 'Via LAN')}
154
+ </OText>
155
+ </WrapperIcon>
156
+ {currentPrinter?.type === 2 && (
157
+ <>
158
+ <View style={{ flexDirection: 'row' }}>
159
+ <Controller
160
+ control={control}
161
+ name={'ip'}
162
+ rules={{
163
+ required: t('VALIDATION_ERROR_IP_ADDRESS_REQUIRED', 'Ip address is required'),
164
+ pattern: {
165
+ value: /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i,
166
+ message: t('INVALID_ERROR_IP_ADDRESS', 'Invalid ip address')
167
+ }
168
+ }}
169
+ defaultValue={currentPrinter?.ip ?? ''}
170
+ render={() => (
171
+ <OInput
172
+ placeholder={t('IP_ADDRESS', 'Ip address')}
173
+ placeholderTextColor={theme.colors.arrowColor}
174
+ style={{
175
+ ...styles.inputStyle,
176
+ borderColor: isErrorIp ? theme.colors.danger500 : theme.colors.tabBar
177
+ }}
178
+ value={currentPrinter?.ip ?? ''}
179
+ selectionColor={theme.colors.primary}
180
+ color={theme.colors.textGray}
181
+ onChange={(value: any) => {
182
+ setValue('ip', value)
183
+ setCurrentPrinter({
184
+ ...currentPrinter,
185
+ ip: value
186
+ })
187
+ }}
188
+ />
189
+ )}
190
+ />
191
+ <TouchableOpacity
192
+ activeOpacity={1}
193
+ disabled={isErrorIp}
194
+ onPress={handleSubmit(onSubmit)}
195
+ style={{ width: 40 }}
196
+ >
197
+ <FeatherIcon
198
+ name='save'
199
+ size={20}
200
+ color={isErrorIp ? theme.colors.tabBar : theme.colors.primary }
201
+ style={{ ...styles.icons, paddingRight: 0 }}
202
+ />
203
+ </TouchableOpacity>
204
+ </View>
205
+ <OText
206
+ size={14}
207
+ color={theme.colors.tabBar}
208
+ style={{ paddingTop: 5, paddingLeft: 10 }}
209
+ >
210
+ {`${t('EXAMPLE_SHORT', 'Ex:')} 8.8.8.8`}
211
+ </OText>
212
+ </>
213
+ )}
214
+ </WrapperIcons>
215
+ </ContainerEdition>
216
+ </Container>
217
+ )
218
+ }
@@ -0,0 +1,61 @@
1
+ import styled from "styled-components/native";
2
+
3
+ export const ContainerEdition = styled.View`
4
+ margin-bottom: 50px;
5
+ `
6
+
7
+ export const BackArrowWrapper = styled.View`
8
+ align-items: center;
9
+ flex-direction: row;
10
+ min-height: 33px;
11
+ `
12
+
13
+ export const BackArrow = styled.TouchableOpacity`
14
+ border-width: 0;
15
+ width: 32px;
16
+ height: 32px;
17
+ tint-color: ${(props: any) => props.theme.colors.textGray};
18
+ background-color: ${(props: any) => props.theme.colors.clear};
19
+ border-color: ${(props: any) => props.theme.colors.clear};
20
+ shadow-color: ${(props: any) => props.theme.colors.clear};
21
+ padding-left: 0;
22
+ padding-right: 0;
23
+ `
24
+
25
+ export const WrapperHeader = styled.View`
26
+ flex-direction: row;
27
+ justify-content: flex-start;
28
+ align-items: center;
29
+ width: 100%;
30
+ `
31
+
32
+ export const WrapperIcons = styled.View`
33
+ flex-direction: column;
34
+ justify-content: flex-start;
35
+ margin-top: 20px;
36
+ `
37
+
38
+ export const WrapperIcon = styled.TouchableOpacity`
39
+ flex-direction: row;
40
+ justify-content: flex-start;
41
+ padding: 8px;
42
+ border-width: 1px;
43
+ border-radius: 8px;
44
+ margin-bottom: 10px;
45
+ `
46
+
47
+ export const ContainerList = styled.View`
48
+ flex-direction: row;
49
+ justify-content: space-between;
50
+ width: 100%;
51
+ padding: 5px 5px 5px 0;
52
+ border-bottom-width: 1px;
53
+ border-bottom-color: ${(props: any) => props.theme.colors.lightGray};
54
+ `
55
+
56
+ export const EnabledAutoPrint = styled.View`
57
+ flex-direction: row;
58
+ justify-content: space-between;
59
+ align-items: center;
60
+ padding: 20px 0px 10px;
61
+ `;
@@ -1,33 +1,28 @@
1
1
  import React, { useEffect, useState } from 'react'
2
- import { ScrollView, StyleSheet, TouchableOpacity, View, Dimensions } from 'react-native'
3
- import { useForm, Controller } from 'react-hook-form';
2
+ import { StyleSheet, TouchableOpacity, View, Dimensions } from 'react-native'
4
3
  import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons'
5
4
  import FeatherIcon from 'react-native-vector-icons/Feather'
6
5
  import MCIcons from 'react-native-vector-icons/MaterialCommunityIcons'
7
- import FAIcons from 'react-native-vector-icons/FontAwesome'
8
6
  import { useTheme } from 'styled-components/native'
9
7
  import ToggleSwitch from 'toggle-switch-react-native';
10
8
  import { useLanguage } from 'ordering-components/native'
11
9
 
12
10
  import { _setStoreData, _retrieveStoreData } from '../../providers/StoreUtil'
13
- import { Container, EnabledAutoPrint } from './styles'
14
- import { OText, OInput} from '../shared'
11
+ import { Container, ContainerList, EnabledAutoPrint } from './styles'
12
+ import { OText, OIcon, OModal } from '../shared'
13
+ import { PrinterEdition } from '../PrinterEdition'
15
14
 
16
15
  export const PrinterSettings = (props: any) => {
17
- const { onClose } = props
16
+ const { navigation, onClose } = props
18
17
 
19
- const [currentPrinter, setCurrentPrinter] = useState<any>(null)
18
+ const [printers, setPrinters] = useState<any>({ list: [] })
20
19
  const [autoPrintEnabled, setAutoPrintEnabled] = useState<boolean>(false)
21
- const [layoutWidth, setLayoutWidth] = useState<any>({ actionsBtns: 0 })
20
+ const [openModal, setOpenModal] = useState({ open: false, data: null })
22
21
 
23
22
  const WIDTH_SCREEN = Dimensions.get('window').width
24
23
 
25
24
  const [, t] = useLanguage()
26
25
  const theme = useTheme()
27
- const { handleSubmit, control, setValue, watch } = useForm();
28
-
29
- const watchIp = watch('ip')
30
- const isErrorIp = !/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(watchIp)
31
26
 
32
27
  const styles = StyleSheet.create({
33
28
  icons: {
@@ -45,7 +40,7 @@ export const PrinterSettings = (props: any) => {
45
40
  wIconContainer: {
46
41
  flexDirection: 'row',
47
42
  alignItems: 'center',
48
- width: WIDTH_SCREEN - 60 - 40
43
+ width: WIDTH_SCREEN - 60 - 10 - 26
49
44
  },
50
45
  wrapperContainer: {
51
46
  flexDirection: 'column',
@@ -63,6 +58,22 @@ export const PrinterSettings = (props: any) => {
63
58
  label: {
64
59
  color: theme.colors.textGray
65
60
  },
61
+ btnBackArrow: {
62
+ borderWidth: 0,
63
+ width: 32,
64
+ height: 32,
65
+ tintColor: theme.colors.textGray,
66
+ backgroundColor: theme.colors.clear,
67
+ borderColor: theme.colors.clear,
68
+ shadowColor: theme.colors.clear,
69
+ paddingLeft: 0,
70
+ paddingRight: 0,
71
+ },
72
+ titleGroups: {
73
+ alignItems: 'center',
74
+ flexDirection: 'row',
75
+ minHeight: 33,
76
+ },
66
77
  })
67
78
 
68
79
  const printerList = [
@@ -89,32 +100,32 @@ export const PrinterSettings = (props: any) => {
89
100
  { model: 'SM-T400i StarPRNT', emulation: 'StarPRNT', portName1: 'BT:SMT400i', type: 1, ip: '', printMode: 'append' },
90
101
  ]
91
102
 
92
- const handleClick = async (item: any, type?: number, ip?: string) => {
103
+ const goToBack = () => navigation?.canGoBack() && navigation.goBack()
104
+
105
+ const handleClick = async ({ item, type, ip, edit }: any) => {
93
106
  let _item = item
94
- if (_item) {
107
+ let _printers = printers.list
108
+ const idx = _printers.findIndex((p: any) => p.model === _item.model)
109
+
110
+ if (idx !== -1 && !edit) {
111
+ _printers.splice(idx, 1);
112
+ } else {
113
+ const _currentPrinter = _printers.find((p: any) => p.model === _item?.model)
95
114
  _item = {
96
- ...currentPrinter,
115
+ ..._currentPrinter,
97
116
  ...item,
98
- type: type ?? currentPrinter?.type,
99
- ip: ip ?? currentPrinter?.ip ?? '',
100
- portName: (type ?? currentPrinter?.type) === 1 || !ip
101
- ? item.portName1 ?? currentPrinter?.portName1
117
+ type: type ?? _currentPrinter?.type ?? 1,
118
+ ip: ip ?? _currentPrinter?.ip ?? '',
119
+ portName: (type ?? _currentPrinter?.type) === 1 || !ip
120
+ ? item.portName1 ?? _currentPrinter?.portName1
102
121
  : `TCP:${ip}`
103
122
  }
123
+ edit ? (_printers[idx] = _item) : _printers.push(_item)
104
124
  }
105
- setCurrentPrinter(_item)
106
- await _setStoreData('printer', _item)
107
- type === 1 && onClose && onClose()
108
- }
109
-
110
- const onLayout = (event: any, type: string) => {
111
- const { width } = event.nativeEvent.layout;
112
- setLayoutWidth({ ...layoutWidth, [type]: width })
113
- };
114
125
 
115
- const onSubmit = ({ ip }: any) => {
116
- handleClick(currentPrinter, 2, ip)
117
- onClose && onClose()
126
+ setPrinters({ list: _printers })
127
+ await _setStoreData('printers', _printers)
128
+ type === 1 && onClose && onClose()
118
129
  }
119
130
 
120
131
  const handleAutoPrint = async () => {
@@ -124,24 +135,23 @@ export const PrinterSettings = (props: any) => {
124
135
 
125
136
  useEffect(() => {
126
137
  const getStorageData = async () => {
127
- const printer = await _retrieveStoreData('printer')
138
+ const printers = await _retrieveStoreData('printers')
128
139
  const autoPrint = await _retrieveStoreData('auto_print_after_accept_order')
129
- setCurrentPrinter(printer)
140
+ setPrinters({ list: printers ?? [] })
130
141
  setAutoPrintEnabled(!!autoPrint)
131
142
  }
132
143
 
133
144
  getStorageData()
134
145
  }, [])
135
146
 
136
- useEffect(() => {
137
- currentPrinter?.ip && !isErrorIp && setValue('ip', currentPrinter?.ip)
138
- }, [currentPrinter?.type])
139
-
140
147
  return (
141
- <ScrollView
142
- showsVerticalScrollIndicator={false}
143
- >
144
- <OText size={24} style={{ paddingLeft: 30 }}>
148
+ <Container>
149
+ <View style={styles.titleGroups}>
150
+ <TouchableOpacity onPress={() => goToBack()} style={styles.btnBackArrow}>
151
+ <OIcon src={theme.images.general.arrow_left} color={theme.colors.textGray} />
152
+ </TouchableOpacity>
153
+ </View>
154
+ <OText size={24} style={{ paddingTop: 0 }}>
145
155
  {t('PRINTER_SETTINGS', 'Printer Settings')}
146
156
  </OText>
147
157
  <EnabledAutoPrint>
@@ -162,118 +172,85 @@ export const PrinterSettings = (props: any) => {
162
172
  animationSpeed={200}
163
173
  />
164
174
  </EnabledAutoPrint>
165
- <View style={{ paddingHorizontal: 30 }}>
175
+ <View>
166
176
  {printerList.map((item: any, i: number) => (
167
- <Container
177
+ <ContainerList
168
178
  key={i}
169
179
  activeOpacity={1}
170
- onPress={() => handleClick(item)}
180
+ onPress={() => handleClick({ item })}
171
181
  >
172
182
  <View style={styles.wrapperContainer}>
173
- <View style={{ flexDirection: 'row' }}>
183
+ <View style={{ flexDirection: 'row', alignItems: 'center' }}>
184
+ <MCIcons
185
+ name={printers.list.find((p: any) => p?.model === item.model) ? "checkbox-marked" : "checkbox-blank-outline"}
186
+ size={26}
187
+ color={theme.colors.primary}
188
+ onPress={() => handleClick({ item })}
189
+ />
174
190
  <TouchableOpacity
175
191
  activeOpacity={1}
176
192
  style={styles.wIconContainer}
177
- onPress={() => handleClick(item)}
193
+ onPress={() => handleClick({ item })}
178
194
  >
179
195
  <SimpleLineIcons
180
196
  name='printer'
181
197
  color={theme.colors.textGray}
182
198
  size={18}
183
- style={{ ...styles.icons, color: currentPrinter?.model === item.model ? theme.colors.primary : theme.colors.textGray }}
199
+ style={{
200
+ ...styles.icons,
201
+ color: printers.list.find((p: any) => p?.model === item.model)
202
+ ? theme.colors.primary
203
+ : theme.colors.textGray
204
+ }}
184
205
  />
185
206
  <OText
186
207
  size={18}
187
- color={currentPrinter?.model === item.model ? theme.colors.primary : theme.colors.textGray}
208
+ color={printers.list.find((p: any) => p?.model === item.model)
209
+ ? theme.colors.primary
210
+ : theme.colors.textGray
211
+ }
188
212
  >
189
213
  {item.model}
190
214
  </OText>
191
215
  </TouchableOpacity>
192
- {currentPrinter?.model === item.model && (
216
+ {!!printers.list.find((p: any) => p?.model === item.model) && (
193
217
  <TouchableOpacity
194
218
  activeOpacity={1}
195
- onPress={() => handleClick(null)}
219
+ onPress={() => setOpenModal({
220
+ open: true,
221
+ data: printers.list.find((p: any) => p?.model === item.model)
222
+ })}
196
223
  style={{ width: 40 }}
197
224
  >
198
225
  <FeatherIcon
199
- name='x-circle'
200
- color={theme.colors.danger500}
226
+ name='edit'
201
227
  size={20}
202
228
  style={styles.icons}
203
229
  />
204
230
  </TouchableOpacity>
205
231
  )}
206
232
  </View>
207
- <View
208
- style={styles.wrapperIcons}
209
- >
210
- <View style={styles.wrapperIcons} onLayout={(e) => onLayout(e, 'actionsBtns')}>
211
- <FAIcons
212
- name='bluetooth'
213
- size={20}
214
- {...(currentPrinter?.type === 1 && currentPrinter?.model === item.model ? { color: theme.colors.primary } : {})}
215
- style={{ ...styles.optionIcons, borderColor: currentPrinter?.type === 1 && currentPrinter?.model === item.model ? theme.colors.primary : theme.colors.textGray }}
216
- onPress={() => handleClick(item, 1)}
217
- />
218
- <MCIcons
219
- name='access-point-network'
220
- size={20}
221
- {...(currentPrinter?.type === 2 && currentPrinter?.model === item.model ? { color: theme.colors.primary } : {})}
222
- style={{ ...styles.optionIcons, borderColor: currentPrinter?.type === 2 && currentPrinter?.model === item.model ? theme.colors.primary : theme.colors.textGray }}
223
- onPress={() => handleClick(item, 2)}
224
- />
225
- </View>
226
- {currentPrinter?.type === 2 && currentPrinter?.model === item.model && (
227
- <View style={{ flexDirection: 'row', width: WIDTH_SCREEN - 60 - layoutWidth.actionsBtns }}>
228
- <Controller
229
- control={control}
230
- name={'ip'}
231
- rules={{
232
- required: t('VALIDATION_ERROR_IP_ADDRESS_REQUIRED', 'Ip address is required'),
233
- pattern: {
234
- value: /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i,
235
- message: t('INVALID_ERROR_IP_ADDRESS', 'Invalid ip address')
236
- }
237
- }}
238
- defaultValue={currentPrinter?.ip ?? ''}
239
- render={() => (
240
- <OInput
241
- placeholder={t('IP_ADDRESS', 'Ip address')}
242
- placeholderTextColor={theme.colors.arrowColor}
243
- style={{ ...styles.inputStyle, borderColor: isErrorIp ? theme.colors.danger500 : theme.colors.tabBar }}
244
- value={currentPrinter?.ip ?? ''}
245
- selectionColor={theme.colors.primary}
246
- color={theme.colors.textGray}
247
- onChange={(value: any) => {
248
- setValue('ip', value)
249
- setCurrentPrinter({
250
- ...currentPrinter,
251
- ip: value
252
- })
253
- }}
254
- />
255
- )}
256
- />
257
- <TouchableOpacity
258
- activeOpacity={1}
259
- disabled={isErrorIp}
260
- onPress={handleSubmit(onSubmit)}
261
- style={{ width: 40 }}
262
- >
263
- <FeatherIcon
264
- name='save'
265
- size={20}
266
- color={isErrorIp ? theme.colors.tabBar : theme.colors.primary }
267
- style={styles.icons}
268
- />
269
- </TouchableOpacity>
270
- </View>
271
- )}
272
- </View>
273
233
  </View>
274
- </Container>
234
+ </ContainerList>
275
235
  ))}
276
236
  </View>
277
- </ScrollView>
237
+ <OModal
238
+ hideIcons
239
+ entireModal
240
+ customClose
241
+ open={openModal.open}
242
+ style={{
243
+ paddingTop: 0,
244
+ marginTop: 0
245
+ }}
246
+ onClose={() => setOpenModal({ open: false, data: null })}
247
+ >
248
+ <PrinterEdition
249
+ printer={openModal.data}
250
+ handleChangePrinter={handleClick}
251
+ onClose={() => setOpenModal({ open: false, data: null })}
252
+ />
253
+ </OModal>
254
+ </Container>
278
255
  )
279
256
  }
@@ -1,6 +1,10 @@
1
1
  import styled from "styled-components/native";
2
2
 
3
3
  export const Container = styled.View`
4
+ margin-bottom: 50px;
5
+ `
6
+
7
+ export const ContainerList = styled.View`
4
8
  flex-direction: row;
5
9
  justify-content: space-between;
6
10
  width: 100%;
@@ -13,5 +17,5 @@ export const EnabledAutoPrint = styled.View`
13
17
  flex-direction: row;
14
18
  justify-content: space-between;
15
19
  align-items: center;
16
- padding: 20px 30px 10px;
20
+ padding: 20px 0px 10px;
17
21
  `;
@@ -63,7 +63,7 @@ const ProfileUI = (props: ProfileParams) => {
63
63
  const { errors } = useForm();
64
64
  const theme = useTheme();
65
65
 
66
- const [phoneInputData, setPhoneInputData] = useState({
66
+ const [phoneInputData, setPhoneInputData] = useState<any>({
67
67
  error: '',
68
68
  phone: {
69
69
  country_phone_code: null,
@@ -78,11 +78,8 @@ const ProfileUI = (props: ProfileParams) => {
78
78
  const allowDriverUpdateData = user?.level !== 4 || configs?.allow_driver_update_data?.value === "1"
79
79
  useEffect(() => {
80
80
  if (phoneInputData.phone.cellphone) {
81
- const codeNumberPhone = phoneInputData.phone.cellphone.slice(0, 3);
82
- const numberPhone = phoneInputData.phone.cellphone.slice(
83
- 3,
84
- phoneInputData.phone.cellphone?.length,
85
- );
81
+ const codeNumberPhone = phoneInputData.phone.country_phone_code
82
+ const numberPhone = phoneInputData.phone.cellphone
86
83
  setPhoneToShow(`(${codeNumberPhone}) ${numberPhone}`);
87
84
  }
88
85
  }, [phoneInputData.phone.cellphone]);
@@ -467,7 +464,6 @@ const ProfileUI = (props: ProfileParams) => {
467
464
  />
468
465
 
469
466
  <OText style={styles.label}>{t('PHONE', 'Phone')}</OText>
470
-
471
467
  <OInput
472
468
  isSecured={true}
473
469
  placeholder={
@@ -520,7 +516,7 @@ const ProfileUI = (props: ProfileParams) => {
520
516
  }} />
521
517
  </Pressable>
522
518
  ) : (
523
- <Pressable style={{ marginBottom: 10 }} onPress={() => setOpenModal(true)}>
519
+ <Pressable style={{ marginBottom: 10 }} onPress={() => navigation.navigate('PrinterSetup')}>
524
520
  <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
525
521
  <OText size={16}>{t('PRINTER_SETTINGS', 'Printer Settings')}</OText>
526
522
  <AntDesignIcon size={18} name='right' />
@@ -554,9 +550,7 @@ const ProfileUI = (props: ProfileParams) => {
554
550
  entireModal
555
551
  hideIcons
556
552
  >
557
- {props.isBusinessApp ? (
558
- <PrinterSettings onClose={() => setOpenModal(false)} />
559
- ) : (
553
+ {!props.isBusinessApp && (
560
554
  <DriverSchedule schedule={user?.schedule} />
561
555
  )}
562
556
  </OModal>
@@ -26,7 +26,6 @@ import {
26
26
  SocialListWrapper
27
27
  } from './styles';
28
28
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
29
- const types = ['food', 'laundry', 'alcohol', 'groceries'];
30
29
 
31
30
  let BusinessInformation: null | React.ElementType = null
32
31
  let BusinessReviews: null | React.ElementType = null
@@ -36,6 +35,7 @@ export const BusinessBasicInformation = (
36
35
  ) => {
37
36
  const { navigation, businessState, isBusinessInfoShow, logo, header, isPreOrder } = props;
38
37
  const { business, loading } = businessState;
38
+ const types = business?.types && business?.types?.filter(({ enabled }) => (enabled)).map(({ name }) => (name))
39
39
 
40
40
  const theme = useTheme();
41
41
  const [orderState] = useOrder();
@@ -146,14 +146,11 @@ export const BusinessBasicInformation = (
146
146
  }
147
147
 
148
148
  const getBusinessType = () => {
149
- if (Object.keys(business || {}).length <= 0) return t('GENERAL', 'General');
149
+ if (!types) return t('GENERAL', 'General');
150
150
  const _types: any = [];
151
151
  types.forEach(
152
- (type) =>
153
- business[type] &&
154
- _types.push(
155
- t(`BUSINESS_TYPE_${type?.replace(/\s/g, '_')?.toUpperCase()}`, type),
156
- ),
152
+ (type: any) =>
153
+ _types.push(type)
157
154
  );
158
155
  return _types.join(', ');
159
156
  };
@@ -182,7 +182,7 @@ const PromotionsUI = (props: PromotionParams) => {
182
182
  title={``}
183
183
  onClose={() => setOpenModal(false)}
184
184
  >
185
- <View style={{ padding: 20 }}>
185
+ <ScrollView style={{ padding: 20 }}>
186
186
  <OText style={{ alignSelf: 'center', fontWeight: '700' }} mBottom={20}>
187
187
  {offerSelected?.name} / {t('VALUE_OF_OFFER', 'Value of offer')}: {offerSelected?.rate_type === 1 ? `${offerSelected?.rate}%` : `${parsePrice(offerSelected?.rate)}`}
188
188
  </OText>
@@ -210,10 +210,7 @@ const PromotionsUI = (props: PromotionParams) => {
210
210
  <OText style={{ marginTop: 10, marginBottom: 10 }}>
211
211
  {t('AVAILABLE_BUSINESSES_FOR_OFFER', 'Available businesses for this offer')}:
212
212
  </OText>
213
- <ScrollView
214
- showsVerticalScrollIndicator={false}
215
- style={{ height: '68%' }}
216
- >
213
+ <View style={{ marginBottom: 70 }}>
217
214
  {offerSelected?.businesses?.map((business: any) => {
218
215
  return (
219
216
  <SingleBusinessOffer key={business.id}>
@@ -244,8 +241,8 @@ const PromotionsUI = (props: PromotionParams) => {
244
241
  </SingleBusinessOffer>
245
242
  )
246
243
  })}
247
- </ScrollView>
248
- </View>
244
+ </View>
245
+ </ScrollView>
249
246
  </OModal>
250
247
  </PromotionsContainer>
251
248
  </Container>