ordering-ui-react-native 0.11.24 → 0.11.28

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 (36) hide show
  1. package/package.json +1 -1
  2. package/src/components/BusinessTypeFilter/index.tsx +155 -105
  3. package/themes/business/src/components/OrderDetails/Delivery.tsx +4 -2
  4. package/themes/business/src/components/OrdersOption/index.tsx +4 -4
  5. package/themes/business/src/types/index.tsx +6 -0
  6. package/themes/doordash/src/components/BusinessTypeFilter/index.tsx +152 -84
  7. package/themes/doordash/src/components/BusinessTypeFilter/styles.tsx +1 -2
  8. package/themes/kiosk/src/components/BusinessMenu/index.tsx +5 -6
  9. package/themes/kiosk/src/components/BusinessProductsListing/index.tsx +6 -14
  10. package/themes/kiosk/src/components/Cart/index.tsx +75 -60
  11. package/themes/kiosk/src/components/Cart/styles.tsx +19 -1
  12. package/themes/kiosk/src/components/CartBottomSheet/index.tsx +5 -2
  13. package/themes/kiosk/src/components/CartItem/index.tsx +144 -57
  14. package/themes/kiosk/src/components/CartItem/styles.tsx +24 -0
  15. package/themes/kiosk/src/components/CategoriesMenu/index.tsx +9 -18
  16. package/themes/kiosk/src/components/LoginForm/index.tsx +1 -8
  17. package/themes/kiosk/src/components/OrderDetails/index.tsx +132 -82
  18. package/themes/kiosk/src/components/OrderDetails/styles.tsx +22 -1
  19. package/themes/kiosk/src/components/PaymentOptions/index.tsx +2 -1
  20. package/themes/kiosk/src/components/ProductForm/index.tsx +7 -2
  21. package/themes/kiosk/src/components/ProductOption/index.tsx +1 -1
  22. package/themes/kiosk/src/components/ProductOption/styles.tsx +2 -2
  23. package/themes/kiosk/src/components/ProductOptionSubOption/index.tsx +56 -52
  24. package/themes/kiosk/src/components/ProductOptionSubOption/styles.tsx +10 -0
  25. package/themes/kiosk/src/components/UpsellingProducts/index.tsx +41 -38
  26. package/themes/kiosk/src/components/shared/OCard.tsx +1 -1
  27. package/themes/kiosk/src/components/shared/OInput.tsx +4 -0
  28. package/themes/kiosk/src/types/index.d.ts +3 -0
  29. package/themes/original/src/components/BusinessTypeFilter/index.tsx +118 -44
  30. package/themes/original/src/components/BusinessTypeFilter/styles.tsx +4 -4
  31. package/themes/original/src/components/BusinessesListing/index.tsx +3 -0
  32. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +122 -0
  33. package/themes/original/src/components/HighestRatedBusinesses/styles.tsx +7 -0
  34. package/themes/original/src/types/index.tsx +4 -0
  35. package/themes/uber-eats/src/components/BusinessTypeFilter/index.tsx +151 -76
  36. package/themes/uber-eats/src/components/BusinessTypeFilter/styles.tsx +0 -9
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect } from 'react';
2
- import { Pressable, StyleSheet, View } from 'react-native';
2
+ import { StyleSheet, View } from 'react-native';
3
3
  import { useForm, Controller } from 'react-hook-form';
4
4
  import { useTheme } from 'styled-components/native';
5
5
 
@@ -22,7 +22,6 @@ import { LANDSCAPE, PORTRAIT, useDeviceOrientation } from '../../../../../src/ho
22
22
  const LoginFormUI = (props: LoginParams) => {
23
23
  const {
24
24
  loginButtonText,
25
- forgotButtonText,
26
25
  formState,
27
26
  handleButtonLoginClick,
28
27
  } = props;
@@ -161,12 +160,6 @@ const LoginFormUI = (props: LoginParams) => {
161
160
  style={{ borderRadius: 0 }}
162
161
  textStyle={{ fontSize: 24 }}
163
162
  />
164
-
165
- <Pressable>
166
- <OText size={24} mBottom={18} style={styles.forgotStyle}>
167
- {forgotButtonText}
168
- </OText>
169
- </Pressable>
170
163
  </>
171
164
  );
172
165
 
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect, useState } from 'react'
2
- import { View, StyleSheet, BackHandler, Alert, Keyboard } from 'react-native'
2
+ import { View, StyleSheet, BackHandler, Alert, Keyboard } from 'react-native'
3
3
  import Spinner from 'react-native-loading-spinner-overlay'
