ordering-ui-react-native 0.21.50 → 0.21.51

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 (82) hide show
  1. package/package.json +1 -1
  2. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +6 -0
  3. package/themes/original/src/components/AddressForm/index.tsx +2 -2
  4. package/themes/original/src/components/AddressForm/styles.tsx +1 -1
  5. package/themes/original/src/components/AddressList/styles.tsx +4 -4
  6. package/themes/original/src/components/BusinessBasicInformation/index.tsx +2 -2
  7. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +1 -1
  8. package/themes/original/src/components/BusinessInformation/styles.tsx +2 -2
  9. package/themes/original/src/components/BusinessItemAccordion/index.tsx +4 -3
  10. package/themes/original/src/components/BusinessListingSearch/index.tsx +4 -5
  11. package/themes/original/src/components/BusinessListingSearch/styles.tsx +1 -1
  12. package/themes/original/src/components/BusinessPreorder/index.tsx +2 -2
  13. package/themes/original/src/components/BusinessProductsCategories/index.tsx +1 -1
  14. package/themes/original/src/components/BusinessProductsListing/index.tsx +7 -7
  15. package/themes/original/src/components/BusinessProductsListing/styles.tsx +2 -2
  16. package/themes/original/src/components/BusinessReviews/index.tsx +1 -1
  17. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +1 -1
  18. package/themes/original/src/components/BusinessesListing/Layout/Appointment/styles.tsx +5 -5
  19. package/themes/original/src/components/BusinessesListing/Layout/Original/FlatListBusinessListFooter.tsx +1 -1
  20. package/themes/original/src/components/BusinessesListing/Layout/Original/FlatListBusinessListHeader.tsx +7 -7
  21. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +1 -1
  22. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +1 -1
  23. package/themes/original/src/components/Cart/index.tsx +13 -4
  24. package/themes/original/src/components/CartContent/index.tsx +59 -38
  25. package/themes/original/src/components/CartStoresListing/styles.tsx +2 -2
  26. package/themes/original/src/components/Checkout/index.tsx +42 -8
  27. package/themes/original/src/components/Checkout/styles.tsx +17 -0
  28. package/themes/original/src/components/CitiesControl/styles.tsx +1 -1
  29. package/themes/original/src/components/Favorite/index.tsx +3 -4
  30. package/themes/original/src/components/Favorite/styles.tsx +0 -2
  31. package/themes/original/src/components/FloatingButton/styles.tsx +1 -1
  32. package/themes/original/src/components/GPSButton/index.tsx +1 -1
  33. package/themes/original/src/components/GiftCard/PurchaseGiftCard/styles.tsx +1 -1
  34. package/themes/original/src/components/GiftCard/RedeemGiftCard/styles.tsx +1 -1
  35. package/themes/original/src/components/GiftCard/SendGiftCard/styles.tsx +1 -1
  36. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +1 -1
  37. package/themes/original/src/components/HighestRatedBusinesses/styles.tsx +1 -1
  38. package/themes/original/src/components/Home/index.tsx +1 -1
  39. package/themes/original/src/components/Messages/styles.tsx +1 -1
  40. package/themes/original/src/components/MomentOption/index.tsx +3 -3
  41. package/themes/original/src/components/MultiCart/index.tsx +1 -1
  42. package/themes/original/src/components/MultiCheckout/index.tsx +4 -4
  43. package/themes/original/src/components/MultiOrdersDetails/index.tsx +1 -1
  44. package/themes/original/src/components/MyOrders/index.tsx +5 -5
  45. package/themes/original/src/components/NetworkError/styles.tsx +2 -2
  46. package/themes/original/src/components/Notifications/index.tsx +2 -4
  47. package/themes/original/src/components/Notifications/styles.tsx +0 -1
  48. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +1 -1
  49. package/themes/original/src/components/OrderDetails/index.tsx +702 -661
  50. package/themes/original/src/components/OrderDetails/styles.tsx +24 -7
  51. package/themes/original/src/components/OrderProgress/styles.tsx +1 -1
  52. package/themes/original/src/components/OrderSummary/index.tsx +3 -1
  53. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/styles.tsx +1 -1
  54. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/styles.tsx +1 -1
  55. package/themes/original/src/components/OrdersOption/index.tsx +1 -1
  56. package/themes/original/src/components/OrdersOption/styles.tsx +1 -1
  57. package/themes/original/src/components/ProductForm/ActionButton.tsx +117 -0
  58. package/themes/original/src/components/ProductForm/ExtraOptions.tsx +56 -0
  59. package/themes/original/src/components/ProductForm/index.tsx +52 -145
  60. package/themes/original/src/components/ProductItemAccordion/index.tsx +5 -0
  61. package/themes/original/src/components/ProductOptionSubOption/index.tsx +1 -1
  62. package/themes/original/src/components/ProfessionalProfile/styles.tsx +3 -3
  63. package/themes/original/src/components/Promotions/index.tsx +4 -4
  64. package/themes/original/src/components/Promotions/styles.tsx +0 -2
  65. package/themes/original/src/components/ReviewDriver/styles.tsx +1 -1
  66. package/themes/original/src/components/ReviewOrder/styles.tsx +1 -1
  67. package/themes/original/src/components/ReviewProducts/styles.tsx +1 -1
  68. package/themes/original/src/components/ServiceForm/index.tsx +1 -1
  69. package/themes/original/src/components/ServiceForm/styles.tsx +4 -4
  70. package/themes/original/src/components/StripeElementsForm/index.tsx +1 -1
  71. package/themes/original/src/components/UpsellingProducts/UpsellingContent.tsx +170 -0
  72. package/themes/original/src/components/UpsellingProducts/UpsellingLayout.tsx +86 -0
  73. package/themes/original/src/components/UpsellingProducts/index.tsx +15 -199
  74. package/themes/original/src/components/UpsellingProducts/styles.tsx +19 -0
  75. package/themes/original/src/components/UserFormDetails/index.tsx +16 -3
  76. package/themes/original/src/components/UserProfile/index.tsx +1 -1
  77. package/themes/original/src/components/WalletTransactions/styles.tsx +1 -0
  78. package/themes/original/src/components/Wallets/index.tsx +1 -3
  79. package/themes/original/src/components/Wallets/styles.tsx +1 -0
  80. package/themes/original/src/components/shared/HeaderTitle.tsx +1 -1
  81. package/themes/original/src/components/shared/OModal.tsx +12 -14
  82. package/themes/original/src/layouts/Container.tsx +1 -1
