ordering-ui-react-native 0.14.69 → 0.14.72

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.
Files changed (39) hide show
  1. package/package.json +1 -1
  2. package/src/components/Checkout/index.tsx +1 -0
  3. package/src/components/PaymentOptions/index.tsx +15 -6
  4. package/src/components/ProductForm/index.tsx +1 -1
  5. package/src/components/StripeElementsForm/index.tsx +48 -27
  6. package/src/components/StripeMethodForm/index.tsx +163 -0
  7. package/src/config.json +2 -0
  8. package/src/types/index.tsx +9 -0
  9. package/themes/kiosk/src/components/BusinessController/index.tsx +67 -0
  10. package/themes/kiosk/src/components/BusinessController/styles.tsx +23 -0
  11. package/themes/kiosk/src/components/BusinessesListing/index.tsx +119 -0
  12. package/themes/kiosk/src/components/BusinessesListing/styles.tsx +24 -0
  13. package/themes/kiosk/src/components/LoginForm/index.tsx +62 -2
  14. package/themes/kiosk/src/components/LogoutButton/index.tsx +74 -0
  15. package/themes/kiosk/src/types/index.d.ts +1 -0
  16. package/themes/original/src/components/BusinessBasicInformation/index.tsx +32 -1
  17. package/themes/original/src/components/BusinessInformation/index.tsx +7 -2
  18. package/themes/original/src/components/BusinessesListing/index.tsx +8 -9
  19. package/themes/original/src/components/Cart/index.tsx +8 -8
  20. package/themes/original/src/components/Checkout/index.tsx +82 -70
  21. package/themes/original/src/components/LoginForm/index.tsx +6 -4
  22. package/themes/original/src/components/OrderDetails/index.tsx +58 -6
  23. package/themes/original/src/components/OrderProgress/index.tsx +39 -31
  24. package/themes/original/src/components/OrderSummary/index.tsx +8 -8
  25. package/themes/original/src/components/OrdersOption/index.tsx +40 -16
  26. package/themes/original/src/components/OrdersOption/styles.tsx +5 -0
  27. package/themes/original/src/components/PhoneInputNumber/index.tsx +1 -1
  28. package/themes/original/src/components/PhoneInputNumber/styles.tsx +1 -1
  29. package/themes/original/src/components/ProductForm/index.tsx +42 -11
  30. package/themes/original/src/components/ProductForm/styles.tsx +1 -1
  31. package/themes/original/src/components/ProductOptionSubOption/index.tsx +1 -1
  32. package/themes/original/src/components/ProductOptionSubOption/styles.tsx +1 -1
  33. package/themes/original/src/components/SingleProductCard/index.tsx +15 -8
  34. package/themes/original/src/components/UpsellingProducts/index.tsx +1 -4
  35. package/themes/original/src/components/UserProfile/index.tsx +13 -11
  36. package/themes/original/src/components/WalletTransactionItem/index.tsx +5 -5
  37. package/themes/original/src/components/Wallets/styles.tsx +1 -1
  38. package/themes/original/src/components/shared/OInput.tsx +6 -2
  39. package/themes/original/src/utils/index.tsx +7 -0
@@ -47,6 +47,7 @@ import { verifyDecimals } from '../../utils';
47
47
  import { OSRow } from '../OrderSummary/styles';
48
48
  import AntIcon from 'react-native-vector-icons/AntDesign'
49
49
  import { TaxInformation } from '../TaxInformation';
50
+ import { Placeholder, PlaceholderLine } from 'rn-placeholder';
50
51
 
