ordering-ui-react-native 0.15.53 → 0.15.56

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.15.53",
3
+ "version": "0.15.56",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -514,7 +514,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
514
514
  </Table>
515
515
  )}
516
516
  {
517
- order?.taxes?.length === 0 && order?.tax_type === 2 && (
517
+ order?.taxes?.length === 0 && order?.tax_type === 2 && order?.summary?.tax > 0 && (
518
518
  <Table>
519
519
  <OText>
520
520
  {t('TAX', 'Tax')} {`(${verifyDecimals(order?.tax, parseNumber)}%)`}
@@ -524,7 +524,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
524
524
  )
525
525
  }
526
526
  {
527
- order?.fees?.length === 0 && (
527
+ order?.fees?.length === 0 && order?.summary?.service_fee > 0 && (
528
528
  <Table>
529
529
  <OText>
530
530
  {t('SERVICE_FEE', 'Service fee')}
@@ -1,18 +1,66 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, useEffect } from 'react';
2
2
  import { StyleSheet, View, Dimensions, Platform } from 'react-native';
3
- import { useLanguage } from 'ordering-components/native';
3
+ import { useForm, Controller } from 'react-hook-form';
4
+ import { useLanguage, useApi } from 'ordering-components/native';
4
5
  import { useTheme } from 'styled-components/native';
5
- import { LogoWrapper, Container, BackgroundImage } from './styles';
6
- import { OButton, OIcon, OText } from '../shared';
6
+ import { LogoWrapper, Container, BackgroundImage, FormInput } from './styles';
7
+ import { OButton, OIcon, OText, OInput } from '../shared';
7
8
  import { _setStoreData } from '../../providers/StoreUtil';
8
9
 
9
10
  export const Home = (props: any) => {
10
- const { onNavigationRedirect } = props;
11
+ const { onNavigationRedirect, useRootPoint } = props;
11
12
  const safeHeight = Platform.OS === 'ios' ? 80 : 40;
12
13
 
13
14
  const theme = useTheme();
15
+ const [ordering, { setOrdering }] = useApi();
14
16
  const [, t] = useLanguage();
17
+ const { control, handleSubmit, errors } = useForm();
15
18
 
19
+
20
+ const styles = StyleSheet.create({
21
+ logo: {
22
+ height: 65,
23
+ width: 300,
24
+ },
25
+ wrapperContent: {
26
+ width: '100%',
27
+ },
28
+ wrapperText: {
29
+ marginBottom: 20,
30
+ },
31
+ textTitle: {
32
+ fontWeight: '600',
33
+ fontStyle: 'normal',
34
+ fontSize: 50,
35
+ },
36
+ textSubtitle: {
37
+ fontWeight: 'normal',
38
+ fontStyle: 'normal',
39
+ fontSize: 14,
40
+ },
41
+ wrapperBtn: {
42
+ marginBottom: 20
43
+ },
44
+ btn: {
45
+ borderRadius: 7.6,
46
+ marginTop: 20,
47
+ },
48
+ btnText: {
49
+ fontFamily: 'Poppins',
50
+ fontStyle: 'normal',
51
+ fontWeight: 'normal',
52
+ fontSize: 18,
53
+ },
54
+ input: {
55
+ borderWidth: 1,
56
+ borderRadius: 7.6,
57
+ borderColor: Object.keys(errors).length > 0 ? theme.colors.error : theme.colors.inputSignup,
58
+ backgroundColor: theme.colors.transparent,
59
+ },
60
+ });
61
+
62
+ const [projectName, setProjectName] = useState<any>(null)
63
+ const [isLoadingProject, setLoadingProject] = useState(false)
16
64
  const [orientation, setOrientation] = useState(
17
65
  Dimensions.get('window').width < Dimensions.get('window').height
18
66
  ? 'Portrait'
@@ -34,6 +82,27 @@ export const Home = (props: any) => {
34
82
  }
35
83
  });
36
84
 
85
+ const onSubmit = (values: any) => {
86
+ setLoadingProject(true)
87
+ setProjectName(values)
88
+ setOrdering({ ...ordering, project: values?.project_name })
89
+ _setStoreData('project_name', values?.project_name)
90
+ };
91
+
92
+ useEffect(() => {
93
+ if (Object.keys(errors).length > 0) {
94
+ setProjectName(null)
95
+ setLoadingProject(false)
96
+ }
97
+ }, [errors])
98
+
99
+ useEffect(() => {
100
+ if (ordering?.project === projectName?.project_name) {
101
+ setLoadingProject(false)
102
+ onNavigationRedirect('Login')
103
+ }
104
+ }, [ordering])
105
+
37
106
  return (
38
107
  <Container height={windowHeight - safeHeight} orientation={orientation}>
39
108
  <BackgroundImage
@@ -54,58 +123,62 @@ export const Home = (props: any) => {
54
123
  </OText>
55
124
  </View>
56
125
 
57
- <View style={styles.wrapperBtn}>
58
- <OButton
59
- text={t('LOGIN', 'Login')}
60
- textStyle={{
61
- ...styles.btnText,
62
- color: theme.colors.inputTextColor,
63
- }}
64
- bgColor={theme.colors.primary}
65
- borderColor={theme.colors.primary}
66
- style={styles.btn}
67
- imgRightSrc={false}
68
- onClick={() => onNavigationRedirect('Login')}
69
- />
70
- </View>
126
+ <>
127
+ {useRootPoint && (
128
+ <FormInput>
129
+ <Controller
130
+ control={control}
131
+ name='project_name'
132
+ rules={{ required: t(`VALIDATION_ERROR_PROJECT_NAME_REQUIRED`, 'The field project name is required') }}
133
+ defaultValue=""
134
+ render={({ onChange, value }: any) => (
135
+ <OInput
136
+ name='project_name'
137
+ placeholderTextColor={theme.colors.arrowColor}
138
+ placeholder={t('PROJECT_NAME', 'Project Name')}
139
+ icon={theme.images.general.project}
140
+ iconColor={theme.colors.arrowColor}
141
+ onChange={(e: any) => onChange(e?.target?.value)}
142
+ selectionColor={theme.colors.primary}
143
+ color={theme.colors.white}
144
+ value={value}
145
+ style={styles.input}
146
+ returnKeyType='done'
147
+ autoCorrect={false}
148
+ autoCapitalize='none'
149
+ blurOnSubmit={false}
150
+ onSubmitEditing={() => handleSubmit(onSubmit)()}
151
+ />
152
+ )}
153
+ />
154
+ </FormInput>
155
+ )}
156
+ {Object.keys(errors).length > 0 && (
157
+ <OText
158
+ color={theme.colors.white}
159
+ style={{ alignSelf: 'center', marginTop: 5 }}
160
+ >
161
+ {errors['project_name'].message}
162
+ </OText>
163
+ )}
164
+ <View style={styles.wrapperBtn}>
165
+ <OButton
166
+ text={useRootPoint ? t('SET_PROJECT', 'Set project') : t('LOGIN', 'Login')}
167
+ textStyle={{
168
+ ...styles.btnText,
169
+ color: theme.colors.inputTextColor,
170
+ }}
171
+ bgColor={theme.colors.primary}
172
+ borderColor={theme.colors.primary}
173
+ isLoading={isLoadingProject}
174
+ style={styles.btn}
175
+ imgRightSrc={false}
176
+ onClick={() => useRootPoint ? handleSubmit(onSubmit)() : onNavigationRedirect('Login')}
177
+ />
178
+ </View>
179
+ </>
71
180
  </View>
72
181
  </BackgroundImage>
73
182
  </Container>
74
183
  );
75
184
  };
76
-
77
- const styles = StyleSheet.create({
78
- logo: {
79
- height: 65,
80
- width: 300,
81
- },
82
- wrapperContent: {
83
- width: '100%',
84
- },
85
- wrapperText: {
86
- marginBottom: 20,
87
- },
88
- textTitle: {
89
- fontWeight: '600',
90
- fontStyle: 'normal',
91
- fontSize: 50,
92
- },
93
- textSubtitle: {
94
- fontWeight: 'normal',
95
- fontStyle: 'normal',
96
- fontSize: 14,
97
- },
98
- wrapperBtn: {
99
- marginBottom: 20,
100
- },
101
- btn: {
102
- borderRadius: 7.6,
103
- marginTop: 20,
104
- },
105
- btnText: {
106
- fontFamily: 'Poppins',
107
- fontStyle: 'normal',
108
- fontWeight: 'normal',
109
- fontSize: 18,
110
- },
111
- });
@@ -1,4 +1,4 @@
1
- import styled from 'styled-components/native';
1
+ import styled, { css } from 'styled-components/native';
2
2
 
3
3
  export const Container = styled.View`
4
4
  width: 100%;
@@ -25,3 +25,10 @@ export const BackgroundImage = styled.ImageBackground`
25
25
  align-items: center;
26
26
  padding: 20px 40px;
27
27
  `;
28
+
29
+ export const FormInput = styled.View`
30
+ display: flex;
31
+ flex-direction: column;
32
+ width: 100%;
33
+ min-height: 50px;
34
+ `;
@@ -101,9 +101,9 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
101
101
  };
102
102
 
103
103
  const handleOpenMapView = async () => {
104
- if (permissions.locationStatus === 'granted') {
104
+ if (permissions?.locationStatus === 'granted') {
105
105
  setOpenModalForMapView(!openModalForMapView);
106
- } else if (permissions.locationStatus === 'blocked') {
106
+ } else if (permissions?.locationStatus === 'blocked') {
107
107
  // redirectToSettings();
108
108
  showToast(
109
109
  ToastType.Error,
@@ -141,9 +141,9 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
141
141
  handleArrowBack()
142
142
  }
143
143
 
144
- const handleAcceptLogisticOrder = (order : any) => {
144
+ const handleAcceptLogisticOrder = (order: any) => {
145
145
  handleClickLogisticOrder?.(1, order?.logistic_order_id)
146
- if(order?.order_group){
146
+ if (order?.order_group) {
147
147
  handleArrowBack()
148
148
  }
149
149
  }
@@ -166,10 +166,10 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
166
166
  ];
167
167
 
168
168
  useEffect(() => {
169
- if (permissions.locationStatus !== 'granted' && openModalForMapView) {
169
+ if (permissions?.locationStatus !== 'granted' && openModalForMapView) {
170
170
  setOpenModalForMapView(false);
171
171
  }
172
- }, [permissions.locationStatus]);
172
+ }, [permissions?.locationStatus]);
173
173
 
174
174
  useEffect(() => {
175
175
  if (openModalForAccept) {
@@ -215,8 +215,8 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
215
215
  }, [messagesReadList]);
216
216
 
217
217
  useEffect(() => {
218
- forceUpdate && handleViewActionOrder && handleViewActionOrder(forceUpdate === 9 ? 'forcePickUp': 'forceDelivery')
219
- },[forceUpdate])
218
+ forceUpdate && handleViewActionOrder && handleViewActionOrder(forceUpdate === 9 ? 'forcePickUp' : 'forceDelivery')
219
+ }, [forceUpdate])
220
220
 
221
221
  const styles = StyleSheet.create({
222
222
  btnPickUp: {
@@ -254,7 +254,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
254
254
  );
255
255
  }
256
256
 
257
- const OrderDetailsInformation = (props : {order: any, isOrderGroup?: boolean, lastOrder?: boolean}) => {
257
+ const OrderDetailsInformation = (props: { order: any, isOrderGroup?: boolean, lastOrder?: boolean }) => {
258
258
  const {
259
259
  order,
260
260
  isOrderGroup,
@@ -11,6 +11,7 @@ import {
11
11
  Table,
12
12
  OrderBill,
13
13
  Total,
14
+ OSRow,
14
15
  } from './styles';
15
16
 
16
17
  import { ProductItemAccordion } from '../ProductItemAccordion';
@@ -75,6 +76,20 @@ export const OrderContentComponent = (props: OrderContent) => {
75
76
  }
76
77
  })
77
78
 
79
+ const getIncludedTaxes = () => {
80
+ if (order?.taxes?.length === 0) {
81
+ return order.tax_type === 1 ? order?.summary?.tax ?? 0 : 0
82
+ } else {
83
+ return order?.taxes.reduce((taxIncluded: number, tax: any) => {
84
+ return taxIncluded + (tax.type === 1 ? tax.summary?.tax : 0)
85
+ }, 0)
86
+ }
87
+ }
88
+
89
+ const getIncludedTaxesDiscounts = () => {
90
+ return order?.taxes?.filter((tax: any) => tax?.type === 1)?.reduce((carry: number, tax: any) => carry + (tax?.summary?.tax_after_discount ?? tax?.summary?.tax), 0)
91
+ }
92
+
78
93
  return (
79
94
  <OrderContent isOrderGroup={isOrderGroup} lastOrder={lastOrder}>
80
95
  {isOrderGroup && (
@@ -281,14 +296,14 @@ export const OrderContentComponent = (props: OrderContent) => {
281
296
  </OText>
282
297
  )}
283
298
  {((order?.delivery_option !== undefined && order?.delivery_type === 1) || !!order?.comment) && (
284
- <View style={{marginTop: 10}}>
299
+ <View style={{ marginTop: 10 }}>
285
300
  {order?.delivery_option !== undefined && order?.delivery_type === 1 && (
286
301
  <OText>
287
302
  {order?.delivery_option?.name}
288
303
  </OText>
289
304
  )}
290
305
  {!!order?.comment && (
291
- <OText style={{fontStyle: 'italic', opacity: 0.6, marginBottom: 5}}>
306
+ <OText style={{ fontStyle: 'italic', opacity: 0.6, marginBottom: 5 }}>
292
307
  {order?.comment}
293
308
  </OText>
294
309
  )}
@@ -323,84 +338,109 @@ export const OrderContentComponent = (props: OrderContent) => {
323
338
  <Table>
324
339
  <OText mBottom={4}>{t('SUBTOTAL', 'Subtotal')}</OText>
325
340
  <OText mBottom={4}>
326
- {parsePrice(
327
- order.tax_type === 1
328
- ? order?.summary?.subtotal + order?.summary?.tax ?? 0
329
- : order?.summary?.subtotal ?? 0,
330
- )}
341
+ {parsePrice(((order?.summary?.subtotal ?? order?.subtotal) + getIncludedTaxes()))}
331
342
  </OText>
332
343
  </Table>
333
-
334
- {order?.tax_type !== 1 && (
344
+ {(order?.summary?.discount > 0 ?? order?.discount > 0) && order?.offers?.length === 0 && (
345
+ <Table>
346
+ {order?.offer_type === 1 ? (
347
+ <OText mBottom={4}>
348
+ {t('DISCOUNT', theme?.defaultLanguages?.DISCOUNT || 'Discount')}{' '}
349
+ <OText>{`(${verifyDecimals(order?.offer_rate, parsePrice)}%)`}</OText>
350
+ </OText>
351
+ ) : (
352
+ <OText mBottom={4}>{t('DISCOUNT', theme?.defaultLanguages?.DISCOUNT || 'Discount')}</OText>
353
+ )}
354
+ <OText>- {parsePrice(order?.summary?.discount ?? order?.discount)}</OText>
355
+ </Table>
356
+ )}
357
+ {
358
+ order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any) => (
359
+ <Table key={offer.id}>
360
+ <OSRow>
361
+ <OText numberOfLines={1} mBottom={4}>
362
+ {offer.name}
363
+ {offer.rate_type === 1 && (
364
+ <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
365
+ )}
366
+ </OText>
367
+ </OSRow>
368
+ <OText mBottom={4}>- {parsePrice(offer?.summary?.discount)}</OText>
369
+ </Table>
370
+ ))
371
+ }
372
+ {order?.summary?.subtotal_with_discount > 0 && order?.summary?.discount > 0 && order?.summary?.total >= 0 && (
373
+ <Table>
374
+ <OText mBottom={4}>{t('SUBTOTAL_WITH_DISCOUNT', 'Subtotal with discount')}</OText>
375
+ {order?.tax_type === 1 ? (
376
+ <OText mBottom={4}>{parsePrice((order?.summary?.subtotal_with_discount + getIncludedTaxesDiscounts() ?? 0))}</OText>
377
+ ) : (
378
+ <OText mBottom={4}>{parsePrice(order?.summary?.subtotal_with_discount ?? 0)}</OText>
379
+ )}
380
+ </Table>
381
+ )}
382
+ {order?.taxes?.length === 0 && order?.tax_type === 2 && order?.summary?.tax > 0 && (
335
383
  <Table>
336
384
  <OText mBottom={4}>
337
- {t('TAX', 'Tax')}
338
- {`(${verifyDecimals(
339
- order?.summary?.tax_rate,
340
- parseNumber,
341
- )}%)`}
385
+ {t('TAX', 'Tax')} {`(${verifyDecimals(order?.tax, parseNumber)}%)`}
342
386
  </OText>
343
-
344
387
  <OText mBottom={4}>
345
388
  {parsePrice(order?.summary?.tax ?? 0)}
346
389
  </OText>
347
- </Table >
390
+ </Table>
348
391
  )}
349
-
350
392
  {
351
- order?.summary?.discount > 0 && (
393
+ order?.fees?.length === 0 && order?.summary?.service_fee > 0 && (
352
394
  <Table>
353
- {order?.offer_type === 1 ? (
354
- <OText mBottom={4}>
355
- <OText>{t('DISCOUNT', 'Discount')}</OText>
356
-
357
- <OText>
358
- {`(${verifyDecimals(
359
- order?.offer_rate,
360
- parsePrice,
361
- )}%)`}
362
- </OText>
363
- </OText>
364
- ) : (
365
- <OText mBottom={4}>{t('DISCOUNT', 'Discount')}</OText>
366
- )}
367
-
368
395
  <OText mBottom={4}>
369
- - {parsePrice(order?.summary?.discount)}
396
+ {t('SERVICE_FEE', 'Service fee')}
397
+ {`(${verifyDecimals(order?.service_fee, parseNumber)}%)`}
370
398
  </OText>
399
+ <OText mBottom={4}>{parsePrice(order?.summary?.service_fee ?? 0)}</OText>
371
400
  </Table>
372
401
  )
373
402
  }
374
-
375
403
  {
376
- order?.summary?.subtotal_with_discount > 0 &&
377
- order?.summary?.discount > 0 &&
378
- order?.summary?.total >= 0 && (
379
- <Table>
380
- <OText mBottom={4}>
381
- {t(
382
- 'SUBTOTAL_WITH_DISCOUNT',
383
- 'Subtotal with discount',
384
- )}
385
- </OText>
386
- {order?.tax_type === 1 ? (
387
- <OText mBottom={4}>
388
- {parsePrice(
389
- order?.summary?.subtotal_with_discount +
390
- order?.summary?.tax ?? 0,
391
- )}
404
+ order?.taxes?.length > 0 && order?.taxes?.filter((tax: any) => tax?.type === 2 && tax?.rate !== 0).map((tax: any) => (
405
+ <Table key={tax.id}>
406
+ <OSRow>
407
+ <OText numberOfLines={1} mBottom={4}>
408
+ {tax.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}
409
+ {`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '}
410
+ </OText>
411
+ </OSRow>
412
+ <OText mBottom={4}>{parsePrice(tax?.summary?.tax_after_discount ?? tax?.summary?.tax ?? 0)}</OText>
413
+ </Table>
414
+ ))
415
+ }
416
+ {
417
+ order?.fees?.length > 0 && order?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0))?.map((fee: any) => (
418
+ <Table key={fee.id}>
419
+ <OSRow>
420
+ <OText numberOfLines={1} mBottom={4}>
421
+ {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}
422
+ ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)} + `}{fee.percentage}%){' '}
392
423
  </OText>
393
- ) : (
394
- <OText mBottom={4}>
395
- {parsePrice(
396
- order?.summary?.subtotal_with_discount ?? 0,
424
+ </OSRow>
425
+ <OText mBottom={4}>{parsePrice(fee?.summary?.fixed + (fee?.summary?.percentage_after_discount ?? fee?.summary?.percentage) ?? 0)}</OText>
426
+ </Table>
427
+ ))
428
+ }
429
+ {
430
+ order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 3)?.map((offer: any) => (
431
+ <Table key={offer.id}>
432
+ <OSRow>
433
+ <OText numberOfLines={1} mBottom={4}>
434
+ {offer.name}
435
+ {offer.rate_type === 1 && (
436
+ <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
397
437
  )}
398
438
  </OText>
399
- )}
439
+ </OSRow>
440
+ <OText mBottom={4}>- {parsePrice(offer?.summary?.discount)}</OText>
400
441
  </Table>
401
- )
442
+ ))
402
443
  }
403
-
404
444
  {
405
445
  order?.summary?.delivery_price > 0 && (
406
446
  <Table>
@@ -414,41 +454,35 @@ export const OrderContentComponent = (props: OrderContent) => {
414
454
  </Table>
415
455
  )
416
456
  }
417
-
418
- <Table>
419
- <OText mBottom={4}>
420
- {t('DRIVER_TIP', 'Driver tip')}{' '}
421
- {order?.summary?.driver_tip > 0 &&
422
- parseInt(configs?.driver_tip_type?.value, 10) === 2 &&
423
- !parseInt(configs?.driver_tip_use_custom?.value, 10) &&
424
- `(${verifyDecimals(
425
- order?.summary?.driver_tip,
426
- parseNumber,
427
- )}%)`}
428
- </OText>
429
-
430
- <OText mBottom={4}>
431
- {parsePrice(order?.summary?.driver_tip ?? 0)}
432
- </OText>
433
- </Table>
434
-
435
457
  {
436
- order?.summary?.service_fee > 0 && (
437
- <Table>
438
- <OText mBottom={4}>
439
- {t('SERVICE_FEE', 'Service Fee')}{' '}
440
- {`(${verifyDecimals(
441
- order?.summary?.service_fee,
442
- parseNumber,
443
- )}%)`}
444
- </OText>
445
-
446
- <OText mBottom={4}>
447
- {parsePrice(order?.summary?.service_fee)}
448
- </OText>
458
+ order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 2)?.map((offer: any) => (
459
+ <Table key={offer.id}>
460
+ <OSRow>
461
+ <OText numberOfLines={1} mBottom={4}>
462
+ {offer.name}
463
+ {offer.rate_type === 1 && (
464
+ <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
465
+ )}
466
+ </OText>
467
+ </OSRow>
468
+ <OText mBottom={4}>- {parsePrice(offer?.summary?.discount)}</OText>
449
469
  </Table>
450
- )
470
+ ))
451
471
  }
472
+ {order?.summary?.driver_tip > 0 && (
473
+ <Table>
474
+ <OText mBottom={4}>
475
+ {t('DRIVER_TIP', 'Driver tip')}
476
+ {order?.summary?.driver_tip > 0 &&
477
+ parseInt(configs?.driver_tip_type?.value, 10) === 2 &&
478
+ !parseInt(configs?.driver_tip_use_custom?.value, 10) &&
479
+ (
480
+ `(${verifyDecimals(order?.summary?.driver_tip, parseNumber)}%)`
481
+ )}
482
+ </OText>
483
+ <OText mBottom={4}>{parsePrice(order?.summary?.driver_tip ?? order?.totalDriverTip)}</OText>
484
+ </Table>
485
+ )}
452
486
 
453
487
  <Total style={{ paddingBottom: 10 }}>
454
488
  <Table>
@@ -460,7 +494,7 @@ export const OrderContentComponent = (props: OrderContent) => {
460
494
  mBottom={4}
461
495
  style={styles.textBold}
462
496
  color={theme.colors.primary}>
463
- {parsePrice(order?.summary?.total ?? 0)}
497
+ {parsePrice(order?.summary?.total ?? order?.total)}
464
498
  </OText>
465
499
  </Table>
466
500
  </Total>
@@ -91,3 +91,10 @@ export const AssignDriver = styled.View`
91
91
  padding-vertical: 10px;
