ordering-ui-react-native 0.12.88 → 0.12.93

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.12.88",
3
+ "version": "0.12.93",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -98,6 +98,7 @@
98
98
  "react-native-restart": "^0.0.22",
99
99
  "react-native-safe-area-context": "^3.1.8",
100
100
  "react-native-screens": "^2.11.0",
101
+ "react-native-select-dropdown": "^1.7.0",
101
102
  "react-native-signature-canvas": "^4.3.0",
102
103
  "react-native-snap-carousel": "^3.9.1",
103
104
  "react-native-sound": "^0.11.1",
@@ -1,7 +1,9 @@
1
1
  import React, { useState, useEffect, useRef } from 'react';
2
2
  import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons';
3
- import { View, StyleSheet, Platform, I18nManager, ScrollView } from 'react-native';
3
+ import { View, StyleSheet, Platform, I18nManager, ScrollView, TouchableOpacity } from 'react-native';
4
4
  import { initStripe, useConfirmPayment } from '@stripe/stripe-react-native';
5
+ import Picker from 'react-native-country-picker-modal';
6
+ import MaterialIcons from 'react-native-vector-icons/MaterialIcons'
5
7
 
6
8
  import {
7
9
  Checkout as CheckoutController,
@@ -40,7 +42,9 @@ import {
40
42
  ChErrors,
41
43
  ChBusinessDetails,
42
44
  ChUserDetails,
43
- TextDetails
45
+ TextDetails,
46
+ DeliveryOptionsContainer,
47
+ DeliveryOptionItem
44
48
  } from './styles';
45
49
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
46
50
 
@@ -51,6 +55,7 @@ import { ActivityIndicator } from 'react-native-paper';
51
55
  import WebView from 'react-native-webview';
52
56
  import Icon from 'react-native-vector-icons/Feather';
53
57
  import { OrderCreating } from '../OrderCreating';
58
+ import { Item } from '../../../themes/uber-eats/src/components/UpsellingProducts/styles';
54
59
 
55
60
  const mapConfigs = {
56
61
  mapZoom: 16,
@@ -84,7 +89,11 @@ const CheckoutUI = (props: any) => {
84
89
  businessLogo,
85
90
  businessName,
86
91
  cartTotal,
87
- currency
92
+ currency,
93
+ deliveryOptionSelected,
94
+ instructionsOptions,
95
+ handleChangeDeliveryOption,
96
+
88
97
  } = props
89
98
 
90
99
  const theme = useTheme();
@@ -104,6 +113,12 @@ const CheckoutUI = (props: any) => {
104
113
  },
105
114
  paddSectionH: {
106
115
  paddingHorizontal: 20
116
+ },
117
+ icon: {
118
+ top: 15,
119
+ right: Platform.OS === 'ios' ? 5 : (I18nManager.isRTL ? 30 : 0),
120
+ position: 'absolute',
121
+ fontSize: 20
107
122
  }
108
123
  })
109
124
 