4
- import {useForm, Controller} from 'react-hook-form'
4
+ import { useForm, Controller } from 'react-hook-form'
5
5
  import {
6
6
  useLanguage,
7
7
  OrderDetails as OrderDetailsConTableoller,
@@ -10,15 +10,19 @@ import {
10
10
  useSession,
11
11
  useToast,
12
12
  ToastType,
13
+ useConfig
13
14
  } from 'ordering-components/native'
14
15
 
15
- import {PhoneInputNumber} from '../PhoneInputNumber'
16
+ import { PhoneInputNumber } from '../PhoneInputNumber'
16
17
  import {
17
18
  OSOrderDetailsWrapper,
18
19
  OSTable,
19
20
  OSActions,
20
21
  OSInputWrapper,
21
- SentReceipt
22
+ SentReceipt,
23
+ Table,
24
+ OrderBill,
25
+ Total,
22
26
  } from './styles'
23
27
  import { OrderDetailsParams, Product } from '../../types'
24
28
  import { Container } from '../../layouts/Container';
@@ -40,10 +44,11 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
40
44
  const theme = useTheme();
41
45
  const [, t] = useLanguage()
42
46
  const [ordering] = useApi()
43
- const [, {showToast}] = useToast()
47
+ const [, { showToast }] = useToast()
44
48
  const [{ parsePrice, parseNumber }] = useUtils()
45
49
  const [orientationState] = useDeviceOrientation()
46
50
  const [{ token }] = useSession()
51
+ const [{ configs }] = useConfig()
47
52
  const { control, handleSubmit, errors } = useForm();
48
53
  const [customerName, setCustomerName] = useState(null)
49
54
  const [countReceipts, setCountReceipts] = useState(5)
@@ -56,6 +61,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
56
61
  },
57
62
  });
58
63
  const { order } = props.order;
64
+ const isTaxIncluded = order?.tax_type === 1
59
65
  const styles = StyleSheet.create({
60
66
  inputsStyle: {
61
67
  borderColor: theme.colors.disabled,
@@ -81,7 +87,10 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
81
87
  color: theme.colors.white,
82
88
  marginLeft: 0,
83
89
  marginRight: 0
84
- }
90
+ },
91
+ textBold: {
92
+ fontWeight: 'bold'
93
+ },
85
94
  });
86
95
 