@@ -10,7 +10,7 @@ export const NavBack = styled.TouchableOpacity`
10
10
 
11
11
 
12
12
  export const Header = styled.View`
13
- padding: 10px 40px;
13
+ padding: 10px 20px;
14
14
  flex: 1;
15
15
  `
16
16
 
@@ -24,7 +24,7 @@ export const OrderContent = styled.View`
24
24
  export const OrderBusiness = styled.View`
25
25
  position: relative;
26
26
  padding-vertical: 10px;
27
- padding-horizontal: 40px;
27
+ padding-horizontal: 20px;
28
28
  background-color: ${(props: any) => props.theme.colors.white};
29
29
  align-items: flex-start;
30
30
  `
@@ -64,7 +64,7 @@ export const SectionTitle = styled.View`
64
64
  `
65
65
 
66
66
  export const OrderCustomer = styled.View`
67
- padding: 20px 40px 10px;
67
+ padding: 20px 20px 10px;
68
68
  background-color: ${(props: any) => props.theme.colors.white};
69
69
  `
70
70
 
@@ -86,7 +86,7 @@ export const InfoBlock = styled.View`
86
86
  export const HeaderInfo = styled.View`
87
87
  flex: 1;
88
88
  background-color: ${(props: any) => props.theme.colors.backgroundGray100};
89
- padding: 20px 40px;
89
+ padding: 20px 20px;
90
90
  `
91
91
 
92
92
  export const OrderProducts = styled(OrderCustomer)``
@@ -100,7 +100,7 @@ export const Table = styled.View`
100
100
  `
101
101
 
102
102
  export const OrderBill = styled.View`
103
- padding-horizontal: 40px;
103
+ padding-horizontal: 20px;
104
104
  padding-vertical: 10px;
105
105
  flex: 1;
106
106
  background-color: ${(props: any) => props.theme.colors.white};
@@ -130,7 +130,7 @@ export const OrderAction = styled.View`
130
130
  `
131
131
 
132
132
  export const PlaceSpotWrapper = styled.View`
133
- padding-horizontal: 40px;
133
+ padding-horizontal: 20px;
134
134
  `
135
135
 
136
136
  export const ProfessionalPhoto = styled.ImageBackground`
@@ -141,4 +141,21 @@ export const ProfessionalPhoto = styled.ImageBackground`
141
141
  width: 80px;