@@ -127,7 +142,7 @@ const CheckoutUI = (props: any) => {
127
142
  const [prog, setProg] = useState(true);
128
143
  const [openOrderCreating, setOpenOrderCreating] = useState(false)
129
144
  const [cardData, setCardData] = useState(null)
130
-
145
+ const [isDeliveryOptionModalVisible, setIsDeliveryOptionModalVisible] = useState(false)
131
146
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
132
147
  ? JSON.parse(configs?.driver_tip_options?.value) || []
133
148
  : configs?.driver_tip_options?.value || []
@@ -136,6 +151,12 @@ const CheckoutUI = (props: any) => {
136
151
  const isPreOrderSetting = configs?.preorder_status_enabled?.value === '1'
137
152
  const cartsWithProducts = carts && Object.values(carts).filter((cart: any) => cart.products.length) || null
138
153
 
154
+ const deliveryOptions = instructionsOptions?.result && instructionsOptions?.result?.filter((option: any) => option?.enabled)?.map(option => {
155
+ return {
156
+ value: option?.id, key: option?.id, label: option?.name
157
+ }
158
+ })
159
+
139
160
  const handlePlaceOrder = () => {
140
161
  if (!userErrors.length) {
141
162
  setOpenOrderCreating(true)
@@ -221,6 +242,11 @@ const CheckoutUI = (props: any) => {
221
242
  setShowGateway({ open: false, closedByUser: true })
222
243
  }
223
244
 
245
+ const changeDeliveryOption = (option : any) => {
246
+ handleChangeDeliveryOption(option)
247
+ setIsDeliveryOptionModalVisible(false)
248
+ }
249
+
224
250
  useEffect(() => {
225
251
  if (validationFields && validationFields?.fields?.checkout) {
226
252
  checkValidationFields()
@@ -428,6 +454,56 @@ const CheckoutUI = (props: any) => {
428
454
  </ChBusinessDetails>
429
455
  </ChSection>
430
456
 
457
+ {!cartState.loading && deliveryOptionSelected !== undefined && options?.type === 1 && (
458
+ <DeliveryOptionsContainer style={style.paddSection}>
459
+ <OText size={20}>{t('DELIVERY_OPTIONS', 'Delivery options')}</OText>
460
+ <View
461
+ style={{
462
+ backgroundColor: theme.colors.inputDisabled,
463
+ borderRadius: 7.5,
464
+ marginBottom: 20,
465
+ flex: 1
466
+ }}>
467
+ <Picker
468
+ countryCode={undefined}
469
+ visible={isDeliveryOptionModalVisible}
470
+ onClose={() => setIsDeliveryOptionModalVisible(false)}
471
+ withCountryNameButton
472
+ renderFlagButton={() => (
473
+ <TouchableOpacity onPress={() => setIsDeliveryOptionModalVisible(true)}>
474
+ <DeliveryOptionItem backgroundColor={theme?.colors?.inputDisabled}>
475
+ <OText
476
+ size={16}
477
+ >
478
+ {deliveryOptions.find((option: any) => option.value === deliveryOptionSelected).label}
479
+ </OText>
480
+ <MaterialIcons name='keyboard-arrow-down' style={style.icon} />
481
+ </DeliveryOptionItem>
482
+ </TouchableOpacity>
483
+ )}
484
+ flatListProps={{
485
+ keyExtractor: (item: any) => item.value,
486
+ data: deliveryOptions || [],
487
+ renderItem: ({ item }: any) => (
488
+ <TouchableOpacity
489
+ onPress={() => changeDeliveryOption(item.value)}
490
+ disabled={
491
+ deliveryOptionSelected === item.value
492
+ }
493
+ >
494
+ <DeliveryOptionItem backgroundColor={deliveryOptionSelected === item.value ? theme.colors.inputDisabled : 'white'}>
495
+ <OText>
496
+ {item.label}
497
+ </OText>
498
+ </DeliveryOptionItem>
499
+ </TouchableOpacity>
500
+ )
501
+ }}
502
+ />
503
+ </View>
504
+ </DeliveryOptionsContainer>
505
+ )}
506
+
431
507
  {!cartState.loading &&
432
508
  cart &&
433
509
  cart?.valid &&
@@ -97,3 +97,16 @@ export const ChErrors = styled.View`
97
97
  align-items: center;
98
98
  margin-bottom: 20px;
99
99
  `
100
+
101
+ export const DeliveryOptionsContainer = styled.View`
102
+ flex: 1;
103
+ margin-top: 10px;
104
+ `
105
+
106
+ export const DeliveryOptionItem = styled.View`
107
+ padding: 15px;
108
+ justify-content: ${(props : any) => props.center ? 'center' : 'space-between'};
109
+ align-items: center;
110
+ flex-direction: row;
111
+ background-color: ${(props : any) => props?.backgroundColor ?? '#fff'};
112
+ `;
@@ -15,7 +15,8 @@ export const NotFoundSource = (props: NotFoundSourceParams) => {
15
15
  content,
16
16
  btnTitle,
17
17
  conditioned,
18
- onClickButton
18
+ onClickButton,
19
+ textSize
19
20
  } = props
20
21
 
21
22
  const theme = useTheme()
@@ -33,8 +34,8 @@ export const NotFoundSource = (props: NotFoundSourceParams) => {
33
34
  />
34
35
  </NotFoundImage>
35
36
  )}
36
- {content && conditioned && !errorImage && <OText color={theme.colors.disabled} size={18} style={{textAlign: 'center'}}>{content}</OText>}
37
- {content && !conditioned && <OText color={theme.colors.disabled} size={18} style={{textAlign: 'center'}}>{content}</OText>}
37
+ {content && conditioned && !errorImage && <OText color={theme.colors.disabled} size={textSize ?? 18} style={{textAlign: 'center'}}>{content}</OText>}
38
+ {content && !conditioned && <OText color={theme.colors.disabled} size={textSize ?? 18} style={{textAlign: 'center'}}>{content}</OText>}
38
39
  {!onClickButton && props.children && (
39
40
  props.children
40
41
  )}
@@ -376,6 +376,18 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
376
376
  <OText style={{ textAlign: 'left' }}>{order?.customer?.address}</OText>
377
377
  </InfoBlock>
378
378
  </Customer>
379
+ {order?.delivery_option !== undefined && order?.delivery_type === 1 && (
380
+ <View>
381
+ <OText size={18} style={{ textAlign: 'left' }}>{t('DELIVERY_PREFERENCE', 'Delivery Preference')}</OText>
382
+ <OText style={{ textAlign: 'left' }}>{order?.delivery_option?.name}</OText>
383
+ </View>
384
+ )}
385
+ {order?.comment && (
386
+ <View>
387
+ <OText size={18} style={{ textAlign: 'left' }} >{t('COMMENT', 'Comment')}</OText>
388
+ <OText style={{ textAlign: 'left' }}>{order?.comment}</OText>
389
+ </View>
390
+ )}
379
391
  {order?.driver && (
380
392
  <>
381
393
  {order?.driver?.location && parseInt(order?.status) === 9 && (
@@ -490,19 +502,19 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
490
502
  ))
491
503
  }
492
504
  {
493
- order?.fees?.length > 0 && order?.fees?.filter((fee : any) => !(fee.fixed === 0 && fee.percentage === 0))?.map((fee: any) => (
494
- <Table key={fee.id}>
495
- <OSRow>
496
- <OText numberOfLines={1}>
497
- {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}
498
- ({parsePrice(fee?.fixed)} + {fee.percentage}%){' '}
499
- </OText>
500
- <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee })}>
501
- <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
502
- </TouchableOpacity>
503
- </OSRow>
504
- <OText>{parsePrice(fee?.fixed + fee?.summary?.percentage || 0)}</OText>
505
- </Table>
505
+ order?.fees?.length > 0 && order?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0))?.map((fee: any) => (
506
+ <Table key={fee.id}>
507
+ <OSRow>
508
+ <OText numberOfLines={1}>
509
+ {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}
510
+ ({parsePrice(fee?.fixed)} + {fee.percentage}%){' '}
511
+ </OText>
512
+ <TouchableOpacity onPress={() => setOpenTaxModal({ open: true, data: fee })}>
513
+ <AntIcon name='exclamationcircleo' size={18} color={theme.colors.primary} />
514
+ </TouchableOpacity>
515
+ </OSRow>
516
+ <OText>{parsePrice(fee?.fixed + fee?.summary?.percentage || 0)}</OText>
517
+ </Table>
506
518
  ))
507
519
  }
508
520
  {order?.summary?.delivery_price > 0 && (
@@ -533,14 +545,6 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
533
545
  </OText>
534
546
  </Table>
535
547
  </Total>
536
- {order?.comment && (
537
- <Table>
538
- <OText style={{flex: 1}}>{t('COMMENT', 'Comment')}</OText>
539
- <OText style={{maxWidth: '70%'}}>
540
- {order?.comment}
541
- </OText>
542
- </Table>
543
- )}
544
548
  {
545
549
  (
546
550
  parseInt(order?.status) === 1 ||
@@ -9,7 +9,7 @@ export const ShareComponent = (props : ShareComponentParams) => {
9
9
  const {orderId, hashkey} = props
10
10
  const [ ,t] = useLanguage()
11
11
  const {showToast} = useToast()
12
- const url = `https://reactdemo.ordering.co/orders/${orderId}?=${hashkey}`
12
+ const url = `${t('SHARE_URL', 'https://reactdemo.tryordering.com/')}orders/${orderId}?=${hashkey}`
13
13
  const onShare = async () => {
14
14
  try {
15
15
  const result = await Share.share({
@@ -271,6 +271,20 @@ export const OrderContentComponent = (props: OrderContent) => {
271
271
  {order?.customer?.zipcode}
272
272
  </OText>
273
273
  )}
274
+ {((order?.delivery_option !== undefined && order?.delivery_type === 1) || !!order?.comment) && (
275
+ <View style={{marginTop: 10}}>
276
+ {order?.delivery_option !== undefined && order?.delivery_type === 1 && (
277
+ <OText>
278
+ {order?.delivery_option?.name}
279
+ </OText>
280
+ )}
281
+ {!!order?.comment && (
282
+ <OText style={{fontStyle: 'italic', opacity: 0.6, marginBottom: 5}}>
283
+ {order?.comment}
284
+ </OText>
285
+ )}
286
+ </View>
287
+ )}
274
288
  {!order?.user_review && pastOrderStatuses.includes(order?.status) && (
275
289
  <OButton
276
290
  style={styles.btnReview}
@@ -440,14 +454,6 @@ export const OrderContentComponent = (props: OrderContent) => {
440
454
  {parsePrice(order?.summary?.total ?? 0)}
441
455
  </OText>
442
456
  </Table>
443
- {!!order?.comment && (
444
- <Table>
445
- <OText style={{ flex: 1 }}>{t('COMMENT', 'Comment')}</OText>
446
- <OText style={{ maxWidth: '70%' }}>
447
- {order?.comment}
448
- </OText>
449
- </Table>
450
- )}
451
457
  </Total>
452
458
  </OrderBill >
453
459
  <OModal
@@ -32,6 +32,8 @@ import {
32
32
  import CalendarPicker from 'react-native-calendar-picker';
33
33
  import { TouchableRipple } from 'react-native-paper';
34
34
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
35
+ import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome';
36
+ import SelectDropdown from 'react-native-select-dropdown';
35
37
 
36
38
  const MomentOptionUI = (props: MomentOptionParams) => {
37
39
  const {
@@ -171,7 +173,6 @@ const MomentOptionUI = (props: MomentOptionParams) => {
171
173
  },
172
174
  };
173
175
  };
174
-
175
176
  return (
176
177
  <>
177
178
  <Container style={{ paddingLeft: 40, paddingRight: 40 }}>
@@ -229,8 +230,56 @@ const MomentOptionUI = (props: MomentOptionParams) => {
229
230
  {datesList.length > 0 && (
230
231
  <View style={styles.dateWrap}>
231
232
  <View style={styles.dateLabel}>
232
- <OText size={12} color={theme.colors.disabled}>{dateSelected}</OText>
233
+ <OText size={12} color={theme.colors.textNormal}>{dateSelected}</OText>
233
234
  </View>
235
+ <SelectDropdown
236
+ defaultButtonText={timeSelected ? timeSelected : t('DELIVERY_TIME', 'Delivery Time')}
237
+ defaultValue={74}
238
+ data={hoursList}
239
+ disabled={orderState.loading}
240
+ onSelect={(selectedItem, index) => {
241
+ setSelectedTime(selectedItem.startTime)
242
+ }}
243
+ buttonTextAfterSelection={(selectedItem, index) => {
244
+ return `${selectedItem.startTime} - ${selectedItem.endTime}`
245
+ }}
246
+ rowTextForSelection={(item, index) => {
247
+ return `${item.startTime} - ${item.endTime}`
248
+ }}
249
+ buttonStyle={{
250
+ backgroundColor: theme.colors.white,
251
+ borderColor: theme.colors.border,
252
+ borderWidth: 1,
253
+ borderRadius: 8,
254
+ height: 40,
255
+ width: '100%',
256
+ flexDirection: 'column',
257
+ alignItems: 'flex-start',
258
+ marginBottom: 20
259
+ }}
260
+ buttonTextStyle={{
261
+ color: theme.colors.textNormal,
262
+ fontSize: 12,
263
+ paddingTop: 10
264
+ }}
265
+ dropdownStyle={{
266
+ borderRadius: 8,
267
+ borderColor: theme.colors.lightGray,
268
+ }}
269
+ rowStyle={{
270
+ borderBottomColor: theme.colors.white,
271
+ backgroundColor: theme.colors.white,
272
+ height: 40,
273
+ flexDirection: 'column',
274
+ alignItems: 'flex-start',
275
+ paddingTop: 8,
276
+ paddingLeft: 22
277
+ }}
278
+ rowTextStyle={{
279
+ color: theme.colors.textNormal,
280
+ fontSize: 14,
281
+ }}
282
+ />
234
283
  <CalendarPicker
235
284
  nextTitle=">"
236
285
  width={width - 80}
@@ -264,50 +313,6 @@ const MomentOptionUI = (props: MomentOptionParams) => {
264
313
  />
265
314
  </View>
266
315
  )}
267
-
268
- {hoursList.length > 0 && optionSelected.isSchedule && (
269
- <>
270
- <TouchableRipple style={styles.timeLabel} onPress={() => { setToggleTime(!toggleTime) }}>
271
- <>
272
- <OIcon src={theme.images.general.clock} width={16} />
273
- <OText style={{ flexGrow: 1, paddingHorizontal: 12 }} color={theme.colors.disabled}>{timeSelected ? timeSelected : t('DELIVERY_TIME', 'Delivery Time')}</OText>
274
- <OIcon src={theme.images.general.arrow_down} width={16} style={{ transform: [{ rotate: toggleTime ? '180deg' : '0deg' }] }} />
275
- </>
276
- </TouchableRipple>
277
- {toggleTime ? (
278
-
279
- <WrapHours nestedScrollEnabled={true}>
280
- <Hours name="hours">
281
- {hoursList.map((hour: any, i: any) => (
282
- <Hour
283
- key={i}
284
- onPress={() => setSelectedTime(hour.startTime)}
285
- disabled={orderState.loading}
286
- style={{ borderColor: selectedTime === hour.startTime ? theme.colors.primary : theme.colors.border }}
287
- >
288
- <OText
289
- color={
290
- selectedTime === hour.startTime
291
- ? theme.colors.primary
292
- : theme.colors.textSecondary
293
- }>
294
- {configs?.format_time?.value === '12'
295
- ? hour.startTime.includes('12')
296
- ? `${hour.startTime}PM`
297
- : parseTime(moment(hour.startTime, 'HH:mm'), {
298
- outputFormat: 'hh:mma',
299
- })
300
- : parseTime(moment(hour.startTime, 'HH:mm'), {
301
- outputFormat: 'HH:mm',
302
- })}
303
- </OText>
304
- </Hour>
305
- ))}
306
- </Hours>
307
- </WrapHours>
308
- ) : null}
309
- </>
310
- )}
311
316
  </WrapDelveryTime>
312
317
  )}
313
318
  </View>
@@ -95,6 +95,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
95
95
 
96
96
  const [openModalForBusiness, setOpenModalForBusiness] = useState(false);
97
97
  const [openModalForDriver, setOpenModalForDriver] = useState(false);
98
+ const [isReviewed, setIsReviewed] = useState(false)
98
99
  const [unreadAlert, setUnreadAlert] = useState({
99
100
  business: false,
100
101
  driver: false,
@@ -339,6 +340,24 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
339
340
  }
340
341
  }
341
342
 
343
+ const handleClickOrderReview = (order: any) => {
344
+ navigation.navigate(
345
+ 'ReviewOrder',
346
+ {
347
+ order: {
348
+ id: order?.id,
349
+ business_id: order?.business_id,
350
+ logo: order.business?.logo,
351
+ driver: order?.driver,
352
+ products: order?.products,
353
+ review: order?.review,
354
+ user_review: order?.user_review
355
+ },
356
+ setIsReviewed
357
+ }
358
+ )
359
+ }
360
+
342
361
  useEffect(() => {
343
362
  BackHandler.addEventListener('hardwareBackPress', handleArrowBack);
344
363
  return () => {
@@ -382,6 +401,10 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
382
401
  }
383
402
  }, [driverLocation]);
384
403
 
404
+ useEffect(() => {
405
+ console.log('order: ', order)
406
+ }, [order]);
407
+
385
408
  return (
386
409
  <OrderDetailsContainer keyboardShouldPersistTaps="handled">
387
410
  <Spinner visible={!order || Object.keys(order).length === 0} />
@@ -409,19 +432,28 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
409
432
  ? parseDate(order?.delivery_datetime_utc)
410
433
  : parseDate(order?.delivery_datetime, { utc: false })}
411
434
  </OText>
412
- <TouchableOpacity
413
- activeOpacity={0.7}
414
- style={{ marginTop: 6 }}
415
- onPress={() => { }}>
416
- <OText
417
- size={10}
418
- lineHeight={15}
419
- color={theme.colors.textSecondary}
420
- style={{ textDecorationLine: 'underline' }}>
421
- {t('REVIEW_ORDER', 'Review order')}
422
- </OText>
423
- </TouchableOpacity>
435
+ {
436
+ (
437
+ parseInt(order?.status) === 1 ||
438
+ parseInt(order?.status) === 11 ||
439
+ parseInt(order?.status) === 15
440
+ ) && !order.review && !isReviewed && (
441
+ <TouchableOpacity
442
+ activeOpacity={0.7}
443
+ style={{ marginTop: 6 }}
444
+ onPress={() => handleClickOrderReview(order)}
424
445
 
446
+ >
447
+ <OText
448
+ size={10}
449
+ lineHeight={15}
450
+ color={theme.colors.textSecondary}
451
+ style={{ textDecorationLine: 'underline' }}
452
+ >
453
+ {t('REVIEW_YOUR_ORDER', 'Review your order')}
454
+ </OText>
455
+ </TouchableOpacity>
456
+ )}
425
457
  <StaturBar>
426
458
  <LinearGradient
427
459
  start={{ x: 0.0, y: 0.0 }}
@@ -567,86 +567,87 @@ export const ProductOptionsUI = (props: any) => {
567
567
 
568
568
  {!loading && !error && product && (
569
569
  <ProductActions>
570
- <OText size={16} lineHeight={24} weight={'600'}>
571
- {productCart.total ? parsePrice(productCart?.total) : ''}
572
- </OText>
573
570
  {productCart && !isSoldOut && maxProductQuantity > 0 && (
574
- <View style={styles.quantityControl}>
575
- <TouchableOpacity
576
- onPress={decrement}
577
- disabled={productCart.quantity === 1 || isSoldOut}>
578
- <OIcon
579
- src={theme.images.general.minus}
580
- width={16}
581
- color={
582
- productCart.quantity === 1 || isSoldOut
583
- ? theme.colors.backgroundGray
584
- : theme.colors.backgroundDark
585
- }
586
- />
587
- </TouchableOpacity>
588
- <OText
589
- size={12}
590
- lineHeight={18}
591
- style={{ minWidth: 29, textAlign: 'center' }}>
592
- {productCart.quantity}
571
+ <>
572
+ <OText size={16} lineHeight={24} weight={'600'}>
573
+ {productCart.total ? parsePrice(productCart?.total) : ''}
593
574
  </OText>
594
- <TouchableOpacity
595
- onPress={increment}
596
- disabled={
597
- maxProductQuantity <= 0 ||
598
- productCart.quantity >= maxProductQuantity ||
599
- isSoldOut
600
- }>
601
- <OIcon
602
- src={theme.images.general.plus}
603
- width={16}
604
- color={
575
+ <View style={styles.quantityControl}>
576
+ <TouchableOpacity
577
+ onPress={decrement}
578
+ disabled={productCart.quantity === 1 || isSoldOut}>
579
+ <OIcon
580
+ src={theme.images.general.minus}
581
+ width={16}
582
+ color={
583
+ productCart.quantity === 1 || isSoldOut
584
+ ? theme.colors.backgroundGray
585
+ : theme.colors.backgroundDark
586
+ }
587
+ />
588
+ </TouchableOpacity>
589
+ <OText
590
+ size={12}
591
+ lineHeight={18}
592
+ style={{ minWidth: 29, textAlign: 'center' }}>
593
+ {productCart.quantity}
594
+ </OText>
595
+ <TouchableOpacity
596
+ onPress={increment}
597
+ disabled={
605
598
  maxProductQuantity <= 0 ||
606
- productCart.quantity >= maxProductQuantity ||
607
- isSoldOut
608
- ? theme.colors.backgroundGray
609
- : theme.colors.backgroundDark
610
- }
611
- />
612
- </TouchableOpacity>
613
- </View>
599
+ productCart.quantity >= maxProductQuantity ||
600
+ isSoldOut
601
+ }>
602
+ <OIcon
603
+ src={theme.images.general.plus}
604
+ width={16}
605
+ color={
606
+ maxProductQuantity <= 0 ||
607
+ productCart.quantity >= maxProductQuantity ||
608
+ isSoldOut
609
+ ? theme.colors.backgroundGray
610
+ : theme.colors.backgroundDark
611
+ }
612
+ />
613
+ </TouchableOpacity>
614
+ </View>
615
+ </>
614
616
  )}
615
617
  <View
616
- style={{
617
- width: isSoldOut || maxProductQuantity <= 0 ? '100%' : '40%',
618
- }}>
618
+ style={{ width: isSoldOut || maxProductQuantity <= 0 ? '100%' : '40%'}}
619
+ >
619
620
  {productCart &&
620
621
  !isSoldOut &&
621
622
  maxProductQuantity > 0 &&
622
623
  auth &&
623
- orderState.options?.address_id && (
624
- <OButton
625
- onClick={() => handleSaveProduct()}
626
- imgRightSrc=""
627
- text={`${orderState.loading
628
- ? t('LOADING', 'Loading')
629
- : editMode
630
- ? t('UPDATE', 'Update')
631
- : t('ADD', 'Add')
632
- }`}
633
- textStyle={{
634
- color: saveErrors ? theme.colors.primary : theme.colors.white,
635
- }}
636
- style={{
637
- backgroundColor: saveErrors ? theme.colors.white : theme.colors.primary,
638
- borderColor: saveErrors ? theme.colors.white : theme.colors.primary,
639
- opacity: saveErrors ? 0.3 : 1,
640
- borderRadius: 7.6,
641
- height: 44,
642
- shadowOpacity: 0,
643
- borderWidth: 1,
644
- }}
645
- />
646
- )}
647
- {auth &&
648
- !orderState.options?.address_id &&
649
- (orderState.loading ? (
624
+ orderState.options?.address_id &&
625
+ (
626
+ <OButton
627
+ onClick={() => handleSaveProduct()}
628
+ imgRightSrc=""
629
+ text={`${orderState.loading
630
+ ? t('LOADING', 'Loading')
631
+ : editMode
632
+ ? t('UPDATE', 'Update')
633
+ : t('ADD', 'Add')
634
+ }`}
635
+ textStyle={{
636
+ color: saveErrors ? theme.colors.primary : theme.colors.white,
637
+ }}
638
+ style={{
639
+ backgroundColor: saveErrors ? theme.colors.white : theme.colors.primary,
640
+ borderColor: saveErrors ? theme.colors.white : theme.colors.primary,
641
+ opacity: saveErrors ? 0.3 : 1,
642
+ borderRadius: 7.6,
643
+ height: 44,
644
+ shadowOpacity: 0,
645
+ borderWidth: 1,
646
+ }}
647
+ />
648
+ )}
649
+ {auth && !orderState.options?.address_id &&(
650
+ orderState.loading ? (
650
651
  <OButton
651
652
  isDisabled
652
653
  text={t('LOADING', 'Loading')}
@@ -654,7 +655,8 @@ export const ProductOptionsUI = (props: any) => {
654
655
  />
655
656
  ) : (
656
657
  <OButton onClick={navigation.navigate('AddressList')} />
657
- ))}
658
+ ))
659
+ }
658
660
  {(!auth || isSoldOut || maxProductQuantity <= 0) && (
659
661
  <OButton
660
662
  isDisabled={isSoldOut || maxProductQuantity <= 0}
@@ -669,6 +671,7 @@ export const ProductOptionsUI = (props: any) => {
669
671
  style={{
670
672
  borderColor: theme.colors.primary,
671
673
  backgroundColor: theme.colors.white,
674
+ borderRadius: 8
672
675
  }}
673
676
  />
674
677
  )}