ordering-ui-react-native 0.14.32 → 0.14.34-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 (60) hide show
  1. package/package.json +2 -2
  2. package/src/components/BusinessItemAccordion/index.tsx +2 -2
  3. package/src/components/BusinessProductsListing/index.tsx +10 -26
  4. package/src/components/Cart/index.tsx +136 -62
  5. package/src/components/Cart/styles.tsx +7 -0
  6. package/src/components/Checkout/index.tsx +10 -6
  7. package/src/components/LogoutButton/index.tsx +14 -0
  8. package/src/components/OrderDetails/index.tsx +102 -34
  9. package/src/components/OrderDetails/styles.tsx +7 -0
  10. package/src/components/OrderSummary/index.tsx +142 -58
  11. package/src/components/OrderSummary/styles.tsx +10 -2
  12. package/src/components/ProductForm/index.tsx +47 -10
  13. package/src/components/ProductForm/styles.tsx +1 -1
  14. package/src/components/SingleProductCard/index.tsx +1 -1
  15. package/src/components/StripeElementsForm/index.tsx +28 -13
  16. package/src/components/TaxInformation/index.tsx +58 -26
  17. package/src/components/UpsellingProducts/index.tsx +13 -31
  18. package/src/components/VerifyPhone/styles.tsx +1 -2
  19. package/src/navigators/HomeNavigator.tsx +6 -0
  20. package/src/pages/ProductDetails.tsx +55 -0
  21. package/src/types/index.tsx +2 -0
  22. package/src/types/react-native-color-matrix-image-filters/index.d.ts +1 -0
  23. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  24. package/themes/doordash/src/components/ProductForm/index.tsx +41 -2
  25. package/themes/doordash/src/components/ProductForm/styles.tsx +1 -1
  26. package/themes/instacart/src/components/ProductForm/index.tsx +40 -1
  27. package/themes/instacart/src/components/ProductForm/styles.tsx +1 -1
  28. package/themes/kiosk/src/components/Cart/index.tsx +14 -21
  29. package/themes/kiosk/src/components/CartItem/index.tsx +9 -7
  30. package/themes/kiosk/src/components/CustomerName/index.tsx +2 -1
  31. package/themes/kiosk/src/components/Intro/index.tsx +4 -4
  32. package/themes/kiosk/src/components/OptionCard/index.tsx +11 -6
  33. package/themes/kiosk/src/components/PaymentOptions/index.tsx +46 -44
  34. package/themes/original/index.tsx +4 -0
  35. package/themes/original/src/components/BusinessItemAccordion/index.tsx +12 -9
  36. package/themes/original/src/components/BusinessItemAccordion/styles.tsx +3 -2
  37. package/themes/original/src/components/BusinessPreorder/index.tsx +37 -35
  38. package/themes/original/src/components/BusinessProductsListing/UpsellingRedirect.tsx +35 -0
  39. package/themes/original/src/components/BusinessProductsListing/index.tsx +22 -49
  40. package/themes/original/src/components/BusinessesListing/index.tsx +100 -75
  41. package/themes/original/src/components/Cart/index.tsx +10 -31
  42. package/themes/original/src/components/Checkout/index.tsx +2 -0
  43. package/themes/original/src/components/Checkout/styles.tsx +1 -0
  44. package/themes/original/src/components/FacebookLogin/index.tsx +20 -5
  45. package/themes/original/src/components/Help/index.tsx +1 -1
  46. package/themes/original/src/components/Home/index.tsx +5 -3
  47. package/themes/original/src/components/LoginForm/index.tsx +50 -49
  48. package/themes/original/src/components/MessageListing/index.tsx +4 -2
  49. package/themes/original/src/components/OrderDetails/index.tsx +3 -1
  50. package/themes/original/src/components/OrderSummary/index.tsx +11 -30
  51. package/themes/original/src/components/PaymentOptionWallet/index.tsx +10 -6
  52. package/themes/original/src/components/PaymentOptionWallet/styles.tsx +1 -0
  53. package/themes/original/src/components/ProductForm/index.tsx +104 -75
  54. package/themes/original/src/components/ProductForm/styles.tsx +10 -3
  55. package/themes/original/src/components/SingleProductCard/index.tsx +21 -11
  56. package/themes/original/src/components/SingleProductCard/styles.tsx +4 -0
  57. package/themes/original/src/components/StripeElementsForm/index.tsx +28 -13
  58. package/themes/original/src/components/UpsellingProducts/index.tsx +85 -83
  59. package/themes/original/src/types/index.tsx +6 -0
  60. package/themes/uber-eats/src/components/ProductForm/index.tsx +43 -2