92
92
  margin-bottom: 10px;
93
93
  `;
94
+
95
+ export const OSRow = styled.View`
96
+ flex-direction: row;
97
+ overflow: hidden;
98
+ width: 70%;
99
+ flex-wrap: wrap;
100
+ `
@@ -10,7 +10,7 @@ import {
10
10
  useValidationFields,
11
11
  } from 'ordering-components/native';
12
12
 
13
- import { CheckoutAction, OrderTypeWrapper, FloatingLayout } from './styles';
13
+ import { CheckoutAction, OrderTypeWrapper, FloatingLayout, OSRow } from './styles';
14
14
 
15
15
  import { OSBill, OSCoupon, OSTable } from '../OrderSummary/styles';
16
16
 
@@ -90,6 +90,20 @@ const CartUI = (props: any) => {
90
90
 
91
91
  const goToBack = () => navigation.goBack();
92
92
 
93
+ const getIncludedTaxes = () => {
94
+ if (cart?.taxes === null) {
95
+ return cart.business.tax_type === 1 ? cart?.tax : 0
96
+ } else {
97
+ return cart?.taxes.reduce((taxIncluded: number, tax: any) => {
98
+ return taxIncluded + (tax.type === 1 ? tax.summary?.tax : 0)
99
+ }, 0)
100
+ }
101
+ }
102
+
103
+ const getIncludedTaxesDiscounts = () => {
104
+ return cart?.taxes?.filter((tax: any) => tax?.type === 1)?.reduce((carry: number, tax: any) => carry + (tax?.summary?.tax_after_discount ?? tax?.summary?.tax), 0)
105
+ }
106
+
93
107
  return (
94
108
  <>
95
109
  <Container>
@@ -177,13 +191,10 @@ const CartUI = (props: any) => {
177
191
  <OSTable>
178
192
  <OText>{t('SUBTOTAL', 'Subtotal')}</OText>
179
193
  <OText>
180
- {cart.business.tax_type === 1
181
- ? parsePrice((cart?.subtotal + cart?.tax) || 0)
182
- : parsePrice(cart?.subtotal || 0)}
194
+ {parsePrice(cart?.subtotal + getIncludedTaxes())}
183
195
  </OText>
184
196
  </OSTable>
185
- {cart?.discount > 0 && cart?.total >= 0 && orientationState?.orientation == PORTRAIT && (
186
-
197
+ {cart?.discount > 0 && cart?.total >= 0 && cart?.offers?.length === 0 && orientationState?.orientation == PORTRAIT && (
187
198
  <OSTable
188
199
  style={{
189
200
  backgroundColor: theme.colors.success,
@@ -226,44 +237,107 @@ const CartUI = (props: any) => {
226
237
  </OText>
227
238
  </OSTable>
228
239
  )}
229
- {cart.business.tax_type !== 1 && (
240
+ {
241
+ cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any) => (
242
+ <OSTable key={offer.id}>
243
+ <OSRow>
244
+ <OText>{offer.name}</OText>
245
+ {offer.rate_type === 1 && (
246
+ <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
247
+ )}
248
+ </OSRow>
249
+ <OText>
250
+ - {parsePrice(offer?.summary?.discount)}
251
+ </OText>
252
+ </OSTable>
253
+ ))
254
+ }
255
+ {cart?.subtotal_with_discount > 0 && cart?.discount > 0 && cart?.total >= 0 && (
230
256
  <OSTable>
231
- <OText>
232
- {t('TAX', 'Tax')}
233
- {`(${verifyDecimals(cart?.business?.tax, parseNumber)}%)`}
234
- </OText>
235
- <OText>{parsePrice(cart?.tax || 0)}</OText>
257
+ <OText numberOfLines={1}>{t('SUBTOTAL_WITH_DISCOUNT', 'Subtotal with discount')}</OText>
258
+ {cart?.business?.tax_type === 1 ? (
259
+ <OText>{parsePrice(cart?.subtotal_with_discount + getIncludedTaxesDiscounts() ?? 0)}</OText>
260
+ ) : (
261
+ <OText>{parsePrice(cart?.subtotal_with_discount ?? 0)}</OText>
262
+ )}
236
263
  </OSTable>
237
264
  )}
265
+ {
266
+ cart.taxes?.length > 0 && cart.taxes.filter((tax: any) => tax.type === 2 && tax?.rate !== 0).map((tax: any) => (
267
+ <OSTable key={tax.id}>
268
+ <OSRow>
269
+ <OText>
270
+ {tax.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
271
+ {`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '}
272
+ </OText>
273
+ </OSRow>
274
+ <OText>{parsePrice(tax?.summary?.tax_after_discount ?? tax?.summary?.tax ?? 0)}</OText>
275
+ </OSTable>
276
+ ))
277
+ }
278
+ {
279
+ cart?.fees?.length > 0 && cart?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0)).map((fee: any) => (
280
+ <OSTable key={fee?.id}>
281
+ <OSRow>
282
+ <OText>
283
+ {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}{' '}
284
+ ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)} + `}{fee.percentage}%){' '}
285
+ </OText>
286
+ </OSRow>
287
+ <OText>{parsePrice(fee?.summary?.fixed + (fee?.summary?.percentage_after_discount ?? fee?.summary?.percentage) ?? 0)}</OText>
288
+ </OSTable>
289
+ ))
290
+ }
291
+ {
292
+ cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 3)?.map((offer: any) => (
293
+ <OSTable key={offer.id}>
294
+ <OSRow>
295
+ <OText>{offer.name}</OText>
296
+ {offer.rate_type === 1 && (
297
+ <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
298
+ )}
299
+ </OSRow>
300
+ <OText>
301
+ - {parsePrice(offer?.summary?.discount)}
302
+ </OText>
303
+ </OSTable>
304
+ ))
305
+ }
238
306
  {selectedOrderType === 1 && cart?.delivery_price > 0 && (
239
307
  <OSTable>
240
308
  <OText>{t('DELIVERY_FEE', 'Delivery Fee')}</OText>
241
309
  <OText>{parsePrice(cart?.delivery_price)}</OText>
242
310
  </OSTable>
243
311
  )}
312
+ {
313
+ cart?.offers?.length > 0 && cart?.offers?.filter((offer: any) => offer?.target === 2)?.map((offer: any) => (
314
+ <OSTable key={offer.id}>
315
+ <OSRow>
316
+ <OText>{offer.name}</OText>
317
+ {offer.rate_type === 1 && (
318
+ <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
319
+ )}
320
+ </OSRow>
321
+ <OText>
322
+ - {parsePrice(offer?.summary?.discount)}
323
+ </OText>
324
+ </OSTable>
325
+ ))
326
+ }
244
327
  {cart?.driver_tip > 0 && (
245
328
  <OSTable>
246
329
  <OText>
247
330
  {t('DRIVER_TIP', 'Driver tip')}
248
331
  {cart?.driver_tip_rate > 0 &&
249
332
  parseInt(configs?.driver_tip_type?.value, 10) === 2 &&
250
- !!!parseInt(configs?.driver_tip_use_custom?.value, 10) &&
333
+ !parseInt(configs?.driver_tip_use_custom?.value, 10) &&
251
334
  (
252
- `(${parseNumber(cart?.driver_tip_rate)}%)`
335
+ `(${verifyDecimals(cart?.driver_tip_rate, parseNumber)}%)`
253
336
  )}
254
337
  </OText>
255
338
  <OText>{parsePrice(cart?.driver_tip)}</OText>
256
339
  </OSTable>
257
340
  )}
258
- {cart?.service_fee > 0 && (
259
- <OSTable>
260
- <OText>
261
- {t('SERVICE_FEE', 'Service Fee')}
262
- {`(${verifyDecimals(cart?.business?.service_fee, parseNumber)}%)`}
263
- </OText>
264
- <OText>{parsePrice(cart?.service_fee)}</OText>
265
- </OSTable>
266
- )}
267
341
  {!cart?.discount_type && isCouponEnabled && !isCartPending && orientationState?.orientation == PORTRAIT && (
268
342
  <OSTable>
269
343
  <OSCoupon>
@@ -279,7 +353,7 @@ const CartUI = (props: any) => {
279
353
  {t('TOTAL', 'Total')}
280
354
  </OText>
281
355
  <OText weight='bold' color={theme.colors.primary}>
282
- {cart?.total >= 1 && parsePrice(cart?.total)}
356
+ {parsePrice(cart?.total >= 0 ? cart?.total : 0)}
283
357
  </OText>
284
358
  </OSTable>
285
359
  </OSBill>
@@ -379,7 +453,7 @@ const CartUI = (props: any) => {
379
453
  <ProductForm
380
454
  productCart={curProduct}
381
455
  businessSlug={cart?.business?.slug}
382
- businessId={cart?.business_id}
456
+ businessId={curProduct?.business_id}
383
457
  categoryId={curProduct?.category_id}
384
458
  productId={curProduct?.id}
385
459
  onSave={handlerProductAction}
@@ -68,3 +68,9 @@ export const FloatingLayout = styled.View`
68
68
  padding-bottom: 20px;