51
52
  export const OrderDetailsUI = (props: OrderDetailsParams) => {
52
53
  const {
@@ -421,7 +422,58 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
421
422
 
422
423
  return (
423
424
  <OrderDetailsContainer keyboardShouldPersistTaps="handled">
424
- <Spinner visible={!order || Object.keys(order).length === 0} />
425
+ {(!order || Object.keys(order).length === 0) && (
426
+ <Placeholder style={{ marginTop: 30 }}>
427
+ <Header>
428
+ <OrderInfo>
429
+ <OrderData>
430
+ <PlaceholderLine width={60} height={15} />
431
+ <PlaceholderLine width={60} height={10} />
432
+ <StaturBar>
433
+ <PlaceholderLine height={15} />
434
+ <PlaceholderLine width={40} height={20} />
435
+ </StaturBar>
436
+ </OrderData>
437
+ <View
438
+ style={{
439
+ height: 8,
440
+ backgroundColor: theme.colors.backgroundGray100,
441
+ marginTop: 18,
442
+ marginHorizontal: -40,
443
+ }}
444
+ />
445
+ </OrderInfo>
446
+ </Header>
447
+ <OrderContent>
448
+ <OrderBusiness>
449
+ <PlaceholderLine width={30} height={20} />
450
+ <PlaceholderLine width={60} height={15} />
451
+ <PlaceholderLine width={75} height={10} />
452
+ <PlaceholderLine width={40} height={10} />
453
+ <PlaceholderLine width={95} height={10} />
454
+ </OrderBusiness>
455
+ </OrderContent>
456
+ <View
457
+ style={{
458
+ height: 8,
459
+ backgroundColor: theme.colors.backgroundGray100,
460
+ marginTop: 18,
461
+ marginHorizontal: -40,
462
+ }}
463
+ />
464
+ <OrderCustomer>
465
+ <PlaceholderLine width={20} height={20} />
466
+ <PlaceholderLine width={70} height={15} />
467
+ <PlaceholderLine width={65} height={10} />
468
+ <PlaceholderLine width={80} height={10} />
469
+ <PlaceholderLine width={70} height={10} />
470
+ <View style={{marginTop: 10}}>
471
+ <PlaceholderLine width={60} height={20} />
472
+ <PlaceholderLine width={40} height={10} />
473
+ </View>
474
+ </OrderCustomer>
475
+ </Placeholder>
476
+ )}
425
477
  {order && Object.keys(order).length > 0 && (
426
478
  <>
427
479
  <Header>
@@ -768,7 +820,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
768
820
  )}
769
821
  </OText>
770
822
  <TouchableOpacity style={{ marginLeft: 5 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_1' })}>
771
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
823
+ <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
772
824
  </TouchableOpacity>
773
825
  </OSRow>
774
826
  <OText size={12} lineHeight={18} weight={'400'} color={theme.colors.textNormal}>- {parsePrice(offer?.summary?.discount)}</OText>
@@ -816,7 +868,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
816
868
  {`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '}
817
869
  </OText>
818
870
  <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: tax, type: 'tax' })}>
819
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
871
+ <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
820
872
  </TouchableOpacity>
821
873
  </OSRow>
822
874
  <OText size={12} lineHeight={18} weight={'400'} color={theme.colors.textNormal}>{parsePrice(tax?.summary?.tax_after_discount ?? tax?.summary?.tax ?? 0)}</OText>
@@ -832,7 +884,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
832
884
  ({parsePrice(fee?.fixed)} + {fee.percentage}%){' '}
833
885
  </OText>
834
886
  <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee, type: 'fee' })}>
835
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
887
+ <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
836
888
  </TouchableOpacity>
837
889
  </OSRow>
838
890
  <OText size={12} lineHeight={18} weight={'400'} color={theme.colors.textNormal}>{parsePrice(fee?.summary?.fixed + (fee?.summary?.percentage_after_discount ?? fee?.summary?.percentage) ?? 0)}</OText>
@@ -850,7 +902,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
850
902
  )}
851
903
  </OText>
852
904
  <TouchableOpacity style={{ marginLeft: 5 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_3' })}>
853
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
905
+ <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
854
906
  </TouchableOpacity>
855
907
  </OSRow>
856
908
  <OText size={12} lineHeight={18} weight={'400'} color={theme.colors.textNormal}>- {parsePrice(offer?.summary?.discount)}</OText>
@@ -874,7 +926,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
874
926
  )}
875
927
  </OText>
876
928
  <TouchableOpacity style={{ marginLeft: 5 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_2' })}>
877
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
929
+ <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
878
930
  </TouchableOpacity>
879
931
  </OSRow>
880
932
  <OText size={12} lineHeight={18} weight={'400'} color={theme.colors.textNormal}>- {parsePrice(offer?.summary?.discount)}</OText>
@@ -21,14 +21,16 @@ import {
21
21
  } from './styles'
22
22
 
23
23
  const OrderProgressUI = (props: any) => {
24
- const {
25
- orderList,
26
- navigation
27
- } = props
24
+ const {
25
+ orderList,
26
+ navigation,
27
+ loadOrders,
28
+ isFocused
29
+ } = props
28
30
 
29
- const theme = useTheme();
31
+ const theme = useTheme();
30
32
 
31
- const [, t] = useLanguage()
33
+ const [, t] = useLanguage()
32
34
  const [{ optimizeImage, parseDate, parseTime }] = useUtils()
33
35
  const [lastOrder, setLastOrder] = useState<any>(null)
34
36
  const imageFails = theme.images.general.emptyActiveOrders
@@ -53,11 +55,11 @@ const OrderProgressUI = (props: any) => {
53
55
  overflow: 'hidden',
54
56
  backgroundColor: 'white',
55
57
  borderRadius: 8,
56
- shadowColor: '#000000',
57
- shadowOffset: { width: 1, height: 1 },
58
- shadowOpacity: 0.1,
59
- shadowRadius: 1,
60
- elevation: 3
58
+ shadowColor: '#000000',
59
+ shadowOffset: { width: 1, height: 1 },
60
+ shadowOpacity: 0.1,
61
+ shadowRadius: 1,
62
+ elevation: 3
61
63
  },
62
64
  logo: {
63
65
  width: 50,
@@ -69,10 +71,10 @@ const OrderProgressUI = (props: any) => {
69
71
  flexDirection: 'row',
70
72
  alignItems: 'center'
71
73
  }
72
- });
74
+ });
73
75
 
74
- const getOrderStatus = (s: any) => {
75
- const status = parseInt(s)
76
+ const getOrderStatus = (s: any) => {
77
+ const status = parseInt(s)
76
78
  const orderStatus = [
77
79
  { key: 0, value: t('PENDING', theme?.defaultLanguages?.PENDING || 'Pending'), slug: 'PENDING', percentage: 25 },
78
80
  { key: 1, value: t('COMPLETED', theme?.defaultLanguages?.COMPLETED || 'Completed'), slug: 'COMPLETED', percentage: 100 },
@@ -98,10 +100,10 @@ const OrderProgressUI = (props: any) => {
98
100
  { key: 21, value: t('ORDER_CUSTOMER_ARRIVED_BUSINESS', theme?.defaultLanguages?.ORDER_CUSTOMER_ARRIVED_BUSINESS || 'Customer arrived to business'), slug: 'ORDER_CUSTOMER_ARRIVED_BUSINESS', percentage: 95 }
99
101
  ]
100
102
 
101
- const objectStatus = orderStatus.find((o) => o.key === status)
103
+ const objectStatus = orderStatus.find((o) => o.key === status)
102
104
 
103
- return objectStatus && objectStatus
104
- }
105
+ return objectStatus && objectStatus
106
+ }
105
107
 
106
108
  const convertDiffToHours = (order: any) => {
107
109
  const time = order.delivery_type === 1 ? order?.business?.delivery_time : order?.business?.pickup_time
@@ -120,18 +122,24 @@ const OrderProgressUI = (props: any) => {
120
122
 
121
123
  useEffect(() => {
122
124
  if (orderList?.orders.length > 0) {
123
- const sortedOrders = orderList.orders.sort((a: any, b:any) => a.id > b.id ? -1 : 1)
125
+ const sortedOrders = orderList.orders.sort((a: any, b: any) => a.id > b.id ? -1 : 1)
124
126
  setLastOrder(sortedOrders[0])
125
127
  }
126
128
  }, [orderList?.orders])
127
129
 
128
- return (
129
- <>
130
+ useEffect(() => {
131
+ if (isFocused) {
132
+ loadOrders()
133
+ }
134
+ }, [isFocused])
135
+
136
+ return (
137
+ <>
130
138
  {orderList?.loading && (
131
- <Placeholder Animation={Fade} height={130}>
132
- <PlaceholderLine height={50} style={{ borderRadius: 8, marginBottom: 10 }} />
133
- <PlaceholderLine height={15} style={{ marginBottom: 10 }} />
134
- <PlaceholderLine height={30} style={{ borderRadius: 8, marginBottom: 10 }} />
139
+ <Placeholder Animation={Fade} height={160}>
140
+ <PlaceholderLine height={60} style={{ borderRadius: 8, marginBottom: 10 }} />
141
+ <PlaceholderLine height={20} style={{ marginBottom: 10 }} />
142
+ <PlaceholderLine height={40} style={{ borderRadius: 8, marginBottom: 10 }} />
135
143
  </Placeholder>
136
144
  )}
137
145
  {!orderList?.loading && orderList?.orders?.length > 0 && lastOrder && (
@@ -141,8 +149,8 @@ const OrderProgressUI = (props: any) => {
141
149
  <FastImage
142
150
  style={{ width: 50, height: 50 }}
143
151
  source={{
144
- uri: optimizeImage(lastOrder?.business?.logo, 'h_50,c_limit'),
145
- priority: FastImage.priority.normal,
152
+ uri: optimizeImage(lastOrder?.business?.logo, 'h_50,c_limit'),
153
+ priority: FastImage.priority.normal,
146
154
  }}
147
155
  resizeMode={FastImage.resizeMode.cover}
148
156
  />
@@ -150,7 +158,7 @@ const OrderProgressUI = (props: any) => {
150
158
  <View style={{
151
159
  paddingHorizontal: 10,
152
160
  flex: 1
153
- }}
161
+ }}
154
162
  >
155
163
  <OText
156
164
  size={13}
@@ -185,7 +193,7 @@ const OrderProgressUI = (props: any) => {
185
193
  {lastOrder?.delivery_datetime_utc
186
194
  ? parseTime(lastOrder?.delivery_datetime_utc, { outputFormat: 'hh:mm A' })
187
195
  : parseTime(lastOrder?.delivery_datetime, { utc: false })}
188
- &nbsp;-&nbsp;
196
+ &nbsp;-&nbsp;
189
197
  {convertDiffToHours(lastOrder)}
190
198
  </OText>
191
199
  </TimeWrapper>
@@ -200,8 +208,8 @@ const OrderProgressUI = (props: any) => {
200
208
  conditioned
201
209
  />
202
210
  )} */}
203
- </>
204
- )
211
+ </>
212
+ )
205
213
  }
206
214
 
207
215
  export const OrderProgress = (props: any) => {
@@ -217,6 +225,6 @@ export const OrderProgress = (props: any) => {
217
225
  }
218
226
  }
219
227
 
220
- return <OrderList {...orderProgressProps} />
228
+ return <OrderList {...orderProgressProps} />
221
229
 
222
230
  }
@@ -154,10 +154,10 @@ const OrderSummaryUI = (props: any) => {
154
154
  <OText size={12}>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
155
155
  )}
156
156
  <TouchableOpacity style={{ marginLeft: 3 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_1' })}>
157
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
157
+ <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
158
158
  </TouchableOpacity>
159
159
  <TouchableOpacity style={{ marginLeft: 3 }} onPress={() => onRemoveOffer(offer?.id)}>
160
- <AntIcon name='closecircle' size={18} color={theme.colors.primary} />
160
+ <AntIcon name='closecircle' size={16} color={theme.colors.primary} />
161
161
  </TouchableOpacity>
162
162
  </OSRow>
163
163
  <OText size={12}>
@@ -186,7 +186,7 @@ const OrderSummaryUI = (props: any) => {
186
186
  {`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '}
187
187
  </OText>
188
188
  <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: tax, type: 'tax' })} >
189
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
189
+ <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
190
190
  </TouchableOpacity>
191
191
  </OSRow>
192
192
  <OText size={12}>{parsePrice(tax?.summary?.tax_after_discount ?? tax?.summary?.tax ?? 0)}</OText>
@@ -202,7 +202,7 @@ const OrderSummaryUI = (props: any) => {
202
202
  ({parsePrice(fee?.fixed)} + {fee?.percentage}%){' '}
203
203
  </OText>
204
204
  <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee, type: 'fee' })} >
205
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
205
+ <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
206
206
  </TouchableOpacity>
207
207
  </OSRow>
208
208
  <OText size={12}>{parsePrice(fee?.summary?.fixed + (fee?.summary?.percentage_after_discount ?? fee?.summary?.percentage) ?? 0)}</OText>
@@ -218,10 +218,10 @@ const OrderSummaryUI = (props: any) => {
218
218
  <OText size={12}>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
219
219
  )}
