ordering-ui-react-native 0.14.26 → 0.14.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.14.26",
3
+ "version": "0.14.30",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -70,6 +70,7 @@
70
70
  "react-native-bootsplash": "^3.2.3",
71
71
  "react-native-calendar-picker": "^7.1.2",
72
72
  "react-native-calendar-strip": "^2.2.5",
73
+ "react-native-color-matrix-image-filters": "^5.2.10",
73
74
  "react-native-country-picker-modal": "^2.0.0",
74
75
  "react-native-credit-card-input": "^0.4.1",
75
76
  "react-native-document-picker": "^5.2.0",
@@ -150,10 +150,10 @@ const CheckoutUI = (props: any) => {
150
150
  const isPreOrderSetting = configs?.preorder_status_enabled?.value === '1'
151
151
  const cartsWithProducts = carts && Object.values(carts).filter((cart: any) => cart.products.length) || null
152
152
 
153
- const deliveryOptions = instructionsOptions?.result && instructionsOptions?.result?.filter((option: any) => option?.enabled)?.map(option => {
153
+ const deliveryOptions = instructionsOptions?.result && instructionsOptions?.result?.filter((option: any) => option?.enabled)?.map((option: any) => {
154
154
  return {
155
- value: option?.id, key: option?.id, label: option?.name
156
- }
155
+ value: option?.id, key: option?.id, label: t(option?.name.toUpperCase().replace(/\s/g, '_'), option?.name)
156
+ }
157
157
  })
158
158
 
159
159
  const handlePlaceOrder = () => {
@@ -132,7 +132,18 @@ export const ProductOptionsUI = (props: any) => {
132
132
  ) : (
133
133
  <>
134
134
  <View style={{ flexDirection: 'column', width: '100%' }}>
135
- <OText size={20} style={{ flex: I18nManager.isRTL ? 0 : 1, marginBottom: 10 }}>{product?.name || productCart.name}</OText>
135
+ <View style={{ flexDirection: 'row', marginTop: 15 }}>
136
+ <OText size={20} style={{ flex: I18nManager.isRTL ? 0 : 1, marginBottom: 10 }}>{product?.name || productCart.name}{' '}</OText>
137
+ {product?.calories && (
138
+ <OText size={16} style={styles.caloriesStyle}>{product?.calories} cal</OText>
139
+ )}
140
+ </View>
141
+ <View style={{ flexDirection: 'row', marginBottom: 10 }}>
142
+ <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
143
+ {product?.offer_price && (
144
+ <OText style={styles.regularPriceStyle}>{parsePrice(product?.offer_price)}</OText>
145
+ )}
146
+ </View>
136
147
  {(product?.estimated_person || (product?.sku && product?.sku !== '-1' && product?.sku !== '1')) && (
137
148
  <OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0, marginBottom: 10 }} color={'#909BA9'}>
138
149
  {
@@ -147,12 +158,6 @@ export const ProductOptionsUI = (props: any) => {
147
158
  }
148
159
  </OText>
149
160
  )}
150
- <View style={{ flexDirection: 'row', marginBottom: 10}}>
151
- <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
152
- {product?.offer_price && (
153
- <OText style={styles.regularPriceStyle}>{parsePrice(product?.offer_price)}</OText>
154
- )}
155
- </View>
156
161
  </View>
157
162
  </>
158
163
  )}
@@ -162,17 +167,17 @@ export const ProductOptionsUI = (props: any) => {
162
167
  </ProductDescription>
163
168
  {loading && !product ? (
164
169
  <>
165
- {[...Array(2)].map((item,i) => (
166
- <Placeholder key={i} style={{marginBottom: 20}} Animation={Fade}>
167
- <PlaceholderLine height={40} style={{ flex: 1, marginTop: 10 }} />
168
- {[...Array(3)].map((item,i) => (
169
- <View key={i} style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
170
- <PlaceholderLine height={30} width={10} style={{marginBottom: 20}} />
171
- <PlaceholderLine height={30} width={50} style={{marginBottom: 20}} />
172
- <PlaceholderLine height={30} width={30} style={{marginBottom: 20}} />
173
- </View>
174
- ))}
175
- </Placeholder>
170
+ {[...Array(2)].map((item, i) => (
171
+ <Placeholder key={i} style={{ marginBottom: 20 }} Animation={Fade}>
172
+ <PlaceholderLine height={40} style={{ flex: 1, marginTop: 10 }} />
173
+ {[...Array(3)].map((item, i) => (
174
+ <View key={i} style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
175
+ <PlaceholderLine height={30} width={10} style={{ marginBottom: 20 }} />
176
+ <PlaceholderLine height={30} width={50} style={{ marginBottom: 20 }} />
177
+ <PlaceholderLine height={30} width={30} style={{ marginBottom: 20 }} />
178
+ </View>
179
+ ))}
180
+ </Placeholder>
176
181
  ))}
177
182
  </>
178
183
  ) : (
@@ -221,7 +226,7 @@ export const ProductOptionsUI = (props: any) => {
221
226
  state={currentState}
222
227
  disabled={isSoldOut || maxProductQuantity <= 0}
223
228
  />
224
- ): null
229
+ ) : null
225
230
  })
226
231
  }
227
232
  </WrapperSubOption>
@@ -383,6 +388,9 @@ const styles = StyleSheet.create({
383
388
  textDecorationLine: 'line-through',
384
389
  marginLeft: 7,
385
390
  marginRight: 7
391
+ },
392
+ caloriesStyle: {
393
+ color: '#808080'
386
394
  }
387
395
  })
388
396
 
@@ -9,16 +9,19 @@ import {
9
9
  BIInfo,
10
10
  BIContentInfo,
11
11
  BITotal,
12
- BIActions
12
+ BIActions,
13
+ PriceContainer
13
14
  } from './styles';
14
- import { OAlert, OIcon, OText } from '../shared';
15
+ import { OAlert, OButton, OIcon, OText } from '../shared';
15
16
 
16
17
  export const BusinessItemAccordion = (props: any) => {
17
18
  const {
18
19
  cart,
19
20
  moment,
20
- singleBusiness,
21
- handleClearProducts
21
+ singleBusiness,
22
+ handleClearProducts,
23
+ handleClickCheckout,
24
+ checkoutButtonDisabled
22
25
  } = props
23
26
 
24
27
  const [orderState] = useOrder();
@@ -41,7 +44,7 @@ export const BusinessItemAccordion = (props: any) => {
41
44
  }, [orderState?.carts])
42
45
 
43
46
  return (
44
- <BIContainer isClosed={isClosed}>
47
+ <BIContainer isClosed={isClosed} checkoutVisible={!isActive && !isClosed && !!isProducts && !checkoutButtonDisabled}>
45
48
  <BIHeader
46
49
  isClosed={isClosed}
47
50
  onPress={() => !isClosed ? setActiveState(!isActive) : isClosed}
@@ -71,37 +74,39 @@ export const BusinessItemAccordion = (props: any) => {
71
74
  {props.onNavigationRedirect && !isClosed && (
72
75
  <>
73
76
  <TouchableOpacity onPress={() => props.onNavigationRedirect('Business', { store: cart?.business?.slug })}>
74
- <OText color={theme.colors.textSecondary} size={12} lineHeight={18} style={{ textDecorationLine: 'underline' }}>{t('GO_TO_STORE', 'Go to store')}</OText>
77
+ <OText color={theme.colors.primary} size={12} lineHeight={18} style={{ textDecorationLine: 'underline' }}>{t('GO_TO_STORE', 'Go to store')}</OText>
75
78
  </TouchableOpacity>
76
- <OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
77
79
  </>
78
80
  )}
79
81
  {!isCartPending && !isClosed && (
80
- <OAlert
81
- title={t('DELETE_CART', 'Delete Cart')}
82
- message={t('QUESTION_DELETE_CART', 'Are you sure to you wants delete the selected cart')}
83
- onAccept={() => handleClearProducts()}
84
- >
85
- <OText size={12} lineHeight={18} color={theme.colors.textSecondary} style={{ textDecorationLine: 'underline' }}>{t('CLEAR_CART', 'Clear cart')}</OText>
86
- </OAlert>
82
+ <>
83
+ <OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
84
+ <OAlert
85
+ title={t('DELETE_CART', 'Delete Cart')}
86
+ message={t('QUESTION_DELETE_CART', 'Are you sure to you wants delete the selected cart')}
87
+ onAccept={() => handleClearProducts()}
88
+ >
89
+ <OText size={12} lineHeight={18} color={theme.colors.primary} style={{ textDecorationLine: 'underline' }}>{t('CLEAR_CART', 'Clear cart')}</OText>
90
+ </OAlert>
91
+ </>
92
+ )}
93
+ {props.handleChangeStore && (
94
+ <>
95
+ <OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
96
+ <TouchableOpacity
97
+ onPress={props.handleChangeStore}
98
+ >
99
+ <OText
100
+ size={12}
101
+ lineHeight={18}
102
+ color={theme.colors.textSecondary}
103
+ style={{ textDecorationLine: 'underline' }}
104
+ >
105
+ {t('CHANGE_STORE', 'Change store')}
106
+ </OText>
107
+ </TouchableOpacity>
108
+ </>
87
109
  )}
88
- {props.handleChangeStore && (
89
- <>
90
- <OText color={theme.colors.textSecondary}>{' \u2022 '}</OText>
91
- <TouchableOpacity
92
- onPress={props.handleChangeStore}
93
- >
94
- <OText
95
- size={12}
96
- lineHeight={18}
97
- color={theme.colors.textSecondary}
98
- style={{ textDecorationLine: 'underline' }}
99
- >
100
- {t('CHANGE_STORE', 'Change store')}
101
- </OText>
102
- </TouchableOpacity>
103
- </>
104
- )}
105
110
  </View>
106
111
  </BIContentInfo>
107
112
  </BIInfo>
@@ -134,6 +139,19 @@ export const BusinessItemAccordion = (props: any) => {
134
139
  )}
135
140
  </BIActions>
136
141
  </BIHeader>
142
+ {!isActive && !isClosed && !!isProducts && !checkoutButtonDisabled && (
143
+ <PriceContainer>
144
+ <OText>{parsePrice(cart?.total)}</OText>
145
+ <OButton
146
+ onClick={handleClickCheckout}
147
+ textStyle={{ color: 'white', textAlign: 'center', flex: 1 }}
148
+ style={{ width: 160, flexDirection: 'row', justifyContent: 'center', borderRadius: 7.6, shadowOpacity: 0 }}
149
+ text={t('CHECKOUT', 'Checkout')}
150
+ bgColor={(cart?.subtotal < cart?.minimum || !cart?.valid_address) ? theme.colors.secundary : theme.colors.primary}
151
+ borderColor={theme.colors.primary}
152
+ />
153
+ </PriceContainer>
154
+ )}
137
155
 
138
156
  <BIContent style={{ display: isActive ? 'flex' : 'none' }}>
139
157
  {props.children}
@@ -52,3 +52,10 @@ export const BIActions = styled.View`
52
52
  align-items: center;
53
53
  justify-content: flex-end;
54
54
  `
55
+
56
+ export const PriceContainer = styled.View`
57
+ flex-direction: row;
58
+ justify-content: space-between;
59
+ align-items: center;
60
+ flex: 1
61
+ `
@@ -42,7 +42,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
42
42
  return (
43
43
  <ProductsContainer>
44
44
  {category.id &&
45
- categoryState.products?.map((product: any) => (
45
+ categoryState.products?.sort((a: any, b: any) => a.rank - b.rank).map((product: any) => (
46
46
  <SingleProductCard
47
47
  key={'prod_' + product.id}
48
48
  isSoldOut={product.inventoried && !product.quantity}
@@ -63,7 +63,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
63
63
  {t('FEATURED', 'Featured')}
64
64
  </OText>
65
65
  <>
66
- {categoryState.products?.map(
66
+ {categoryState.products?.sort((a: any, b: any) => a.rank - b.rank).map(
67
67
  (product: any, i: any) =>
68
68
  product.featured && (
69
69
  <SingleProductCard
@@ -110,7 +110,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
110
110
  </OText>
111
111
  </View>
112
112
  <>
113
- {products.map((product: any, i: any) => (
113
+ {products.sort((a: any, b: any) => a.rank - b.rank).map((product: any, i: any) => (
114
114
  <SingleProductCard
115
115
  key={i}
116
116
  isSoldOut={product.inventoried && !product.quantity}
@@ -145,6 +145,8 @@ const CartUI = (props: any) => {
145
145
  handleCartOpen={handleCartOpen}
146
146
  onNavigationRedirect={props.onNavigationRedirect}
147
147
  handleChangeStore={props.isFranchiseApp ? () => setOpenChangeStore(true) : null}
148
+ handleClickCheckout={() => setOpenUpselling(true)}
149
+ checkoutButtonDisabled={(openUpselling && !canOpenUpselling) || cart?.subtotal < cart?.minimum || !cart?.valid_address}
148
150
  >
149
151
  {cart?.products?.length > 0 && cart?.products.map((product: any) => (
150
152
  <ProductItemAccordion
@@ -137,7 +137,7 @@ const CheckoutUI = (props: any) => {
137
137
 
138
138
  const deliveryOptions = instructionsOptions?.result && instructionsOptions?.result?.filter((option: any) => option?.enabled)?.map((option: any) => {
139
139
  return {
140
- value: option?.id, key: option?.id, label: option?.name
140
+ value: option?.id, key: option?.id, label: t(option?.name.toUpperCase().replace(/\s/g, '_'), option?.name)
141
141
  }
142
142
  })
143
143
 
@@ -12,6 +12,9 @@ import { ProductOption } from '../ProductOption';
12
12
  import Swiper from 'react-native-swiper'
13
13
  import FastImage from 'react-native-fast-image';
14
14
  import IconAntDesign from 'react-native-vector-icons/AntDesign';
15
+ import {
16
+ Grayscale
17
+ } from 'react-native-color-matrix-image-filters'
15
18
 
16
19
  import { View, TouchableOpacity, StyleSheet, Dimensions, Platform, AppRegistry, I18nManager } from 'react-native';
17
20
 
@@ -28,7 +31,9 @@ import {
28
31
  WrapperSubOption,
29
32
  ProductComment,
30
33
  ProductActions,
31
- ExtraOptionWrap
34
+ ExtraOptionWrap,
35
+ WeightUnitSwitch,
36
+ WeightUnitItem
32
37
  } from './styles';
33
38
  import { OButton, OIcon, OInput, OText } from '../shared';
34
39
  import { ScrollView } from 'react-native-gesture-handler';
@@ -127,6 +132,9 @@ export const ProductOptionsUI = (props: any) => {
127
132
  height: 32,
128
133
  borderRadius: 16,
129
134
  backgroundColor: 'rgba(208,208,208,0.5)'
135
+ },
136
+ unitItem: {
137
+ fontSize: 12
130
138
  }
131
139
  });
132
140
 
@@ -141,6 +149,12 @@ export const ProductOptionsUI = (props: any) => {
141
149
  const { top, bottom } = useSafeAreaInsets();
142
150
  const { height } = useWindowDimensions();
143
151
  const [selOpt, setSelectedOpt] = useState(0);
152
+ const [isHaveWeight, setIsHaveWeight] = useState(false)
153
+ const [qtyBy, setQtyBy] = useState({
154
+ weight_unit: false,
155
+ pieces: true
156
+ })
157
+ const [pricePerWeightUnit, setPricePerWeightUnit] = useState(null)
144
158
 
145
159
  const swiperRef: any = useRef(null)
146
160
 
@@ -149,9 +163,12 @@ export const ProductOptionsUI = (props: any) => {
149
163
  if (errors[`id:${id}`]) {
150
164
  bgColor = 'rgba(255, 0, 0, 0.05)';
151
165
  }
152
- if (isSoldOut || maxProductQuantity <= 0) {
166
+ if (maxProductQuantity <= 0) {
153
167
  bgColor = 'hsl(0, 0%, 72%)';
154
168
  }
169
+ if (isSoldOut) {
170
+ bgColor = theme.colors.white;
171
+ }
155
172
  return bgColor;
156
173
  };
157
174
 
@@ -193,6 +210,10 @@ export const ProductOptionsUI = (props: any) => {
193
210
  navigation.navigate('Login');
194
211
  };
195
212
 
213
+ const handleSwitchQtyUnit = (val: string) => {
214
+ setQtyBy({ [val]: true, [!val]: false })
215
+ }
216
+
196
217
  useEffect(() => {
197
218
  const productImgList: any = []
198
219
  product?.images && productImgList.push(product.images)
@@ -202,6 +223,11 @@ export const ProductOptionsUI = (props: any) => {
202
223
  }
203
224
  }
204
225
  setGallery(productImgList)
226
+
227
+ if (product?.weight && product?.weight_unit) {
228
+ setIsHaveWeight(true)
229
+ setPricePerWeightUnit(product?.price / product?.weight)
230
+ }
205
231
  }, [product])
206
232
 
207
233
  const saveErrors =
@@ -316,13 +342,15 @@ export const ProductOptionsUI = (props: any) => {
316
342
  style={styles.slide1}
317
343
  key={i}
318
344
  >
319
- <FastImage
320
- style={{ height: '100%' }}
321
- source={{
322
- uri: optimizeImage(img, 'h_258,c_limit'),
323
- priority: FastImage.priority.normal,
324
- }}
325
- />
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>
326
354
  </View>
327
355
  ))}
328
356
  </Swiper>
@@ -346,17 +374,19 @@ export const ProductOptionsUI = (props: any) => {
346
374
  opacity: index === thumbsSwiper ? 1 : 0.8
347
375
  }}
348
376
  >
349
- <OIcon
350
- url={img}
351
- style={{
352
- borderColor: theme.colors.lightGray,
353
- borderRadius: 8,
354
- minHeight: '100%'
355
- }}
356
- width={56}
357
- height={56}
358
- cover
359
- />
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>
360
390
  </View>
361
391
  </TouchableOpacity>
362
392
 
@@ -380,13 +410,30 @@ export const ProductOptionsUI = (props: any) => {
380
410
  </Placeholder>
381
411
  ) : (
382
412
  <>
383
- <OText
384
- size={20}
385
- lineHeight={30}
386
- weight={'600'}
387
- style={{ flex: 1, marginBottom: 5 }}>
388
- {product?.name || productCart.name}
389
- </OText>
413
+ <View style={{ flexDirection: 'row' }}>
414
+ <OText
415
+ size={20}
416
+ lineHeight={30}
417
+ weight={'600'}
418
+ style={{ flex: 1, marginBottom: 10 }}>
419
+ {product?.name || productCart.name}
420
+ </OText>
421
+ {product?.calories && (
422
+ <OText size={16} style={{ color: '#808080' }}>{product?.calories} cal
423
+ </OText>
424
+ )}
425
+ </View>
426
+ <View style={{ flexDirection: 'row', marginBottom: 10 }}>
427
+ <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
428
+ {product?.offer_price && (
429
+ <OText style={{ fontSize: 14,
430
+ color: '#808080',
431
+ textDecorationLine: 'line-through',
432
+ marginLeft: 7,
433
+ marginRight: 7
434
+ }}>{parsePrice(product?.offer_price)}</OText>
435
+ )}
436
+ </View>
390
437
  {((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (product?.estimated_person)) && (
391
438
  <OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={'#909BA9'} mBottom={7}>
392
439
  {
@@ -401,9 +448,13 @@ export const ProductOptionsUI = (props: any) => {
401
448
  }
402
449
  </OText>
403
450
  )}
404
- <OText size={16} lineHeight={24} color={theme.colors.textNormal}>
405
- {productCart.price ? parsePrice(productCart.price) : ''}
406
- </OText>
451
+ {isHaveWeight ? (
452
+ <OText size={16} lineHeight={24} color={theme.colors.textNormal}>{parsePrice(pricePerWeightUnit)} / {product?.weight_unit}</OText>
453
+ ) : (
454
+ <OText size={16} lineHeight={24} color={theme.colors.textNormal}>
455
+ {productCart.price ? parsePrice(productCart.price) : ''}
456
+ </OText>
457
+ )}
407
458
  </>
408
459
  )}
409
460
  </ProductTitle>
@@ -488,13 +539,7 @@ export const ProductOptionsUI = (props: any) => {
488
539
  {t('INGREDIENTS', 'Ingredients')}
489
540
  </OText>
490
541
  </SectionTitle>
491
- <WrapperIngredients
492
- style={{
493
- backgroundColor:
494
- isSoldOut || maxProductQuantity <= 0
495
- ? 'hsl(0, 0%, 72%)'
496
- : theme.colors.white,
497
- }}>
542
+ <WrapperIngredients>
498
543
  {product?.ingredients.map((ingredient: any) => (
499
544
  <ProductIngredient
500
545
  key={ingredient.id}
@@ -503,6 +548,7 @@ export const ProductOptionsUI = (props: any) => {
503
548
  productCart.ingredients[`id:${ingredient.id}`]
504
549
  }
505
550
  onChange={handleChangeIngredientState}
551
+ isSoldOut={isSoldOut}
506
552
  />
507
553
  ))}
508
554
  </WrapperIngredients>
@@ -540,6 +586,7 @@ export const ProductOptionsUI = (props: any) => {
540
586
  return (
541
587
  <ProductOptionSubOption
542
588
  key={suboption.id}
589
+ isSoldOut={isSoldOut}
543
590
  onChange={
544
591
  handleChangeSuboptionState
545
592
  }
@@ -573,13 +620,7 @@ export const ProductOptionsUI = (props: any) => {
573
620
  {t('INGREDIENTS', 'Ingredients')}
574
621
  </OText>
575
622
  </SectionTitle>
576
- <WrapperIngredients
577
- style={{
578
- backgroundColor:
579
- isSoldOut || maxProductQuantity <= 0
580
- ? 'hsl(0, 0%, 72%)'
581
- : theme.colors.white,
582
- }}>
623
+ <WrapperIngredients>
583
624
  {product?.ingredients.map((ingredient: any) => (
584
625
  <ProductIngredient
585
626
  key={ingredient.id}
@@ -588,6 +629,7 @@ export const ProductOptionsUI = (props: any) => {
588
629
  productCart.ingredients[`id:${ingredient.id}`]
589
630
  }
590
631
  onChange={handleChangeIngredientState}
632
+ isSoldOut={isSoldOut}
591
633
  />
592
634
  ))}
593
635
  </WrapperIngredients>
@@ -720,8 +762,10 @@ export const ProductOptionsUI = (props: any) => {
720
762
  <OText
721
763
  size={12}
722
764
  lineHeight={18}
723
- style={{ minWidth: 29, textAlign: 'center' }}>
724
- {productCart.quantity}
765
+ style={{ minWidth: 29, textAlign: 'center' }}
766
+ >
767
+ {qtyBy?.pieces && productCart.quantity}
768
+ {qtyBy?.weight_unit && productCart.quantity * product?.weight}
725
769
  </OText>
726
770
  <TouchableOpacity
727
771
  onPress={increment}
@@ -742,6 +786,36 @@ export const ProductOptionsUI = (props: any) => {
742
786
  }
743
787
  />
744
788
  </TouchableOpacity>
789
+ <WeightUnitSwitch>
790
+ <TouchableOpacity
791
+ onPress={() => handleSwitchQtyUnit('pieces')}
792
+ >
793
+ <WeightUnitItem active={qtyBy?.pieces}>
794
+ <OText
795
+ size={12}
796
+ lineHeight={18}
797
+ color={qtyBy?.pieces ? theme.colors.primary : theme.colors.textNormal}
798
+ >
799
+ {t('PIECES', 'pieces')}
800
+ </OText>
801
+ </WeightUnitItem>
802
+ </TouchableOpacity>
803
+ <View style={{ alignItems: 'flex-start' }}>
804
+ <TouchableOpacity
805
+ onPress={() => handleSwitchQtyUnit('weight_unit')}
806
+ >
807
+ <WeightUnitItem active={qtyBy?.weight_unit}>
808
+ <OText
809
+ size={12}
810
+ lineHeight={18}
811
+ color={qtyBy?.weight_unit ? theme.colors.primary : theme.colors.textNormal}
812
+ >
813
+ {product?.weight_unit}
814
+ </OText>
815
+ </WeightUnitItem>
816
+ </TouchableOpacity>
817
+ </View>
818
+ </WeightUnitSwitch>
745
819
  </View>
746
820
  )}
747
821
  <View
@@ -78,3 +78,15 @@ export const ProductActions = styled.View`
78
78
  export const ExtraOptionWrap = styled.ScrollView`
79
79
  margin-horizontal: -40px;
80
80
  `;
81
+
82
+ export const WeightUnitSwitch = styled.View`
83
+ margin-left: 10px;
84
+ `
85
+ export const WeightUnitItem = styled.View`
86
+ padding: 1px 5px;
87
+ border-radius: 4px;
88
+
89
+ ${({ active }: any) => active && css`
90
+ background-color: ${(props: any) => props.theme.colors.primary}20;
91
+ `}
92
+ `
@@ -10,18 +10,19 @@ const ProductIngredientUI = (props: any) => {
10
10
  const {
11
11
  state,
12
12
  ingredient,
13
- toggleSelect
13
+ toggleSelect,
14
+ isSoldOut
14
15
  } = props
15
16
 
16
17
  const theme = useTheme();
17
18
 
18
19
  return (
19
- <Container onPress={() => toggleSelect()}>
20
+ <Container disabled={isSoldOut} onPress={() => toggleSelect()}>
20
21
  <View>
21
- {state?.selected ? (
22
+ {state?.selected && !isSoldOut ? (
22
23
  <MaterialCommunityIcon name='checkbox-marked' color={theme.colors.primary} size={24} />
23
24
  ) : (
24
- <MaterialCommunityIcon name='checkbox-blank-outline' color={theme.colors.backgroundDark} size={24} />
25
+ <MaterialCommunityIcon name='checkbox-blank-outline' color='#cbcbcb' size={24} />
25
26
  )}
26
27
  </View>
27
28
  <OText mLeft={10}>
@@ -53,8 +53,8 @@ export const ProductOptionSubOptionUI = (props: any) => {
53
53
  const price = option?.with_half_option && suboption?.half_price && state.position !== 'whole' ? suboption?.half_price : suboption?.price
54
54
 
55
55
  return (
56
- <Container disabled={disabled}>
57
- <IconControl onPress={() => handleSuboptionClick()}>
56
+ <Container>
57
+ <IconControl disabled={disabled} onPress={() => handleSuboptionClick()}>
58
58
  {((option?.min === 0 && option?.max === 1) || option?.max > 1) ? (
59
59
  state?.selected ? (
60
60
  <OIcon src={theme.images.general.check_act} color={theme.colors.primary} width={16} />
@@ -73,30 +73,30 @@ export const ProductOptionSubOptionUI = (props: any) => {
73
73
  </OText>
74
74
  </IconControl>
75
75
  {showMessage && <OText size={10} mLeft={4} mRight={4} style={{ flex: 1, textAlign: 'center' }} color={theme.colors.primary}>{`${t('OPTIONS_MAX_LIMIT', 'Maximum options to choose')}: ${option?.max}`}</OText>}
76
- {option?.allow_suboption_quantity && (
76
+ {option?.allow_suboption_quantity && state?.selected && (
77
77
  <QuantityControl>
78
- <Checkbox disabled={state.quantity === 0} onPress={decrement}>
78
+ <Checkbox disabled={disabled || state.quantity === 0} onPress={decrement}>
79
79
  <OIcon
80
80
  src={theme.images.general.minus}
81
81
  width={16}
82
- color={state.quantity === 0 ? theme.colors.disabled : theme.colors.primary}
82
+ color={state.quantity === 0 || disabled ? theme.colors.disabled : theme.colors.primary}
83
83
  />
84
84
  </Checkbox>
85
85
  <OText mLeft={5} mRight={5}>
86
86
  {state.quantity}
87
87
  </OText>
88
- <Checkbox disabled={disableIncrement} onPress={increment}>
88
+ <Checkbox disabled={disabled || disableIncrement} onPress={increment}>
89
89
  <OIcon
90
90
  src={theme.images.general.plus}
91
91
  width={16}
92
- color={disableIncrement ? theme.colors.disabled : theme.colors.primary}
92
+ color={disableIncrement || disabled ? theme.colors.disabled : theme.colors.primary}
93
93
  />
94
94
  </Checkbox>
95
95
  </QuantityControl>
96
96
  )}
97
- {option?.with_half_option && (
97
+ {option?.with_half_option && state?.selected && (
98
98
  <PositionControl>
99
- <Circle onPress={() => changePosition('left')}>
99
+ <Circle disabled={disabled} onPress={() => changePosition('left')}>
100
100
  <OIcon
101
101
  src={theme.images.general.half_l}
102
102
  color={state.selected && state.position === 'left' ? theme.colors.primary : '#cbcbcb'}
@@ -104,14 +104,14 @@ export const ProductOptionSubOptionUI = (props: any) => {
104
104
  style={styles.inverse}
105
105
  />
106
106
  </Circle>
107
- <Circle onPress={() => changePosition('whole')}>
107
+ <Circle disabled={disabled} onPress={() => changePosition('whole')}>
108
108
  <OIcon
109
109
  src={theme.images.general.half_f}
110
110
  color={state.selected && state.position === 'whole' ? theme.colors.primary : '#cbcbcb'}
111
111
  width={16}
112
112
  />
113
113
  </Circle>
114
- <Circle onPress={() => changePosition('right')}>
114
+ <Circle disabled={disabled} onPress={() => changePosition('right')}>
115
115
  <OIcon
116
116
  src={theme.images.general.half_r}
117
117
  color={state.selected && state.position === 'right' ? theme.colors.primary : '#cbcbcb'}