ordering-ui-react-native 0.21.99 → 0.22.1
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 +1 -1
- package/themes/business/src/components/OrderDetails/Business.tsx +48 -0
- package/themes/business/src/components/OrderDetails/usePrinterCommands.tsx +140 -0
- package/themes/business/src/components/PrinterSettings/index.tsx +117 -0
- package/themes/business/src/components/PrinterSettings/styles.tsx +10 -0
- package/themes/business/src/components/UserFormDetails/index.tsx +111 -107
- package/themes/business/src/components/UserProfileForm/index.tsx +31 -12
- package/themes/business/src/hooks/useLocation.tsx +2 -2
- package/themes/business/src/types/index.tsx +1 -0
- package/themes/original/src/components/Checkout/index.tsx +1 -1
package/package.json
CHANGED
|
@@ -4,8 +4,10 @@ import {
|
|
|
4
4
|
View,
|
|
5
5
|
TouchableOpacity,
|
|
6
6
|
ActivityIndicator,
|
|
7
|
+
Alert,
|
|
7
8
|
} from 'react-native';
|
|
8
9
|
import Clipboard from '@react-native-clipboard/clipboard';
|
|
10
|
+
import { StarPRNT } from 'react-native-star-prnt';
|
|
9
11
|
import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
|
|
10
12
|
import { useTheme } from 'styled-components/native';
|
|
11
13
|
import {
|
|
@@ -35,6 +37,8 @@ import CountryPicker from 'react-native-country-picker-modal';
|
|
|
35
37
|
import { NotFoundSource } from '../NotFoundSource';
|
|
36
38
|
import { OrderHeaderComponent } from './OrderHeaderComponent';
|
|
37
39
|
import { OrderContentComponent } from './OrderContentComponent';
|
|
40
|
+
import { _retrieveStoreData } from '../../providers/StoreUtil'
|
|
41
|
+
import { usePrinterCommands } from './usePrinterCommands'
|
|
38
42
|
|
|
39
43
|
export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
40
44
|
const {
|
|
@@ -57,6 +61,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
57
61
|
const [{ parsePrice, parseNumber, parseDate }] = useUtils();
|
|
58
62
|
const [{ user, token }] = useSession();
|
|
59
63
|
const [{ configs }] = useConfig();
|
|
64
|
+
const { generateCommands } = usePrinterCommands()
|
|
60
65
|
const [, { showToast }] = useToast();
|
|
61
66
|
const [unreadAlert, setUnreadAlert] = useState({
|
|
62
67
|
business: false,
|
|
@@ -70,6 +75,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
70
75
|
const [openModalForAccept, setOpenModalForAccept] = useState(false);
|
|
71
76
|
const [openModalForMapView, setOpenModalForMapView] = useState(false);
|
|
72
77
|
const [isDriverModalVisible, setIsDriverModalVisible] = useState(false);
|
|
78
|
+
const [printerSettings, setPrinterSettings] = useState('')
|
|
73
79
|
|
|
74
80
|
if (order?.status === 7 || order?.status === 4) {
|
|
75
81
|
if (drivers?.length > 0 && drivers) {
|
|
@@ -291,7 +297,40 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
291
297
|
setOpenModalForAccept(true);
|
|
292
298
|
};
|
|
293
299
|
|
|
300
|
+
const printAction = async (printerSettings: any, commands: any) => {
|
|
301
|
+
try {
|
|
302
|
+
var printResult = await StarPRNT.print(printerSettings?.emulation, commands, printerSettings?.portName);
|
|
303
|
+
Alert.alert(
|
|
304
|
+
t('PRINT_SUCCESS_TITLE', 'Print Success'),
|
|
305
|
+
t('PRINT_SUCCESS_SUBTITLE', `Go check your _printer_ printer!`).replace('_printer_', printerSettings?.model),
|
|
306
|
+
[
|
|
307
|
+
{text: 'OK', onPress: () => null},
|
|
308
|
+
],
|
|
309
|
+
{ cancelable: false }
|
|
310
|
+
)
|
|
311
|
+
} catch (e) {
|
|
312
|
+
Alert.alert(
|
|
313
|
+
t('PRINT_FAIL_TITLE', 'Connection Failed'),
|
|
314
|
+
t('PRINT_FAIL_SUBTITLE', 'Make sure your Star Printer is turned on and have thermal paper in it.'),
|
|
315
|
+
[
|
|
316
|
+
{text: 'OK', onPress: () => null},
|
|
317
|
+
],
|
|
318
|
+
{ cancelable: false }
|
|
319
|
+
)
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
294
323
|
const handleViewSummaryOrder = () => {
|
|
324
|
+
if (printerSettings) {
|
|
325
|
+
const commands: any = generateCommands({
|
|
326
|
+
...order,
|
|
327
|
+
orderStatus: getOrderStatus(order?.status, t)?.value
|
|
328
|
+
})
|
|
329
|
+
commands.push({ appendCutPaper: StarPRNT.CutPaperAction.PartialCutWithFeed })
|
|
330
|
+
|
|
331
|
+
printAction(printerSettings, commands)
|
|
332
|
+
return
|
|
333
|
+
}
|
|
295
334
|
navigation?.navigate &&
|
|
296
335
|
navigation.navigate('OrderSummary', {
|
|
297
336
|
order,
|
|
@@ -372,6 +411,15 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
|
|
|
372
411
|
}
|
|
373
412
|
}, [driverLocation]);
|
|
374
413
|
|
|
414
|
+
useEffect(() => {
|
|
415
|
+
const getPrinterDefault = async () => {
|
|
416
|
+
const printer = await _retrieveStoreData('printer')
|
|
417
|
+
setPrinterSettings(printer)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
getPrinterDefault()
|
|
421
|
+
}, [])
|
|
422
|
+
|
|
375
423
|
const styles = StyleSheet.create({
|
|
376
424
|
driverOff: {
|
|
377
425
|
backgroundColor: theme.colors.notAvailable,
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { useConfig, useUtils, useLanguage} from 'ordering-components/native'
|
|
2
|
+
|
|
3
|
+
import { verifyDecimals, getProductPrice } from '../../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook to create commands for star micronics printer using PassPRNT library
|
|
7
|
+
* @returns array of strings
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const usePrinterCommands = () => {
|
|
11
|
+
const [, t] = useLanguage()
|
|
12
|
+
const [{ configs }] = useConfig();
|
|
13
|
+
const [{ parsePrice, parseNumber, parseDate }] = useUtils();
|
|
14
|
+
|
|
15
|
+
const deliveryStatus: any = {
|
|
16
|
+
1: t('DELIVERY', 'Delivery'),
|
|
17
|
+
2: t('PICK_UP', 'Pick up'),
|
|
18
|
+
3: t('EAT_IN', 'Eat In'),
|
|
19
|
+
4: t('CURBSIDE', 'Curbside'),
|
|
20
|
+
5: t('DRIVER_THRU', 'Driver thru'),
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const walletName: any = {
|
|
24
|
+
cash: {
|
|
25
|
+
name: t('CASH_WALLET', 'Cash Wallet')
|
|
26
|
+
},
|
|
27
|
+
credit_point: {
|
|
28
|
+
name: t('POINTS_WALLET', 'Points Wallet')
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const percentTip = (order: any) =>
|
|
33
|
+
parseInt(configs?.driver_tip_type?.value, 10) === 2 &&
|
|
34
|
+
!parseInt(configs?.driver_tip_use_custom?.value, 10) &&
|
|
35
|
+
verifyDecimals(order?.summary?.driver_tip, parseNumber);
|
|
36
|
+
|
|
37
|
+
const handlePaymethodsListString = (order: any) => {
|
|
38
|
+
const paymethodsList = order?.payment_events?.filter((item: any) => item.event === 'payment').map((paymethod: any) => {
|
|
39
|
+
return paymethod?.wallet_event
|
|
40
|
+
? walletName[paymethod?.wallet_event?.wallet?.type]?.name
|
|
41
|
+
: t(paymethod?.paymethod?.gateway?.toUpperCase(), paymethod?.paymethod?.name)
|
|
42
|
+
})
|
|
43
|
+
return paymethodsList.join(', ')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const paymethodsLength = (order: any) => order?.payment_events?.filter((item: any) => item.event === 'payment')?.length
|
|
47
|
+
|
|
48
|
+
const customerName = (order: any) => `${order?.customer?.name ?? ''} ${order?.customer?.middle_name ?? ''} ${order?.customer?.lastname ?? ''} ${order?.customer?.second_lastname ?? ''}`?.replace(' ', ' ')?.trim() ?? ''
|
|
49
|
+
|
|
50
|
+
const generateCommands = (order: any) => {
|
|
51
|
+
let commands: any = [];
|
|
52
|
+
|
|
53
|
+
const textProps = {
|
|
54
|
+
fontSize: 12,
|
|
55
|
+
absolutePosition: 40
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const generateProductsText = () => {
|
|
59
|
+
const list: any = []
|
|
60
|
+
|
|
61
|
+
if (order?.products.length) {
|
|
62
|
+
order?.products.map((product: any) => {
|
|
63
|
+
list.push(`${product?.quantity} ${product?.name} \t\t\t ${parsePrice(product.total ?? getProductPrice(product))}`)
|
|
64
|
+
|
|
65
|
+
product.options?.map((option: any) => {
|
|
66
|
+
list.push(`\t ${option.name}`)
|
|
67
|
+
|
|
68
|
+
option.suboptions?.map((suboption: any) => {
|
|
69
|
+
const { quantity, name, position, price } = suboption
|
|
70
|
+
const pos = position && position !== 'whole' ? `(${t(position.toUpperCase(), position)})` : ''
|
|
71
|
+
const string = name !== 'No'
|
|
72
|
+
? pos
|
|
73
|
+
? `${quantity} x ${name} ${pos} +${parsePrice(price)}`
|
|
74
|
+
: `${quantity} x ${name} +${parsePrice(price)}`
|
|
75
|
+
: 'No'
|
|
76
|
+
|
|
77
|
+
list.push(`\t\t ${string}`)
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
if (product.comment) {
|
|
82
|
+
list.push(`\t ${t('COMMENT', 'Comment')}`)
|
|
83
|
+
list.push(`\t\t ${product.comment}`)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
list.push('------------------------------------------------',)
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return list
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const appends: any = [
|
|
94
|
+
`${t('ORDER_NO', 'Order No.')} ${order.id}`,
|
|
95
|
+
'\n', // need to replace with other break line command
|
|
96
|
+
order.orderStatus,
|
|
97
|
+
`${t('DELIVERY_TYPE', 'Delivery Type')}: ${deliveryStatus[order?.delivery_type]}`,
|
|
98
|
+
`${t('DELIVERY_DATE', 'Delivery Date')}: ${order?.delivery_datetime_utc ? parseDate(order?.delivery_datetime_utc) : parseDate(order?.delivery_datetime, { utc: false })}`,
|
|
99
|
+
`${t(`PAYMENT_METHOD${paymethodsLength(order) > 1 ? 'S' : ''}`, `Payment method${paymethodsLength(order) > 1 ? 's' : ''}`)}: ${handlePaymethodsListString(order)}`,
|
|
100
|
+
'\n', // need to replace with other break line command
|
|
101
|
+
`${t('CUSTOMER_DETAILS', 'Customer details')}`,
|
|
102
|
+
`${t('FULL_NAME', 'Full Name')}: ${customerName(order)}`,
|
|
103
|
+
`${t('EMAIL', 'Email')}: ${order?.customer?.email}`,
|
|
104
|
+
`${t('MOBILE_PHONE', 'Mobile Phone')}: ${order?.customer?.cellphone}`,
|
|
105
|
+
`${!!order?.customer?.phone ? `${t('MOBILE_PHONE', 'Mobile Phone')}: ${order?.customer?.phone}` : '\n'}`,
|
|
106
|
+
`${t('FULL_ADDRESS', 'Full Addres')}: ${order?.customer?.address}`,
|
|
107
|
+
`${!!order?.customer?.internal_number ? `${t('INTERNAL_NUMBER', 'Internal Number')}: ${order?.customer?.internal_number}` : '\n'}`,
|
|
108
|
+
`${!!order?.customer?.zipcode ? `${t('ZIPCODE', 'Zipcode')}: ${order?.customer?.zipcode}` : '\n'}`,
|
|
109
|
+
'\n', // need to replace with other break line command
|
|
110
|
+
`${t('BUSINESS_DETAILS', 'Business details')}`,
|
|
111
|
+
order?.business?.name,
|
|
112
|
+
order?.business?.email,
|
|
113
|
+
`${t('BUSINESS_PHONE', 'Business Phone')}: ${order?.business?.cellphone}`,
|
|
114
|
+
`${!!order?.business?.phone ? `${t('BUSINESS_PHONE', 'Business Phone')}: ${order?.business?.phone}` : '\n'}`,
|
|
115
|
+
`${t('ADDRESS', 'Address')}: ${order?.business?.address}`,
|
|
116
|
+
`${!!order?.business?.address_notes ? `${t('SPECIAL_ADDRESS', 'Special Address')}: ${order?.business?.address_notes}` : '\n'}`,
|
|
117
|
+
'\n', // need to replace with other break line command
|
|
118
|
+
`${t('ORDER_DETAILS', 'Order Details')}`,
|
|
119
|
+
...generateProductsText(),
|
|
120
|
+
'\n', // need to replace with other break line command
|
|
121
|
+
`${t('SUBTOTAL', 'Subtotal')} \t\t\t ${parsePrice(order.tax_type === 1 ? (order?.summary?.subtotal + order?.summary?.tax) ?? 0 : order?.summary?.subtotal ?? 0)}`,
|
|
122
|
+
`${order?.summary?.discount > 0 ? `${order?.offer_type === 1 ? `${t('DISCOUNT', 'Discount')} (${verifyDecimals(order?.offer_rate, parsePrice)}%)` : t('DISCOUNT', 'Discount')} \t\t\t ${parsePrice(order?.summary?.discount)}` : '\n'}`,
|
|
123
|
+
`${order?.tax_type !== 1 ? `${t('TAX', 'Tax')} (${verifyDecimals(order?.summary?.tax_rate, parseNumber)}%) \t\t\t ${parsePrice(order?.summary?.tax ?? 0)}` : '\n'}`,
|
|
124
|
+
`${order?.summary?.delivery_price > 0 ? `${t('DELIVERY_FEE', 'Delivery Fee')} \t\t\t ${parsePrice(order?.summary?.delivery_price ?? 0)}` : '\n'}`,
|
|
125
|
+
`${t('DRIVER_TIP', 'Driver tip')} ${percentTip(order) ? `(${percentTip(order)}%)` : ''} \t\t\t ${parsePrice(order?.summary?.driver_tip ?? 0)}`,
|
|
126
|
+
`${t('SERVICE_FEE', 'Service Fee')} (${verifyDecimals(order?.summary?.service_fee, parseNumber)}%) \t\t\t ${parsePrice(order?.summary?.service_fee ?? 0)}`,
|
|
127
|
+
'------------------------------------------------',
|
|
128
|
+
`${t('TOTAL', 'Total')} \t\t\t ${parsePrice(order?.summary?.total ?? 0)}`
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
commands = [
|
|
132
|
+
...commands,
|
|
133
|
+
...appends.map((append: any) => ({ appendBitmapText: append, ...textProps }))
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
return commands
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return { generateCommands }
|
|
140
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
|
+
import { ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native'
|
|
3
|
+
import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons'
|
|
4
|
+
import FeatherIcon from 'react-native-vector-icons/Feather'
|
|
5
|
+
import { useTheme } from 'styled-components/native'
|
|
6
|
+
import { useLanguage } from 'ordering-components/native'
|
|
7
|
+
|
|
8
|
+
import { _setStoreData, _retrieveStoreData } from '../../providers/StoreUtil'
|
|
9
|
+
import { Container } from './styles'
|
|
10
|
+
import { OText } from '../shared'
|
|
11
|
+
|
|
12
|
+
export const PrinterSettings = (props: any) => {
|
|
13
|
+
const { onClose } = props
|
|
14
|
+
|
|
15
|
+
const [currentPrinter, setCurrentPrinter] = useState<any>(null)
|
|
16
|
+
|
|
17
|
+
const [, t] = useLanguage()
|
|
18
|
+
const theme = useTheme()
|
|
19
|
+
|
|
20
|
+
const styles = StyleSheet.create({
|
|
21
|
+
icons: {
|
|
22
|
+
maxWidth: 40,
|
|
23
|
+
height: 40,
|
|
24
|
+
padding: 10,
|
|
25
|
+
alignItems: 'flex-end'
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const printerList = [
|
|
30
|
+
{ model: 'mPOP', emulation: 'StarPRNT', portName: 'BT:TSP100' },
|
|
31
|
+
{ model: 'FVP10', emulation: 'StarLine', portName: 'BT:TSP100' },
|
|
32
|
+
{ model: 'TSP100', emulation: 'StarGraphic', portName: 'BT:TSP100' },
|
|
33
|
+
{ model: 'TSP65011', emulation: 'StarLine', portName: 'BT:TSP100' },
|
|
34
|
+
{ model: 'TSP7001', emulation: 'StarLine', portName: 'BT:TSP100' },
|
|
35
|
+
{ model: 'TSP80011', emulation: 'StarLine', portName: 'BT:TSP100' },
|
|
36
|
+
{ model: 'SP700', emulation: 'StarDotimpact', portName: 'BT:TSP100' },
|
|
37
|
+
{ model: 'SM-S210i', emulation: 'EscPosMobile', portName: 'BT:TSP100' },
|
|
38
|
+
{ model: 'SM-S220i', emulation: 'EscPosMobile', portName: 'BT:TSP100' },
|
|
39
|
+
{ model: 'SM-S230i', emulation: 'EscosMobile', portName: 'BT:TSP100' },
|
|
40
|
+
{ model: 'SM-T300i/T300', emulation: 'EscPosMobile', portName: 'BT:TSP100' },
|
|
41
|
+
{ model: 'SM-T400i', emulation: 'EscosMobile', portName: 'BT:TSP100' },
|
|
42
|
+
{ model: 'SM-L200', emulation: 'StarPRNT', portName: 'BT:TSP100' },
|
|
43
|
+
{ model: 'SM-L300', emulation: 'StarPRNT', portName: 'BT:TSP100' },
|
|
44
|
+
{ model: 'BSC10', emulation: 'EscPos', portName: 'BT:TSP100' },
|
|
45
|
+
{ model: 'SM-S210i StarPRNT', emulation: 'StarPRNT', portName: 'BT:TSP100' },
|
|
46
|
+
{ model: 'SM-S220i StarPRNT', emulation: 'StarPRNT', portName: 'BT:TSP100' },
|
|
47
|
+
{ model: 'SM-S230i StarPRNT', emulation: 'StarPRNT', portName: 'BT:TSP100' },
|
|
48
|
+
{ model: 'SM-T300i/T300 StarPRNT', emulation: 'StarPRNT', portName: 'BT:TSP100' },
|
|
49
|
+
{ model: 'SM-T400i StarPRNT', emulation: 'StarPRNT', portName: 'BT:TSP100' },
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
const handleClick = async (item: any) => {
|
|
53
|
+
setCurrentPrinter(item)
|
|
54
|
+
await _setStoreData('printer', item)
|
|
55
|
+
onClose && onClose()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const getPrinterDefault = async () => {
|
|
60
|
+
const printer = await _retrieveStoreData('printer')
|
|
61
|
+
setCurrentPrinter(printer)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
getPrinterDefault()
|
|
65
|
+
}, [])
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<ScrollView
|
|
69
|
+
showsVerticalScrollIndicator={false}
|
|
70
|
+
>
|
|
71
|
+
<OText size={24} style={{ paddingLeft: 30 }}>
|
|
72
|
+
{t('PRINTER_SETTINGS', 'Printer Settings')}
|
|
73
|
+
</OText>
|
|
74
|
+
<View style={{ padding: 30 }}>
|
|
75
|
+
{printerList.map((item: any, i: number) => (
|
|
76
|
+
<Container
|
|
77
|
+
key={i}
|
|
78
|
+
activeOpacity={1}
|
|
79
|
+
onPress={() => handleClick(item)}
|
|
80
|
+
>
|
|
81
|
+
<TouchableOpacity
|
|
82
|
+
activeOpacity={1}
|
|
83
|
+
style={{ flexDirection: 'row', alignItems: 'center' }}
|
|
84
|
+
onPress={() => handleClick(item)}
|
|
85
|
+
>
|
|
86
|
+
<SimpleLineIcons
|
|
87
|
+
name='printer'
|
|
88
|
+
color={theme.colors.textGray}
|
|
89
|
+
size={18}
|
|
90
|
+
style={{ ...styles.icons, color: currentPrinter?.model === item.model ? theme.colors.primary : theme.colors.textGray }}
|
|
91
|
+
/>
|
|
92
|
+
<OText
|
|
93
|
+
size={18}
|
|
94
|
+
color={currentPrinter?.model === item.model ? theme.colors.primary : theme.colors.textGray}
|
|
95
|
+
>
|
|
96
|
+
{item.model}
|
|
97
|
+
</OText>
|
|
98
|
+
</TouchableOpacity>
|
|
99
|
+
{currentPrinter?.model === item.model && (
|
|
100
|
+
<TouchableOpacity
|
|
101
|
+
activeOpacity={1}
|
|
102
|
+
onPress={() => handleClick(null)}
|
|
103
|
+
>
|
|
104
|
+
<FeatherIcon
|
|
105
|
+
name='x-circle'
|
|
106
|
+
color={theme.colors.danger500}
|
|
107
|
+
size={20}
|
|
108
|
+
style={styles.icons}
|
|
109
|
+
/>
|
|
110
|
+
</TouchableOpacity>
|
|
111
|
+
)}
|
|
112
|
+
</Container>
|
|
113
|
+
))}
|
|
114
|
+
</View>
|
|
115
|
+
</ScrollView>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import styled from "styled-components/native";
|
|
2
|
+
|
|
3
|
+
export const Container = styled.View`
|
|
4
|
+
flex-direction: row;
|
|
5
|
+
justify-content: space-between;
|
|
6
|
+
width: 100%;
|
|
7
|
+
padding: 5px 5px 5px 0;
|
|
8
|
+
border-bottom-width: 1px;
|
|
9
|
+
border-bottom-color: ${(props: any) => props.theme.colors.lightGray};
|
|
10
|
+
`
|
|
@@ -36,7 +36,8 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
36
36
|
handleCancelEdit,
|
|
37
37
|
toggleIsEdit,
|
|
38
38
|
isCheckout,
|
|
39
|
-
isAlsea
|
|
39
|
+
isAlsea,
|
|
40
|
+
allowDriverUpdateData
|
|
40
41
|
} = props;
|
|
41
42
|
|
|
42
43
|
const theme = useTheme();
|
|
@@ -66,9 +67,9 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
66
67
|
const rules: any = {
|
|
67
68
|
required: isRequiredField(field.code)
|
|
68
69
|
? t(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
`VALIDATION_ERROR_${field.code.toUpperCase()}_REQUIRED`,
|
|
71
|
+
`${field.name} is required`,
|
|
72
|
+
).replace('_attribute_', t(field.name, field.code))
|
|
72
73
|
: null,
|
|
73
74
|
};
|
|
74
75
|
if (field.code && field.code === 'email') {
|
|
@@ -261,90 +262,93 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
261
262
|
sortInputFields({ values: validationFields?.fields?.checkout })
|
|
262
263
|
.length > 0 && (
|
|
263
264
|
<UDWrapper>
|
|
264
|
-
{
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
{
|
|
275
|
-
|
|
265
|
+
{allowDriverUpdateData && (
|
|
266
|
+
<>
|
|
267
|
+
{sortInputFields({
|
|
268
|
+
values: validationFields.fields?.checkout,
|
|
269
|
+
}).map(
|
|
270
|
+
(field: any) =>
|
|
271
|
+
showField &&
|
|
272
|
+
showField(field.code) &&
|
|
273
|
+
!isAlsea
|
|
274
|
+
&& (
|
|
275
|
+
<React.Fragment key={field.id}>
|
|
276
|
+
<OText style={styles.label}>
|
|
277
|
+
{t(field?.code.toUpperCase(), field?.name)}
|
|
278
|
+
</OText>
|
|
276
279
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
.toLowerCase()
|
|
310
|
-
.replace(/[&,()%";:ç?<>{}\\[\]\s]/g, ''),
|
|
311
|
-
);
|
|
312
|
-
field.code !== 'email'
|
|
313
|
-
? handleChangeInput(val)
|
|
314
|
-
: handleChangeInput({
|
|
315
|
-
target: {
|
|
316
|
-
name: 'email',
|
|
317
|
-
value: val.target.value
|
|
280
|
+
<Controller
|
|
281
|
+
key={field.id}
|
|
282
|
+
control={control}
|
|
283
|
+
render={() => (
|
|
284
|
+
<OInput
|
|
285
|
+
name={field.code}
|
|
286
|
+
placeholder={t(
|
|
287
|
+
field.code.toUpperCase(),
|
|
288
|
+
field?.name,
|
|
289
|
+
)}
|
|
290
|
+
placeholderTextColor={theme.colors.arrowColor}
|
|
291
|
+
style={styles.inputStyle}
|
|
292
|
+
icon={
|
|
293
|
+
field.code === 'email'
|
|
294
|
+
? theme.images.general.email
|
|
295
|
+
: theme.images.general.user
|
|
296
|
+
}
|
|
297
|
+
autoCapitalize={
|
|
298
|
+
field.code === 'email' ? 'none' : 'sentences'
|
|
299
|
+
}
|
|
300
|
+
isDisabled={!isEdit}
|
|
301
|
+
value={
|
|
302
|
+
formState?.changes[field.code] ??
|
|
303
|
+
(user && user[field.code]) ??
|
|
304
|
+
''
|
|
305
|
+
}
|
|
306
|
+
onChange={(val: any) => {
|
|
307
|
+
field.code !== 'email'
|
|
308
|
+
? setValue(field.code, val.target.value)
|
|
309
|
+
: setValue(
|
|
310
|
+
field.code,
|
|
311
|
+
val.target.value
|
|
318
312
|
.toLowerCase()
|
|
319
|
-
.replace(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
313
|
+
.replace(/[&,()%";:ç?<>{}\\[\]\s]/g, ''),
|
|
314
|
+
);
|
|
315
|
+
field.code !== 'email'
|
|
316
|
+
? handleChangeInput(val)
|
|
317
|
+
: handleChangeInput({
|
|
318
|
+
target: {
|
|
319
|
+
name: 'email',
|
|
320
|
+
value: val.target.value
|
|
321
|
+
.toLowerCase()
|
|
322
|
+
.replace(
|
|
323
|
+
/[&,()%";:ç?<>{}\\[\]\s]/g,
|
|
324
|
+
'',
|
|
325
|
+
),
|
|
326
|
+
},
|
|
327
|
+
});
|
|
328
|
+
}}
|
|
329
|
+
autoCorrect={field.code === 'email' && false}
|
|
330
|
+
type={
|
|
331
|
+
field.code === 'email'
|
|
332
|
+
? 'email-address'
|
|
333
|
+
: 'default'
|
|
334
|
+
}
|
|
335
|
+
returnKeyType="done"
|
|
336
|
+
autoCompleteType={
|
|
337
|
+
field.code === 'email' ? 'email' : 'off'
|
|
338
|
+
}
|
|
339
|
+
selectionColor={theme.colors.primary}
|
|
340
|
+
color={theme.colors.textGray}
|
|
341
|
+
/>
|
|
342
|
+
)}
|
|
343
|
+
name={field.code}
|
|
344
|
+
rules={getInputRules(field)}
|
|
345
|
+
defaultValue={user && user[field.code]}
|
|
338
346
|
/>
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
/>
|
|
344
|
-
</React.Fragment>
|
|
345
|
-
),
|
|
347
|
+
</React.Fragment>
|
|
348
|
+
),
|
|
349
|
+
)}
|
|
350
|
+
</>
|
|
346
351
|
)}
|
|
347
|
-
|
|
348
352
|
<OText style={styles.label}>{t('PASSWORD', 'Password')}</OText>
|
|
349
353
|
|
|
350
354
|
<Controller
|
|
@@ -445,7 +449,7 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
445
449
|
</OText>
|
|
446
450
|
)}
|
|
447
451
|
|
|
448
|
-
{!!showInputPhoneNumber && !isAlsea && (
|
|
452
|
+
{!!showInputPhoneNumber && !isAlsea && allowDriverUpdateData && (
|
|
449
453
|
<WrapperPhone>
|
|
450
454
|
<PhoneInputNumber
|
|
451
455
|
data={phoneInputData}
|
|
@@ -487,28 +491,28 @@ export const UserFormDetailsUI = (props: any) => {
|
|
|
487
491
|
isEdit) ||
|
|
488
492
|
(watchPassword?.length > 0 && watchConfirmPassword?.length > 0) ||
|
|
489
493
|
formState?.loading) && (
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
494
|
+
<View style={{ flex: 1, marginLeft: 5 }}>
|
|
495
|
+
<OButton
|
|
496
|
+
text={
|
|
497
|
+
formState.loading
|
|
498
|
+
? t('UPDATING', 'Updating')
|
|
499
|
+
: t('UPDATE', 'Update')
|
|
500
|
+
}
|
|
501
|
+
bgColor={theme.colors.primary}
|
|
502
|
+
textStyle={{
|
|
503
|
+
...styles.btnText,
|
|
504
|
+
color: formState.loading
|
|
505
|
+
? theme.colors.textGray
|
|
506
|
+
: theme.colors.white,
|
|
507
|
+
}}
|
|
508
|
+
borderColor={theme.colors.primary}
|
|
509
|
+
isDisabled={formState.loading}
|
|
510
|
+
imgRightSrc={null}
|
|
511
|
+
style={styles.editButton}
|
|
512
|
+
onClick={handleSubmit(onSubmit)}
|
|
513
|
+
/>
|
|
514
|
+
</View>
|
|
515
|
+
)}
|
|
512
516
|
</EditButton>
|
|
513
517
|
)}
|
|
514
518
|
</>
|
|
@@ -24,6 +24,7 @@ import { LogoutButton } from '../LogoutButton';
|
|
|
24
24
|
import { LanguageSelector } from '../LanguageSelector';
|
|
25
25
|
import { UserFormDetailsUI } from '../UserFormDetails';
|
|
26
26
|
import { DriverSchedule } from '../DriverSchedule'
|
|
27
|
+
import { PrinterSettings } from '../PrinterSettings'
|
|
27
28
|
import ToggleSwitch from 'toggle-switch-react-native';
|
|
28
29
|
import { UDWrapper } from '../UserFormDetails/styles';
|
|
29
30
|
import {
|
|
@@ -502,17 +503,31 @@ const ProfileUI = (props: ProfileParams) => {
|
|
|
502
503
|
/>
|
|
503
504
|
</EditButton>
|
|
504
505
|
)}
|
|
505
|
-
|
|
506
|
-
<
|
|
507
|
-
<
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
506
|
+
{!props.isBusinessApp ? (
|
|
507
|
+
<Pressable style={{ marginBottom: 10 }} onPress={() => setOpenModal(true)}>
|
|
508
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
509
|
+
<OText size={16}>{t('SCHEDULE', 'Schedule')}</OText>
|
|
510
|
+
<AntDesignIcon size={18} name='right' />
|
|
511
|
+
</View>
|
|
512
|
+
<View style={{
|
|
513
|
+
borderBottomColor: theme.colors.tabBar,
|
|
514
|
+
borderBottomWidth: 1,
|
|
515
|
+
marginTop: 10
|
|
516
|
+
}} />
|
|
517
|
+
</Pressable>
|
|
518
|
+
) : (
|
|
519
|
+
<Pressable style={{ marginBottom: 10 }} onPress={() => setOpenModal(true)}>
|
|
520
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
521
|
+
<OText size={16}>{t('PRINTER_SETTINGS', 'Printer Settings')}</OText>
|
|
522
|
+
<AntDesignIcon size={18} name='right' />
|
|
523
|
+
</View>
|
|
524
|
+
<View style={{
|
|
525
|
+
borderBottomColor: theme.colors.tabBar,
|
|
526
|
+
borderBottomWidth: 1,
|
|
527
|
+
marginTop: 10
|
|
528
|
+
}} />
|
|
529
|
+
</Pressable>
|
|
530
|
+
)}
|
|
516
531
|
<Pressable style={{ marginBottom: 10 }} onPress={() => navigation.navigate('Sessions')}>
|
|
517
532
|
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
518
533
|
<OText size={16}>{t('SESSIONS', 'Sessions')}</OText>
|
|
@@ -535,7 +550,11 @@ const ProfileUI = (props: ProfileParams) => {
|
|
|
535
550
|
entireModal
|
|
536
551
|
hideIcons
|
|
537
552
|
>
|
|
538
|
-
|
|
553
|
+
{props.isBusinessApp ? (
|
|
554
|
+
<PrinterSettings onClose={() => setOpenModal(false)} />
|
|
555
|
+
) : (
|
|
556
|
+
<DriverSchedule schedule={user?.schedule} />
|
|
557
|
+
)}
|
|
539
558
|
</OModal>
|
|
540
559
|
</ScrollView>
|
|
541
560
|
)}
|
|
@@ -48,8 +48,8 @@ export const useLocation = () => {
|
|
|
48
48
|
GeoLocation.getCurrentPosition(
|
|
49
49
|
({ coords }) => {
|
|
50
50
|
resolve({
|
|
51
|
-
latitude: typeof coords.latitude
|
|
52
|
-
longitude: typeof coords.longitude
|
|
51
|
+
latitude: typeof coords.latitude === 'number' && !Number.isNaN(coords.latitude) ? coords.latitude : 0,
|
|
52
|
+
longitude: typeof coords.longitude === 'number' && !Number.isNaN(coords.longitude) ? coords.longitude : 0,
|
|
53
53
|
speed: coords.speed,
|
|
54
54
|
});
|
|
55
55
|
},
|
|
@@ -771,7 +771,7 @@ const CheckoutUI = (props: any) => {
|
|
|
771
771
|
cart?.status !== 2 &&
|
|
772
772
|
validationFields?.fields?.checkout?.driver_tip?.enabled &&
|
|
773
773
|
driverTipsOptions && driverTipsOptions?.length > 0 &&
|
|
774
|
-
|
|
774
|
+
cart?.business_id &&
|
|
775
775
|
(
|
|
776
776
|
<ChSection>
|
|
777
777
|
<ChDriverTips>
|