220
220
  <TouchableOpacity style={{ marginLeft: 3 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_3' })}>
221
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
221
+ <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
222
222
  </TouchableOpacity>
223
223
  <TouchableOpacity style={{ marginLeft: 3 }} onPress={() => onRemoveOffer(offer?.id)}>
224
- <AntIcon name='closecircle' size={18} color={theme.colors.primary} />
224
+ <AntIcon name='closecircle' size={16} color={theme.colors.primary} />
225
225
  </TouchableOpacity>
226
226
  </OSRow>
227
227
  <OText size={12}>
@@ -245,10 +245,10 @@ const OrderSummaryUI = (props: any) => {
245
245
  <OText size={12}>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
246
246
  )}
247
247
  <TouchableOpacity style={{ marginLeft: 3 }} onPress={() => setOpenTaxModal({ open: true, data: offer, type: 'offer_target_2' })}>
248
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
248
+ <AntIcon name='infocirlceo' size={16} color={theme.colors.primary} />
249
249
  </TouchableOpacity>
250
250
  <TouchableOpacity style={{ marginLeft: 3 }} onPress={() => onRemoveOffer(offer?.id)}>
251
- <AntIcon name='closecircle' size={18} color={theme.colors.primary} />
251
+ <AntIcon name='closecircle' size={16} color={theme.colors.primary} />
252
252
  </TouchableOpacity>
253
253
  </OSRow>
254
254
  <OText size={12}>
@@ -2,12 +2,12 @@ import React, { useState, useEffect } from 'react'
2
2
  import { OrderList, useLanguage, useOrder, ToastType, useToast } from 'ordering-components/native'
3
3
  import { useTheme } from 'styled-components/native';
4
4
  import { useFocusEffect } from '@react-navigation/native'
5
- import { OText } from '../shared'
5
+ import { OText, OButton } from '../shared'
6
6
  import { NotFoundSource } from '../NotFoundSource'
7
7
  import { ActiveOrders } from '../ActiveOrders'
8
8
  import { PreviousOrders } from '../PreviousOrders'
9
9
 
10
- import { OptionTitle } from './styles'
10
+ import { OptionTitle, NoOrdersWrapper } from './styles'
11
11
  import { OrdersOptionParams } from '../../types'
12
12
 
13
13
  import {
@@ -32,6 +32,8 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
32
32
  loadMoreStatus,
33
33
  loadMoreOrders,
34
34
  loadOrders,
35
+ setOrdersLength,
36
+ ordersLength
35
37
  } = props
36
38
 
37
39
  const theme = useTheme();
@@ -112,28 +114,50 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
112
114
  }