69
69
  `)}
70
70
  `
71
+
72
+ export const OSRow = styled.View`
73
+ flex-direction: row;
74
+ overflow: hidden;
75
+ width: 80%;
76
+ `
@@ -23,6 +23,7 @@ import {
23
23
  Table,
24
24
  OrderBill,
25
25
  Total,
26
+ OSRow,
26
27
  } from './styles'
27
28
  import { OrderDetailsParams, Product } from '../../types'
28
29
  import { Container } from '../../layouts/Container';
@@ -178,6 +179,20 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
178
179
  setIsLoading(false)
179
180
  }
180
181
 
182
+ const getIncludedTaxes = () => {
183
+ if (order?.taxes?.length === 0) {
184
+ return order.tax_type === 1 ? order?.summary?.tax ?? 0 : 0
185
+ } else {
186
+ return order?.taxes.reduce((taxIncluded: number, tax: any) => {
187
+ return taxIncluded + (tax.type === 1 ? tax.summary?.tax : 0)
188
+ }, 0)
189
+ }
190
+ }
191
+
192
+ const getIncludedTaxesDiscounts = () => {
193
+ return order?.taxes?.filter((tax: any) => tax?.type === 1)?.reduce((carry: number, tax: any) => carry + (tax?.summary?.tax_after_discount ?? tax?.summary?.tax), 0)
194
+ }
195
+
181
196
  useEffect(() => {
182
197
  const backAction = () => {
183
198
  Alert.alert(`${t('HOLD_ON', 'Hold on')}!`, `${t('ARE_YOU_SURE_YOU_WANT_TO_GO_BACK', 'Are you sure you want to go back')}?`, [
@@ -209,7 +224,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
209
224
  const getCustomerName = async () => {
210
225
  try {
211
226
  const { customerName: name } = await _retrieveStoreData('customer_name')
212
- setCustomerName(name)
227
+ setCustomerName(name)
213
228
  } catch (e) {
214
229
  if (e) {
215
230
  setCustomerName(null)
@@ -217,8 +232,8 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
217
232
  }
218
233
  }
219
234
  getCustomerName()
220
- const redirectHome = setTimeout(() =>{
221
- _setStoreData('customer_name', {customerName: ''});
235
+ const redirectHome = setTimeout(() => {
236
+ _setStoreData('customer_name', { customerName: '' });
222
237
  navigation.reset({
223
238
  routes: [{ name: 'Intro' }],
224
239
  });
@@ -345,7 +360,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
345
360
  <OButton
346
361
  text={`${t('YOU_ARE_DONE', 'You are done! Click to close')}!`}
347
362
  onClick={() => {
348
- _setStoreData('customer_name', {customerName: ''});
363
+ _setStoreData('customer_name', { customerName: '' });
349
364
  navigation.reset({
350
365
  routes: [{ name: 'Intro' }],
351
366
  });
@@ -419,46 +434,135 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
419
434
  <Table>
420
435
  <OText>{t('SUBTOTAL', 'Subtotal')}</OText>
421
436
  <OText>
422
- {parsePrice(isTaxIncluded
423
- ? (order?.summary?.subtotal + order?.summary?.tax) ?? 0
424
- : order?.summary?.subtotal ?? 0
425
- )}
437
+ {parsePrice(((order?.summary?.subtotal ?? order?.subtotal) + getIncludedTaxes()))}
426
438
  </OText>
427
439
  </Table>
428
- {order?.summary?.discount > 0 && (
440
+ {(order?.summary?.discount > 0 ?? order?.discount > 0) && order?.offers?.length === 0 && (
429
441
  <Table>
430
442
  {order?.offer_type === 1 ? (
431
443
  <OText>
432
444
  {t('DISCOUNT', 'Discount')}
433
- <OText>{`(${verifyDecimals(order?.offer_rate, parsePrice)}%)`}</OText>
445
+ <OText>{`(${verifyDecimals(
446
+ order?.offer_rate,
447
+ parsePrice,
448
+ )}%)`}</OText>
434
449
  </OText>
435
450
  ) : (
436
451
  <OText>{t('DISCOUNT', 'Discount')}</OText>
437
452
  )}
438
- <OText>- {parsePrice(order?.summary?.discount)}</OText>
453
+ <OText>
454
+ - {parsePrice(order?.summary?.discount || order?.discount)}
455
+ </OText>
439
456
  </Table>
440
457
  )}
458
+ {
459
+ order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any) => (
460
+ <Table key={offer.id}>
461
+ <OSRow>
462
+ <OText>
463
+ {offer.name}
464
+ {offer.rate_type === 1 && (
465
+ <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
466
+ )}
467
+ </OText>
468
+ </OSRow>
469
+ <OText>- {parsePrice(offer?.summary?.discount)}</OText>
470
+ </Table>
471
+ ))
472
+ }
441
473
  {order?.summary?.subtotal_with_discount > 0 && order?.summary?.discount > 0 && order?.summary?.total >= 0 && (
442
474
  <Table>
443
475
  <OText>{t('SUBTOTAL_WITH_DISCOUNT', 'Subtotal with discount')}</OText>
444
- <OText>{parsePrice(order?.summary?.subtotal_with_discount ?? 0)}</OText>
445
- </Table>
446
- )}
447
- {order?.tax_type !== 1 && (
448
- <Table>
449
- <OText>
450
- {t('TAX', 'Tax')}
451
- {`(${verifyDecimals(order?.summary?.tax_rate, parseNumber)}%)`}
452
- </OText>
453
- <OText>{parsePrice(order?.summary?.tax)}</OText>
476
+ {order?.tax_type === 1 ? (
477
+ <OText>{parsePrice((order?.summary?.subtotal_with_discount + getIncludedTaxesDiscounts() ?? 0))}</OText>
478
+ ) : (
479
+ <OText>{parsePrice(order?.summary?.subtotal_with_discount ?? 0)}</OText>
480
+ )}
454
481
  </Table>
455
482
  )}
483
+ {
484
+ order?.taxes?.length === 0 && order?.tax_type === 2 && (
485
+ <Table>
486
+ <OText>
487
+ {t('TAX', 'Tax')} {`(${verifyDecimals(order?.tax, parseNumber)}%)`}
488
+ </OText>
489
+ <OText>{parsePrice(order?.summary?.tax || 0)}</OText>
490
+ </Table>
491
+ )
492
+ }
493
+ {
494
+ order?.fees?.length === 0 && (
495
+ <Table>
496
+ <OText>
497
+ {t('SERVICE_FEE', 'Service fee')}
498
+ {`(${verifyDecimals(order?.service_fee, parseNumber)}%)`}
499
+ </OText>
500
+ <OText>{parsePrice(order?.summary?.service_fee || 0)}</OText>
501
+ </Table>
502
+ )
503
+ }
504
+ {
505
+ order?.taxes?.length > 0 && order?.taxes?.filter((tax: any) => tax?.type === 2 && tax?.rate !== 0).map((tax: any) => (
506
+ <Table key={tax.id}>
507
+ <OSRow>
508
+ <OText>
509
+ {tax.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}
510
+ {`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '}
511
+ </OText>
512
+ </OSRow>
513
+ <OText>{parsePrice(tax?.summary?.tax_after_discount ?? tax?.summary?.tax ?? 0)}</OText>
514
+ </Table>
515
+ ))
516
+ }
517
+ {
518
+ order?.fees?.length > 0 && order?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0))?.map((fee: any) => (
519
+ <Table key={fee.id}>
520
+ <OSRow>
521
+ <OText>
522
+ {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}
523
+ ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)} + `}{fee.percentage}%){' '}
524
+ </OText>
525
+ </OSRow>
526
+ <OText>{parsePrice(fee?.summary?.fixed + (fee?.summary?.percentage_after_discount ?? fee?.summary?.percentage) ?? 0)}</OText>
527
+ </Table>
528
+ ))
529
+ }
530
+ {
531
+ order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 3)?.map((offer: any) => (
532
+ <Table key={offer.id}>
533
+ <OSRow>
534
+ <OText>
535
+ {offer.name}
536
+ {offer.rate_type === 1 && (
537
+ <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
538
+ )}
539
+ </OText>
540
+ </OSRow>
541
+ <OText>- {parsePrice(offer?.summary?.discount)}</OText>
542
+ </Table>
543
+ ))
544
+ }
456
545
  {order?.summary?.delivery_price > 0 && (
457
546
  <Table>
458
547
  <OText>{t('DELIVERY_FEE', 'Delivery Fee')}</OText>
459
548
  <OText>{parsePrice(order?.summary?.delivery_price)}</OText>
460
549
  </Table>
461
550
  )}
551
+ {
552
+ order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 2)?.map((offer: any) => (
553
+ <Table key={offer.id}>
554
+ <OSRow>
555
+ <OText>
556
+ {offer.name}
557
+ {offer.rate_type === 1 && (
558
+ <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
559
+ )}
560
+ </OText>
561
+ </OSRow>
562
+ <OText>- {parsePrice(offer?.summary?.discount)}</OText>
563
+ </Table>
564
+ ))
565
+ }
462
566
  {order?.summary?.driver_tip > 0 && (
463
567
  <Table>
464
568
  <OText>
@@ -470,23 +574,14 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
470
574
  `(${verifyDecimals(order?.summary?.driver_tip, parseNumber)}%)`
471
575
  )}
472
576
  </OText>
473
- <OText>{parsePrice(order?.summary?.driver_tip ?? 0)}</OText>
474
- </Table>
475
- )}
476
- {order?.summary?.service_fee > 0 && (
477
- <Table>
478
- <OText>
479
- {t('SERVICE_FEE', 'Service Fee')}
480
- {`(${verifyDecimals(order?.summary?.service_fee, parseNumber)}%)`}
481
- </OText>
482
- <OText>{parsePrice(order?.summary?.service_fee)}</OText>
577
+ <OText>{parsePrice(order?.summary?.driver_tip ?? order?.totalDriverTip)}</OText>
483
578
  </Table>
484
579
  )}
485
580
  <Total>
486
581
  <Table>
487
582
  <OText style={styles.textBold}>{t('TOTAL', 'Total')}</OText>
488
583
  <OText style={styles.textBold} color={theme.colors.primary}>
489
- {parsePrice(order?.summary?.total ?? 0)}
584
+ {parsePrice(order?.summary?.total ?? order?.total)}
490
585
  </OText>
491
586
  </Table>
492
587
  </Total>
@@ -508,14 +603,14 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
508
603
  <OIconButton
509
604
  bgColor="transparent"
510
605
  borderColor="transparent"
511
- RenderIcon={() =>
512
- <EvilIcons
513
- name={'close'}
514
- size={40}
515
- color={theme.colors.primary}
516
- />
606
+ RenderIcon={() =>
607
+ <EvilIcons
608
+ name={'close'}
609
+ size={40}
610
+ color={theme.colors.primary}
611
+ />
517
612
  }
518
- style={{ flex:1, justifyContent: 'flex-end', left: 30 }}
613
+ style={{ flex: 1, justifyContent: 'flex-end', left: 30 }}
519
614
  onClick={() => {
520
615
  navigation.reset({
521
616
  routes: [{ name: 'Intro' }],
@@ -51,3 +51,8 @@ export const Total = styled.View`
51
51
  padding-vertical: 10px;
52
52
  `
53
53
 
54
+ export const OSRow = styled.View`
55
+ flex-direction: row;
56
+ overflow: hidden;
57
+ width: 80%;
58
+ `
@@ -472,6 +472,8 @@ export interface Cart {
472
472
  delivery_price_with_discount: number;
473
473
  total: number;
474
474
  clearInactivityTimeout: any;
475
+ taxes: Array<any>;
476
+ fees: Array<any>;
475
477
  }
476
478
 
477
479
  export interface NoNetworkParams {
@@ -1,6 +1,6 @@
1
- import React, { useEffect } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import { Platform, Text, StyleSheet } from 'react-native';
3
- import { useApi, useSession, useLanguage, useConfig } from 'ordering-components/native';
3
+ import { useApi, useSession, useLanguage, useConfig, useToast, ToastType } from 'ordering-components/native';
4
4
  import { appleAuthAndroid, appleAuth } from '@invertase/react-native-apple-authentication';
5
5
  import uuid from 'react-native-uuid';
6
6
  import Icon from 'react-native-vector-icons/FontAwesome5';
@@ -18,7 +18,12 @@ export const AppleLogin = (props: any) => {
18
18
  const [ordering] = useApi();
19
19
  const [{ auth }] = useSession();
20
20
  const [, t] = useLanguage();
21
- const [{ configs }] = useConfig()
21
+ const [{ configs }] = useConfig();
22
+ const [, {showToast}] = useToast()
23
+ const [credentialStateForUser, updateCredentialStateForUser] = useState<any>(-1);
24
+
25
+ let user : any= null
26
+
22
27
  const buttonText = auth
23
28
  ? t('CONTINUE_WITH_APPLE', 'Logout with Apple')
24
29
  : t('CONTINUE_WITH_FACEBOOK', 'Continue with Apple');
@@ -39,8 +44,8 @@ export const AppleLogin = (props: any) => {
39
44
  handleLoading && handleLoading(false)
40
45
  }
41
46
  } else {
47
+ showToast(ToastType.Error, `Error login on apple from api Code: ${code}`, 10000)
42
48
  handleLoading && handleLoading(false)
43
- logoutFromApple()
44
49
  }
45
50
  } catch (err: any) {
46
51
  handleLoading && handleLoading(false)
@@ -48,33 +53,52 @@ export const AppleLogin = (props: any) => {
48
53
  }
49
54
  }
50
55
 
51
- const logoutFromApple = () => {
52
-
56
+ const fetchAndUpdateCredentialState = async (updateCredentialStateForUser : any) => {
57
+ if (user === null) {
58
+ updateCredentialStateForUser('N/A');
59
+ } else {
60
+ const credentialState = await appleAuth.getCredentialStateForUser(user);
61
+ if (credentialState === appleAuth.State.AUTHORIZED) {
62
+ updateCredentialStateForUser('AUTHORIZED');
63
+ } else {
64
+ updateCredentialStateForUser(credentialState);
65
+ }
66
+ }
53
67
  }
54
68
 
55
- const onIOSButtonPress = async () => {
69
+ const onIOSButtonPress = async (updateCredentialStateForUser : any) => {
56
70
  try {
57
71
  const appleAuthRequestResponse = await appleAuth.performRequest({
58
72
  requestedOperation: appleAuth.Operation.LOGIN,
59
73
  requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],
60
74
  });
61
75
 
62
- // get current authentication state for user
63
- // /!\ This method must be tested on a real device. On the iOS simulator it always throws an error.
64
- const credentialState = await appleAuth.getCredentialStateForUser(appleAuthRequestResponse.user);
65
-
66
- // use credentialState response to ensure the user is authenticated
67
- if (credentialState === appleAuth.State.AUTHORIZED) {
68
- // user is authenticated
69
- if (appleAuthRequestResponse.authorizationCode) {
70
- performAppleLogin(appleAuthRequestResponse.authorizationCode)
71
- }
76
+ const {
77
+ user: newUser,
78
+ email,
79
+ identityToken,
80
+ authorizationCode
81
+ } = appleAuthRequestResponse;
82
+
83
+ user = newUser;
84
+
85
+ fetchAndUpdateCredentialState(updateCredentialStateForUser).catch(error =>
86
+ updateCredentialStateForUser(`Error: ${error.code}`),
87
+ );
88
+
89
+ if (identityToken && authorizationCode) {
90
+ showToast(ToastType.Success, `Apple Authentication Completed, ${email}`)
91
+ performAppleLogin(authorizationCode)
92
+ } else {
93
+ handleErrors && handleErrors('UNABLE_LOGIN_TOKEN', 'Unable to login, no token found')
72
94
  }
95
+
73
96
  } catch (err: any) {
74
97
  handleLoading && handleLoading(false)
75
98
  handleErrors && handleErrors(err.message)
76
99
  }
77
100
  }
101
+
78
102
  const onAndroidButtonPress = async () => {
79
103
  try {
80
104
  // Generate secure, random values for state and nonce
@@ -108,10 +132,20 @@ export const AppleLogin = (props: any) => {
108
132
  }
109
133
 
110
134
  useEffect(() => {
111
- if (Platform.OS == 'android') return;
112
- // onCredentialRevoked returns a function that will remove the event listener. useEffect will call this function when the component unmounts
135
+ if (!appleAuth.isSupported || Platform.OS === 'android') return;
136
+
137
+ fetchAndUpdateCredentialState(updateCredentialStateForUser).catch(error =>
138
+ updateCredentialStateForUser(`Error: ${error.code}`),
139
+ );
140
+ }, []);
141
+
142
+ useEffect(() => {
143
+ if (!appleAuth.isSupported || Platform.OS === 'android') return;
144
+
113
145
  return appleAuth.onCredentialRevoked(async () => {
114
- console.warn('If this function executes, User Credentials have been Revoked');
146
+ fetchAndUpdateCredentialState(updateCredentialStateForUser).catch(error =>
147
+ updateCredentialStateForUser(`Error: ${error.code}`),
148
+ );
115
149
  });
116
150
  }, []);
117
151
 
@@ -123,9 +157,12 @@ export const AppleLogin = (props: any) => {
123
157
 
124
158
  return (
125
159
  <Container>
160
+ {credentialStateForUser !== -1 && (
161
+ <Text>{credentialStateForUser}</Text>
162
+ )}
126
163
  {canShowButton() &&
127
164
  <AppleButton
128
- onPress={() => Platform.OS == 'android' ? onAndroidButtonPress() : onIOSButtonPress()}
165
+ onPress={() => Platform.OS == 'android' ? onAndroidButtonPress() : onIOSButtonPress(updateCredentialStateForUser)}
129
166
  >
130
167
  <Icon
131
168
  name="apple"
@@ -248,7 +248,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
248
248
  style={{ borderRadius: 7.6 }}
249
249
  />
250
250
  )}
251
- <OText>{openDescription?.description}</OText>
251
+ <OText mBottom={40}>{openDescription?.description}</OText>
252
252
  </ScrollView>
253
253
  </OModal>
254
254
  </ProductsContainer>
@@ -90,33 +90,12 @@ const BusinessReviewsUI = (props: BusinessReviewsParams) => {
90
90
  </View>
91
91
  );
92
92
 
93
- const ReviewItem = ({ comment, created_at, total, customer }: any) => (
93
+ const ReviewItem = ({ comment, created_at, total }: any) => (
94
94
  <View style={{ marginBottom: 30 }}>
95
- <View
96
- style={{ flexDirection: 'row', marginBottom: 19, alignItems: 'center' }}>
97
- <OIcon
98
- url={theme.images.dummies.customerPhoto}
99
- width={38}
100
- height={38}
101
- style={{
102
- borderRadius: 7.6,
103
- borderWidth: 1,
104
- borderColor: theme.colors.border,
105
- marginEnd: 9,
106
- }}
107
- />
108
- <View>
109
- <OText size={12} color={theme.colors.textNormal} weight={'500'}>
110
- {customer?.name || 'Jane Cooper'}
111
- </OText>
112
- <OText size={10} color={theme.colors.textSecondary}>
113
- {moment(created_at).format('MMMM d, yyyy • hh:mm')}
114
- </OText>
115
- </View>
116
- </View>
117
- <OText size={10} color={theme.colors.textNormal}>
118
- {comment}
95
+ <OText size={12} color={theme.colors.textSecondary}>
96
+ {moment(created_at).format('MMMM d, yyyy hh:mm')}
119
97
  </OText>
98
+ <OText size={12} color={theme.colors.textNormal}>{comment}</OText>
120
99
  </View>
121
100
  );
122
101
 
@@ -112,7 +112,7 @@ const OrderSummaryUI = (props: any) => {
112
112
  {cart?.products?.length > 0 && (
113
113
  <>
114
114
  <OSProductList>
115
- {cart?.products.map((product: any) => (
115
+ {cart?.products?.map((product: any) => (
116
116
  <ProductItemAccordion
117
117
  key={product.code}
118
118
  product={product}