ordering-ui-react-native 0.15.29 → 0.15.30
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/index.tsx +2 -0
- package/themes/business/src/components/OrderDetails/Business.tsx +1 -0
- package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +85 -17
- package/themes/business/src/components/OrdersListManager/index.tsx +871 -0
- package/themes/business/src/components/OrdersListManager/styles.tsx +123 -0
- package/themes/business/src/components/OrdersListManager/utils.tsx +216 -0
- package/themes/business/src/components/PreviousOrders/index.tsx +19 -7
- package/themes/original/src/components/BusinessProductsListing/index.tsx +10 -23
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components/native';
|
|
2
|
+
|
|
3
|
+
export const FiltersTab = styled.View`
|
|
4
|
+
margin-bottom: 20px;
|
|
5
|
+
min-height: 30px;
|
|
6
|
+
max-height: 35px;
|
|
7
|
+
flex: 1;
|
|
8
|
+
width: 100%;
|
|
9
|
+
`
|
|
10
|
+
|
|
11
|
+
export const TabsContainer = styled.View`
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: row;
|
|
14
|
+
justify-content: space-between;
|
|
15
|
+
border-bottom-width: 1px;
|
|
16
|
+
flex: 1;
|
|
17
|
+
width: 100%;
|
|
18
|
+
border-bottom-color: ${(props: any) => props.theme.colors.tabBar};
|
|
19
|
+
`
|
|
20
|
+
|
|
21
|
+
export const Tag = styled.Pressable`
|
|
22
|
+
background-color: ${({ isSelected }: { isSelected: string }) => isSelected};
|
|
23
|
+
justify-content: center;
|
|
24
|
+
align-items: center;
|
|
25
|
+
min-height: 34px;
|
|
26
|
+
padding: 4px 10px;
|
|
27
|
+
border-radius: 50px;
|
|
28
|
+
margin-right: 15px;
|
|
29
|
+
`
|
|
30
|
+
|
|
31
|
+
export const IconWrapper = styled.View`
|
|
32
|
+
flex-direction: row;
|
|
33
|
+
align-items: center;
|
|
34
|
+
background: #fff;
|
|
35
|
+
`
|
|
36
|
+
|
|
37
|
+
export const ModalContainer = styled.ScrollView`
|
|
38
|
+
padding: 0px 30px;
|
|
39
|
+
`
|
|
40
|
+
|
|
41
|
+
export const ModalTitle = styled.Text`
|
|
42
|
+
font-family: Poppins;
|
|
43
|
+
font-style: normal;
|
|
44
|
+
font-weight: bold;
|
|
45
|
+
font-size: 20px;
|
|
46
|
+
color: ${(props: any) => props.theme.colors.textGray};
|
|
47
|
+
margin-bottom: 24px;
|
|
48
|
+
`
|
|
49
|
+
|
|
50
|
+
export const FilterBtnWrapper = styled.TouchableOpacity`
|
|
51
|
+
background-color: ${(props: any) => props.theme.colors.inputDisabled};
|
|
52
|
+
border-radius: 7.6px;
|
|
53
|
+
margin-vertical: 5px;
|
|
54
|
+
padding: 15px 20px;
|
|
55
|
+
flex-direction: row;
|
|
56
|
+
align-items: center;
|
|
57
|
+
justify-content: space-between;
|
|
58
|
+
margin-bottom: 24px;
|
|
59
|
+
`
|
|
60
|
+
|
|
61
|
+
export const TabPressable = styled.Pressable`
|
|
62
|
+
align-items: center;
|
|
63
|
+
border-color: ${(props: any) => props.theme.colors.textGray};
|
|
64
|
+
border-bottom-width: ${(props: any) => props.isSelected ? '1px' : '0px'};
|
|
65
|
+
padding-horizontal: 10px;
|
|
66
|
+
`
|
|
67
|
+
export const OrderStatus = styled.View`
|
|
68
|
+
margin-right: 5px;
|
|
69
|
+
width: 3px;
|
|
70
|
+
height: 90%;
|
|
71
|
+
border-radius: 6px;
|
|
72
|
+
|
|
73
|
+
${(props: any) => props.timeState === 'in_time' && css`
|
|
74
|
+
background-color: #00D27A;
|
|
75
|
+
`}
|
|
76
|
+
|
|
77
|
+
${(props: any) => props.timeState === 'at_risk' && css`
|
|
78
|
+
background-color: #FFC700;
|
|
79
|
+
`}
|
|
80
|
+
|
|
81
|
+
${(props: any) => props.timeState === 'delayed' && css`
|
|
82
|
+
background-color: #E63757;
|
|
83
|
+
`}
|
|
84
|
+
`
|
|
85
|
+
|
|
86
|
+
export const SlaOption = styled.View`
|
|
87
|
+
flex-direction: row;
|
|
88
|
+
align-items: center;
|
|
89
|
+
`
|
|
90
|
+
|
|
91
|
+
export const SearchModalContent = styled.View``
|
|
92
|
+
|
|
93
|
+
export const SlaSettingModalContent = styled.View``
|
|
94
|
+
|
|
95
|
+
export const DeliveryStatusWrapper = styled.View`
|
|
96
|
+
position: relative;
|
|
97
|
+
`
|
|
98
|
+
export const VerticalLine = styled.View`
|
|
99
|
+
position: absolute;
|
|
100
|
+
background: #E9ECEF;
|
|
101
|
+
position: absolute;
|
|
102
|
+
width: 1px;
|
|
103
|
+
height: 100%;
|
|
104
|
+
top: 7px;
|
|
105
|
+
left: 7px;
|
|
106
|
+
`
|
|
107
|
+
|
|
108
|
+
export const Actions = styled.View``
|
|
109
|
+
|
|
110
|
+
export const Sides = styled.View`
|
|
111
|
+
flex-direction: row;
|
|
112
|
+
height: 100%;
|
|
113
|
+
`
|
|
114
|
+
|
|
115
|
+
export const LeftSide = styled.View`
|
|
116
|
+
width: 30%;
|
|
117
|
+
`
|
|
118
|
+
|
|
119
|
+
export const RightSide = styled.View`
|
|
120
|
+
width: 70%;
|
|
121
|
+
border-width: 2px;
|
|
122
|
+
border-color: ${(props: any) => props.theme.colors.gray100};
|
|
123
|
+
`
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import React, { useState, useEffect } from 'react'
|
|
2
|
+
import { StyleSheet, Pressable } from 'react-native'
|
|
3
|
+
import { useLanguage, useUtils, useConfig } from 'ordering-components/native'
|
|
4
|
+
import styled, { useTheme } from 'styled-components/native'
|
|
5
|
+
|
|
6
|
+
import { OText, OIcon } from '../shared';
|
|
7
|
+
|
|
8
|
+
export const useOrderUtils = () => {
|
|
9
|
+
const theme = useTheme();
|
|
10
|
+
const [, t] = useLanguage();
|
|
11
|
+
const [{ parseDate }] = useUtils()
|
|
12
|
+
|
|
13
|
+
const calculateDate = (type: any, from: any, to: any) => {
|
|
14
|
+
switch (type) {
|
|
15
|
+
case 'today':
|
|
16
|
+
const date = parseDate(new Date(), { outputFormat: 'MM/DD/YYYY' })
|
|
17
|
+
return { from: `${date} 00:00:00`, to: `${date} 23:59:59` }
|
|
18
|
+
case 'yesterday':
|
|
19
|
+
const yesterday = new Date()
|
|
20
|
+
yesterday.setDate(yesterday.getDate() - 1)
|
|
21
|
+
const start1 = parseDate(yesterday, { outputFormat: 'MM/DD/YYYY' })
|
|
22
|
+
const end1 = parseDate(new Date(), { outputFormat: 'MM/DD/YYYY' })
|
|
23
|
+
return { from: `${start1} 00:00:00`, to: `${end1} 23:59:59` }
|
|
24
|
+
case 'last_7days':
|
|
25
|
+
const last_7days = new Date()
|
|
26
|
+
last_7days.setDate(last_7days.getDate() - 6)
|
|
27
|
+
const start7 = parseDate(last_7days, { outputFormat: 'MM/DD/YYYY' })
|
|
28
|
+
const end7 = parseDate(new Date(), { outputFormat: 'MM/DD/YYYY' })
|
|
29
|
+
return { from: `${start7} 00:00:00`, to: `${end7} 23:59:59` }
|
|
30
|
+
case 'last_30days':
|
|
31
|
+
const last_30days = new Date()
|
|
32
|
+
last_30days.setDate(last_30days.getDate() - 29)
|
|
33
|
+
const start30 = parseDate(last_30days, { outputFormat: 'MM/DD/YYYY' })
|
|
34
|
+
const end30 = parseDate(new Date(), { outputFormat: 'MM/DD/YYYY' })
|
|
35
|
+
return { from: `${start30} 00:00:00`, to: `${end30} 23:59:59` }
|
|
36
|
+
default:
|
|
37
|
+
const start = from ? `${parseDate(from, { outputFormat: 'MM/DD/YYYY' })} 00:00:00` : ''
|
|
38
|
+
const end = to ? `${parseDate(to, { outputFormat: 'MM/DD/YYYY' })} 23:59:59` : ''
|
|
39
|
+
return { from: start, to: end }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const preorderTypeList = [
|
|
44
|
+
{ key: null, name: t('SLA', 'SLA\'s') },
|
|
45
|
+
{ key: 'in_time', name: t('OK', 'Ok') },
|
|
46
|
+
{ key: 'at_risk', name: t('AT_RISK', 'At Risk') },
|
|
47
|
+
{ key: 'delayed', name: t('DELAYED', 'Delayed') }
|
|
48
|
+
]
|
|
49
|
+
const defaultOrderTypes = [
|
|
50
|
+
{ key: 1, name: t('DELIVERY', 'Delivery') },
|
|
51
|
+
{ key: 2, name: t('PICKUP', 'Pickup') },
|
|
52
|
+
{ key: 3, name: t('EAT_IN', 'Eat in') },
|
|
53
|
+
{ key: 4, name: t('CURBSIDE', 'Curbside') },
|
|
54
|
+
{ key: 5, name: t('DRIVE_THRU', 'Drive thru') }
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
const deliveryStatus = [
|
|
58
|
+
{
|
|
59
|
+
key: t('OK', 'Ok'),
|
|
60
|
+
des: t('DELIVERY_OK_STATUS_DESC', 'Get delivery time from the businesses.'),
|
|
61
|
+
timmer: false,
|
|
62
|
+
icon: theme.images.general?.clock1,
|
|
63
|
+
backColor: '#00D27A'
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
key: t('AT_RISK', 'At risk'),
|
|
67
|
+
des: t('DELIVERY_ATRISK_STATUS_DESC', 'Is the time between delivery time of busines and the delayed time.'),
|
|
68
|
+
timmer: false,
|
|
69
|
+
icon: theme.images.general?.clockRisk,
|
|
70
|
+
backColor: '#FFC700'
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
key: t('DELAYED', 'Delayed'),
|
|
74
|
+
des: t('DELIVERY_DELAYED_STATUS_DESC', 'If this time is exceeded, the order will be delayed.'),
|
|
75
|
+
timmer: true,
|
|
76
|
+
icon: theme.images.general?.clockDelayed,
|
|
77
|
+
backColor: '#E63757'
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
const defaultSearchList = {
|
|
82
|
+
id: '',
|
|
83
|
+
state: '',
|
|
84
|
+
city: '',
|
|
85
|
+
business: '',
|
|
86
|
+
delivery_type: '',
|
|
87
|
+
paymethod: '',
|
|
88
|
+
driver: '',
|
|
89
|
+
timeStatus: '',
|
|
90
|
+
date: {
|
|
91
|
+
from: '',
|
|
92
|
+
to: '',
|
|
93
|
+
type: ''
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const constants = {
|
|
98
|
+
preorderTypeList,
|
|
99
|
+
defaultOrderTypes,
|
|
100
|
+
deliveryStatus,
|
|
101
|
+
defaultSearchList,
|
|
102
|
+
calculateDate
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return [constants];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const StatusBlock = (props: any) => {
|
|
109
|
+
const { item, last } = props
|
|
110
|
+
const [showTime, setShowTime] = useState(false)
|
|
111
|
+
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (last) {
|
|
114
|
+
setShowTime(true)
|
|
115
|
+
}
|
|
116
|
+
}, [last])
|
|
117
|
+
|
|
118
|
+
const StatusItems = styled.View`
|
|
119
|
+
position: relative;
|
|
120
|
+
margin-bottom: 20px;
|
|
121
|
+
z-index: 2;
|
|
122
|
+
`
|
|
123
|
+
const ItemHeader = styled.View`
|
|
124
|
+
flex-direction: row;
|
|
125
|
+
margin-bottom: 5px;
|
|
126
|
+
`
|
|
127
|
+
|
|
128
|
+
const IconWrapper = styled.View`
|
|
129
|
+
flex-direction: row;
|
|
130
|
+
align-items: center;
|
|
131
|
+
background: #fff;
|
|
132
|
+
`
|
|
133
|
+
|
|
134
|
+
const ItemStatus = styled.View`
|
|
135
|
+
width: 4px;
|
|
136
|
+
height: 22px;
|
|
137
|
+
margin: 0 15px;
|
|
138
|
+
border-radius: 4px;
|
|
139
|
+
background: ${(props: any) => props.backColor};
|
|
140
|
+
`
|
|
141
|
+
|
|
142
|
+
const ItemContent = styled.View`
|
|
143
|
+
display: flex;
|
|
144
|
+
padding: 0 30px;
|
|
145
|
+
`
|
|
146
|
+
|
|
147
|
+
const OverLine = styled.View`
|
|
148
|
+
position: absolute;
|
|
149
|
+
height: 100%;
|
|
150
|
+
width: 15px;
|
|
151
|
+
top: 20px;
|
|
152
|
+
left: 0;
|
|
153
|
+
background-color: #fff;
|
|
154
|
+
z-index: 2;
|
|
155
|
+
`
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<StatusItems>
|
|
159
|
+
<Pressable style={{ marginBottom: 10 }}>
|
|
160
|
+
<ItemHeader>
|
|
161
|
+
<IconWrapper>
|
|
162
|
+
<OIcon
|
|
163
|
+
src={item?.icon}
|
|
164
|
+
width={16}
|
|
165
|
+
height={16}
|
|
166
|
+
color={item?.backColor}
|
|
167
|
+
/>
|
|
168
|
+
</IconWrapper>
|
|
169
|
+
<ItemStatus backColor={item?.backColor} />
|
|
170
|
+
<OText>{item?.key}</OText>
|
|
171
|
+
</ItemHeader>
|
|
172
|
+
</Pressable>
|
|
173
|
+
<ItemContent>
|
|
174
|
+
<OText>{item?.des}</OText>
|
|
175
|
+
</ItemContent>
|
|
176
|
+
{showTime && ( <Timer /> )}
|
|
177
|
+
{last && ( <OverLine /> )}
|
|
178
|
+
</StatusItems>
|
|
179
|
+
)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export const Timer = () => {
|
|
183
|
+
const [, t] = useLanguage()
|
|
184
|
+
const theme = useTheme()
|
|
185
|
+
const [{ configs }] = useConfig();
|
|
186
|
+
|
|
187
|
+
const styles = StyleSheet.create({
|
|
188
|
+
settingTime: {
|
|
189
|
+
fontSize: 14,
|
|
190
|
+
borderWidth: 1,
|
|
191
|
+
borderRadius: 7.6,
|
|
192
|
+
margin: 0,
|
|
193
|
+
marginRight: 10,
|
|
194
|
+
paddingHorizontal: 10,
|
|
195
|
+
paddingTop: 5,
|
|
196
|
+
borderColor: theme.colors.disabled
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
const TimerInputWrapper = styled.View`
|
|
201
|
+
color: ${(props: any) => props.theme.colors.disabled};
|
|
202
|
+
margin-top: 15px;
|
|
203
|
+
margin-left: 30px;
|
|
204
|
+
margin-right: 30px;
|
|
205
|
+
flex-direction: row;
|
|
206
|
+
align-items: flex-end;
|
|
207
|
+
`
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<TimerInputWrapper>
|
|
211
|
+
<OText style={styles.settingTime} color={theme.colors.disabled}>{configs?.order_deadlines_delayed_time?.value}</OText>
|
|
212
|
+
<OText>{t('MIN', 'min')}</OText>
|
|
213
|
+
</TimerInputWrapper>
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
|
|
@@ -8,6 +8,9 @@ import {
|
|
|
8
8
|
Card, Logo, Information, MyOrderOptions, NotificationIcon, AcceptOrRejectOrder, Timestatus
|
|
9
9
|
} from './styles';
|
|
10
10
|
import EntypoIcon from 'react-native-vector-icons/Entypo'
|
|
11
|
+
import { DeviceOrientationMethods } from '../../../../../src/hooks/DeviceOrientation'
|
|
12
|
+
|
|
13
|
+
const { useDeviceOrientation, PORTRAIT } = DeviceOrientationMethods
|
|
11
14
|
|
|
12
15
|
export const PreviousOrders = (props: any) => {
|
|
13
16
|
const {
|
|
@@ -18,25 +21,33 @@ export const PreviousOrders = (props: any) => {
|
|
|
18
21
|
isLogisticOrder,
|
|
19
22
|
handleClickLogisticOrder,
|
|
20
23
|
slaSettingTime,
|
|
21
|
-
currentTabSelected
|
|
24
|
+
currentTabSelected,
|
|
25
|
+
currentOrdenSelected
|
|
22
26
|
} = props;
|
|
23
27
|
const [, t] = useLanguage();
|
|
24
28
|
const [{ parseDate, optimizeImage }] = useUtils();
|
|
25
29
|
const theme = useTheme();
|
|
26
30
|
const [currentTime, setCurrentTime] = useState()
|
|
31
|
+
const [orientationState] = useDeviceOrientation();
|
|
32
|
+
|
|
33
|
+
const IS_PORTRAIT = orientationState.orientation === PORTRAIT
|
|
27
34
|
|
|
28
35
|
const handlePressOrder = (order: any) => {
|
|
29
36
|
if (order?.locked && isLogisticOrder) return
|
|
30
37
|
handleClickOrder && handleClickOrder(order)
|
|
31
|
-
|
|
32
|
-
|
|
38
|
+
if (props.handleClickEvent) {
|
|
39
|
+
props.handleClickEvent({ ...order, isLogistic: isLogisticOrder })
|
|
40
|
+
} else {
|
|
41
|
+
onNavigationRedirect &&
|
|
42
|
+
onNavigationRedirect('OrderDetails', { order: { ...order, isLogistic: isLogisticOrder }, handleClickLogisticOrder });
|
|
43
|
+
}
|
|
33
44
|
};
|
|
34
45
|
|
|
35
46
|
const styles = StyleSheet.create({
|
|
36
47
|
cardButton: {
|
|
37
48
|
flex: 1,
|
|
38
|
-
|
|
39
|
-
marginBottom:
|
|
49
|
+
paddingVertical: 20,
|
|
50
|
+
marginBottom: IS_PORTRAIT ? 20 : 0,
|
|
40
51
|
marginLeft: 3,
|
|
41
52
|
},
|
|
42
53
|
icon: {
|
|
@@ -115,8 +126,9 @@ export const PreviousOrders = (props: any) => {
|
|
|
115
126
|
return (
|
|
116
127
|
<View
|
|
117
128
|
style={{
|
|
118
|
-
backgroundColor: order?.locked && isLogisticOrder ? '#ccc' : '#fff',
|
|
119
|
-
marginBottom: isLogisticOrder ? 10 : 0
|
|
129
|
+
backgroundColor: currentOrdenSelected === order?.id ? theme.colors.gray100 : order?.locked && isLogisticOrder ? '#ccc' : '#fff',
|
|
130
|
+
marginBottom: isLogisticOrder ? 10 : 0,
|
|
131
|
+
// justifyContent: 'center'
|
|
120
132
|
}}
|
|
121
133
|
key={order.id}
|
|
122
134
|
>
|
|
@@ -98,24 +98,11 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
const onProductClick = (product: any) => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
productCart: cartProduct,
|
|
107
|
-
businessSlug: business?.slug,
|
|
108
|
-
categoryId: cartProduct?.category_id,
|
|
109
|
-
productId: cartProduct?.id,
|
|
110
|
-
})
|
|
111
|
-
} else {
|
|
112
|
-
onRedirect('ProductDetails', {
|
|
113
|
-
product: product,
|
|
114
|
-
businessSlug: business.slug,
|
|
115
|
-
businessId: business.id,
|
|
116
|
-
})
|
|
117
|
-
}
|
|
118
|
-
|
|
101
|
+
onRedirect('ProductDetails', {
|
|
102
|
+
product: product,
|
|
103
|
+
businessSlug: business.slug,
|
|
104
|
+
businessId: business.id,
|
|
105
|
+
})
|
|
119
106
|
}
|
|
120
107
|
|
|
121
108
|
const handleCancel = () => {
|
|
@@ -169,8 +156,8 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
169
156
|
|
|
170
157
|
const handleTouchDrag = useCallback(() => {
|
|
171
158
|
setCategoryClicked(false);
|
|
172
|
-
|
|
173
|
-
|
|
159
|
+
}, []);
|
|
160
|
+
|
|
174
161
|
const handleBackNavigation = () => {
|
|
175
162
|
navigation?.canGoBack() ? navigation.goBack() : navigation.navigate('BottomTab')
|
|
176
163
|
}
|
|
@@ -251,7 +238,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
251
238
|
selectedCategoryId={selectedCategoryId}
|
|
252
239
|
lazyLoadProductsRecommended={business?.lazy_load_products_recommended}
|
|
253
240
|
setSelectedCategoryId={setSelectedCategoryId}
|
|
254
|
-
|
|
241
|
+
setCategoryClicked={setCategoryClicked}
|
|
255
242
|
/>
|
|
256
243
|
)}
|
|
257
244
|
</>
|
|
@@ -329,13 +316,13 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
|
|
|
329
316
|
business={currentCart?.business}
|
|
330
317
|
cartProducts={currentCart?.products}
|
|
331
318
|
cart={currentCart}
|
|
332
|
-
|
|
319
|
+
setOpenUpselling={setOpenUpselling}
|
|
333
320
|
handleUpsellingPage={handleUpsellingPage}
|
|
334
321
|
handleCloseUpsellingPage={handleCloseUpsellingPage}
|
|
335
322
|
openUpselling={openUpselling}
|
|
336
323
|
canOpenUpselling={canOpenUpselling}
|
|
337
324
|
setCanOpenUpselling={setCanOpenUpselling}
|
|
338
|
-
|
|
325
|
+
onRedirect={onRedirect}
|
|
339
326
|
/>
|
|
340
327
|
)}
|
|
341
328
|
</SafeAreaView>
|