142
142
  resize-mode: cover;
143
143
  margin-right: 10px;
144
- `;
144
+ `;
145
+
146
+ export const TopActions = styled.TouchableOpacity`
147
+ height: 60px;
148
+ justify-content: center;
149
+ min-width: 30px;
150
+ padding-right: 15px;
151
+ `;
152
+
153
+ export const TopHeader = styled.View`
154
+ width: 100%;
155
+ flex-direction: row;
156
+ align-items: center;
157
+ justify-content: space-between;
158
+ z-index: 1;
159
+ height: 60px;
160
+ min-height: 60px;
161
+ `
@@ -32,5 +32,5 @@ export const OrderInfoWrapper = styled.View`
32
32
  export const OrderProgressWrapper = styled.View`
33
33
  margin-top: 37px;
34
34
  margin-bottom: 20px;
35
- padding-horizontal: 40px;
35
+ padding-horizontal: 20px;
36
36
  `
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, useRef } from 'react';
2
2
  import { ActivityIndicator, View } from 'react-native'
3
3
  import {
4
4
  Cart,
@@ -56,6 +56,7 @@ const OrderSummaryUI = (props: any) => {
56
56
  const [orderState] = useOrder();
57
57
  const [{ parsePrice, parseNumber }] = useUtils();
58
58
  const [validationFields] = useValidationFields();
59
+ const commentRef = useRef()
59
60
  const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null, type: '' })
60
61
  const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled;
61
62
  const hideCartComments = !validationFields?.fields?.checkout?.comments?.enabled
@@ -341,6 +342,7 @@ const OrderSummaryUI = (props: any) => {
341
342
  marginTop: 10,
342
343
  borderRadius: 8
343
344
  }}
345
+ forwardRef={commentRef}
344
346
  multiline
345
347
  />
346
348
  {commentState?.loading && (
@@ -2,5 +2,5 @@ import styled, { css } from 'styled-components/native'
2
2
 
3
3
  export const ListWrapper = styled.View`
4
4
  background-color: ${(props: any) => props.theme.colors.backgroundLight};
5
- padding-horizontal: ${(props : any) => props.isBusinessesSearchList ? '0' : '40px'};
5
+ padding-horizontal: ${(props : any) => props.isBusinessesSearchList ? '0' : '20px'};
6
6
  `;
@@ -2,5 +2,5 @@ import styled from 'styled-components/native'
2
2
 
3
3
  export const ListWrapper = styled.View`
4
4
  background-color: ${(props: any) => props.theme.colors.backgroundLight};
5
- padding-horizontal: ${(props : any) => props.isBusinessesSearchList ? '0' : '40px'};
5
+ padding-horizontal: ${(props : any) => props.isBusinessesSearchList ? '0' : '20px'};
6
6
  `;
@@ -312,7 +312,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
312
312
  />
313
313
  )
314
314
  )}
315
- {loading && !hideOrders && (
315
+ {loading && !hideOrders && !preOrders && (
316
316
  <>
317
317
  {!activeOrders ? (
318
318
  <Placeholder style={{ marginTop: 30 }} Animation={Fade}>
@@ -3,7 +3,7 @@ import styled, { css } from 'styled-components/native'
3
3
  export const OptionTitle = styled.View`
4
4
  margin-top: 24px;
5
5
  ${(props : any) => props.titleContent && css`
6
- margin-left: ${() => props.isBusinessesSearchList ? '0' : '40px'};
6
+ margin-left: ${() => props.isBusinessesSearchList ? '0' : '20px'};
7
7
  `}