113
115
  }, [loadMoreStatus, loading, pagination])
114
116
 
117
+ useEffect(() => {
118
+ if (loading) return
119
+
120
+ const updateOrders = orders.filter((order: any) => orderStatus.includes(order.status))
121
+
122
+ if (activeOrders) {
123
+ setOrdersLength && setOrdersLength({ ...ordersLength, activeOrdersLength: updateOrders?.length })
124
+ } else if (!preOrders) {
125
+ setOrdersLength && setOrdersLength({ ...ordersLength, previousOrdersLength: updateOrders?.length })
126
+ }
127
+ }, [orders?.length])
128
+
115
129
  return (
116
130
  <>
117
- {(orders.length > 0) && (
118
- <>
119
- <OptionTitle>
120
- <OText size={16} lineHeight={24} weight={'500'} color={theme.colors.textNormal} mBottom={10} >
121
- {titleContent || (activeOrders
122
- ? t('ACTIVE', 'Active')
123
- : preOrders
124
- ? t('PREORDERS', 'Preorders')
125
- : t('PAST', 'Past'))}
126
- </OText>
127
- </OptionTitle>
128
- </>
129
- )}
130
- {!loading && orders.length === 0 && (
131
+ <OptionTitle>
132
+ <OText size={16} lineHeight={24} weight={'500'} color={theme.colors.textNormal} mBottom={10} >
133
+ {titleContent || (activeOrders
134
+ ? t('ACTIVE', 'Active')
135
+ : preOrders
136
+ ? t('PREORDERS', 'Preorders')
137
+ : t('PAST', 'Past'))}
138
+ </OText>
139
+ </OptionTitle>
140
+ {!(activeOrders && ordersLength.activeOrdersLength === 0 && ordersLength.previousOrdersLength === 0) && !loading && orders.length === 0 && (
131
141
  <NotFoundSource
132
142
  content={t('NO_RESULTS_FOUND', 'Sorry, no results found')}
133
143
  image={imageFails}
134
144
  conditioned
135
145
  />
136
146
  )}
147
+ {!loading && ordersLength.activeOrdersLength === 0 && ordersLength.previousOrdersLength === 0 && activeOrders && (
148
+ <NoOrdersWrapper>
149
+ <OText size={14} numberOfLines={1}>
150
+ {t('YOU_DONT_HAVE_ORDERS', 'You don\'t have any orders')}
151
+ </OText>
152
+ <OButton
153
+ text={t('ORDER_NOW', 'Order now')}
154
+ onClick={() => onNavigationRedirect && onNavigationRedirect('BusinessList')}
155
+ textStyle={{ color: 'white', fontSize: 14 }}
156
+ style={{ borderRadius: 7.6, marginBottom: 10, marginTop: 10, height: 44, paddingLeft: 10, paddingRight: 10 }}
157
+ />
158
+
159
+ </NoOrdersWrapper>
160
+ )}
137
161
  {loading && (
138
162
  <>
139
163
  {!activeOrders ? (
@@ -3,3 +3,8 @@ import styled from 'styled-components/native'
3
3
  export const OptionTitle = styled.View`
4
4
  margin-top: 24px;
5
5
  `
6
+
7
+ export const NoOrdersWrapper = styled.View`
8
+ flex-direction: column;
9
+ align-items: center;
10
+ `
@@ -96,7 +96,7 @@ export const PhoneInputNumber = (props: PhoneInputParams) => {
96
96
  }, [userphoneNumber])
97
97
 
98
98
  return (
99
- <Wrapper>
99
+ <Wrapper onPress={() => forwardRef?.current?.focus?.()}>
100
100
  <PhoneInput
101
101
  ref={phoneInput}
102
102
  disabled={isDisabled}
@@ -1,3 +1,3 @@
1
1
  import styled from 'styled-components/native';
2
2
 
3
- export const Wrapper = styled.View``
3
+ export const Wrapper = styled.Pressable``
@@ -4,7 +4,9 @@ import {
4
4
  useSession,
5
5
  useLanguage,
6
6
  useOrder,
7
- useUtils
7
+ useUtils,
8
+ ToastType,
9
+ useToast
8
10
  } from 'ordering-components/native';
9
11
  import { useTheme } from 'styled-components/native';
10
12
  import { ProductIngredient } from '../ProductIngredient';
@@ -13,11 +15,12 @@ import Swiper from 'react-native-swiper'
13
15
  import FastImage from 'react-native-fast-image';
14
16
  import IconAntDesign from 'react-native-vector-icons/AntDesign';
15
17
  import YoutubePlayer from "react-native-youtube-iframe"
18
+ import { TextInput } from 'react-native'
16
19
  import {
17
20
  Grayscale
18
21
  } from 'react-native-color-matrix-image-filters'
19
22
 
20
- import { View, TouchableOpacity, StyleSheet, Dimensions, I18nManager, SafeAreaView, Button, Alert } from 'react-native';
23
+ import { View, TouchableOpacity, StyleSheet, Dimensions, I18nManager, SafeAreaView, Platform, Button } from 'react-native';
21
24
 
22
25
  import {
23
26
  WrapHeader,
@@ -54,6 +57,7 @@ export const ProductOptionsUI = (props: any) => {
54
57
  productCart,
55
58
  increment,
56
59
  decrement,
60
+ handleChangeProductCartQuantity,
57
61
  showOption,
58
62
  maxProductQuantity,
59
63
  errors,
@@ -65,6 +69,7 @@ export const ProductOptionsUI = (props: any) => {
65
69
  } = props;
66
70
 
67
71
  const theme = useTheme();
72
+ const [, { showToast }] = useToast()
68
73
 
69
74
  const styles = StyleSheet.create({
70
75
  mainContainer: {
@@ -236,6 +241,14 @@ export const ProductOptionsUI = (props: any) => {
236
241
  setPlaying((prev) => !prev);
237
242
  }, []);
238
243
 
244
+ const onChangeProductCartQuantity = (quantity: number) => {
245
+ if (quantity >= maxProductQuantity) {
246
+ showToast(ToastType.Error, t('MAX_QUANTITY', 'The max quantity is _number_').replace('_number_', maxProductQuantity))
247
+ return
248
+ }
249
+ handleChangeProductCartQuantity(quantity)
250
+ }
251
+
239
252
  useEffect(() => {
240
253
  const imageList: any = []
241
254
  const videoList: any = []
@@ -816,7 +829,7 @@ export const ProductOptionsUI = (props: any) => {
816
829
  )}
817
830
  </ScrollView>
818
831
  {!loading && !error && product && (
819
- <ProductActions>
832
+ <ProductActions ios={Platform?.OS === 'ios'}>
820
833
  <OText size={16} lineHeight={24} weight={'600'}>
821
834
  {productCart.total ? parsePrice(productCart?.total) : ''}
822
835
  </OText>
@@ -835,14 +848,32 @@ export const ProductOptionsUI = (props: any) => {
835
848
  }
836
849
  />
837
850
  </TouchableOpacity>
838
- <OText
839
- size={12}
840
- lineHeight={18}
841
- style={{ minWidth: 40, textAlign: 'center' }}
842
- >
843
- {qtyBy?.pieces && productCart.quantity}
844
- {qtyBy?.weight_unit && productCart.quantity * product?.weight}
845
- </OText>
851
+ {qtyBy?.pieces && (
852
+ <TextInput
853
+ keyboardType='numeric'
854
+ value={`${productCart.quantity}` || ''}
855
+ onChangeText={(val: any) => onChangeProductCartQuantity(parseInt(val))}
856
+ editable={!orderState.loading}
857
+ style={{
858
+ borderWidth: 1,
859
+ textAlign: 'center',
860
+ minWidth: 60,
861
+ borderRadius: 8,
862
+ borderColor: theme.colors.inputBorderColor,
863
+ height: 44,
864
+ marginHorizontal: 10
865
+ }}
866
+ />
867
+ )}
868
+ {qtyBy?.weight_unit && (
869
+ <OText
870
+ size={12}
871
+ lineHeight={18}
872
+ style={{ minWidth: 40, textAlign: 'center' }}
873
+ >
874
+ {productCart.quantity * product?.weight}
875
+ </OText>
876
+ )}
846
877
  <TouchableOpacity
847
878
  onPress={increment}
848
879
  disabled={
@@ -71,7 +71,7 @@ export const ProductActions = styled.View`
71
71
  position: absolute;
72
72
  bottom: 0px;
73
73
  min-height: 70px;
74
- padding-top: 12px;
74
+ padding-top: ${(props : any) => props.ios ? '20px' : '0'};
75
75
  padding-horizontal: 40px;
76
76
  width: 100%;
77
77
  flex-direction: row;
@@ -52,7 +52,7 @@ export const ProductOptionSubOptionUI = (props: any) => {
52
52
  const disableIncrement = option?.limit_suboptions_by_max ? balance === option?.max : state.quantity === suboption?.max || (!state.selected && balance === option?.max)
53
53
  const price = option?.with_half_option && suboption?.half_price && state.position !== 'whole' ? suboption?.half_price : suboption?.price
54
54
  return (
55
- <Container>
55
+ <Container onPress={() => handleSuboptionClick()}>
56
56
  <IconControl disabled={disabled} onPress={() => handleSuboptionClick()}>
57
57
  {((option?.min === 0 && option?.max === 1) || option?.max > 1) ? (
58
58
  state?.selected ? (
@@ -1,6 +1,6 @@
1
1
  import styled, { css } from 'styled-components/native'
2
2
 
3
- export const Container = styled.View`
3
+ export const Container = styled.TouchableOpacity`
4
4
  flex-direction: row;
5
5
  align-items: center;
6
6
  justify-content: space-between;
@@ -135,14 +135,21 @@ export const SingleProductCard = (props: SingleProductCardParams) => {
135
135
  {product?.description}
136
136
  </OText>
137
137
  </CardInfo>
138
- <FastImage
139
- style={styles.productStyle}
140
- source={{
141
- uri: optimizeImage(product?.images, 'h_75,c_limit'),
142
- priority: FastImage.priority.normal,
143
- }}
144
- resizeMode={FastImage.resizeMode.cover}
145
- />
138
+ {product?.images ? (
139
+ <FastImage
140
+ style={styles.productStyle}
141
+ source={{
142
+ uri: optimizeImage(product?.images, 'h_75,c_limit'),
143
+ priority: FastImage.priority.normal,
144
+ }}
145
+ resizeMode={FastImage.resizeMode.cover}
146
+ />
147
+ ) : (
148
+ <OIcon
149
+ src={theme?.images?.dummies?.product}
150
+ style={styles.productStyle}
151
+ />
152
+ )}
146
153
  {(isSoldOut || maxProductQuantity <= 0) && (
147
154
  <SoldOut>
148
155
  <OText size={12} weight="bold" color={theme.colors.textSecondary} style={styles.soldOutTextStyle}>
@@ -155,9 +155,6 @@ const UpsellingProductsUI = (props: UpsellingProductsParams) => {
155
155
  <TopActions onPress={() => onGoBack()}>
156
156
  <OIcon src={theme.images.general.arrow_left} width={15} />
157
157
  </TopActions>
158
- <TopActions style={styles.cancelBtn} onPress={() => handleUpsellingPage()}>
159
- <OText size={12} color={theme.colors.textSecondary}>{t('CANCEL', 'Cancel')}</OText>
160
- </TopActions>
161
158
  </TopBar>
162
159
  <ScrollView style={{ marginBottom: props.isPage ? 40 : bottom + (Platform.OS == 'ios' ? 96 : 130) }} showsVerticalScrollIndicator={false}>
163
160
  <View style={{ paddingHorizontal: 40 }}>
@@ -178,7 +175,7 @@ const UpsellingProductsUI = (props: UpsellingProductsParams) => {
178
175
  <View
179
176
  style={{
180
177
  alignItems: 'center',
181
- bottom: props.isPage ? 20 : Platform.OS === 'ios' ? bottom + 59 : bottom + 125
178
+ bottom: props.isPage ? Platform.OS === 'ios' ? 0 : 20 : Platform.OS === 'ios' ? bottom + 59 : bottom + 125
182
179
  }}
183
180
  >
184
181
  <OButton