87
96
  const optionsToSendReceipt: Opt[] = [
@@ -121,9 +130,9 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
121
130
  onChange(value.toLowerCase().replace(/[&,()%";:ç?<>{}\\[\]\s]/g, ''));
122
131
  };
123
132
 
124
- const onSubmit = async (values : any) => {
133
+ const onSubmit = async (values: any) => {
125
134
  Keyboard.dismiss();
126
- if(countReceipts <= 0){
135
+ if (countReceipts <= 0) {
127
136
  showToast(ToastType.Error, t('MAXIMUM_RECEIPTS_SEND_EXCEEDED', 'The maximum receipts sent has been exceeded'))
128
137
  return
129
138
  }
@@ -148,21 +157,21 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
148
157
  name: customerName
149
158
  }
150
159
  }
151
- try{
160
+ try {
152
161
  const response = await fetch(`${ordering.root}/orders/${order.id}/receipt`, {
153
162
  method: 'POST',
154
- headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`},
163
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
155
164
  body: JSON.stringify(body),
156
165
  })
157
- const {error, result} = await response.json()
158
- if(error){
166
+ const { error, result } = await response.json()
167
+ if (error) {
159
168
  showToast(ToastType.Error, result)
160
169
  } else {
161
170
  showToast(ToastType.Success, t('RECEIPT_SEND_SUCCESSFULLY', 'Receipt send successfully'))
162
171
  setCountReceipts(countReceipts - 1)
163
172
  }
164
173
 
165
- } catch (error : any) {
174
+ } catch (error: any) {
166
175
  showToast(ToastType.Error, error.message)
167
176
  }
168
177
  setIsLoading(false)
@@ -197,7 +206,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
197
206
 
198
207
  useEffect(() => {
199
208
  const getCustomerName = async () => {
200
- const {customerName : name} = await _retrieveStoreData('customer_name')
209
+ const { customerName: name } = await _retrieveStoreData('customer_name')
201
210
  setCustomerName(name)
202
211
  }
203
212
  getCustomerName()
@@ -209,7 +218,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
209
218
  const list = Object.values(errors);
210
219
  let stringError = '';
211
220
  if (phoneInputData.error) {
212
- list.unshift({message: phoneInputData.error});
221
+ list.unshift({ message: phoneInputData.error });
213
222
  }
214
223
  if (
215
224
  optionToSendReceipt?.value === _SMS &&
@@ -260,37 +269,37 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
260
269
  <OSTable>
261
270
  {optionToSendReceipt?.value === _EMAIL && (
262
271
  <Controller
263
- control={control}
264
- render={({onChange, value} : any) => (
265
- <OInput
266
- placeholder="yourname@mailhost.com"
267
- onChange={(e: any) => handleChangeInputEmail(e, onChange)}
268
- style={styles.inputsStyle}
269
- value={value}
270
- autoCapitalize="none"
271
- autoCorrect={false}
272
- returnKeyType="done"
273
- onSubmitEditing={handleSubmit(onSubmit)}
274
- blurOnSubmit
275
- type="email-address"
276
- />
277
- )}
278
- name="email"
279
- rules={{
280
- required: t(
281
- 'VALIDATION_ERROR_EMAIL_REQUIRED',
282
- 'The field Email is required',
283
- ).replace('_attribute_', t('EMAIL', 'Email')),
284
- pattern: {
285
- value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
286
- message: t(
287
- 'INVALID_ERROR_EMAIL',
288
- 'Invalid email address',
272
+ control={control}
273
+ render={({ onChange, value }: any) => (
274
+ <OInput
275
+ placeholder="yourname@mailhost.com"
276
+ onChange={(e: any) => handleChangeInputEmail(e, onChange)}
277
+ style={styles.inputsStyle}
278
+ value={value}
279
+ autoCapitalize="none"
280
+ autoCorrect={false}
281
+ returnKeyType="done"
282
+ onSubmitEditing={handleSubmit(onSubmit)}
283
+ blurOnSubmit
284
+ type="email-address"
285
+ />
286
+ )}
287
+ name="email"
288
+ rules={{
289
+ required: t(
290
+ 'VALIDATION_ERROR_EMAIL_REQUIRED',
291
+ 'The field Email is required',
289
292
  ).replace('_attribute_', t('EMAIL', 'Email')),
290
- },
291
- }}
292
- defaultValue=""
293
- />
293
+ pattern: {
294
+ value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
295
+ message: t(
296
+ 'INVALID_ERROR_EMAIL',
297
+ 'Invalid email address',
298
+ ).replace('_attribute_', t('EMAIL', 'Email')),
299
+ },
300
+ }}
301
+ defaultValue=""
302
+ />
294
303
  )}
295
304
 
296
305
  {optionToSendReceipt?.value === _SMS && (
@@ -301,7 +310,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
301
310
  returnKeyType: 'done',
302
311
  onSubmitEditing: handleSubmit(onSubmit),
303
312
  }}
304
- />
313
+ />
305
314
  )}
306
315
 
307
316
  <OButton
@@ -337,7 +346,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
337
346
  }}
338
347
  >
339
348
  <OSTable>
340
- <View style={{flexDirection: 'row', bottom: 10}}>
349
+ <View style={{ flexDirection: 'row', bottom: 10 }}>
341
350
  <OText
342
351
  size={orientationState?.dimensions?.width * 0.039}
343
352
  weight="700"
@@ -388,41 +397,82 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
388
397
  </OSTable>
389
398
  )}
390
399
 
391
- {((order?.summary?.discount || order?.discount) > 0 && (order?.summary?.total || order?.total) >= 0) && (<OSTable>
392
- <OText
393
- weight="bold"
394
- mBottom={15}
395
- >
396
- {t('PROMO_CODE', 'Promo code')}
397
- {'\n'}
398
- <OText weight="400" style={{fontSize: 14}}>
399
- {order?.offer_type === 1 ? `${verifyDecimals(order?.offer_rate, parseNumber)}%` : parsePrice(order?.summary?.discount || order?.discount)} {t('OFF', 'off')}
400
- </OText>
401
- </OText>
402
-
403
- <OText
404
- color={theme.colors.primary}
405
- weight="bold"
406
- >
407
- {`-${parsePrice(order?.summary?.discount || order?.discount)}`}
408
- </OText>
409
- </OSTable>)}
410
-
411
- <OSTable style={{ justifyContent: 'flex-end' }}>
412
- <OText
413
- weight="bold"
414
- style={{ textAlign: 'right' }}
415
- >
416
- {t('TOTAL', 'Total')}
417
- {'\n'}
418
- <OText
419
- color={theme.colors.primary}
420
- weight="bold"
421
- >
422
- {parsePrice(order?.summary?.total || order?.total)}
400
+ <OrderBill>
401
+ <Table>
402
+ <OText>{t('SUBTOTAL', 'Subtotal')}</OText>
403
+ <OText>
404
+ {parsePrice(isTaxIncluded
405
+ ? (order?.summary?.subtotal + order?.summary?.tax) ?? 0
406
+ : order?.summary?.subtotal ?? 0
407
+ )}
423
408
  </OText>
424
- </OText>
425
- </OSTable>
409
+ </Table>
410
+ {order?.summary?.discount > 0 && (
411
+ <Table>
412
+ {order?.offer_type === 1 ? (
413
+ <OText>
414
+ {t('DISCOUNT', 'Discount')}
415
+ <OText>{`(${verifyDecimals(order?.offer_rate, parsePrice)}%)`}</OText>
416
+ </OText>
417
+ ) : (
418
+ <OText>{t('DISCOUNT', 'Discount')}</OText>
419
+ )}
420
+ <OText>- {parsePrice(order?.summary?.discount)}</OText>
421
+ </Table>
422
+ )}
423
+ {order?.summary?.subtotal_with_discount > 0 && order?.summary?.discount > 0 && order?.summary?.total >= 0 && (
424
+ <Table>
425
+ <OText>{t('SUBTOTAL_WITH_DISCOUNT', 'Subtotal with discount')}</OText>
426
+ <OText>{parsePrice(order?.summary?.subtotal_with_discount ?? 0)}</OText>
427
+ </Table>
428
+ )}
429
+ {order?.tax_type !== 1 && (
430
+ <Table>
431
+ <OText>
432
+ {t('TAX', 'Tax')}
433
+ {`(${verifyDecimals(order?.summary?.tax_rate, parseNumber)}%)`}
434
+ </OText>
435
+ <OText>{parsePrice(order?.summary?.tax)}</OText>
436
+ </Table>
437
+ )}
438
+ {order?.summary?.delivery_price > 0 && (
439
+ <Table>
440
+ <OText>{t('DELIVERY_FEE', 'Delivery Fee')}</OText>
441
+ <OText>{parsePrice(order?.summary?.delivery_price)}</OText>
442
+ </Table>
443
+ )}
444
+ {order?.summary?.driver_tip > 0 && (
445
+ <Table>
446
+ <OText>
447
+ {t('DRIVER_TIP', 'Driver tip')}
448
+ {order?.summary?.driver_tip > 0 &&
449
+ parseInt(configs?.driver_tip_type?.value, 10) === 2 &&
450
+ !parseInt(configs?.driver_tip_use_custom?.value, 10) &&
451
+ (
452
+ `(${verifyDecimals(order?.summary?.driver_tip, parseNumber)}%)`
453
+ )}
454
+ </OText>
455
+ <OText>{parsePrice(order?.summary?.driver_tip ?? 0)}</OText>
456
+ </Table>
457
+ )}
458
+ {order?.summary?.service_fee > 0 && (
459
+ <Table>
460
+ <OText>
461
+ {t('SERVICE_FEE', 'Service Fee')}
462
+ {`(${verifyDecimals(order?.summary?.service_fee, parseNumber)}%)`}
463
+ </OText>
464
+ <OText>{parsePrice(order?.summary?.service_fee)}</OText>
465
+ </Table>
466
+ )}
467
+ <Total>
468
+ <Table>
469
+ <OText style={styles.textBold}>{t('TOTAL', 'Total')}</OText>
470
+ <OText style={styles.textBold} color={theme.colors.primary}>
471
+ {parsePrice(order?.summary?.total ?? 0)}
472
+ </OText>
473
+ </Table>
474
+ </Total>
475
+ </OrderBill>
426
476
  </OSOrderDetailsWrapper>
427
477
  );
428
478
 
@@ -435,7 +485,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
435
485
  <Container>
436
486
  <NavBar
437
487
  title={t('TAKE_YOUR_RECEIPT', 'Take your receipt')}
438
- style={{right: 10}}
488
+ style={{ right: 10 }}
439
489
  />
440
490
 
441
491
  <View style={{
@@ -29,4 +29,25 @@ export const OSInputWrapper = styled.View`
29
29
 
30
30
  export const SentReceipt = styled.View`
31
31
  flex-direction: row;
32
- `
32
+ `
33
+
34
+ export const Table = styled.View`
35
+ flex-direction: row;
36
+ justify-content: space-between;
37
+ flex: 1;
38
+ align-items: center;
39
+ `
40
+
41
+ export const OrderBill = styled.View`
42
+ padding-horizontal: 30px;
43
+ padding-vertical: 10px;
44
+ flex: 1;
45
+ background-color: ${(props: any) => props.theme.colors.paleGray};
46
+ `
47
+
48
+ export const Total = styled.View`
49
+ border-top-width: 1px;
50
+ border-top-color: #d9d9d9;
51
+ padding-vertical: 10px;
52
+ `
53
+
@@ -83,7 +83,8 @@ const PaymentOptionsUI = (props: any) => {
83
83
  }
84
84
  }, [isOpenMethod.paymethod, placing, isLoading, paySelected]);
85
85
 
86
- const includePaymethods = ['cash', 'card_delivery', 'stripe'];
86
+ // const includePaymethods = ['cash', 'card_delivery', 'stripe'];
87
+ const includePaymethods = ['cash', 'card_delivery'];
87
88
 
88
89
  const supportedMethods = paymethodsList.paymethods.filter((p: any) =>
89
90
  includePaymethods.includes(p.gateway),
@@ -36,6 +36,7 @@ import { ProductOptionSubOption } from '../ProductOptionSubOption'
36
36
  import { NotFoundSource } from '../NotFoundSource'
37
37
  import NavBar from '../NavBar'
38
38
  import { useDeviceOrientation } from '../../../../../src/hooks/DeviceOrientation'
39
+ import { useCartBottomSheet } from '../../providers/CartBottomSheetProvider';
39
40
 
40
41
  export const ProductOptionsUI = (props: any) => {
41
42
  const {
@@ -63,6 +64,7 @@ export const ProductOptionsUI = (props: any) => {
63
64
  const [orderState] = useOrder();
64
65
  const [{ auth }] = useSession();
65
66
  const [orientationState] = useDeviceOrientation();
67
+ const [, { showCartBottomSheet }] = useCartBottomSheet();
66
68
 
67
69
  const { product, loading, error } = productObject;
68
70
 
@@ -84,6 +86,7 @@ export const ProductOptionsUI = (props: any) => {
84
86
  const isErrors = Object.values(errors).length > 0
85
87
  if (!isErrors) {
86
88
  handleSave && handleSave()
89
+ showCartBottomSheet()
87
90
  return
88
91
  }
89
92
  }
@@ -254,12 +257,14 @@ export const ProductOptionsUI = (props: any) => {
254
257
  flexDirection: 'row',
255
258
  alignItems: 'center',
256
259
  padding: 20,
260
+ paddingTop: 0,
261
+ paddingBottom: 10
257
262
  }}
258
263
  >
259
264
  <OImage
260
265
  source={{uri: product?.images}}
261
- width={80}
262
- height={80}
266
+ width={70}
267
+ height={70}
263
268
  resizeMode="cover"
264
269
  borderRadius={6}
265
270
  />
@@ -30,7 +30,7 @@ const ProductOptionUI = (props: any) => {
30
30
  <Container style={{color: error ? 'orange' : theme.colors.white}}>
31
31
  <WrapHeader>
32
32
  <OText
33
- size={28}
33
+ size={26}
34
34
  weight="bold"
35
35
  >
36
36
  {option.name}
@@ -4,12 +4,12 @@ export const Container = styled.View`
4
4
  `
5
5
 
6
6
  export const WrapHeader = styled.View`
7
- padding: 15px 0px;
7
+ padding: 15px;
8
8
  display: flex;
9
9
  justify-content: space-between;
10
10
  align-items: center;
11
11
  flex-direction: row;
12
- background-color: ${(props: any) => props.theme.colors.white};
12
+ background-color: ${(props: any) => props.theme.colors.paleGray};
13
13
  border-top-left-radius: 10px;
14
14
  border-top-right-radius: 10px;
15
15
  `
@@ -13,7 +13,9 @@ import {
13
13
  QuantityControl,
14
14
  Checkbox,
15
15
  PositionControl,
16
- Circle
16
+ Circle,
17
+ LeftSide,
18
+ RightSide
17
19
  } from './styles'
18
20
  import { OText } from '../shared'
19
21
  import { useTheme } from 'styled-components/native'
@@ -66,24 +68,33 @@ export const ProductOptionSubOptionUI = (props: any) => {
66
68
 
67
69
  return (
68
70
  <Container onPress={() => handleSuboptionClick()} disabled={disabled}>
71
+ <LeftSide>
72
+ {((option?.min === 0 && option?.max === 1) || option?.max > 1) ? (
73
+ state?.selected ? (
74
+ <MaterialCommunityIcon name='checkbox-marked' color={theme.colors.primary} size={24} />
75
+ ) : (
76
+ <MaterialCommunityIcon name='checkbox-blank-outline' color={theme.colors.backgroundDark} size={24} />
77
+ )
78
+ ) : (
79
+ state?.selected ? (
80
+ <MaterialCommunityIcon name='radiobox-marked' color={theme.colors.primary} size={24} />
81
+ ) : (
82
+ <MaterialCommunityIcon name='radiobox-blank' color={theme.colors.backgroundDark} size={24} />
83
+ )
84
+ )}
69
85
  <View
70
86
  style={{
71
- alignItems: "flex-start"
87
+ alignItems: "flex-start",
88
+ marginLeft: 10,
72
89
  }}
73
90
  >
74
91
  <OText size={20}>
75
92
  {suboption?.name}
76
93
  </OText>
77
- <OText
78
- color="#909BA9"
79
- size={16}
80
- weight="bold"
81
- >
82
- + {parsePrice(price)}
83
- </OText>
84
94
  </View>
85
-
95
+ </LeftSide>
86
96
  {showMessage && <OText mLeft={10} mRight={10} style={{ flex: 1, textAlign: 'center' }} color={theme.colors.primary}>{`${t('OPTIONS_MAX_LIMIT', 'Maximum options to choose')}: ${option?.max}`}</OText>}
97
+ <RightSide>
87
98
  {option?.allow_suboption_quantity && (
88
99
  <QuantityControl>
89
100
  <Checkbox disabled={state.quantity === 0} onPress={handleDecrement}>
@@ -105,49 +116,42 @@ export const ProductOptionSubOptionUI = (props: any) => {
105
116
  </Checkbox>
106
117
  </QuantityControl>
107
118
  )}
108
- {
109
- option?.with_half_option && (
110
- <PositionControl>
111
- <Circle onPress={() => handlePosition('left')}>
112
- <MaterialCommunityIcon
113
- name='circle-half-full'
114
- color={state.selected && state.position === 'left' ? theme.colors.primary : theme.colors.backgroundDark}
115
- size={24}
116
- style={styles.inverse}
117
- />
118
- </Circle>
119
- <Circle onPress={() => handlePosition('whole')}>
120
- <MaterialCommunityIcon
121
- name='checkbox-blank-circle'
122
- color={state.selected && state.position === 'whole' ? theme.colors.primary : theme.colors.backgroundDark}
123
- size={24}
124
- />
125
- </Circle>
126
- <Circle onPress={() => handlePosition('right')}>
127
- <MaterialCommunityIcon
128
- name='circle-half-full'
129
- color={state.selected && state.position === 'right' ? theme.colors.primary : theme.colors.backgroundDark}
130
- size={24}
131
- />
132
- </Circle>
133
- </PositionControl>
134
- )
135
- }
136
- <>
137
- {((option?.min === 0 && option?.max === 1) || option?.max > 1) ? (
138
- state?.selected ? (
139
- <MaterialCommunityIcon name='checkbox-marked' color={theme.colors.primary} size={24} />
140
- ) : (
141
- <MaterialCommunityIcon name='checkbox-blank-outline' color={theme.colors.backgroundDark} size={24} />
142
- )
143
- ) : (
144
- state?.selected ? (
145
- <MaterialCommunityIcon name='radiobox-marked' color={theme.colors.primary} size={24} />
146
- ) : (
147
- <MaterialCommunityIcon name='radiobox-blank' color={theme.colors.backgroundDark} size={24} />
119
+ {
120
+ option?.with_half_option && (
121
+ <PositionControl>
122
+ <Circle onPress={() => handlePosition('left')}>
123
+ <MaterialCommunityIcon
124
+ name='circle-half-full'
125
+ color={state.selected && state.position === 'left' ? theme.colors.primary : theme.colors.backgroundDark}
126
+ size={24}
127
+ style={styles.inverse}
128
+ />
129
+ </Circle>
130
+ <Circle onPress={() => handlePosition('whole')}>
131
+ <MaterialCommunityIcon
132
+ name='checkbox-blank-circle'
133
+ color={state.selected && state.position === 'whole' ? theme.colors.primary : theme.colors.backgroundDark}
134
+ size={24}
135
+ />
136
+ </Circle>
137
+ <Circle onPress={() => handlePosition('right')}>
138
+ <MaterialCommunityIcon
139
+ name='circle-half-full'
140
+ color={state.selected && state.position === 'right' ? theme.colors.primary : theme.colors.backgroundDark}
141
+ size={24}
142
+ />
143
+ </Circle>
144
+ </PositionControl>
148
145
  )
149
- )}
150
- </>
146
+ }
147
+ <OText
148
+ color="#909BA9"
149
+ size={16}
150
+ weight="bold"
151
+ >
152
+ + {parsePrice(price)}
153
+ </OText>
154
+ </RightSide>
151
155
  </Container>
152
156
  )
153
157
  }
@@ -30,3 +30,13 @@ export const Checkbox = styled.TouchableOpacity`
30
30
 
31
31
  export const Circle = styled.TouchableOpacity`
32
32
  `
33
+
34
+ export const LeftSide = styled.View`
35
+ flex-direction: row;
36
+ align-items: center;
37
+ `
38
+
39
+ export const RightSide = styled.View`
40
+ flex-direction: row;
41
+ align-items: center;
42
+ `