8
8
  `
9
9
 
@@ -0,0 +1,117 @@
1
+ import React from 'react'
2
+ import { useSession, useOrder, useLanguage } from 'ordering-components/native'
3
+ import { useTheme } from 'styled-components/native'
4
+ import { TouchableOpacity, View } from 'react-native'
5
+ import { OButton, OText } from '../shared';
6
+ import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
7
+
8
+ export const ActionButton = (props : any) => {
9
+ const {
10
+ navigation,
11
+ isHaveWeight,
12
+ isSoldOut,
13
+ maxProductQuantity,
14
+ productCart,
15
+ handleSaveProduct,
16
+ editMode,
17
+ product,
18
+ errors,
19
+ productAddedToCartLength,
20
+ handleRedirectLogin,
21
+ guestCheckoutEnabled,
22
+ orderTypeEnabled,
23
+ handleUpdateGuest,
24
+ actionStatus
25
+ } = props
26
+ const [,t] = useLanguage()
27
+ const [{ auth }] = useSession()
28
+ const [orderState] = useOrder()
29
+ const theme = useTheme()
30
+
31
+ const saveErrors =
32
+ orderState.loading ||
33
+ maxProductQuantity === 0 ||
34
+ Object.keys(errors)?.length > 0;
35
+
36
+ return (
37
+ <View
38
+ style={{
39
+ width: isHaveWeight ? '100%' : ((isSoldOut || maxProductQuantity <= 0) ? '60%' : '40%'),
40
+ }}>
41
+ {((productCart &&
42
+ auth &&
43
+ orderState.options?.address_id) || (isSoldOut || maxProductQuantity <= 0)) && (
44
+ <OButton
45
+ onClick={() => handleSaveProduct()}
46
+ imgRightSrc=""
47
+ text={`${orderState.loading
48
+ ? t('LOADING', 'Loading')
49
+ : (isSoldOut || maxProductQuantity <= 0)
50
+ ? t('SOLD_OUT', 'Sold out')
51
+ : editMode
52
+ ? t('UPDATE', 'Update')
53
+ : t('ADD', 'Add')
54
+ }`}
55
+ isDisabled={isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order))}
56
+ textStyle={{
57
+ color: saveErrors || isSoldOut || maxProductQuantity <= 0 ? theme.colors.primary : theme.colors.white,
58
+ fontSize: orderState.loading || editMode ? 10 : 14
59
+ }}
60
+ style={{
61
+ backgroundColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order)) ? theme.colors.lightGray : theme.colors.primary,
62
+ borderColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order)) ? theme.colors.white : theme.colors.primary,
63
+ opacity: saveErrors || isSoldOut || maxProductQuantity <= 0 ? 0.3 : 1,
64
+ borderRadius: 7.6,
65
+ height: 44,
66
+ shadowOpacity: 0,
67
+ borderWidth: 1,
68
+ marginTop: isHaveWeight ? 10 : 0
69
+ }}
70
+ />
71
+ )}
72
+ {auth &&
73
+ !orderState.options?.address_id &&
74
+ (orderState.loading ? (
75
+ <OButton
76
+ isDisabled
77
+ text={t('LOADING', 'Loading')}
78
+ imgRightSrc=""
79
+ textStyle={{ fontSize: 10 }}
80
+ />
81
+ ) : (
82
+ <OButton onClick={navigation.navigate('AddressList')} />
83
+ ))}
84
+ {!auth && (
85
+ <OButton
86
+ isDisabled={isSoldOut || maxProductQuantity <= 0}
87
+ onClick={() => handleRedirectLogin()}
88
+ text={
89
+ isSoldOut || maxProductQuantity <= 0
90
+ ? t('SOLD_OUT', 'Sold out')
91
+ : t('LOGIN_SIGNUP', 'Login / Sign Up')
92
+ }
93
+ imgRightSrc=""
94
+ textStyle={{ color: theme.colors.primary, fontSize: 13, textAlign: 'center' }}
95
+ style={{
96
+ height: 42,
97
+ borderColor: theme.colors.primary,
98
+ backgroundColor: theme.colors.white,
99
+ paddingLeft: 0,
100
+ paddingRight: 0
101
+ }}
102
+ />
103
+ )}
104
+ {!auth && guestCheckoutEnabled && orderTypeEnabled && (
105
+ <TouchableOpacity style={{ marginTop: 10 }} onPress={handleUpdateGuest}>
106
+ {actionStatus?.loading ? (
107
+ <Placeholder Animation={Fade}>
108
+ <PlaceholderLine height={20} />
109
+ </Placeholder>
110
+ ) : (
111
+ <OText color={theme.colors.primary} size={13} style={{ textAlign: 'center' }}>{t('AS_GUEST_USER', 'As guest user')}</OText>
112
+ )}
113
+ </TouchableOpacity>
114
+ )}
115
+ </View>
116
+ )
117
+ }
@@ -0,0 +1,56 @@
1
+ import React from 'react'
2
+ import { TouchableOpacity } from 'react-native';
3
+ import { useTheme } from 'styled-components/native';
4
+ import { OText } from '../shared';
5
+
6
+ export const ExtraOptions = (props : any) => {
7
+ const {
8
+ options,
9
+ setSelectedOpt,
10
+ scrollViewRef,
11
+ optionLayout,
12
+ editionsLayoutY,
13
+ styles,
14
+ selOpt
15
+ } = props
16
+
17
+ const theme = useTheme()
18
+
19
+ return (
20
+ <>
21
+ {options.map(({ id, name, respect_to, suboptions }: any) => (
22
+ <React.Fragment key={`cont_key_${id}`}>
23
+ {respect_to == null && suboptions?.length > 0 && (
24
+ <TouchableOpacity
25
+ key={`eopt_key_${id}`}
26
+ onPress={() => {
27
+ setSelectedOpt(id)
28
+ scrollViewRef?.current?.scrollTo && scrollViewRef.current.scrollTo({
29
+ y: optionLayout[`id:${id}`]?.y + editionsLayoutY - 50,
30
+ animated: true
31
+ })
32
+ }}
33
+ style={[
34
+ styles.extraItem,
35
+ {
36
+ borderBottomColor:
37
+ selOpt == id ? theme.colors.textNormal : theme.colors.backgroundPage,
38
+ },
39
+ ]}>
40
+ <OText
41
+ color={
42
+ selOpt == id ? theme.colors.textNormal : theme.colors.textSecondary
43
+ }
44
+ size={12}
45
+ weight={selOpt == id ? '600' : 'normal'}
46
+ style={{ maxWidth: 150 }}
47
+ numberOfLines={1}>
48
+ {name}
49
+ </OText>
50
+ </TouchableOpacity>
51
+ )}
52
+ </React.Fragment>
53
+ ))}
54
+ </>
55
+ )
56
+ }
@@ -56,8 +56,12 @@ import { NotFoundSource } from '../NotFoundSource';
56
56
  import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
57
57
  import NavBar from '../NavBar';
58
58
  import { orderTypeList } from '../../utils';
59
+ import { ActionButton } from './ActionButton'
60
+ import { ExtraOptions } from './ExtraOptions'
59
61
  const windowWidth = Dimensions.get('window').width;
60
62
 
63
+
64
+
61
65
  export const ProductOptionsUI = (props: any) => {
62
66
  const {
63
67
  navigation,
@@ -79,11 +83,10 @@ export const ProductOptionsUI = (props: any) => {
79
83
  actionStatus,
80
84
  handleCreateGuestUser
81
85
  } = props;
82
-
83
86
  const theme = useTheme();
84
87
  const [, { showToast }] = useToast()
85
88
  const [events] = useEvent()
86
-
89
+ const commentRef = useRef()
87
90
  const isChewLayout = theme?.header?.components?.layout?.type?.toLowerCase() === 'chew'
88
91
 
89
92
  const styles = StyleSheet.create({
@@ -138,7 +141,7 @@ export const ProductOptionsUI = (props: any) => {
138
141
  slide1: {
139
142
  flex: 1,
140
143
  alignItems: 'center',
141
- width: '100%',
144
+ width: '100%'
142
145
  },
143
146
  mainSwiper: {
144
147
  height: 258,
@@ -177,7 +180,7 @@ export const ProductOptionsUI = (props: any) => {
177
180
  marginTop: 10
178
181
  },
179
182
  wrapperNavbar: {
180
- paddingHorizontal: 30,
183
+ paddingHorizontal: 20,
181
184
  paddingTop: 0,
182
185
  }
183
186
  });
@@ -208,7 +211,7 @@ export const ProductOptionsUI = (props: any) => {
208
211
  const [editionsLayoutY, setEditionsLayoutY] = useState(null)
209
212
  const [viewedProduct, setViewedProduct] = useState<any>(null)
210
213
  const [showTitle, setShowTitle] = useState(false)
211
-
214
+ const productOptionsMounted = useRef(false)
212
215
  const guestCheckoutEnabled = configs?.guest_checkout_enabled?.value === '1'
213
216
  const orderTypeEnabled = !orderTypeList[orderState?.options?.type - 1] || configs?.allowed_order_types_guest_checkout?.value?.includes(orderTypeList[orderState?.options?.type - 1])
214
217
 
@@ -320,58 +323,18 @@ export const ProductOptionsUI = (props: any) => {
320
323
  const guestToken = uuid.v4()
321
324
  if (guestToken) handleCreateGuestUser({ guest_token: guestToken })
322
325
  }
326
+
327
+ let _optionLayout : any = {}
323
328
 
324
- const handleOnLayout = (event: any, optionId: any) => {
325
- const _optionLayout = { ...optionLayout }
329
+ const handleOnLayout = (event: any, optionId: any, lastMounts: boolean) => {
330
+ _optionLayout = { ..._optionLayout }
326
331
  const optionKey = 'id:' + optionId
327
332
  _optionLayout[optionKey] = { y: event.nativeEvent.layout?.y }
328
- setOptionLayout(_optionLayout)
333
+ if (lastMounts) {
334
+ setOptionLayout(_optionLayout)
335
+ }
329
336
  }
330
337
 
331
- const saveErrors =
332
- orderState.loading ||
333
- maxProductQuantity === 0 ||
334
- Object.keys(errors)?.length > 0;
335
-
336
-
337
- const ExtraOptions = ({ eID, options }: any) => (
338
- <>
339
- {options.map(({ id, name, respect_to, suboptions }: any) => (
340
- <React.Fragment key={`cont_key_${id}`}>
341
- {respect_to == null && suboptions?.length > 0 && (
342
- <TouchableOpacity
343
- key={`eopt_key_${id}`}
344
- onPress={() => {
345
- setSelectedOpt(id)
346
- scrollViewRef?.current?.scrollTo && scrollViewRef.current.scrollTo({
347
- y: optionLayout[`id:${id}`]?.y + editionsLayoutY - 50,
348
- animated: true
349
- })
350
- }}
351
- style={[
352
- styles.extraItem,
353
- {
354
- borderBottomColor:
355
- selOpt == id ? theme.colors.textNormal : theme.colors.backgroundPage,
356
- },
357
- ]}>
358
- <OText
359
- color={
360
- selOpt == id ? theme.colors.textNormal : theme.colors.textSecondary
361
- }
362
- size={12}
363
- weight={selOpt == id ? '600' : 'normal'}
364
- style={{ maxWidth: 150 }}
365
- numberOfLines={1}>
366
- {name}
367
- </OText>
368
- </TouchableOpacity>
369
- )}
370
- </React.Fragment>
371
- ))}
372
- </>
373
- );
374
-
375
338
  const handleScroll = ({ nativeEvent: { contentOffset } }: any) => {
376
339
  setShowTitle(contentOffset.y > 30)
377
340
  }
@@ -431,90 +394,6 @@ export const ProductOptionsUI = (props: any) => {
431
394
  }
432
395
  }, [product])
433
396
 
434
- const ActionButton = () => {
435
- return (
436
- <View
437
- style={{
438
- width: isHaveWeight ? '100%' : ((isSoldOut || maxProductQuantity <= 0) ? '60%' : '40%'),
439
- }}>
440
- {((productCart &&
441
- auth &&
442
- orderState.options?.address_id) || (isSoldOut || maxProductQuantity <= 0)) && (
443
- <OButton
444
- onClick={() => handleSaveProduct()}
445
- imgRightSrc=""
446
- text={`${orderState.loading
447
- ? t('LOADING', 'Loading')
448
- : (isSoldOut || maxProductQuantity <= 0)
449
- ? t('SOLD_OUT', 'Sold out')
450
- : editMode
451
- ? t('UPDATE', 'Update')
452
- : t('ADD', 'Add')
453
- }`}
454
- isDisabled={isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order))}
455
- textStyle={{
456
- color: saveErrors || isSoldOut || maxProductQuantity <= 0 ? theme.colors.primary : theme.colors.white,
457
- fontSize: orderState.loading || editMode ? 10 : 14
458
- }}
459
- style={{
460
- backgroundColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order)) ? theme.colors.lightGray : theme.colors.primary,
461
- borderColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && ((productCart?.quantity + productAddedToCartLength) < product?.minimum_per_order)) || (product?.maximum_per_order && ((productCart?.quantity + productAddedToCartLength) > product?.maximum_per_order)) ? theme.colors.white : theme.colors.primary,
462
- opacity: saveErrors || isSoldOut || maxProductQuantity <= 0 ? 0.3 : 1,
463
- borderRadius: 7.6,
464
- height: 44,
465
- shadowOpacity: 0,
466
- borderWidth: 1,
467
- marginTop: isHaveWeight ? 10 : 0
468
- }}
469
- />
470
- )}
471
- {auth &&
472
- !orderState.options?.address_id &&
473
- (orderState.loading ? (
474
- <OButton
475
- isDisabled
476
- text={t('LOADING', 'Loading')}
477
- imgRightSrc=""
478
- textStyle={{ fontSize: 10 }}
479
- />
480
- ) : (
481
- <OButton onClick={navigation.navigate('AddressList')} />
482
- ))}
483
- {!auth && (
484
- <OButton
485
- isDisabled={isSoldOut || maxProductQuantity <= 0}
486
- onClick={() => handleRedirectLogin()}
487
- text={
488
- isSoldOut || maxProductQuantity <= 0
489
- ? t('SOLD_OUT', 'Sold out')
490
- : t('LOGIN_SIGNUP', 'Login / Sign Up')
491
- }
492
- imgRightSrc=""
493
- textStyle={{ color: theme.colors.primary, fontSize: 13, textAlign: 'center' }}
494
- style={{
495
- height: 42,
496
- borderColor: theme.colors.primary,
497
- backgroundColor: theme.colors.white,
498
- paddingLeft: 0,
499
- paddingRight: 0
500
- }}
501
- />
502
- )}
503
- {!auth && guestCheckoutEnabled && orderTypeEnabled && (
504
- <TouchableOpacity style={{ marginTop: 10 }} onPress={handleUpdateGuest}>
505
- {actionStatus?.loading ? (
506
- <Placeholder Animation={Fade}>
507
- <PlaceholderLine height={20} />
508
- </Placeholder>
509
- ) : (
510
- <OText color={theme.colors.primary} size={13} style={{ textAlign: 'center' }}>{t('AS_GUEST_USER', 'As guest user')}</OText>
511
- )}
512
- </TouchableOpacity>
513
- )}
514
- </View>
515
- )
516
- }
517
-
518
397
  useEffect(() => {
519
398
  const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
520
399
  scrollViewRef.current.scrollToEnd({ animated: true })
@@ -530,6 +409,33 @@ export const ProductOptionsUI = (props: any) => {
530
409
  events.emit('product_viewed', product)
531
410
  }, [product?.id, viewedProduct])
532
411
 
412
+ const actionButtonProps = {
413
+ navigation,
414
+ isHaveWeight,
415
+ isSoldOut,
416
+ maxProductQuantity,
417
+ productCart,
418
+ handleSaveProduct,
419
+ editMode,
420
+ product,
421
+ errors,
422
+ productAddedToCartLength,
423
+ handleRedirectLogin,
424
+ guestCheckoutEnabled,
425
+ orderTypeEnabled,
426
+ handleUpdateGuest,
427
+ actionStatus
428
+ }
429
+
430
+ const extraOptionsProps = {
431
+ setSelectedOpt,
432
+ scrollViewRef,
433
+ optionLayout,
434
+ editionsLayoutY,
435
+ styles,
436
+ selOpt
437
+ }
438
+
533
439
  return (
534
440
  <SafeAreaView style={{ flex: 1 }}>
535
441
  <View style={styles.wrapperNavbar}>
@@ -635,7 +541,7 @@ export const ProductOptionsUI = (props: any) => {
635
541
  <ScrollView
636
542
  horizontal
637
543
  contentContainerStyle={{
638
- paddingHorizontal: 30,
544
+ paddingHorizontal: 20,
639
545
  paddingVertical: 15
640
546
  }}
641
547
  >
@@ -688,7 +594,7 @@ export const ProductOptionsUI = (props: any) => {
688
594
  )}
689
595
  </WrapHeader>
690
596
  <ProductSummary
691
- ph={isChewLayout ? 20 : 30}
597
+ ph={20}
692
598
  onLayout={(event: any) => setSummaryRefHeight(event.nativeEvent.layout?.height)}
693
599
  >
694
600
  <ProductTitle>
@@ -822,7 +728,7 @@ export const ProductOptionsUI = (props: any) => {
822
728
  </TouchableOpacity>
823
729
  )}
824
730
  {product?.extras?.map((extra: any) =>
825
- <ExtraOptions key={extra.id} options={extra.options} />
731
+ <ExtraOptions key={extra.id} options={extra.options} {...extraOptionsProps} />
826
732
  )}
827
733
  </ExtraOptionWrap>
828
734
  )}
@@ -866,14 +772,14 @@ export const ProductOptionsUI = (props: any) => {
866
772
  </>
867
773
  ) : (
868
774
  <ProductEditions
869
- style={{ paddingHorizontal: isChewLayout ? 20 : 30 }}
775
+ style={{ paddingHorizontal: 20 }}
870
776
  onLayout={(event: any) => {
871
777
  setEditionsLayoutY(event.nativeEvent.layout?.y)
872
778
  }}
873
779
  >
874
780
  <>
875
781
  {product?.ingredients?.length > 0 && (
876
- <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, 0)}>
782
+ <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, 0, true)}>
877
783
  <SectionTitle>
878
784
  <OText size={16}>
879
785
  {t('INGREDIENTS', 'Ingredients')}
@@ -895,13 +801,13 @@ export const ProductOptionsUI = (props: any) => {
895
801
  </View>
896
802
  )}
897
803
  {product?.extras?.sort((a: any, b: any) => a.rank - b.rank).map((extra: any) =>
898
- extra.options?.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => {
804
+ extra.options?.sort((a: any, b: any) => a.rank - b.rank).map((option: any, i: number) => {
899
805
  const currentState =
900
806
  productCart.options[`id:${option.id}`] || {};
901
807
  return (
902
808
  <React.Fragment key={`popt_${option.id}`}>
903
809
  {showOption(option) && (
904
- <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, option?.id)}>
810
+ <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, option?.id, extra.options?.length <= i + 2)}>
905
811
  <ProductOption
906
812
  option={option}
907
813
  currentState={currentState}
@@ -967,6 +873,7 @@ export const ProductOptionsUI = (props: any) => {
967
873
  !(productCart && !isSoldOut && maxProductQuantity)
968
874
  }
969
875
  style={styles.comment}
876
+ forwardRef={commentRef}
970
877
  />
971
878
  </ProductComment>
972
879
  )}
@@ -1086,9 +993,9 @@ export const ProductOptionsUI = (props: any) => {
1086
993
  )}
1087
994
  </>
1088
995
  )}
1089
- {!isHaveWeight && <ActionButton />}
996
+ {!isHaveWeight && <ActionButton {...actionButtonProps} />}
1090
997
  </View>
1091
- {isHaveWeight && <ActionButton />}
998
+ {isHaveWeight && <ActionButton {...actionButtonProps} />}
1092
999
  </ProductActions>
1093
1000
  )}
1094
1001
  </SafeAreaView>
@@ -215,6 +215,11 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
215
215
  style={pickerStyle}
216
216
  useNativeAndroidPickerStyle={false}
217
217
  placeholder={{}}
218
+ touchableWrapperProps={{
219
+ style: {
220
+ width: 40,
221
+ }
222
+ }}
218
223
  Icon={() => <View style={pickerStyle.icon}><OIcon src={theme.images.general.arrow_down} color={theme.colors.textNormal} width={8} /></View>}
219
224
  disabled={orderState.loading}
220
225
  />
@@ -82,7 +82,7 @@ export const ProductOptionSubOptionUI = (props: any) => {
82
82
 
83
83
  return (
84
84
  <View>
85
- <Container onPress={!(option?.with_half_option || option?.allow_suboption_quantity) ? () => handleSuboptionClick() : null}>
85
+ <Container onPress={!((option?.with_half_option || option?.allow_suboption_quantity) && state?.selected) ? () => handleSuboptionClick() : null}>
86
86
  <IconControl disabled={disabled} onPress={() => handleSuboptionClick()}>
87
87
  {((option?.min === 0 && option?.max === 1) || option?.max > 1) ? (
88
88
  state?.selected ? (
@@ -12,7 +12,7 @@ export const ProfessionalPhoto = styled.ImageBackground`
12
12
 
13
13
  export const InfoWrapper = styled.View`
14
14
  margin-vertical: 30px;
15
- padding-horizontal: 40px;
15
+ padding-horizontal: 20px;
16
16
  `
17
17
 
18
18
  export const Divider = styled.View`
@@ -22,7 +22,7 @@ export const Divider = styled.View`
22
22
  `
23
23
 
24
24
  export const ScheduleWrapper = styled.View`
25
- padding-horizontal: 40px;
25
+ padding-horizontal: 20px;
26
26
  margin-top: 30px;
27
27
  `
28
28
 
@@ -43,4 +43,4 @@ export const CalendarWrapper = styled.View`
43
43
  border-color: ${(props: any) => props.theme.colors.backgroundGray200};
44
44
  border-radius: 7.6px;
45
45
  padding: 15px;
46
- `
46
+ `