@@ -436,59 +436,60 @@ const LoginFormUI = (props: LoginParams) => {
436
436
  </>
437
437
  )}
438
438
 
439
- <View
440
- style={{
441
- flexDirection: 'row',
442
- width: '100%',
443
- justifyContent: 'space-between',
444
- alignItems: 'center',
445
- marginVertical: 15
446
- }}>
447
- <View style={loginStyle.line} />
448
- <OText
449
- size={14}
450
- mBottom={10}
451
- style={{ paddingHorizontal: 19 }}
452
- color={theme.colors.disabled}>
453
- {t('OR', 'or')}
454
- </OText>
455
- <View style={loginStyle.line} />
456
- </View>
457
-
458
439
  {configs && Object.keys(configs).length > 0 ? (
459
440
  (((configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') && configs?.facebook_id?.value) ||
460
441
  (configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null)) &&
461
442
  (
462
- <ButtonsWrapper>
463
- <SocialButtons>
464
- {(configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') &&
465
- configs?.facebook_id?.value && (
466
- <FacebookLogin
467
- notificationState={notificationState}
468
- handleErrors={(err: any) => showToast(ToastType.Error, err)}
469
- handleLoading={(val: boolean) => setIsFBLoading(val)}
470
- handleSuccessFacebookLogin={handleSuccessFacebook}
471
- />
472
- )}
473
- {(configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && (
474
- <GoogleLogin
475
- notificationState={notificationState}
476
- webClientId={configs?.google_login_client_id?.value}
477
- handleErrors={(err: any) => showToast(ToastType.Error, err)}
478
- handleLoading={(val: boolean) => setIsFBLoading(val)}
479
- handleSuccessGoogleLogin={handleSuccessFacebook}
480
- />
481
- )}
482
- {(configs?.apple_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && (
483
- <AppleLogin
484
- notificationState={notificationState}
485
- handleErrors={(err: any) => showToast(ToastType.Error, err)}
486
- handleLoading={(val: boolean) => setIsFBLoading(val)}
487
- handleSuccessAppleLogin={handleSuccessFacebook}
488
- />
489
- )}
490
- </SocialButtons>
491
- </ButtonsWrapper>
443
+ <>
444
+ <View
445
+ style={{
446
+ flexDirection: 'row',
447
+ width: '100%',
448
+ justifyContent: 'space-between',
449
+ alignItems: 'center',
450
+ marginVertical: 15
451
+ }}>
452
+ <View style={loginStyle.line} />
453
+ <OText
454
+ size={14}
455
+ mBottom={10}
456
+ style={{ paddingHorizontal: 19 }}
457
+ color={theme.colors.disabled}>
458
+ {t('OR', 'or')}
459
+ </OText>
460
+ <View style={loginStyle.line} />
461
+ </View>
462
+ <ButtonsWrapper>
463
+ <SocialButtons>
464
+ {(configs?.facebook_login?.value === 'true' || configs?.facebook_login?.value === '1') &&
465
+ configs?.facebook_id?.value && (
466
+ <FacebookLogin
467
+ notificationState={notificationState}
468
+ handleErrors={(err: any) => showToast(ToastType.Error, err)}
469
+ handleLoading={(val: boolean) => setIsFBLoading(val)}
470
+ handleSuccessFacebookLogin={handleSuccessFacebook}
471
+ />
472
+ )}
473
+ {(configs?.google_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && (
474
+ <GoogleLogin
475
+ notificationState={notificationState}
476
+ webClientId={configs?.google_login_client_id?.value}
477
+ handleErrors={(err: any) => showToast(ToastType.Error, err)}
478
+ handleLoading={(val: boolean) => setIsFBLoading(val)}
479
+ handleSuccessGoogleLogin={handleSuccessFacebook}
480
+ />
481
+ )}
482
+ {(configs?.apple_login_client_id?.value !== '' && configs?.google_login_client_id?.value !== null) && (
483
+ <AppleLogin
484
+ notificationState={notificationState}
485
+ handleErrors={(err: any) => showToast(ToastType.Error, err)}
486
+ handleLoading={(val: boolean) => setIsFBLoading(val)}
487
+ handleSuccessAppleLogin={handleSuccessFacebook}
488
+ />
489
+ )}
490
+ </SocialButtons>
491
+ </ButtonsWrapper>
492
+ </>
492
493
  )
493
494
  ) : (
494
495
  <SkeletonWrapper>
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useEffect } from 'react'
2
- import { useLanguage, useOrder, ToastType, useToast, OrderList, OrderDetails as OrderDetailsConTableoller } from 'ordering-components/native'
2
+ import { useLanguage, useOrder, ToastType, useToast, OrderList, OrderDetails as OrderDetailsConTableoller, useBusiness } from 'ordering-components/native'
3
3
  import { useTheme } from 'styled-components/native';
4
4
  import { useFocusEffect } from '@react-navigation/native'
5
5
  import { OText, OModal } from '../shared'
@@ -214,6 +214,7 @@ const OrderMessageUI = (props: any) => {
214
214
  }
215
215
 
216
216
  export const OrderListing = (props: OrdersOptionParams) => {
217
+ const [businessState] = useBusiness();
217
218
  const OrderListingProps = {
218
219
  ...props,
219
220
  UIComponent: OrdersOptionUI,
@@ -224,6 +225,7 @@ export const OrderListing = (props: OrdersOptionParams) => {
224
225
  pageSize: 10,
225
226
  controlType: 'infinity'
226
227
  },
228
+ businessId: businessState?.business?.id,
227
229
  profileMessages: true,
228
230
  orderBy: 'last_direct_message_at',
229
231
  orderDirection: 'asc'
@@ -287,6 +289,7 @@ export const MessageListing = (props: MessageListingParams) => {
287
289
  setSelectedOrderId={setSelectedOrderId}
288
290
  setOrderList={setOrderListStatus}
289
291
  setOpenMessges={setOpenMessges}
292
+ franchiseId={props.franchiseId}
290
293
  />
291
294
  {openMessages && seletedOrder && (
292
295
  <OModal
@@ -304,4 +307,3 @@ export const MessageListing = (props: MessageListingParams) => {
304
307
  </MessageListingWrapper>
305
308
  )
306
309
  }
307
-
@@ -611,7 +611,9 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
611
611
  <OText size={16} style={{ textAlign: 'left' }} color={theme.colors.textNormal}>
612
612
  {t('DELIVERY_PREFERENCE', 'Delivery Preference')}
613
613
  </OText>
614
- <OText size={12} style={{ textAlign: 'left' }} color={theme.colors.textNormal}>{order?.delivery_option?.name ?? t('EITHER_WAY', 'Either way')}</OText>
614
+ <OText size={12} style={{ textAlign: 'left' }} color={theme.colors.textNormal}>
615
+ {order?.delivery_option?.name ? t(order?.delivery_option?.name.toUpperCase().replace(/\s/g, '_')) : t('EITHER_WAY', 'Either way')}
616
+ </OText>
615
617
  </View>
616
618
  )}
617
619
  {order?.comment && (
@@ -20,7 +20,6 @@ import {
20
20
  import { ProductItemAccordion } from '../ProductItemAccordion';
21
21
  import { CouponControl } from '../CouponControl';
22
22
  import { OInput, OModal, OText } from '../shared';
23
- import { ProductForm } from '../ProductForm';
24
23
  import { verifyDecimals } from '../../utils';
25
24
  import AntIcon from 'react-native-vector-icons/AntDesign'
26
25
  import { TaxInformation } from '../TaxInformation';
@@ -35,7 +34,8 @@ const OrderSummaryUI = (props: any) => {
35
34
  isCartPending,
36
35
  isFromCheckout,
37
36
  commentState,
38
- handleChangeComment
37
+ handleChangeComment,
38
+ onNavigationRedirect
39
39
  } = props;
40
40
 
41
41
  const theme = useTheme()
@@ -44,8 +44,6 @@ const OrderSummaryUI = (props: any) => {
44
44
  const [orderState] = useOrder();
45
45
  const [{ parsePrice, parseNumber }] = useUtils();
46
46
  const [validationFields] = useValidationFields();
47
- const [openProduct, setModalIsOpen] = useState(false)
48
- const [curProduct, setCurProduct] = useState<any>(null)
49
47
  const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null })
50
48
 
51
49
  const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled;
@@ -55,14 +53,15 @@ const OrderSummaryUI = (props: any) => {
55
53
  }
56
54
 
57
55
  const handleEditProduct = (product: any) => {
58
- setCurProduct(product)
59
- setModalIsOpen(true)
60
- }
61
-
62
- const handlerProductAction = (product: any) => {
63
- if (Object.keys(product).length) {
64
- setModalIsOpen(false)
65
- }
56
+ onNavigationRedirect('ProductDetails', {
57
+ isCartProduct: true,
58
+ productCart: product,
59
+ businessSlug: cart?.business?.slug,
60
+ businessId: cart?.business_id,
61
+ categoryId: product?.category_id,
62
+ productId: product?.id,
63
+ isFromCheckout: isFromCheckout,
64
+ })
66
65
  }
67
66
 
68
67
  const getIncludedTaxes = () => {
@@ -242,24 +241,6 @@ const OrderSummaryUI = (props: any) => {
242
241
  )}
243
242
  </OSBill>
244
243
  )}
245
- <OModal
246
- open={openProduct}
247
- entireModal
248
- customClose
249
- onClose={() => setModalIsOpen(false)}
250
- >
251
- <ProductForm
252
- isCartProduct
253
- productCart={curProduct}
254
- businessSlug={cart?.business?.slug}
255
- businessId={cart?.business_id}
256
- categoryId={curProduct?.category_id}
257
- productId={curProduct?.id}
258
- onSave={handlerProductAction}
259
- onClose={() => setModalIsOpen(false)}
260
- isFromCheckout={isFromCheckout}
261
- />
262
- </OModal>
263
244
  <OModal
264
245
  open={openTaxModal.open}
265
246
  onClose={() => setOpenTaxModal({ open: false, data: null })}
@@ -7,6 +7,7 @@ import {
7
7
  PaymentOptionWallet as PaymentOptionWalletController,
8
8
  useLanguage,
9
9
  useUtils,
10
+ useOrder
10
11
  } from 'ordering-components/native'
11
12
 
12
13
  import {
@@ -18,7 +19,7 @@ import { OText } from '../shared'
18
19
 
19
20
  const PaymentOptionWalletUI = (props: any) => {
20
21
  const {
21
- cart,
22
+ businessId,
22
23
  walletsState,
23
24
  selectWallet,
24
25
  deletetWalletSelected
@@ -26,8 +27,11 @@ const PaymentOptionWalletUI = (props: any) => {
26
27
 
27
28
  const theme = useTheme()
28
29
  const [, t] = useLanguage()
30
+ const [{ carts }] = useOrder()
29
31
  const [{ parsePrice }] = useUtils()
30
32
 
33
+ const cart = carts?.[`businessId:${businessId}`] ?? {}
34
+
31
35
  const styles = StyleSheet.create({
32
36
  checkBoxStyle: {
33
37
  width: 25,
@@ -65,10 +69,10 @@ const PaymentOptionWalletUI = (props: any) => {
65
69
  };
66
70
 
67
71
  useEffect(() => {
68
- if (!walletsState.loading) {
72
+ if (!walletsState.loading && walletsState.result?.length) {
69
73
  setCheckedState(
70
- walletsState.result.map((wallet: any) => {
71
- return !!cart?.wallets?.find((w: any) => w.id === wallet.id)
74
+ walletsState.result?.map((wallet: any) => {
75
+ return !!cart?.payment_events?.find((w: any) => w.wallet_id === wallet.id)
72
76
  })
73
77
  )
74
78
  }
@@ -101,7 +105,7 @@ const PaymentOptionWalletUI = (props: any) => {
101
105
  onTintColor={theme.colors.primary}
102
106
  style={Platform.OS === 'ios' && styles.checkBoxStyle}
103
107
  />
104
- <View style={{ alignItems: 'baseline' }}>
108
+ <View style={{ alignItems: 'baseline', marginLeft: 5 }}>
105
109
  <View>
106
110
  <OText
107
111
  style={((cart?.balance === 0 && !checkedState[idx]) || wallet.balance === 0) ?{
@@ -114,7 +118,7 @@ const PaymentOptionWalletUI = (props: any) => {
114
118
  </View>
115
119
  </SectionLeft>
116
120
 
117
- <View style={{maxWidth: '40%', alignItems: 'flex-end' }}>
121
+ <View style={{maxWidth: '35%', alignItems: 'flex-end' }}>
118
122
  {wallet.type === 'cash' && (
119
123
  <OText>
120
124
  {parsePrice(wallet?.balance)}
@@ -17,6 +17,7 @@ export const Container = styled.View`
17
17
  `
18
18
 
19
19
  export const SectionLeft = styled.View`
20
+ margin-left: 20px;
20
21
  max-width: 55%;
21
22
  display: flex;
22
23
  flex-direction: row;
@@ -16,10 +16,9 @@ import {
16
16
  Grayscale
17
17
  } from 'react-native-color-matrix-image-filters'
18
18
 
19
- import { View, TouchableOpacity, StyleSheet, Dimensions, Platform, AppRegistry, I18nManager } from 'react-native';
19
+ import { View, TouchableOpacity, StyleSheet, Dimensions, I18nManager, SafeAreaView } from 'react-native';
20
20
 
21
21
  import {
22
- ProductHeader,
23
22
  WrapHeader,
24
23
  TopHeader,
25
24
  WrapContent,
@@ -33,16 +32,15 @@ import {
33
32
  ProductActions,
34
33
  ExtraOptionWrap,
35
34
  WeightUnitSwitch,
36
- WeightUnitItem
35
+ WeightUnitItem,
36
+ TopActions
37
37
  } from './styles';
38
38
  import { OButton, OIcon, OInput, OText } from '../shared';
39
39
  import { ScrollView } from 'react-native-gesture-handler';
40
40
  import { ProductOptionSubOption } from '../ProductOptionSubOption';
41
41
  import { NotFoundSource } from '../NotFoundSource';
42
42
  import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
43
- import { useSafeAreaInsets } from 'react-native-safe-area-context';
44
43
  import { useState } from 'react';
45
- import { useWindowDimensions } from 'react-native';
46
44
 
47
45
  const windowHeight = Dimensions.get('window').height;
48
46
  const windowWidth = Dimensions.get('window').width;
@@ -63,8 +61,6 @@ export const ProductOptionsUI = (props: any) => {
63
61
  handleChangeSuboptionState,
64
62
  handleChangeCommentState,
65
63
  productObject,
66
- onClose,
67
- isFromCheckout,
68
64
  } = props;
69
65
 
70
66
  const theme = useTheme();
@@ -97,7 +93,7 @@ export const ProductOptionsUI = (props: any) => {
97
93
  },
98
94
  btnBackArrow: {
99
95
  borderWidth: 0,
100
- backgroundColor: 'rgba(0,0,0,0.3)',
96
+ backgroundColor: '#FFF',
101
97
  borderRadius: 24,
102
98
  marginRight: 15,
103
99
  },
@@ -135,6 +131,20 @@ export const ProductOptionsUI = (props: any) => {
135
131
  },
136
132
  unitItem: {
137
133
  fontSize: 12
134
+ },
135
+ productTagWrapper: {
136
+ flexDirection: 'row',
137
+ alignItems: 'center'
138
+ },
139
+ productTagImageStyle: {
140
+ width: 32,
141
+ height: 32,
142
+ borderRadius: 8,
143
+ resizeMode: 'cover'
144
+ },
145
+ productTagNameStyle: {
146
+ paddingHorizontal: 6,
147
+ marginRight: 5
138
148
  }
139
149
  });
140
150
 
@@ -146,15 +156,13 @@ export const ProductOptionsUI = (props: any) => {
146
156
  const [gallery, setGallery] = useState([])
147
157
  const [thumbsSwiper, setThumbsSwiper] = useState(0)
148
158
 
149
- const { top, bottom } = useSafeAreaInsets();
150
- const { height } = useWindowDimensions();
151
159
  const [selOpt, setSelectedOpt] = useState(0);
152
160
  const [isHaveWeight, setIsHaveWeight] = useState(false)
153
161
  const [qtyBy, setQtyBy] = useState({
154
162
  weight_unit: false,
155
163
  pieces: true
156
164
  })
157
- const [pricePerWeightUnit, setPricePerWeightUnit] = useState(null)
165
+ const [pricePerWeightUnit, setPricePerWeightUnit] = useState<any>(null)
158
166
 
159
167
  const swiperRef: any = useRef(null)
160
168
 
@@ -173,10 +181,8 @@ export const ProductOptionsUI = (props: any) => {
173
181
  };
174
182
 
175
183
  const handleSaveProduct = () => {
176
- console.log('----- click handle ------')
177
184
  const isErrors = Object.values(errors).length > 0;
178
185
  if (!isErrors) {
179
- console.log('----- save handle ------')
180
186
  handleSave && handleSave();
181
187
  return;
182
188
  }
@@ -206,8 +212,9 @@ export const ProductOptionsUI = (props: any) => {
206
212
  }
207
213
 
208
214
  const handleRedirectLogin = () => {
209
- onClose();
210
- navigation.navigate('Login');
215
+ navigation.navigate('Login', {
216
+ store_slug: props.businessSlug
217
+ });
211
218
  };
212
219
 
213
220
  const handleSwitchQtyUnit = (val: string) => {
@@ -284,14 +291,16 @@ export const ProductOptionsUI = (props: any) => {
284
291
  </>
285
292
  );
286
293
 
294
+ const handleGoBack = navigation?.canGoBack()
295
+ ? () => navigation.goBack()
296
+ : () => navigation.navigate('Business', { store: props.businessSlug })
297
+
287
298
  return (
288
- <>
299
+ <SafeAreaView style={{ flex: 1 }}>
289
300
  <TopHeader>
290
- <TouchableOpacity
291
- style={styles.headerItem}
292
- onPress={onClose}>
293
- <OIcon src={theme.images.general.close} width={16} />
294
- </TouchableOpacity>
301
+ <TopActions onPress={() => handleGoBack()}>
302
+ <OIcon src={theme.images.general.arrow_left} width={15} />
303
+ </TopActions>
295
304
  </TopHeader>
296
305
  <ScrollView>
297
306
  {!error && (
@@ -342,15 +351,13 @@ export const ProductOptionsUI = (props: any) => {
342
351
  style={styles.slide1}
343
352
  key={i}
344
353
  >
345
- <Grayscale amount={isSoldOut ? 1 : 0}>
346
- <FastImage
347
- style={{ height: '100%' }}
348
- source={{
349
- uri: optimizeImage(img, 'h_258,c_limit'),
350
- priority: FastImage.priority.normal,
351
- }}
352
- />
353
- </Grayscale>
354
+ <FastImage
355
+ style={{ height: '100%', opacity: isSoldOut ? 0.5 : 1 }}
356
+ source={{
357
+ uri: optimizeImage(img, 'h_258,c_limit'),
358
+ priority: FastImage.priority.normal,
359
+ }}
360
+ />
354
361
  </View>
355
362
  ))}
356
363
  </Swiper>
@@ -374,19 +381,18 @@ export const ProductOptionsUI = (props: any) => {
374
381
  opacity: index === thumbsSwiper ? 1 : 0.8
375
382
  }}
376
383
  >
377
- <Grayscale amount={isSoldOut ? 1 : 0}>
378
- <OIcon
379
- url={img}
380
- style={{
381
- borderColor: theme.colors.lightGray,
382
- borderRadius: 8,
383
- minHeight: '100%'
384
- }}
385
- width={56}
386
- height={56}
387
- cover
388
- />
389
- </Grayscale>
384
+ <OIcon
385
+ url={img}
386
+ style={{
387
+ borderColor: theme.colors.lightGray,
388
+ borderRadius: 8,
389
+ minHeight: '100%',
390
+ opacity: isSoldOut ? 0.5 : 1
391
+ }}
392
+ width={56}
393
+ height={56}
394
+ cover
395
+ />
390
396
  </View>
391
397
  </TouchableOpacity>
392
398
 
@@ -418,12 +424,12 @@ export const ProductOptionsUI = (props: any) => {
418
424
  style={{ flex: 1, marginBottom: 10 }}>
419
425
  {product?.name || productCart.name}
420
426
  </OText>
421
- {product?.calories && (
427
+ {!!product?.calories && (
422
428
  <OText size={16} style={{ color: '#808080' }}>{product?.calories} cal
423
429
  </OText>
424
430
  )}
425
431
  </View>
426
- {((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (product?.estimated_person)) && (
432
+ {((!!product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (!!product?.estimated_person)) && (
427
433
  <OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={'#909BA9'} mBottom={7}>
428
434
  {
429
435
  ((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (productCart?.sku && productCart?.sku !== '-1' && productCart?.sku !== '1'))
@@ -442,7 +448,7 @@ export const ProductOptionsUI = (props: any) => {
442
448
  ) : (
443
449
  <View style={{ flexDirection: 'row', marginBottom: 10 }}>
444
450
  <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
445
- {product?.offer_price && (
451
+ {product?.offer_price !== null && product?.in_offer && (
446
452
  <OText style={{
447
453
  fontSize: 14,
448
454
  color: '#808080',
@@ -461,6 +467,31 @@ export const ProductOptionsUI = (props: any) => {
461
467
  {product?.description || productCart?.description}
462
468
  </OText>
463
469
  </ProductDescription>
470
+ <ScrollView
471
+ horizontal
472
+ showsHorizontalScrollIndicator={false}
473
+ contentContainerStyle={{ paddingBottom: 30 }}
474
+ >
475
+ {product?.tags?.map((tag: any) => (
476
+ <View
477
+ key={tag.id}
478
+ style={styles.productTagWrapper}
479
+ >
480
+ {!!tag?.image ? (
481
+ <OIcon
482
+ url={optimizeImage(tag?.image, 'h_40,c_limit')}
483
+ style={styles.productTagImageStyle}
484
+ />
485
+ ) : (
486
+ <OIcon
487
+ src={theme.images?.dummies?.product}
488
+ style={styles.productTagImageStyle}
489
+ />
490
+ )}
491
+ <OText color={theme.colors.textSecondary} size={12} style={styles.productTagNameStyle}>{tag.name}</OText>
492
+ </View>
493
+ ))}
494
+ </ScrollView>
464
495
  {loading && !product ? (
465
496
  <>
466
497
  {[...Array(2)].map((item, i) => (
@@ -729,16 +760,12 @@ export const ProductOptionsUI = (props: any) => {
729
760
  </WrapContent>
730
761
  </View>
731
762
  )}
732
- {error && error.length > 0 && (
763
+ {!!error && error.length > 0 && (
733
764
  <NotFoundSource content={error[0]?.message || error[0]} />
734
765
  )}
735
766
  </ScrollView>
736
767
  {!loading && !error && product && (
737
- <ProductActions
738
- style={{
739
- paddingBottom: Platform.OS === 'ios' ? bottom + 30 : bottom + 80
740
- }}
741
- >
768
+ <ProductActions>
742
769
  <OText size={16} lineHeight={24} weight={'600'}>
743
770
  {productCart.total ? parsePrice(productCart?.total) : ''}
744
771
  </OText>
@@ -760,7 +787,7 @@ export const ProductOptionsUI = (props: any) => {
760
787
  <OText
761
788
  size={12}
762
789
  lineHeight={18}
763
- style={{ minWidth: 29, textAlign: 'center' }}
790
+ style={{ minWidth: 40, textAlign: 'center' }}
764
791
  >
765
792
  {qtyBy?.pieces && productCart.quantity}
766
793
  {qtyBy?.weight_unit && productCart.quantity * product?.weight}
@@ -784,36 +811,38 @@ export const ProductOptionsUI = (props: any) => {
784
811
  }
785
812
  />
786
813
  </TouchableOpacity>
787
- <WeightUnitSwitch>
788
- <TouchableOpacity
789
- onPress={() => handleSwitchQtyUnit('pieces')}
790
- >
791
- <WeightUnitItem active={qtyBy?.pieces}>
792
- <OText
793
- size={12}
794
- lineHeight={18}
795
- color={qtyBy?.pieces ? theme.colors.primary : theme.colors.textNormal}
796
- >
797
- {t('PIECES', 'pieces')}
798
- </OText>
799
- </WeightUnitItem>
800
- </TouchableOpacity>
801
- <View style={{ alignItems: 'flex-start' }}>
814
+ {isHaveWeight && (
815
+ <WeightUnitSwitch>
802
816
  <TouchableOpacity
803
- onPress={() => handleSwitchQtyUnit('weight_unit')}
817
+ onPress={() => handleSwitchQtyUnit('pieces')}
804
818
  >
805
- <WeightUnitItem active={qtyBy?.weight_unit}>
819
+ <WeightUnitItem active={qtyBy?.pieces}>
806
820
  <OText
807
821
  size={12}
808
822
  lineHeight={18}
809
- color={qtyBy?.weight_unit ? theme.colors.primary : theme.colors.textNormal}
823
+ color={qtyBy?.pieces ? theme.colors.primary : theme.colors.textNormal}
810
824
  >
811
- {product?.weight_unit}
825
+ {t('PIECES', 'pcs')}
812
826
  </OText>
813
827
  </WeightUnitItem>
814
828
  </TouchableOpacity>
815
- </View>
816
- </WeightUnitSwitch>
829
+ <View style={{ alignItems: 'flex-start' }}>
830
+ <TouchableOpacity
831
+ onPress={() => handleSwitchQtyUnit('weight_unit')}
832
+ >
833
+ <WeightUnitItem active={qtyBy?.weight_unit}>
834
+ <OText
835
+ size={12}
836
+ lineHeight={18}
837
+ color={qtyBy?.weight_unit ? theme.colors.primary : theme.colors.textNormal}
838
+ >
839
+ {product?.weight_unit}
840
+ </OText>
841
+ </WeightUnitItem>
842
+ </TouchableOpacity>
843
+ </View>
844
+ </WeightUnitSwitch>
845
+ )}
817
846
  </View>
818
847
  )}
819
848
  <View
@@ -882,7 +911,7 @@ export const ProductOptionsUI = (props: any) => {
882
911
  </View>
883
912
  </ProductActions>
884
913
  )}
885
- </>
914
+ </SafeAreaView>
886
915
  );
887
916
  };
888
917
 
@@ -5,13 +5,20 @@ export const WrapHeader = styled.View`
5
5
  z-index: 1;
6
6
  `
7
7
 
8
+ export const TopActions = styled.TouchableOpacity`
9
+ height: 44px;
10
+ justify-content: center;
11
+ padding-horizontal: 30px;
12
+ `;
13
+
8
14
  export const TopHeader = styled.View`
9
15
  width: 100%;
10
16
  flex-direction: row;
11
17
  align-items: center;
12
18
  justify-content: space-between;
13
19
  z-index: 1;
14
- padding-horizontal: 40px;
20
+ height: 60px;
21
+ min-height: 60px;
15
22
  `
16
23
 
17
24
  export const ProductHeader = styled.ImageBackground`
@@ -37,7 +44,7 @@ export const ProductTitle = styled.View`
37
44
  `
38
45
 
39
46
  export const ProductDescription = styled.View`
40
- margin-bottom: 30px;
47
+ margin-bottom: 20px;
41
48
  `
42
49
 
43
50
  export const ProductEditions = styled.View`
@@ -89,4 +96,4 @@ export const WeightUnitItem = styled.View`
89
96
  ${({ active }: any) => active && css`
90
97
  background-color: ${(props: any) => props.theme.colors.primary}20;
91
98
  `}
92
- `
99
+ `