ordering-ui-react-native 0.16.12 → 0.16.13-release

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 (213) hide show
  1. package/package.json +8 -4
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/ActiveOrders/index.tsx +61 -63
  4. package/src/components/ActiveOrders/styles.tsx +8 -14
  5. package/src/components/AddressForm/index.tsx +18 -2
  6. package/src/components/BusinessBasicInformation/index.tsx +11 -19
  7. package/src/components/BusinessController/index.tsx +10 -8
  8. package/src/components/BusinessInformation/index.tsx +22 -0
  9. package/src/components/BusinessProductsList/index.tsx +10 -10
  10. package/src/components/BusinessTypeFilter/index.tsx +1 -2
  11. package/src/components/BusinessesListing/index.tsx +1 -1
  12. package/src/components/Checkout/index.tsx +2 -1
  13. package/src/components/LanguageSelector/index.tsx +21 -16
  14. package/src/components/LoginForm/index.tsx +118 -30
  15. package/src/components/LoginForm/styles.tsx +6 -0
  16. package/src/components/Messages/index.tsx +2 -2
  17. package/src/components/NotificationSetting/index.tsx +85 -0
  18. package/src/components/OrderDetails/index.tsx +7 -21
  19. package/src/components/OrdersOption/index.tsx +54 -56
  20. package/src/components/PaymentOptions/index.tsx +335 -365
  21. package/src/components/PaymentOptionsWebView/index.tsx +120 -121
  22. package/src/components/ReviewDriver/index.tsx +1 -1
  23. package/src/components/ReviewOrder/index.tsx +2 -1
  24. package/src/components/ReviewProducts/index.tsx +11 -0
  25. package/src/components/SignupForm/index.tsx +143 -61
  26. package/src/components/SingleProductReview/index.tsx +8 -5
  27. package/src/components/StripeElementsForm/index.tsx +25 -16
  28. package/src/components/VerifyPhone/styles.tsx +1 -2
  29. package/src/components/shared/OBottomPopup.tsx +6 -2
  30. package/src/index.tsx +2 -0
  31. package/src/navigators/CheckoutNavigator.tsx +6 -0
  32. package/src/navigators/HomeNavigator.tsx +6 -0
  33. package/src/pages/BusinessesListing.tsx +7 -6
  34. package/src/pages/MultiCheckout.tsx +31 -0
  35. package/src/pages/MultiOrdersDetails.tsx +27 -0
  36. package/src/pages/OrderDetails.tsx +1 -1
  37. package/src/pages/ReviewDriver.tsx +2 -2
  38. package/src/pages/ReviewOrder.tsx +2 -2
  39. package/src/theme.json +0 -1
  40. package/src/types/@fatnlazycat/react-native-recaptcha-v3/index.d.ts +1 -0
  41. package/src/types/index.tsx +13 -9
  42. package/src/utils/index.tsx +0 -1
  43. package/themes/business/index.tsx +4 -0
  44. package/themes/business/src/components/BusinessController/index.tsx +2 -2
  45. package/themes/business/src/components/Chat/index.tsx +42 -34
  46. package/themes/business/src/components/DriverMap/index.tsx +13 -10
  47. package/themes/business/src/components/DriverSchedule/index.tsx +71 -0
  48. package/themes/business/src/components/DriverSchedule/styles.tsx +6 -0
  49. package/themes/business/src/components/LoginForm/index.tsx +111 -74
  50. package/themes/business/src/components/MapView/index.tsx +1 -1
  51. package/themes/business/src/components/MessagesOption/index.tsx +11 -1
  52. package/themes/business/src/components/OrderDetails/Business.tsx +1 -1
  53. package/themes/business/src/components/OrderDetails/Delivery.tsx +3 -3
  54. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +19 -18
  55. package/themes/business/src/components/OrdersListManager/index.tsx +10 -3
  56. package/themes/business/src/components/OrdersOption/index.tsx +65 -21
  57. package/themes/business/src/components/OrdersOption/styles.tsx +5 -1
  58. package/themes/business/src/components/OrdersOptionBusiness/index.tsx +15 -1
  59. package/themes/business/src/components/OrdersOptionCity/index.tsx +15 -1
  60. package/themes/business/src/components/OrdersOptionDate/index.tsx +19 -6
  61. package/themes/business/src/components/OrdersOptionDelivery/index.tsx +15 -1
  62. package/themes/business/src/components/OrdersOptionDriver/index.tsx +15 -1
  63. package/themes/business/src/components/OrdersOptionPaymethod/index.tsx +15 -1
  64. package/themes/business/src/components/OrdersOptionStatus/index.tsx +10 -1
  65. package/themes/business/src/components/PreviousMessages/index.tsx +17 -18
  66. package/themes/business/src/components/PreviousOrders/index.tsx +21 -23
  67. package/themes/business/src/components/ProductItemAccordion/index.tsx +5 -4
  68. package/themes/business/src/components/ReviewCustomer/index.tsx +1 -1
  69. package/themes/business/src/components/ScheduleBlocked/index.tsx +53 -0
  70. package/themes/business/src/components/UserFormDetails/index.tsx +5 -2
  71. package/themes/business/src/components/UserProfileForm/index.tsx +28 -4
  72. package/themes/business/src/components/shared/ODropDown.tsx +42 -8
  73. package/themes/business/src/components/shared/ODropDownCalendar.tsx +36 -7
  74. package/themes/business/src/components/shared/OModal.tsx +40 -37
  75. package/themes/business/src/types/index.tsx +14 -9
  76. package/themes/business/src/utils/index.tsx +10 -0
  77. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  78. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  79. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  80. package/themes/kiosk/src/components/BusinessMenu/index.tsx +2 -1
  81. package/themes/kiosk/src/components/CartItem/index.tsx +4 -3
  82. package/themes/kiosk/src/components/CategoriesMenu/index.tsx +1 -0
  83. package/themes/kiosk/src/components/Checkout/index.tsx +6 -0
  84. package/themes/kiosk/src/components/DrawerView/index.tsx +1 -0
  85. package/themes/kiosk/src/components/DrawerView/styles.tsx +2 -2
  86. package/themes/kiosk/src/components/LoginForm/index.tsx +121 -10
  87. package/themes/kiosk/src/components/LoginForm/styles.tsx +5 -0
  88. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  89. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  90. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +8 -10
  91. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  92. package/themes/kiosk/src/types/index.d.ts +2 -0
  93. package/themes/original/index.tsx +16 -0
  94. package/themes/original/src/components/AddressForm/index.tsx +136 -133
  95. package/themes/original/src/components/AddressList/index.tsx +1 -1
  96. package/themes/original/src/components/AppleLogin/index.tsx +4 -4
  97. package/themes/original/src/components/BusinessBasicInformation/index.tsx +302 -160
  98. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +6 -2
  99. package/themes/original/src/components/BusinessController/index.tsx +173 -108
  100. package/themes/original/src/components/BusinessItemAccordion/index.tsx +12 -9
  101. package/themes/original/src/components/BusinessItemAccordion/styles.tsx +3 -1
  102. package/themes/original/src/components/BusinessListingSearch/BusinessControllerSkeletons/index.tsx +57 -0
  103. package/themes/original/src/components/BusinessListingSearch/MaxSectionItem/index.tsx +59 -0
  104. package/themes/original/src/components/BusinessListingSearch/MaxSectionItem/styles.tsx +13 -0
  105. package/themes/original/src/components/BusinessListingSearch/index.tsx +106 -126
  106. package/themes/original/src/components/BusinessListingSearch/styles.tsx +18 -13
  107. package/themes/original/src/components/BusinessProductsList/CategoryDescription/index.tsx +44 -0
  108. package/themes/original/src/components/BusinessProductsList/SubcategoriesComponent/index.tsx +87 -0
  109. package/themes/original/src/components/BusinessProductsList/SubcategoriesComponent/styles.tsx +12 -0
  110. package/themes/original/src/components/BusinessProductsList/index.tsx +60 -77
  111. package/themes/original/src/components/BusinessProductsList/styles.tsx +0 -3
  112. package/themes/original/src/components/BusinessProductsListing/index.tsx +290 -181
  113. package/themes/original/src/components/BusinessProductsListing/styles.tsx +18 -0
  114. package/themes/original/src/components/BusinessReviews/index.tsx +6 -1
  115. package/themes/original/src/components/BusinessTypeFilter/index.tsx +109 -40
  116. package/themes/original/src/components/BusinessTypeFilter/styles.tsx +2 -0
  117. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +561 -0
  118. package/themes/original/src/components/BusinessesListing/{styles.tsx → Layout/Appointment/styles.tsx} +24 -2
  119. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +676 -0
  120. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +137 -0
  121. package/themes/original/src/components/BusinessesListing/index.tsx +100 -484
  122. package/themes/original/src/components/Cart/index.tsx +81 -36
  123. package/themes/original/src/components/Cart/styles.tsx +4 -0
  124. package/themes/original/src/components/CartContent/index.tsx +22 -16
  125. package/themes/original/src/components/Checkout/index.tsx +106 -66
  126. package/themes/original/src/components/Checkout/styles.tsx +0 -1
  127. package/themes/original/src/components/DriverTips/index.tsx +4 -4
  128. package/themes/original/src/components/DriverTips/styles.tsx +2 -1
  129. package/themes/original/src/components/Favorite/index.tsx +1 -0
  130. package/themes/original/src/components/Favorite/styles.tsx +1 -0
  131. package/themes/original/src/components/FavoriteList/index.tsx +143 -94
  132. package/themes/original/src/components/GPSButton/index.tsx +25 -17
  133. package/themes/original/src/components/GoogleMap/index.tsx +20 -12
  134. package/themes/original/src/components/HelpAccountAndPayment/index.tsx +8 -3
  135. package/themes/original/src/components/HelpGuide/index.tsx +8 -3
  136. package/themes/original/src/components/HelpOrder/index.tsx +8 -3
  137. package/themes/original/src/components/LoginForm/Otp/index.tsx +3 -2
  138. package/themes/original/src/components/LoginForm/index.tsx +79 -42
  139. package/themes/original/src/components/Messages/index.tsx +17 -17
  140. package/themes/original/src/components/MomentSelector/index.tsx +197 -0
  141. package/themes/original/src/components/MomentSelector/styles.tsx +6 -0
  142. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +243 -0
  143. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/styles.tsx +46 -0
  144. package/themes/original/src/components/MultiCheckout/index.tsx +304 -0
  145. package/themes/original/src/components/MultiCheckout/styles.tsx +59 -0
  146. package/themes/original/src/components/MultiOrdersDetails/SingleOrderCard.tsx +372 -0
  147. package/themes/original/src/components/MultiOrdersDetails/index.tsx +262 -0
  148. package/themes/original/src/components/MultiOrdersDetails/styles.tsx +50 -0
  149. package/themes/original/src/components/MyOrders/index.tsx +177 -27
  150. package/themes/original/src/components/MyOrders/styles.tsx +8 -1
  151. package/themes/original/src/components/NavBar/index.tsx +11 -5
  152. package/themes/original/src/components/NetworkError/index.tsx +5 -3
  153. package/themes/original/src/components/NotFoundSource/index.tsx +2 -1
  154. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +167 -0
  155. package/themes/original/src/components/OrderDetails/index.tsx +125 -40
  156. package/themes/original/src/components/OrderDetails/styles.tsx +5 -2
  157. package/themes/original/src/components/OrderItAgain/index.tsx +75 -0
  158. package/themes/original/src/components/OrderItAgain/styles.tsx +10 -0
  159. package/themes/original/src/components/OrderProgress/index.tsx +8 -2
  160. package/themes/original/src/components/OrderSummary/index.tsx +1 -34
  161. package/themes/original/src/components/OrderTypeSelector/index.tsx +84 -36
  162. package/themes/original/src/components/OrderTypeSelector/styles.tsx +19 -1
  163. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +144 -0
  164. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/styles.tsx +6 -0
  165. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/index.tsx +56 -0
  166. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/styles.tsx +6 -0
  167. package/themes/original/src/components/OrdersOption/index.tsx +126 -37
  168. package/themes/original/src/components/OrdersOption/styles.tsx +4 -1
  169. package/themes/original/src/components/PaymentOptionWallet/index.tsx +56 -56
  170. package/themes/original/src/components/PaymentOptions/index.tsx +57 -37
  171. package/themes/original/src/components/PhoneInputNumber/index.tsx +4 -10
  172. package/themes/original/src/components/PlaceSpot/index.tsx +243 -47
  173. package/themes/original/src/components/PlaceSpot/styles.tsx +0 -2
  174. package/themes/original/src/components/ProductForm/index.tsx +712 -655
  175. package/themes/original/src/components/ProductForm/styles.tsx +9 -7
  176. package/themes/original/src/components/ProductItemAccordion/index.tsx +40 -27
  177. package/themes/original/src/components/ProductOption/index.tsx +1 -1
  178. package/themes/original/src/components/ProfessionalFilter/index.tsx +129 -0
  179. package/themes/original/src/components/ProfessionalFilter/styles.tsx +0 -0
  180. package/themes/original/src/components/ProfessionalProfile/index.tsx +309 -0
  181. package/themes/original/src/components/ProfessionalProfile/styles.tsx +46 -0
  182. package/themes/original/src/components/ReviewDriver/index.tsx +6 -6
  183. package/themes/original/src/components/ReviewOrder/index.tsx +18 -3
  184. package/themes/original/src/components/ReviewProducts/index.tsx +1 -1
  185. package/themes/original/src/components/ReviewTrigger/index.tsx +118 -0
  186. package/themes/original/src/components/ReviewTrigger/styles.tsx +34 -0
  187. package/themes/original/src/components/SearchBar/index.tsx +10 -5
  188. package/themes/original/src/components/ServiceForm/index.tsx +608 -0
  189. package/themes/original/src/components/ServiceForm/styles.tsx +50 -0
  190. package/themes/original/src/components/SignupForm/index.tsx +301 -158
  191. package/themes/original/src/components/SingleOrderCard/index.tsx +213 -177
  192. package/themes/original/src/components/SingleProductCard/index.tsx +198 -110
  193. package/themes/original/src/components/SingleProductCard/styles.tsx +2 -2
  194. package/themes/original/src/components/SingleProductReview/index.tsx +30 -3
  195. package/themes/original/src/components/SingleProductReview/styles.tsx +12 -0
  196. package/themes/original/src/components/StripeElementsForm/index.tsx +25 -9
  197. package/themes/original/src/components/StripeElementsForm/naked.tsx +2 -2
  198. package/themes/original/src/components/UpsellingProducts/index.tsx +14 -4
  199. package/themes/original/src/components/UserDetails/index.tsx +32 -18
  200. package/themes/original/src/components/UserFormDetails/index.tsx +107 -73
  201. package/themes/original/src/components/UserProfile/index.tsx +8 -1
  202. package/themes/original/src/components/UserProfileForm/index.tsx +15 -10
  203. package/themes/original/src/components/WalletTransactions/index.tsx +76 -0
  204. package/themes/original/src/components/WalletTransactions/styles.tsx +13 -0
  205. package/themes/original/src/components/Wallets/index.tsx +174 -162
  206. package/themes/original/src/components/Wallets/styles.tsx +10 -8
  207. package/themes/original/src/components/shared/OBottomPopup.tsx +47 -14
  208. package/themes/original/src/components/shared/OButton.tsx +10 -3
  209. package/themes/original/src/components/shared/OInput.tsx +3 -2
  210. package/themes/original/src/layouts/FloatingBottomContainer.tsx +5 -1
  211. package/themes/original/src/types/index.tsx +160 -47
  212. package/themes/original/src/utils/index.tsx +77 -0
  213. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
@@ -1,4 +1,16 @@
1
- import React, { useEffect, useRef, useCallback } from 'react';
1
+ import React, { useEffect, useRef, useState, useCallback } from 'react';
2
+ import {
3
+ View,
4
+ Keyboard,
5
+ TextInput,
6
+ TouchableOpacity,
7
+ StyleSheet,
8
+ Dimensions,
9
+ I18nManager,
10
+ SafeAreaView,
11
+ Platform,
12
+ Button
13
+ } from 'react-native';
2
14
  import {
3
15
  ProductForm as ProductOptions,
4
16
  useSession,
@@ -15,17 +27,10 @@ import Swiper from 'react-native-swiper'
15
27
  import FastImage from 'react-native-fast-image';
16
28
  import IconAntDesign from 'react-native-vector-icons/AntDesign';
17
29
  import YoutubePlayer from "react-native-youtube-iframe"
18
- import { TextInput } from 'react-native'
19
- import {
20
- Grayscale
21
- } from 'react-native-color-matrix-image-filters'
22
-
23
- import { View, TouchableOpacity, StyleSheet, Dimensions, I18nManager, SafeAreaView, Platform, Button } from 'react-native';
24
30
 
25
31
  import {
26
32
  WrapHeader,
27
33
  TopHeader,
28
- WrapContent,
29
34
  ProductTitle,
30
35
  ProductDescription,
31
36
  ProductEditions,
@@ -45,8 +50,6 @@ import { ScrollView } from 'react-native-gesture-handler';
45
50
  import { ProductOptionSubOption } from '../ProductOptionSubOption';
46
51
  import { NotFoundSource } from '../NotFoundSource';
47
52
  import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
48
- import { useState } from 'react';
49
- const windowHeight = Dimensions.get('window').height;
50
53
  const windowWidth = Dimensions.get('window').width;
51
54
 
52
55
  export const ProductOptionsUI = (props: any) => {
@@ -66,6 +69,7 @@ export const ProductOptionsUI = (props: any) => {
66
69
  handleChangeSuboptionState,
67
70
  handleChangeCommentState,
68
71
  productObject,
72
+ productAddedToCartLength
69
73
  } = props;
70
74
 
71
75
  const theme = useTheme();
@@ -151,6 +155,13 @@ export const ProductOptionsUI = (props: any) => {
151
155
  productTagNameStyle: {
152
156
  paddingHorizontal: 6,
153
157
  marginRight: 5
158
+ },
159
+ actionContainer: {
160
+ flexDirection: 'row',
161
+ alignItems: 'center',
162
+ justifyContent: 'space-between',
163
+ width: '100%',
164
+ marginTop: 10
154
165
  }
155
166
  });
156
167
 
@@ -162,7 +173,7 @@ export const ProductOptionsUI = (props: any) => {
162
173
  const [gallery, setGallery] = useState([])
163
174
  const [thumbsSwiper, setThumbsSwiper] = useState(0)
164
175
  const [indexGallery, setIndexGallery] = useState(0)
165
- const [selOpt, setSelectedOpt] = useState(0);
176
+ const [selOpt, setSelectedOpt] = useState(-1);
166
177
  const [isHaveWeight, setIsHaveWeight] = useState(false)
167
178
  const [playing, setPlaying] = useState(false);
168
179
  const [qtyBy, setQtyBy] = useState({
@@ -304,7 +315,9 @@ export const ProductOptionsUI = (props: any) => {
304
315
  selOpt == id ? theme.colors.textNormal : theme.colors.textSecondary
305
316
  }
306
317
  size={selOpt == id ? 14 : 12}
307
- weight={selOpt == id ? '600' : 'normal'}>
318
+ weight={selOpt == id ? '600' : 'normal'}
319
+ style={{ maxWidth: 150 }}
320
+ numberOfLines={1}>
308
321
  {name}
309
322
  </OText>
310
323
  </TouchableOpacity>
@@ -314,6 +327,14 @@ export const ProductOptionsUI = (props: any) => {
314
327
  </>
315
328
  );
316
329
 
330
+ const handleScroll = ({ nativeEvent: { contentOffset, layoutMeasurement } }: any) => {
331
+
332
+ const _topOption = Object.keys(optionLayout).find(((option: any) => Math.abs(contentOffset?.y - layoutMeasurement?.height - optionLayout[option]?.y) < 20))
333
+ if (_topOption) {
334
+ const _topOptionId = Number(_topOption.replace('id:', ''))
335
+ }
336
+ }
337
+
317
338
  const handleGoBack = navigation?.canGoBack()
318
339
  ? () => navigation.goBack()
319
340
  : () => navigation.navigate('Business', { store: props.businessSlug })
@@ -328,7 +349,7 @@ export const ProductOptionsUI = (props: any) => {
328
349
  useEffect(() => {
329
350
  const imageList: any = []
330
351
  const videoList: any = []
331
- product?.images && imageList.push(product.images)
352
+ product?.images?.length > 0 ? imageList.push(product.images) : imageList.push(theme?.images?.dummies?.product)
332
353
  if (product?.gallery && product?.gallery.length > 0) {
333
354
  for (const img of product?.gallery) {
334
355
  if (img?.file) {
@@ -366,693 +387,719 @@ export const ProductOptionsUI = (props: any) => {
366
387
  }
367
388
  }, [product])
368
389
 
390
+ const ActionButton = () => {
391
+ return (
392
+ <View
393
+ style={{
394
+ width: isHaveWeight ? '100%' : ((isSoldOut || maxProductQuantity <= 0) ? '60%' : '40%'),
395
+ }}>
396
+ {((productCart &&
397
+ auth &&
398
+ orderState.options?.address_id) || (isSoldOut || maxProductQuantity <= 0)) && (
399
+ <OButton
400
+ onClick={() => handleSaveProduct()}
401
+ imgRightSrc=""
402
+ text={`${orderState.loading
403
+ ? t('LOADING', 'Loading')
404
+ : (isSoldOut || maxProductQuantity <= 0)
405
+ ? t('SOLD_OUT', 'Sold out')
406
+ : editMode
407
+ ? t('UPDATE', 'Update')
408
+ : t('ADD', 'Add')
409
+ }`}
410
+ 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))}
411
+ textStyle={{
412
+ color: saveErrors || isSoldOut || maxProductQuantity <= 0 ? theme.colors.primary : theme.colors.white,
413
+ fontSize: orderState.loading || editMode ? 10 : 14
414
+ }}
415
+ style={{
416
+ 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,
417
+ 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,
418
+ opacity: saveErrors || isSoldOut || maxProductQuantity <= 0 ? 0.3 : 1,
419
+ borderRadius: 7.6,
420
+ height: 44,
421
+ shadowOpacity: 0,
422
+ borderWidth: 1,
423
+ marginTop: isHaveWeight ? 10 : 0
424
+ }}
425
+ />
426
+ )}
427
+ {auth &&
428
+ !orderState.options?.address_id &&
429
+ (orderState.loading ? (
430
+ <OButton
431
+ isDisabled
432
+ text={t('LOADING', 'Loading')}
433
+ imgRightSrc=""
434
+ textStyle={{ fontSize: 10 }}
435
+ />
436
+ ) : (
437
+ <OButton onClick={navigation.navigate('AddressList')} />
438
+ ))}
439
+ {!auth && (
440
+ <OButton
441
+ isDisabled={isSoldOut || maxProductQuantity <= 0}
442
+ onClick={() => handleRedirectLogin()}
443
+ text={
444
+ isSoldOut || maxProductQuantity <= 0
445
+ ? t('SOLD_OUT', 'Sold out')
446
+ : t('LOGIN_SIGNUP', 'Login / Sign Up')
447
+ }
448
+ imgRightSrc=""
449
+ textStyle={{ color: theme.colors.primary, fontSize: 14 }}
450
+ style={{
451
+ height: 44,
452
+ borderColor: theme.colors.primary,
453
+ backgroundColor: theme.colors.white,
454
+ }}
455
+ />
456
+ )}
457
+ </View>
458
+ )
459
+ }
460
+
461
+ useEffect(() => {
462
+ const keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', () => {
463
+ scrollViewRef.current.scrollToEnd({ animated: true })
464
+ })
465
+ return () => {
466
+ keyboardDidShowListener.remove()
467
+ }
468
+ }, [])
469
+
470
+
369
471
  return (
370
472
  <SafeAreaView style={{ flex: 1 }}>
371
473
  <TopHeader>
372
474
  <TopActions onPress={() => handleGoBack()}>
373
- <OIcon src={theme.images.general.arrow_left} width={15} />
475
+ <IconAntDesign name='arrowleft' size={26} />
374
476
  </TopActions>
375
477
  </TopHeader>
376
- <ScrollView ref={scrollViewRef}>
377
- {!error && (
378
- <View style={{ paddingBottom: 80 }}>
379
- <WrapHeader onLayout={(event: any) => setHeaderRefHeight(event.nativeEvent.layout?.height)}>
380
- {loading && !product ? (
381
- <View style={styles.productHeaderSkeleton}>
382
- <Placeholder Animation={Fade}>
383
- <PlaceholderLine
384
- height={258}
385
- style={{ borderRadius: 0 }}
386
- width={windowWidth}
387
- />
388
- </Placeholder>
389
- </View>
390
- ) : (
391
- <>
392
- <Swiper
393
- loop={false}
394
- ref={swiperRef}
395
- showsButtons={true}
396
- style={styles.mainSwiper}
397
- showsPagination={false}
398
- onIndexChanged={(index) => handleChangeMainIndex(index)}
399
- prevButton={
400
- <View style={styles.swiperButton}>
401
- <IconAntDesign
402
- name="caretleft"
403
- color={theme.colors.white}
404
- size={13}
405
- // style={styles.starIcon}
406
- />
407
- </View>
408
- }
409
- nextButton={
410
- <View style={styles.swiperButton}>
411
- <IconAntDesign
412
- name="caretright"
413
- color={theme.colors.white}
414
- size={13}
415
- // style={styles.starIcon}
478
+ {!error && (
479
+ <ScrollView
480
+ ref={scrollViewRef}
481
+ contentContainerStyle={{ paddingBottom: 80 }}
482
+ stickyHeaderIndices={[2]}
483
+ onScroll={handleScroll}
484
+ >
485
+ <WrapHeader onLayout={(event: any) => setHeaderRefHeight(event.nativeEvent.layout?.height)}>
486
+ {loading && !product ? (
487
+ <View style={styles.productHeaderSkeleton}>
488
+ <Placeholder Animation={Fade}>
489
+ <PlaceholderLine
490
+ height={258}
491
+ style={{ borderRadius: 0 }}
492
+ width={windowWidth}
493
+ />
494
+ </Placeholder>
495
+ </View>
496
+ ) : (
497
+ <>
498
+ <Swiper
499
+ loop={false}
500
+ ref={swiperRef}
501
+ showsButtons={true}
502
+ style={styles.mainSwiper}
503
+ showsPagination={false}
504
+ onIndexChanged={(index) => handleChangeMainIndex(index)}
505
+ prevButton={
506
+ <View style={styles.swiperButton}>
507
+ <IconAntDesign
508
+ name="caretleft"
509
+ color={theme.colors.white}
510
+ size={13}
511
+ // style={styles.starIcon}
512
+ />
513
+ </View>
514
+ }
515
+ nextButton={
516
+ <View style={styles.swiperButton}>
517
+ <IconAntDesign
518
+ name="caretright"
519
+ color={theme.colors.white}
520
+ size={13}
521
+ // style={styles.starIcon}
522
+ />
523
+ </View>
524
+ }
525
+ >
526
+ {gallery && gallery.length > 0 && gallery.map((img, i) => (
527
+ <View
528
+ style={styles.slide1}
529
+ key={i}
530
+ >
531
+ {String(img).includes('image') ? (
532
+ <FastImage
533
+ style={{ height: '100%', opacity: isSoldOut ? 0.5 : 1 }}
534
+ source={{
535
+ uri: optimizeImage(img, 'h_1024,c_limit'),
536
+ priority: FastImage.priority.normal,
537
+ }}
416
538
  />
417
- </View>
418
- }
419
- >
420
- {gallery && gallery.length > 0 && gallery.map((img, i) => (
539
+ ) : (
540
+ <>
541
+ <YoutubePlayer
542
+ height={300}
543
+ play={playing}
544
+ videoId={img}
545
+ onChangeState={onStateChange}
546
+ />
547
+ <Button title={playing ? "pause" : "play"} onPress={togglePlaying} />
548
+ </>
549
+ )}
550
+ </View>
551
+ ))}
552
+ </Swiper>
553
+ <ScrollView
554
+ horizontal
555
+ contentContainerStyle={{
556
+ paddingHorizontal: 30,
557
+ paddingVertical: 15
558
+ }}
559
+ >
560
+ {gallery.length > 0 && gallery.map((img, index) => (
561
+ <TouchableOpacity
562
+ key={index}
563
+ onPress={() => handleClickThumb(index)}
564
+ >
421
565
  <View
422
- style={styles.slide1}
423
- key={i}
566
+ style={{
567
+ height: 56,
568
+ borderRadius: 8,
569
+ margin: 8,
570
+ opacity: index === thumbsSwiper ? 1 : 0.8
571
+ }}
424
572
  >
425
- {img.includes('image') ? (
426
- <FastImage
427
- style={{ height: '100%', opacity: isSoldOut ? 0.5 : 1 }}
428
- source={{
429
- uri: optimizeImage(img, 'h_1024,c_limit'),
430
- priority: FastImage.priority.normal,
573
+ {String(img).includes('image') ? (
574
+ <OIcon
575
+ url={img}
576
+ style={{
577
+ borderColor: theme.colors.lightGray,
578
+ borderRadius: 8,
579
+ minHeight: '100%',
580
+ opacity: isSoldOut ? 0.5 : 1
431
581
  }}
582
+ width={56}
583
+ height={56}
584
+ cover
432
585
  />
433
586
  ) : (
434
- <>
435
- <YoutubePlayer
436
- height={300}
437
- play={playing}
438
- videoId={img}
439
- onChangeState={onStateChange}
440
- />
441
- <Button title={playing ? "pause" : "play"} onPress={togglePlaying} />
442
- </>
587
+ <OIcon
588
+ url={'http://img.youtube.com/vi/' + img + '/0.jpg'}
589
+ style={{
590
+ borderColor: theme.colors.lightGray,
591
+ borderRadius: 8,
592
+ minHeight: '100%',
593
+ opacity: isSoldOut ? 0.5 : 1
594
+ }}
595
+ width={56}
596
+ height={56}
597
+ cover
598
+ />
443
599
  )}
444
600
  </View>
445
- ))}
446
- </Swiper>
447
- <ScrollView
448
- horizontal
449
- contentContainerStyle={{
450
- paddingHorizontal: 30,
451
- paddingVertical: 15
452
- }}
453
- >
454
- {gallery.length > 0 && gallery.map((img, index) => (
455
- <TouchableOpacity
456
- key={index}
457
- onPress={() => handleClickThumb(index)}
458
- >
459
- <View
460
- style={{
461
- height: 56,
462
- borderRadius: 8,
463
- margin: 8,
464
- opacity: index === thumbsSwiper ? 1 : 0.8
465
- }}
466
- >
467
- {img.includes('image') ? (
468
- <OIcon
469
- url={img}
470
- style={{
471
- borderColor: theme.colors.lightGray,
472
- borderRadius: 8,
473
- minHeight: '100%',
474
- opacity: isSoldOut ? 0.5 : 1
475
- }}
476
- width={56}
477
- height={56}
478
- cover
479
- />
480
- ) : (
481
- <OIcon
482
- url={'http://img.youtube.com/vi/' + img + '/0.jpg'}
483
- style={{
484
- borderColor: theme.colors.lightGray,
485
- borderRadius: 8,
486
- minHeight: '100%',
487
- opacity: isSoldOut ? 0.5 : 1
488
- }}
489
- width={56}
490
- height={56}
491
- cover
492
- />
493
- )}
494
- </View>
495
- </TouchableOpacity>
601
+ </TouchableOpacity>
496
602
 
497
- ))}
498
- </ScrollView>
603
+ ))}
604
+ </ScrollView>
605
+ </>
606
+ )}
607
+ </WrapHeader>
608
+ <ProductSummary onLayout={(event: any) => setSummaryRefHeight(event.nativeEvent.layout?.height)}>
609
+ <ProductTitle>
610
+ {loading && !product ? (
611
+ <Placeholder Animation={Fade}>
612
+ <View
613
+ style={{
614
+ flexDirection: 'row',
615
+ justifyContent: 'space-between',
616
+ }}>
617
+ <PlaceholderLine width={40} height={20} />
618
+ <PlaceholderLine width={30} height={20} />
619
+ </View>
620
+ </Placeholder>
621
+ ) : (
622
+ <>
623
+ <View style={{ flexDirection: 'row' }}>
624
+ <OText
625
+ size={20}
626
+ lineHeight={30}
627
+ weight={'600'}
628
+ style={{ flex: 1, marginBottom: 10 }}>
629
+ {product?.name || productCart.name}
630
+ </OText>
631
+ {!!product?.calories && (
632
+ <OText size={16} style={{ color: '#808080' }}>{product?.calories} cal
633
+ </OText>
634
+ )}
635
+ </View>
636
+ {((!!product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (!!product?.estimated_person)) && (
637
+ <OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={'#909BA9'} mBottom={7}>
638
+ {
639
+ ((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (productCart?.sku && productCart?.sku !== '-1' && productCart?.sku !== '1'))
640
+ && <>{t('SKU', 'Sku')}{' '}{product?.sku || productCart?.sku}</>
641
+ }
642
+ {product?.sku && product?.sku !== '-1' && product?.sku !== '1' && product?.estimated_person && (
643
+ <>&nbsp;&#183;&nbsp;</>
644
+ )}
645
+ {product?.estimated_person
646
+ && <>{product?.estimated_person}{' '}{t('ESTIMATED_PERSONS', 'persons')}</>
647
+ }
648
+ </OText>
649
+ )}
650
+ {isHaveWeight ? (
651
+ <OText size={16} lineHeight={24} color={theme.colors.primary}>{parsePrice(pricePerWeightUnit)} / {product?.weight_unit}</OText>
652
+ ) : (
653
+ <View style={{ flexDirection: 'row', marginBottom: 10 }}>
654
+ <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
655
+ {product?.offer_price !== null && product?.in_offer && (
656
+ <OText style={{
657
+ fontSize: 14,
658
+ color: '#808080',
659
+ textDecorationLine: 'line-through',
660
+ marginLeft: 7,
661
+ marginRight: 7
662
+ }}>{product?.offer_price ? parsePrice(product?.offer_price) : ''}</OText>
663
+ )}
664
+ </View>
665
+ )}
499
666
  </>
500
667
  )}
501
- </WrapHeader>
502
- <WrapContent>
503
- <ProductSummary onLayout={(event: any) => setSummaryRefHeight(event.nativeEvent.layout?.height)}>
504
- <ProductTitle>
505
- {loading && !product ? (
506
- <Placeholder Animation={Fade}>
507
- <View
508
- style={{
509
- flexDirection: 'row',
510
- justifyContent: 'space-between',
511
- }}>
512
- <PlaceholderLine width={40} height={20} />
513
- <PlaceholderLine width={30} height={20} />
514
- </View>
515
- </Placeholder>
668
+ </ProductTitle>
669
+ <ProductDescription>
670
+ <OText color={theme.colors.textSecondary} size={12} lineHeight={18}>
671
+ {product?.description || productCart?.description}
672
+ </OText>
673
+ </ProductDescription>
674
+ <ScrollView
675
+ horizontal
676
+ showsHorizontalScrollIndicator={false}
677
+ contentContainerStyle={{ paddingBottom: 30 }}
678
+ >
679
+ {product?.tags?.map((tag: any) => (
680
+ <View
681
+ key={tag.id}
682
+ style={styles.productTagWrapper}
683
+ >
684
+ {!!tag?.image ? (
685
+ <OIcon
686
+ url={optimizeImage(tag?.image, 'h_40,c_limit')}
687
+ style={styles.productTagImageStyle}
688
+ />
516
689
  ) : (
517
- <>
518
- <View style={{ flexDirection: 'row' }}>
519
- <OText
520
- size={20}
521
- lineHeight={30}
522
- weight={'600'}
523
- style={{ flex: 1, marginBottom: 10 }}>
524
- {product?.name || productCart.name}
525
- </OText>
526
- {!!product?.calories && (
527
- <OText size={16} style={{ color: '#808080' }}>{product?.calories} cal
528
- </OText>
529
- )}
530
- </View>
531
- {((!!product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (!!product?.estimated_person)) && (
532
- <OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={'#909BA9'} mBottom={7}>
533
- {
534
- ((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (productCart?.sku && productCart?.sku !== '-1' && productCart?.sku !== '1'))
535
- && <>{t('SKU', 'Sku')}{' '}{product?.sku || productCart?.sku}</>
536
- }
537
- {product?.sku && product?.sku !== '-1' && product?.sku !== '1' && product?.estimated_person && (
538
- <>&nbsp;&#183;&nbsp;</>
539
- )}
540
- {product?.estimated_person
541
- && <>{product?.estimated_person}{' '}{t('ESTIMATED_PERSONS', 'persons')}</>
542
- }
543
- </OText>
544
- )}
545
- {isHaveWeight ? (
546
- <OText size={16} lineHeight={24} color={theme.colors.primary}>{parsePrice(pricePerWeightUnit)} / {product?.weight_unit}</OText>
547
- ) : (
548
- <View style={{ flexDirection: 'row', marginBottom: 10 }}>
549
- <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
550
- {product?.offer_price !== null && product?.in_offer && (
551
- <OText style={{
552
- fontSize: 14,
553
- color: '#808080',
554
- textDecorationLine: 'line-through',
555
- marginLeft: 7,
556
- marginRight: 7
557
- }}>{product?.offer_price ? parsePrice(product?.offer_price) : ''}</OText>
558
- )}
559
- </View>
560
- )}
561
- </>
690
+ <OIcon
691
+ src={theme.images?.dummies?.product}
692
+ style={styles.productTagImageStyle}
693
+ />
562
694
  )}
563
- </ProductTitle>
564
- <ProductDescription>
565
- <OText color={theme.colors.textSecondary} size={12} lineHeight={18}>
566
- {product?.description || productCart?.description}
695
+ <OText color={theme.colors.textSecondary} size={12} style={styles.productTagNameStyle}>{tag.name}</OText>
696
+ </View>
697
+ ))}
698
+ </ScrollView>
699
+ </ProductSummary>
700
+ {(!loading && product) && (
701
+ <ExtraOptionWrap
702
+ horizontal
703
+ showsHorizontalScrollIndicator={false}
704
+ style={{ marginBottom: 20 }}
705
+ contentContainerStyle={{ paddingHorizontal: 33, backgroundColor: theme.colors.white }}
706
+ >
707
+ <TouchableOpacity
708
+ key={`eopt_key_00`}
709
+ onPress={() => setSelectedOpt(-1)}
710
+ style={[
711
+ styles.extraItem,
712
+ {
713
+ borderBottomColor: selOpt == -1 ? theme.colors.textNormal : theme.colors.border,
714
+ },
715
+ ]}>
716
+ <OText
717
+ color={selOpt == -1 ? theme.colors.textNormal : theme.colors.textSecondary}
718
+ size={selOpt == -1 ? 14 : 12}
719
+ weight={selOpt == -1 ? '600' : 'normal'}>
720
+ {t('ALL', 'All')}
721
+ </OText>
722
+ </TouchableOpacity>
723
+ {product?.ingredients.length > 0 && (
724
+ <TouchableOpacity
725
+ key={`eopt_key_01`}
726
+ onPress={() => setSelectedOpt(0)}
727
+ style={[
728
+ styles.extraItem,
729
+ {
730
+ borderBottomColor:
731
+ selOpt == 0 ? theme.colors.textNormal : theme.colors.border,
732
+ },
733
+ ]}>
734
+ <OText
735
+ color={selOpt == 0 ? theme.colors.textNormal : theme.colors.textSecondary}
736
+ size={selOpt == 0 ? 14 : 12}
737
+ weight={selOpt == 0 ? '600' : 'normal'}>
738
+ {t('INGREDIENTS', 'Ingredients')}
567
739
  </OText>
568
- </ProductDescription>
569
- <ScrollView
570
- horizontal
571
- showsHorizontalScrollIndicator={false}
572
- contentContainerStyle={{ paddingBottom: 30 }}
573
- >
574
- {product?.tags?.map((tag: any) => (
740
+ </TouchableOpacity>
741
+ )}
742
+ {product?.extras.map((extra: any) =>
743
+ <ExtraOptions key={extra.id} options={extra.options} />
744
+ )}
745
+ </ExtraOptionWrap>
746
+ )}
747
+ {loading && !product ? (
748
+ <>
749
+ {[...Array(2)].map((item, i) => (
750
+ <Placeholder
751
+ key={i}
752
+ style={{ marginBottom: 20 }}
753
+ Animation={Fade}>
754
+ <PlaceholderLine
755
+ height={40}
756
+ style={{ flex: 1, marginTop: 10 }}
757
+ />
758
+ {[...Array(3)].map((item, i) => (
575
759
  <View
576
- key={tag.id}
577
- style={styles.productTagWrapper}
578
- >
579
- {!!tag?.image ? (
580
- <OIcon
581
- url={optimizeImage(tag?.image, 'h_40,c_limit')}
582
- style={styles.productTagImageStyle}
583
- />
584
- ) : (
585
- <OIcon
586
- src={theme.images?.dummies?.product}
587
- style={styles.productTagImageStyle}
588
- />
589
- )}
590
- <OText color={theme.colors.textSecondary} size={12} style={styles.productTagNameStyle}>{tag.name}</OText>
760
+ key={'place_key_' + i}
761
+ style={{
762
+ flexDirection: 'row',
763
+ justifyContent: 'space-between',
764
+ }}>
765
+ <PlaceholderLine
766
+ height={30}
767
+ width={10}
768
+ style={{ marginBottom: 20 }}
769
+ />
770
+ <PlaceholderLine
771
+ height={30}
772
+ width={50}
773
+ style={{ marginBottom: 20 }}
774
+ />
775
+ <PlaceholderLine
776
+ height={30}
777
+ width={30}
778
+ style={{ marginBottom: 20 }}
779
+ />
591
780
  </View>
592
781
  ))}
593
- </ScrollView>
594
- </ProductSummary>
595
- {loading && !product ? (
782
+ </Placeholder>
783
+ ))}
784
+ </>
785
+ ) : (
786
+ <ProductEditions>
787
+ {selOpt === -1 ? (
596
788
  <>
597
- {[...Array(2)].map((item, i) => (
598
- <Placeholder
599
- key={i}
600
- style={{ marginBottom: 20 }}
601
- Animation={Fade}>
602
- <PlaceholderLine
603
- height={40}
604
- style={{ flex: 1, marginTop: 10 }}
605
- />
606
- {[...Array(3)].map((item, i) => (
607
- <View
608
- key={'place_key_' + i}
609
- style={{
610
- flexDirection: 'row',
611
- justifyContent: 'space-between',
612
- }}>
613
- <PlaceholderLine
614
- height={30}
615
- width={10}
616
- style={{ marginBottom: 20 }}
617
- />
618
- <PlaceholderLine
619
- height={30}
620
- width={50}
621
- style={{ marginBottom: 20 }}
622
- />
623
- <PlaceholderLine
624
- height={30}
625
- width={30}
626
- style={{ marginBottom: 20 }}
789
+ {product?.ingredients.length > 0 && (
790
+ <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, 0)}>
791
+ <SectionTitle>
792
+ <OText size={16}>
793
+ {t('INGREDIENTS', 'Ingredients')}
794
+ </OText>
795
+ </SectionTitle>
796
+ <WrapperIngredients>
797
+ {product?.ingredients.map((ingredient: any) => (
798
+ <ProductIngredient
799
+ key={ingredient.id}
800
+ ingredient={ingredient}
801
+ state={
802
+ productCart.ingredients[`id:${ingredient.id}`]
803
+ }
804
+ onChange={handleChangeIngredientState}
805
+ isSoldOut={isSoldOut}
627
806
  />
628
- </View>
629
- ))}
630
- </Placeholder>
631
- ))}
807
+ ))}
808
+ </WrapperIngredients>
809
+ </View>
810
+ )}
811
+ {product?.extras.sort((a: any, b: any) => a.rank - b.rank).map((extra: any) =>
812
+ extra.options.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => {
813
+ const currentState =
814
+ productCart.options[`id:${option.id}`] || {};
815
+ return (
816
+ <React.Fragment key={`popt_${option.id}`}>
817
+ {showOption(option) && (
818
+ <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, option?.id)}>
819
+ <ProductOption
820
+ option={option}
821
+ currentState={currentState}
822
+ error={errors[`id:${option.id}`]}>
823
+ <WrapperSubOption
824
+ style={{
825
+ backgroundColor: isError(option.id),
826
+ borderRadius: 7.6
827
+ }}>
828
+ {option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map(
829
+ (suboption: any) => {
830
+ const currentState =
831
+ productCart.options[
832
+ `id:${option.id}`
833
+ ]?.suboptions[
834
+ `id:${suboption.id}`
835
+ ] || {};
836
+ const balance =
837
+ productCart.options[
838
+ `id:${option.id}`
839
+ ]?.balance || 0;
840
+ return (
841
+ <ProductOptionSubOption
842
+ key={suboption.id}
843
+ isSoldOut={isSoldOut}
844
+ onChange={
845
+ handleChangeSuboptionState
846
+ }
847
+ balance={balance}
848
+ option={option}
849
+ suboption={suboption}
850
+ state={currentState}
851
+ disabled={
852
+ isSoldOut ||
853
+ maxProductQuantity <= 0
854
+ }
855
+ setIsScrollAvailable={setIsScrollAvailable}
856
+ error={errors[`id:${option.id}`]}
857
+ />
858
+ );
859
+ },
860
+ )}
861
+ </WrapperSubOption>
862
+ </ProductOption>
863
+ </View>
864
+ )}
865
+ </React.Fragment>
866
+ );
867
+ }),
868
+ )}
632
869
  </>
633
870
  ) : (
634
- <ProductEditions>
635
- <ExtraOptionWrap
636
- horizontal
637
- showsHorizontalScrollIndicator={false}
638
- style={{ marginBottom: 20 }}
639
- contentContainerStyle={{ paddingHorizontal: 33 }}
640
- >
641
- <TouchableOpacity
642
- key={`eopt_all_0`}
643
- onPress={() => setSelectedOpt(0)}
644
- style={[
645
- styles.extraItem,
646
- {
647
- borderBottomColor: selOpt == 0 ? theme.colors.textNormal : theme.colors.border,
648
- },
649
- ]}>
650
- <OText
651
- color={selOpt == 0 ? theme.colors.textNormal : theme.colors.textSecondary}
652
- size={selOpt == 0 ? 14 : 12}
653
- weight={selOpt == 0 ? '600' : 'normal'}>
654
- {t('ALL', 'All')}
655
- </OText>
656
- </TouchableOpacity>
657
- {product?.ingredients.length > 0 && (
658
- <TouchableOpacity
659
- key={`eopt_all_00`}
660
- onPress={() => setSelectedOpt(-1)}
661
- style={[
662
- styles.extraItem,
663
- {
664
- borderBottomColor:
665
- selOpt == -1 ? theme.colors.textNormal : theme.colors.border,
666
- },
667
- ]}>
668
- <OText
669
- color={selOpt == -1 ? theme.colors.textNormal : theme.colors.textSecondary}
670
- size={selOpt == -1 ? 14 : 12}
671
- weight={selOpt == -1 ? '600' : 'normal'}>
871
+ <>
872
+ {selOpt === 0 ? (
873
+ <View style={styles.optionContainer}>
874
+ <SectionTitle>
875
+ <OText size={16}>
672
876
  {t('INGREDIENTS', 'Ingredients')}
673
877
  </OText>
674
- </TouchableOpacity>
675
- )}
676
- {product?.extras.map((extra: any) =>
677
- <ExtraOptions key={extra.id} options={extra.options} />
678
- )}
679
- </ExtraOptionWrap>
680
-
681
- {selOpt == 0 ? (
878
+ </SectionTitle>
879
+ <WrapperIngredients>
880
+ {product?.ingredients.map((ingredient: any) => (
881
+ <ProductIngredient
882
+ key={ingredient.id}
883
+ ingredient={ingredient}
884
+ state={
885
+ productCart.ingredients[`id:${ingredient.id}`]
886
+ }
887
+ onChange={handleChangeIngredientState}
888
+ isSoldOut={isSoldOut}
889
+ />
890
+ ))}
891
+ </WrapperIngredients>
892
+ </View>
893
+ ) : (
682
894
  <>
683
- {product?.ingredients.length > 0 && (
684
- <View style={styles.optionContainer}>
685
- <SectionTitle>
686
- <OText size={16}>
687
- {t('INGREDIENTS', 'Ingredients')}
688
- </OText>
689
- </SectionTitle>
690
- <WrapperIngredients>
691
- {product?.ingredients.map((ingredient: any) => (
692
- <ProductIngredient
693
- key={ingredient.id}
694
- ingredient={ingredient}
695
- state={
696
- productCart.ingredients[`id:${ingredient.id}`]
697
- }
698
- onChange={handleChangeIngredientState}
699
- isSoldOut={isSoldOut}
700
- />
701
- ))}
702
- </WrapperIngredients>
703
- </View>
704
- )}
705
- {product?.extras.sort((a: any, b: any) => a.rank - b.rank).map((extra: any) =>
895
+ {product?.extras.map((extra: any) =>
706
896
  extra.options.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => {
707
- const currentState =
708
- productCart.options[`id:${option.id}`] || {};
709
- return (
710
- <React.Fragment key={`popt_${option.id}`}>
711
- {showOption(option) && (
712
- <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, option?.id)}>
713
- <ProductOption
714
- option={option}
715
- currentState={currentState}
716
- error={errors[`id:${option.id}`]}>
717
- <WrapperSubOption
718
- style={{
719
- backgroundColor: isError(option.id),
720
- borderRadius: 7.6
721
- }}>
722
- {option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map(
723
- (suboption: any) => {
724
- const currentState =
725
- productCart.options[
726
- `id:${option.id}`
727
- ]?.suboptions[
728
- `id:${suboption.id}`
729
- ] || {};
730
- const balance =
731
- productCart.options[
732
- `id:${option.id}`
733
- ]?.balance || 0;
734
- return (
735
- <ProductOptionSubOption
736
- key={suboption.id}
737
- isSoldOut={isSoldOut}
738
- onChange={
739
- handleChangeSuboptionState
740
- }
741
- balance={balance}
742
- option={option}
743
- suboption={suboption}
744
- state={currentState}
745
- disabled={
746
- isSoldOut ||
747
- maxProductQuantity <= 0
748
- }
749
- setIsScrollAvailable={setIsScrollAvailable}
750
- error={errors[`id:${option.id}`]}
751
- />
752
- );
753
- },
754
- )}
755
- </WrapperSubOption>
756
- </ProductOption>
757
- </View>
758
- )}
759
- </React.Fragment>
760
- );
897
+ if (
898
+ option.id == selOpt ||
899
+ (hasRespected(
900
+ extra.options,
901
+ option.respect_to,
902
+ ) &&
903
+ showOption(option))
904
+ ) {
905
+ const currentState =
906
+ productCart.options[`id:${option.id}`] || {};
907
+ return (
908
+ <React.Fragment key={option.id}>
909
+ {showOption(option) && (
910
+ <View style={styles.optionContainer}>
911
+ <ProductOption
912
+ option={option}
913
+ currentState={currentState}
914
+ error={errors[`id:${option.id}`]}>
915
+ <WrapperSubOption
916
+ style={{
917
+ backgroundColor: isError(
918
+ option.id,
919
+ ),
920
+ }}>
921
+ {option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map(
922
+ (suboption: any) => {
923
+ const currentState =
924
+ productCart.options[
925
+ `id:${option.id}`
926
+ ]?.suboptions[
927
+ `id:${suboption.id}`
928
+ ] || {};
929
+ const balance =
930
+ productCart.options[
931
+ `id:${option.id}`
932
+ ]?.balance || 0;
933
+ return (
934
+ <ProductOptionSubOption
935
+ key={suboption.id}
936
+ onChange={
937
+ handleChangeSuboptionState
938
+ }
939
+ balance={balance}
940
+ option={option}
941
+ suboption={suboption}
942
+ state={currentState}
943
+ disabled={
944
+ isSoldOut ||
945
+ maxProductQuantity <= 0
946
+ }
947
+ />
948
+ );
949
+ },
950
+ )}
951
+ </WrapperSubOption>
952
+ </ProductOption>
953
+ </View>
954
+ )}
955
+ </React.Fragment>
956
+ );
957
+ }
761
958
  }),
762
959
  )}
763
960
  </>
764
- ) : (
765
- <>
766
- {selOpt == -1 ? (
767
- <View style={styles.optionContainer}>
768
- <SectionTitle>
769
- <OText size={16}>
770
- {t('INGREDIENTS', 'Ingredients')}
771
- </OText>
772
- </SectionTitle>
773
- <WrapperIngredients>
774
- {product?.ingredients.map((ingredient: any) => (
775
- <ProductIngredient
776
- key={ingredient.id}
777
- ingredient={ingredient}
778
- state={
779
- productCart.ingredients[`id:${ingredient.id}`]
780
- }
781
- onChange={handleChangeIngredientState}
782
- isSoldOut={isSoldOut}
783
- />
784
- ))}
785
- </WrapperIngredients>
786
- </View>
787
- ) : (
788
- <>
789
- {product?.extras.map((extra: any) =>
790
- extra.options.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => {
791
- if (
792
- option.id == selOpt ||
793
- (hasRespected(
794
- extra.options,
795
- option.respect_to,
796
- ) &&
797
- showOption(option))
798
- ) {
799
- const currentState =
800
- productCart.options[`id:${option.id}`] || {};
801
- return (
802
- <React.Fragment key={option.id}>
803
- {showOption(option) && (
804
- <View style={styles.optionContainer}>
805
- <ProductOption
806
- option={option}
807
- currentState={currentState}
808
- error={errors[`id:${option.id}`]}>
809
- <WrapperSubOption
810
- style={{
811
- backgroundColor: isError(
812
- option.id,
813
- ),
814
- }}>
815
- {option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map(
816
- (suboption: any) => {
817
- const currentState =
818
- productCart.options[
819
- `id:${option.id}`
820
- ]?.suboptions[
821
- `id:${suboption.id}`
822
- ] || {};
823
- const balance =
824
- productCart.options[
825
- `id:${option.id}`
826
- ]?.balance || 0;
827
- return (
828
- <ProductOptionSubOption
829
- key={suboption.id}
830
- onChange={
831
- handleChangeSuboptionState
832
- }
833
- balance={balance}
834
- option={option}
835
- suboption={suboption}
836
- state={currentState}
837
- disabled={
838
- isSoldOut ||
839
- maxProductQuantity <= 0
840
- }
841
- />
842
- );
843
- },
844
- )}
845
- </WrapperSubOption>
846
- </ProductOption>
847
- </View>
848
- )}
849
- </React.Fragment>
850
- );
851
- }
852
- }),
853
- )}
854
- </>
855
- )}
856
- </>
857
961
  )}
858
- {!product?.hide_special_instructions && (
859
- <ProductComment>
860
- <SectionTitle>
861
- <OText size={16} weight={'600'} lineHeight={24}>
862
- {t('SPECIAL_COMMENT', 'Special comment')}
863
- </OText>
864
- </SectionTitle>
865
- <OInput
866
- multiline
867
- placeholder={t('SPECIAL_COMMENT', 'Special comment')}
868
- value={productCart.comment}
869
- onChange={(val: string) =>
870
- handleChangeCommentState({ target: { value: val } })
871
- }
872
- isDisabled={
873
- !(productCart && !isSoldOut && maxProductQuantity)
874
- }
875
- style={styles.comment}
876
- />
877
- </ProductComment>
878
- )}
879
- </ProductEditions>
880
- )}
881
- </WrapContent>
882
- </View>
883
- )}
884
- {!!error && error.length > 0 && (
885
- <NotFoundSource content={error[0]?.message || error[0]} />
886
- )}
887
- </ScrollView>
888
- {!loading && !error && product && (
889
- <ProductActions ios={Platform?.OS === 'ios'}>
890
- <View>
891
- <OText size={16} lineHeight={24} weight={'600'}>
892
- {productCart.total ? parsePrice(productCart?.total) : ''}
893
- </OText>
894
- {product?.minimum_per_order && productCart?.quantity < product?.minimum_per_order && <OText size={12} color={theme.colors?.red}>{t('MOBILE_MINIMUM_TO_ORDER', 'Min. _number_ ').replace('_number_', product?.minimum_per_order)}</OText>}
895
- {product?.maximum_per_order && productCart?.quantity > product?.maximum_per_order && <OText size={12} color={theme.colors?.red}>{t('MOBILE_MAXIMUM_TO_ORDER', 'Max. _number_'.replace('_number_', product?.maximum_per_order))}</OText>}
896
- </View>
897
- {productCart && !isSoldOut && maxProductQuantity > 0 && (
898
- <View style={styles.quantityControl}>
899
- <TouchableOpacity
900
- onPress={decrement}
901
- disabled={productCart.quantity === 1 || isSoldOut}>
902
- <OIcon
903
- src={theme.images.general.minus}
904
- width={16}
905
- color={
906
- productCart.quantity === 1 || isSoldOut
907
- ? theme.colors.backgroundGray
908
- : theme.colors.backgroundDark
909
- }
910
- />
911
- </TouchableOpacity>
912
- {qtyBy?.pieces && (
913
- <TextInput
914
- keyboardType='numeric'
915
- value={`${productCart?.quantity > 0 ? productCart?.quantity : ''}`}
916
- onChangeText={(val: any) => onChangeProductCartQuantity(parseInt(val))}
917
- editable={!orderState.loading}
918
- style={{
919
- borderWidth: 1,
920
- textAlign: 'center',
921
- minWidth: 60,
922
- borderRadius: 8,
923
- borderColor: theme.colors.inputBorderColor,
924
- height: 44,
925
- marginHorizontal: 10
926
- }}
927
- />
962
+ </>
928
963
  )}
929
- {qtyBy?.weight_unit && (
930
- <OText
931
- size={12}
932
- lineHeight={18}
933
- style={{ minWidth: 40, textAlign: 'center' }}
934
- >
935
- {productCart.quantity * product?.weight}
936
- </OText>
964
+ {!product?.hide_special_instructions && (
965
+ <ProductComment>
966
+ <SectionTitle>
967
+ <OText size={16} weight={'600'} lineHeight={24}>
968
+ {t('SPECIAL_COMMENT', 'Special comment')}
969
+ </OText>
970
+ </SectionTitle>
971
+ <OInput
972
+ multiline
973
+ placeholder={t('SPECIAL_COMMENT', 'Special comment')}
974
+ value={productCart.comment}
975
+ onChange={(val: string) =>
976
+ handleChangeCommentState({ target: { value: val } })
977
+ }
978
+ isDisabled={
979
+ !(productCart && !isSoldOut && maxProductQuantity)
980
+ }
981
+ style={styles.comment}
982
+ />
983
+ </ProductComment>
937
984
  )}
938
- <TouchableOpacity
939
- onPress={increment}
940
- disabled={
941
- maxProductQuantity <= 0 ||
942
- productCart.quantity >= maxProductQuantity ||
943
- isSoldOut
944
- }>
945
- <OIcon
946
- src={theme.images.general.plus}
947
- width={16}
948
- color={
949
- maxProductQuantity <= 0 ||
950
- productCart.quantity >= maxProductQuantity ||
951
- isSoldOut
952
- ? theme.colors.backgroundGray
953
- : theme.colors.backgroundDark
954
- }
955
- />
956
- </TouchableOpacity>
957
- {isHaveWeight && (
958
- <WeightUnitSwitch>
985
+ </ProductEditions>
986
+ )}
987
+ {!!error && error.length > 0 && (
988
+ <NotFoundSource content={error[0]?.message || error[0]} />
989
+ )}
990
+ </ScrollView>
991
+ )}
992
+ {!loading && !error && product && (
993
+ <ProductActions ios={Platform?.OS === 'ios'} isColumn={isHaveWeight}>
994
+ <View style={styles.actionContainer}>
995
+ <View>
996
+ <OText size={16} lineHeight={24} weight={'600'}>
997
+ {productCart.total ? parsePrice(productCart?.total) : ''}
998
+ </OText>
999
+ {product?.minimum_per_order && (productCart?.quantity + productAddedToCartLength) <= product?.minimum_per_order && productCart?.quantity !== 1 && <OText size={12} color={theme.colors?.red}>{t('MOBILE_MINIMUM_TO_ORDER', 'Min. _number_ ').replace('_number_', product?.minimum_per_order)}</OText>}
1000
+ {product?.maximum_per_order && (productCart?.quantity + productAddedToCartLength) >= product?.maximum_per_order && <OText size={12} color={theme.colors?.red}>{t('MOBILE_MAXIMUM_TO_ORDER', 'Max. _number_'.replace('_number_', product?.maximum_per_order))}</OText>}
1001
+ </View>
1002
+ {productCart && !isSoldOut && maxProductQuantity > 0 && (
1003
+ <>
1004
+ <View style={styles.quantityControl}>
959
1005
  <TouchableOpacity
960
- onPress={() => handleSwitchQtyUnit('pieces')}
961
- >
962
- <WeightUnitItem active={qtyBy?.pieces}>
963
- <OText
964
- size={12}
965
- lineHeight={18}
966
- color={qtyBy?.pieces ? theme.colors.primary : theme.colors.textNormal}
967
- >
968
- {t('PIECES', 'pcs')}
969
- </OText>
970
- </WeightUnitItem>
1006
+ onPress={decrement}
1007
+ disabled={productCart.quantity === 1 || !productCart.quantity || isSoldOut || ((productCart?.quantity + productAddedToCartLength) <= product?.minimum_per_order)}>
1008
+ <OIcon
1009
+ src={theme.images.general.minus}
1010
+ width={16}
1011
+ color={
1012
+ productCart.quantity === 1 || isSoldOut
1013
+ ? theme.colors.backgroundGray
1014
+ : theme.colors.backgroundDark
1015
+ }
1016
+ />
1017
+ </TouchableOpacity>
1018
+ {qtyBy?.pieces && (
1019
+ <TextInput
1020
+ keyboardType='numeric'
1021
+ value={`${productCart?.quantity > 0 ? productCart?.quantity : ''}`}
1022
+ onChangeText={(val: any) => onChangeProductCartQuantity(parseInt(val))}
1023
+ editable={!orderState.loading}
1024
+ style={{
1025
+ borderWidth: 1,
1026
+ textAlign: 'center',
1027
+ minWidth: 60,
1028
+ borderRadius: 8,
1029
+ borderColor: theme.colors.inputBorderColor,
1030
+ height: 44,
1031
+ marginHorizontal: 10
1032
+ }}
1033
+ />
1034
+ )}
1035
+ {qtyBy?.weight_unit && (
1036
+ <OText
1037
+ size={12}
1038
+ lineHeight={18}
1039
+ style={{ minWidth: 40, textAlign: 'center' }}
1040
+ >
1041
+ {productCart.quantity * product?.weight}
1042
+ </OText>
1043
+ )}
1044
+ <TouchableOpacity
1045
+ onPress={increment}
1046
+ disabled={
1047
+ maxProductQuantity <= 0 ||
1048
+ (productCart?.quantity + productAddedToCartLength) >= maxProductQuantity ||
1049
+ ((productCart?.quantity + productAddedToCartLength) >= product?.maximum_per_order && product?.maximum_per_order) ||
1050
+ isSoldOut
1051
+ }>
1052
+ <OIcon
1053
+ src={theme.images.general.plus}
1054
+ width={16}
1055
+ color={
1056
+ maxProductQuantity <= 0 ||
1057
+ (productCart?.quantity + productAddedToCartLength) >= maxProductQuantity ||
1058
+ ((productCart?.quantity + productAddedToCartLength) >= product?.maximum_per_order && product?.maximum_per_order) ||
1059
+ isSoldOut
1060
+ ? theme.colors.backgroundGray
1061
+ : theme.colors.backgroundDark
1062
+ }
1063
+ />
971
1064
  </TouchableOpacity>
972
- <View style={{ alignItems: 'flex-start' }}>
1065
+ </View>
1066
+ {isHaveWeight && (
1067
+ <WeightUnitSwitch>
973
1068
  <TouchableOpacity
974
- onPress={() => handleSwitchQtyUnit('weight_unit')}
1069
+ onPress={() => handleSwitchQtyUnit('pieces')}
975
1070
  >
976
- <WeightUnitItem active={qtyBy?.weight_unit}>
1071
+ <WeightUnitItem active={qtyBy?.pieces}>
977
1072
  <OText
978
1073
  size={12}
979
1074
  lineHeight={18}
980
- color={qtyBy?.weight_unit ? theme.colors.primary : theme.colors.textNormal}
1075
+ color={qtyBy?.pieces ? theme.colors.primary : theme.colors.textNormal}
981
1076
  >
982
- {product?.weight_unit}
1077
+ {t('PIECES', 'pcs')}
983
1078
  </OText>
984
1079
  </WeightUnitItem>
985
1080
  </TouchableOpacity>
986
- </View>
987
- </WeightUnitSwitch>
988
- )}
989
- </View>
990
- )}
991
- <View
992
- style={{
993
- width: isSoldOut || maxProductQuantity <= 0 ? '60%' : '40%',
994
- }}>
995
- {((productCart &&
996
- auth &&
997
- orderState.options?.address_id) || (isSoldOut || maxProductQuantity <= 0)) && (
998
- <OButton
999
- onClick={() => handleSaveProduct()}
1000
- imgRightSrc=""
1001
- text={`${orderState.loading
1002
- ? t('LOADING', 'Loading')
1003
- : (isSoldOut || maxProductQuantity <= 0)
1004
- ? t('SOLD_OUT', 'Sold out')
1005
- : editMode
1006
- ? t('UPDATE', 'Update')
1007
- : t('ADD', 'Add')
1008
- }`}
1009
- isDisabled={isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && (productCart?.quantity < product?.minimum_per_order)) || (product?.maximum_per_order && (productCart?.quantity > product?.maximum_per_order))}
1010
- textStyle={{
1011
- color: saveErrors || isSoldOut || maxProductQuantity <= 0 ? theme.colors.primary : theme.colors.white,
1012
- fontSize: orderState.loading || editMode ? 10 : 14
1013
- }}
1014
- style={{
1015
- backgroundColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && (productCart?.quantity < product?.minimum_per_order)) || (product?.maximum_per_order && (productCart?.quantity > product?.maximum_per_order)) ? theme.colors.lightGray : theme.colors.primary,
1016
- borderColor: saveErrors || isSoldOut || maxProductQuantity <= 0 || (product?.minimum_per_order && (productCart?.quantity < product?.minimum_per_order)) || (product?.maximum_per_order && (productCart?.quantity > product?.maximum_per_order)) ? theme.colors.white : theme.colors.primary,
1017
- opacity: saveErrors || isSoldOut || maxProductQuantity <= 0 ? 0.3 : 1,
1018
- borderRadius: 7.6,
1019
- height: 44,
1020
- shadowOpacity: 0,
1021
- borderWidth: 1,
1022
- }}
1023
- />
1024
- )}
1025
- {auth &&
1026
- !orderState.options?.address_id &&
1027
- (orderState.loading ? (
1028
- <OButton
1029
- isDisabled
1030
- text={t('LOADING', 'Loading')}
1031
- imgRightSrc=""
1032
- textStyle={{ fontSize: 10 }}
1033
- />
1034
- ) : (
1035
- <OButton onClick={navigation.navigate('AddressList')} />
1036
- ))}
1037
- {!auth && (
1038
- <OButton
1039
- isDisabled={isSoldOut || maxProductQuantity <= 0}
1040
- onClick={() => handleRedirectLogin()}
1041
- text={
1042
- isSoldOut || maxProductQuantity <= 0
1043
- ? t('SOLD_OUT', 'Sold out')
1044
- : t('LOGIN_SIGNUP', 'Login / Sign Up')
1045
- }
1046
- imgRightSrc=""
1047
- textStyle={{ color: theme.colors.primary, fontSize: 14 }}
1048
- style={{
1049
- height: 44,
1050
- borderColor: theme.colors.primary,
1051
- backgroundColor: theme.colors.white,
1052
- }}
1053
- />
1081
+ <View style={{ alignItems: 'flex-start' }}>
1082
+ <TouchableOpacity
1083
+ onPress={() => handleSwitchQtyUnit('weight_unit')}
1084
+ >
1085
+ <WeightUnitItem active={qtyBy?.weight_unit}>
1086
+ <OText
1087
+ size={12}
1088
+ lineHeight={18}
1089
+ color={qtyBy?.weight_unit ? theme.colors.primary : theme.colors.textNormal}
1090
+ >
1091
+ {product?.weight_unit}
1092
+ </OText>
1093
+ </WeightUnitItem>
1094
+ </TouchableOpacity>
1095
+ </View>
1096
+ </WeightUnitSwitch>
1097
+ )}
1098
+ </>
1054
1099
  )}
1100
+ {!isHaveWeight && <ActionButton />}
1055
1101
  </View>
1102
+ {isHaveWeight && <ActionButton />}
1056
1103
  </ProductActions>
1057
1104
  )}
1058
1105
  </SafeAreaView>
@@ -1061,10 +1108,20 @@ export const ProductOptionsUI = (props: any) => {
1061
1108
 
1062
1109
 
1063
1110
  export const ProductForm = (props: any) => {
1064
- const productOptionsProps = {
1065
- ...props,
1066
- UIComponent: ProductOptionsUI,
1067
- };
1111
+ const productOptionsProps = {
1112
+ ...props,
1113
+ productCart: {
1114
+ ...props.productCart,
1115
+ quantity: props.productCart?.code
1116
+ ? props.productCart?.quantity
1117
+ : props?.product?.minimum_per_order || 1
1118
+ },
1119
+ UIComponent: ProductOptionsUI
1120
+ }
1068
1121
 
1069
- return <ProductOptions {...productOptionsProps} />;
1122
+ return <ProductOptions {...productOptionsProps} />
1070
1123
  };
1124
+
1125
+ ProductForm.defaultProps = {
1126
+ productAddedToCartLength: 0
1127
+ }