ordering-ui-react-native 0.17.66 → 0.17.68

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 (37) hide show
  1. package/package.json +1 -1
  2. package/src/components/shared/OToast.tsx +2 -2
  3. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +31 -27
  4. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +3 -3
  5. package/themes/business/src/components/OrdersOption/index.tsx +14 -58
  6. package/themes/business/src/components/PreviousOrders/OrderItem.tsx +250 -0
  7. package/themes/business/src/components/PreviousOrders/OrdersGroupedItem.tsx +115 -0
  8. package/themes/business/src/components/PreviousOrders/index.tsx +332 -242
  9. package/themes/business/src/components/PreviousOrders/styles.tsx +30 -2
  10. package/themes/business/src/components/ReviewCustomer/index.tsx +12 -2
  11. package/themes/business/src/components/shared/OLink.tsx +24 -12
  12. package/themes/business/src/components/shared/OText.tsx +3 -2
  13. package/themes/business/src/types/index.tsx +6 -1
  14. package/themes/original/index.tsx +2 -0
  15. package/themes/original/src/components/BusinessController/index.tsx +16 -2
  16. package/themes/original/src/components/BusinessController/styles.tsx +13 -1
  17. package/themes/original/src/components/BusinessInformation/index.tsx +10 -31
  18. package/themes/original/src/components/BusinessProductsListing/index.tsx +1 -0
  19. package/themes/original/src/components/Cart/index.tsx +31 -2
  20. package/themes/original/src/components/FloatingButton/index.tsx +13 -11
  21. package/themes/original/src/components/LoginForm/Otp/index.tsx +0 -6
  22. package/themes/original/src/components/LoginForm/Otp/styles.tsx +0 -1
  23. package/themes/original/src/components/Messages/index.tsx +15 -0
  24. package/themes/original/src/components/MultiCart/index.tsx +63 -0
  25. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +6 -7
  26. package/themes/original/src/components/MultiCheckout/index.tsx +4 -2
  27. package/themes/original/src/components/MultiOrdersDetails/index.tsx +14 -0
  28. package/themes/original/src/components/OrdersOption/index.tsx +32 -2
  29. package/themes/original/src/components/ReviewOrder/index.tsx +26 -9
  30. package/themes/original/src/components/ReviewOrder/styles.tsx +7 -0
  31. package/themes/original/src/components/ReviewTrigger/index.tsx +27 -9
  32. package/themes/original/src/components/ReviewTrigger/styles.tsx +8 -1
  33. package/themes/original/src/components/ScheduleAccordion/index.tsx +68 -0
  34. package/themes/original/src/components/ScheduleAccordion/styles.tsx +14 -0
  35. package/themes/original/src/components/SingleOrderCard/index.tsx +54 -19
  36. package/themes/original/src/components/SingleOrderCard/styles.tsx +10 -1
  37. package/themes/original/src/types/index.tsx +2 -0
@@ -39,7 +39,8 @@ const ReviewCustomerUI = (props: ReviewCustomerParams) => {
39
39
  reviewState,
40
40
  setReviewState,
41
41
  actionState,
42
- handleSendCustomerReview
42
+ handleSendCustomerReview,
43
+ handleCustomCustomerReview
43
44
  } = props
44
45
 
45
46
  const theme = useTheme()
@@ -153,6 +154,15 @@ const ReviewCustomerUI = (props: ReviewCustomerParams) => {
153
154
 
154
155
  const customerName = `${order?.customer?.name ?? ''} ${order?.customer?.middle_name ?? ''} ${order?.customer?.lastname ?? ''} ${order?.customer?.second_lastname ?? ''}`?.replace(' ', ' ')?.trim() ?? ''
155
156
 
157
+ const handleReviewClick = () => {
158
+ handleCustomCustomerReview
159
+ ? handleCustomCustomerReview({
160
+ qualification: reviewState?.qualification,
161
+ comment: reviewState?.comment
162
+ })
163
+ : handleSendCustomerReview()
164
+ }
165
+
156
166
  return (
157
167
  <KeyboardAvoidingView
158
168
  enabled
@@ -303,7 +313,7 @@ const ReviewCustomerUI = (props: ReviewCustomerParams) => {
303
313
 
304
314
  <ActionButtonWrapper>
305
315
  <FloatingButton
306
- firstButtonClick={() => handleSendCustomerReview()}
316
+ firstButtonClick={() => handleReviewClick()}
307
317
  btnText={actionState.loading ? t('LOADING', 'Loading') : t('SEND_REVIEW', 'Send Review')}
308
318
  color={theme.colors.primary}
309
319
  widthButton={'100%'}
@@ -29,8 +29,19 @@ const OLink = (props: Props): React.ReactElement => {
29
29
  ],
30
30
  );
31
31
 
32
+ const handleInvalidNumberAlert = () =>
33
+ Alert.alert(
34
+ t('ERROR_OPENING_THE_LINK', 'Error opening the link'),
35
+ t('INVALID_NUMBER', 'Invalid number'),
36
+ [
37
+ {
38
+ text: t('OK', 'Ok'),
39
+ },
40
+ ],
41
+ );
42
+
32
43
  const handleOpenUrl = async (breakFunction = false) => {
33
- if(breakFunction) {
44
+ if (breakFunction) {
34
45
  return
35
46
  }
36
47
  if (!url) {
@@ -40,8 +51,9 @@ const OLink = (props: Props): React.ReactElement => {
40
51
 
41
52
  try {
42
53
  const supported = await Linking.canOpenURL(url);
43
-
44
- if (supported) {
54
+ if (url && url?.includes('tel:')) {
55
+ url?.includes('invalid') ? handleInvalidNumberAlert() : await Linking.openURL(url)
56
+ } else if (supported) {
45
57
  await Linking.openURL(url);
46
58
  } else {
47
59
  handleAlert();
@@ -57,17 +69,17 @@ const OLink = (props: Props): React.ReactElement => {
57
69
  <OButton
58
70
  onClick={() => handleOpenUrl()}
59
71
  text={shorcut} imgRightSrc=''
60
- textStyle={{color: 'white'}}
61
- style={{width: '100%', alignSelf: 'center', borderRadius: 10}}
72
+ textStyle={{ color: 'white' }}
73
+ style={{ width: '100%', alignSelf: 'center', borderRadius: 10 }}
62
74
  />
63
75
  ) : (
64
- <OText
65
- style={TextStyle}
66
- numberOfLines={1}
67
- ellipsizeMode="tail"
68
- color={color}>
69
- {shorcut}
70
- </OText>
76
+ <OText
77
+ style={TextStyle}
78
+ numberOfLines={1}
79
+ ellipsizeMode="tail"
80
+ color={color}>
81
+ {shorcut}
82
+ </OText>
71
83
  )}
72
84
  </Pressable>
73
85
  );
@@ -40,12 +40,13 @@ interface Props {
40
40
  numberOfLines?: number;
41
41
  ellipsizeMode?: string;
42
42
  adjustsFontSizeToFit?: boolean;
43
- textDecorationLine?: string
43
+ textDecorationLine?: string;
44
+ lineHeight?: number;
44
45
  }
45
46
 
46
47
  const OText = (props: Props): React.ReactElement => {
47
48
  return (
48
- <SText {...props} style={props.style}>
49
+ <SText {...props} style={[props.style, { lineHeight: props.lineHeight }]}>
49
50
  {props.children}
50
51
  {props.space && ' '}
51
52
  </SText>
@@ -311,6 +311,10 @@ export interface OrdersOptionParams {
311
311
  isLogisticActivated?: boolean;
312
312
  isAlsea?: boolean;
313
313
  checkNotification?: boolean;
314
+ ordersGroupedFormatted?: any;
315
+ handleChangeOrderStatus?: () => void;
316
+ handleSendCustomerReview?: () => void;
317
+ orderDetailsProps?: any;
314
318
  }
315
319
  export interface ActiveOrdersParams {
316
320
  orders?: any;
@@ -569,7 +573,7 @@ export interface AcceptOrRejectOrderParams {
569
573
  loading?: boolean;
570
574
  action: string;
571
575
  orderId?: number;
572
- handleUpdateOrder?: (status: number, isAccept: any) => {};
576
+ handleUpdateOrder?: () => void;
573
577
  notShowCustomerPhone?: boolean | undefined;
574
578
  actions?: actions;
575
579
  titleAccept?: textTranslate;
@@ -598,6 +602,7 @@ export interface ReviewCustomerParams {
598
602
  actionState?: any,
599
603
  handleChangeQualification?: any,
600
604
  handleSendCustomerReview?: any,
605
+ handleCustomCustomerReview?: any,
601
606
  }
602
607
 
603
608
  export interface NoNetworkParams {
@@ -68,6 +68,7 @@ import { SingleProductCard } from './src/components/SingleProductCard';
68
68
  import { SingleOrderCard } from './src/components/SingleOrderCard';
69
69
  import { UpsellingRedirect } from './src/components/BusinessProductsListing/UpsellingRedirect';
70
70
  import { ProductItemAccordion } from './src/components/ProductItemAccordion';
71
+ import { ScheduleAccordion } from './src/components/ScheduleAccordion';
71
72
  import { BusinessItemAccordion } from './src/components/BusinessItemAccordion';
72
73
  import { CouponControl } from './src/components/CouponControl';
73
74
  import { TaxInformation } from './src/components/TaxInformation';
@@ -231,6 +232,7 @@ export {
231
232
  SingleOrderCard,
232
233
  UpsellingRedirect,
233
234
  ProductItemAccordion,
235
+ ScheduleAccordion,
234
236
  BusinessItemAccordion,
235
237
  CouponControl,
236
238
  TaxInformation,
@@ -25,7 +25,8 @@ import {
25
25
  BusinessLogo,
26
26
  Reviews,
27
27
  RibbonBox,
28
- ReviewAndFavorite
28
+ ReviewAndFavorite,
29
+ OfferBox
29
30
  } from './styles';
30
31
  import { useTheme } from 'styled-components/native';
31
32
  import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome5';
@@ -50,7 +51,8 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
50
51
  businessPickupTime,
51
52
  businessDistance,
52
53
  handleFavoriteBusiness,
53
- enableIntersection
54
+ enableIntersection,
55
+ getBusinessOffer
54
56
  } = props;
55
57
 
56
58
  const [{ parsePrice, parseDistance, parseNumber, optimizeImage }] = useUtils();
@@ -201,6 +203,18 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
201
203
  <FontAwesomeIcon name="crown" size={26} color="gold" />
202
204
  </View>
203
205
  )}
206
+ {(!isCustomLayout) && (
207
+ getBusinessOffer((business?.offers)) &&
208
+ <OfferBox>
209
+ <OText
210
+ size={10}
211
+ weight={'400'}
212
+ numberOfLines={2}
213
+ ellipsizeMode='tail'
214
+ lineHeight={13}
215
+ >{getBusinessOffer((business?.offers)) || parsePrice(0)}</OText>
216
+ </OfferBox>
217
+ )}
204
218
  <BusinessState>
205
219
  {!isBusinessOpen && (configState?.configs?.preorder_status_enabled?.value === '1') && (
206
220
  <View style={styles.businessStateView}>
@@ -39,7 +39,7 @@ export const BusinessState = styled.View`
39
39
  `
40
40
 
41
41
  export const BusinessLogo = styled.View`
42
-
42
+
43
43
  `
44
44
 
45
45
  export const ReviewAndFavorite = styled.View`
@@ -73,3 +73,15 @@ export const RibbonBox = styled.View`
73
73
  border-radius: 50px;
74
74
  `}
75
75
  `
76
+
77
+ export const OfferBox = styled.View`
78
+ position: absolute;
79
+ z-index: 1;
80
+ top: 20px;
81
+ right: 10px;
82
+ border-radius: 50px;
83
+ color: ${(props: any) => props.theme.colors.textThird};
84
+ background: ${(props: any) => props.theme.colors.inputBorderColor};
85
+ padding: 3px 8px;
86
+ max-width: 180px;
87
+ `
@@ -16,26 +16,19 @@ import {
16
16
  DivideView,
17
17
  MediaWrapper,
18
18
  } from './styles';
19
- import { Platform, StyleSheet, View } from 'react-native';
19
+ import { StyleSheet, View } from 'react-native';
20
20
  import { BusinessInformationParams } from '../../types';
21
21
  import { GoogleMap } from '../GoogleMap';
22
22
  import { WebView } from 'react-native-webview';
23
23
  import { formatUrlVideo } from '../../utils'
24
+ import { ScheduleAccordion } from '../ScheduleAccordion';
24
25
  const BusinessInformationUI = (props: BusinessInformationParams) => {
25
26
  const { businessState, businessSchedule, businessLocation } = props;
26
27
 
27
28
  const theme = useTheme();
28
29
  const [, t] = useLanguage();
29
30
  const [{ optimizeImage }] = useUtils();
30
- const daysOfWeek = [
31
- t('SUNDAY_ABBREVIATION', 'Sun'),
32
- t('MONDAY_ABBREVIATION', 'Mon'),
33
- t('TUESDAY_ABBREVIATION', 'Tues'),
34
- t('WEDNESDAY_ABBREVIATION', 'Wed'),
35
- t('THURSDAY_ABBREVIATION', 'Thur'),
36
- t('FRIDAY_ABBREVIATION', 'Fri'),
37
- t('SATURDAY_ABBREVIATION', 'Sat'),
38
- ];
31
+
39
32
  const scheduleFormatted = ({
40
33
  hour,
41
34
  minute,
@@ -112,25 +105,11 @@ const BusinessInformationUI = (props: BusinessInformationParams) => {
112
105
  <WrapScheduleBlock>
113
106
  {businessSchedule.map((schedule: any, i: number) => (
114
107
  <ScheduleBlock key={i}>
115
- <OText
116
- lineHeight={21}
117
- mBottom={16}
118
- size={14}
119
- weight={Platform.OS === 'android' ? 'bold' : '600'}
120
- style={{ flexBasis: '20%' }}>
121
- {daysOfWeek[i].toUpperCase()}
122
- </OText>
123
- {schedule.enabled ? (
124
- <OText mBottom={16}>
125
- {scheduleFormatted(schedule.lapses[0].open) +
126
- ' - ' +
127
- scheduleFormatted(schedule.lapses[0].close)}
128
- </OText>
129
- ) : (
130
- <OText color={theme.colors.red} mBottom={16}>
131
- {t('CLOSED', 'Closed')}
132
- </OText>
133
- )}
108
+ <ScheduleAccordion
109
+ weekIndex={i}
110
+ scheduleFormatted={scheduleFormatted}
111
+ schedule={schedule}
112
+ />
134
113
  </ScheduleBlock>
135
114
  ))}
136
115
  </WrapScheduleBlock>
@@ -152,10 +131,10 @@ const BusinessInformationUI = (props: BusinessInformationParams) => {
152
131
  style={{ width: 210, height: 127, borderRadius: 7.6 }}
153
132
  javaScriptEnabled={true}
154
133
  domStorageEnabled={true}
155
- source={{
134
+ source={{
156
135
  html: `
157
136
  <iframe width='80%' height='80%' src="${formatUrlVideo(v.video)}" frameBorder='0' allow='autoplay; encrypted-media' allowFullScreen />
158
- `,
137
+ `,
159
138
  }}
160
139
  mediaPlaybackRequiresUserAction={true}
161
140
  />
@@ -530,6 +530,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
530
530
  btnLeftValue={currentCart?.products.reduce((prev: number, product: any) => prev + product.quantity, 0)}
531
531
  btnRightValue={parsePrice(currentCart?.total)}
532
532
  disabled={subtotalWithTaxes < currentCart?.minimum || openUpselling}
533
+ hideButton={isCheckoutMultiBusinessEnabled}
533
534
  handleClick={() => setOpenUpselling(true)}
534
535
  />
535
536
  </View>
@@ -104,9 +104,38 @@ const CartUI = (props: any) => {
104
104
  const handleUpsellingPage = () => {
105
105
  setOpenUpselling(false)
106
106
  setCanOpenUpselling(false)
107
- if (isCheckoutMultiBusinessEnabled && openCarts.length > 1) {
107
+ const cartSelectedHasGroup = cart?.group?.uuid
108
+ const cartFilterValidation = (cart : any) => cart?.valid && cart?.status !== 2
109
+ const cartsGroupLength = cartSelectedHasGroup ? Object.values(orderState.carts).filter((_cart : any) => _cart?.group?.uuid === cartSelectedHasGroup && cartFilterValidation(_cart))?.length : 0
110
+ if (cartsGroupLength > 1 && isCheckoutMultiBusinessEnabled) {
108
111
  props.onNavigationRedirect('CheckoutNavigator', {
109
- screen: 'MultiCheckout'
112
+ screen: 'MultiCheckout',
113
+ cartUuid: cart?.group?.uuid
114
+ })
115
+ return
116
+ }
117
+ const cartGroupsCount : any = {}
118
+ Object.values(orderState.carts).filter(_cart => cartFilterValidation(_cart))?.forEach((_cart : any) => {
119
+ if (cartGroupsCount[_cart?.group?.uuid]) {
120
+ cartGroupsCount[_cart?.group?.uuid] += 1
121
+ } else {
122
+ cartGroupsCount[_cart?.group?.uuid] = 1
123
+ }
124
+ })
125
+ let groupForTheCart
126
+ const groupForAddCartArray = Object.keys(cartGroupsCount).filter(cartGroupUuid => cartGroupsCount[cartGroupUuid] > 0 && cartGroupsCount[cartGroupUuid] < 5)
127
+ const max = Math.max(...groupForAddCartArray.map(uuid => cartGroupsCount[uuid]))
128
+ const indexes = groupForAddCartArray.filter(uuid => cartGroupsCount[uuid] === max)
129
+ if (indexes?.length > 1) {
130
+ groupForTheCart = indexes.find(uuid => uuid !== 'undefined')
131
+ } else {
132
+ groupForTheCart = indexes[0]
133
+ }
134
+ if (isCheckoutMultiBusinessEnabled && openCarts.length > 1 && groupForTheCart) {
135
+ props.onNavigationRedirect('CheckoutNavigator', {
136
+ screen: 'MultiCart',
137
+ cartUuid: cart.uuid,
138
+ cartGroup: groupForTheCart === 'undefined' ? 'create' : groupForTheCart
110
139
  })
111
140
  } else {
112
141
  props.onNavigationRedirect('CheckoutNavigator', {
@@ -22,7 +22,8 @@ const FloatingButtonUI = (props: FloatingButtonParams) => {
22
22
  disabled,
23
23
  isSecondaryBtn,
24
24
  handleEmpty,
25
- iosBottom
25
+ iosBottom,
26
+ hideButton
26
27
  } = props;
27
28
 
28
29
  const [, t] = useLanguage();
@@ -77,16 +78,17 @@ const FloatingButtonUI = (props: FloatingButtonParams) => {
77
78
  </View>
78
79
  )}
79
80
  </View>
80
- <Button
81
- style={[isSecondaryBtn ? styles.secondaryBtn : styles.primaryBtn]}
82
- onPress={handleButtonClick}
83
- disabled={disabled}
84
- >
85
- <OText color={isSecondaryBtn ? theme.colors.textSecondary : theme.colors.white} lineHeight={24} size={14} weight={'400'}>
86
- {btnText}
87
- </OText>
88
- </Button>
89
-
81
+ {!hideButton && (
82
+ <Button
83
+ style={[isSecondaryBtn ? styles.secondaryBtn : styles.primaryBtn]}
84
+ onPress={handleButtonClick}
85
+ disabled={disabled}
86
+ >
87
+ <OText color={isSecondaryBtn ? theme.colors.textSecondary : theme.colors.white} lineHeight={24} size={14} weight={'400'}>
88
+ {btnText}
89
+ </OText>
90
+ </Button>
91
+ )}
90
92
  </Container>
91
93
  );
92
94
  };
@@ -59,11 +59,6 @@ export const Otp = (props: otpParams) => {
59
59
  justifyContent: 'space-between',
60
60
  marginVertical: 30
61
61
  },
62
- focusStyles: {
63
- borderColor: theme.colors.primary,
64
- borderWidth: 1,
65
- borderRadius: 8
66
- },
67
62
  underlineStyleBase: {
68
63
  width: 45,
69
64
  height: 50,
@@ -91,7 +86,6 @@ export const Otp = (props: otpParams) => {
91
86
  numberOfInputs={pinCount || 6}
92
87
  style={loginStyle.container}
93
88
  inputStyles={loginStyle.underlineStyleBase}
94
- focusStyles={loginStyle.focusStyles}
95
89
  handleChange={setCode}
96
90
  />
97
91
  <TouchableOpacity onPress={() => handleOnSubmit()} disabled={otpLeftTime > 520}>
@@ -3,5 +3,4 @@ import styled from 'styled-components/native';
3
3
  export const OTPContainer = styled.View`
4
4
  padding: 20px;
5
5
  align-items: center;
6
- flex: 1
7
6
  `
@@ -1,4 +1,5 @@
1
1
  import React, { useEffect, useState } from 'react'
2
+ import Clipboard from '@react-native-clipboard/clipboard';
2
3
  import { Messages as MessagesController, useSession, useUtils, useLanguage, ToastType, useToast } from 'ordering-components/native'
3
4
  import { useTheme } from 'styled-components/native';
4
5
  import { launchImageLibrary } from 'react-native-image-picker'
@@ -397,6 +398,19 @@ const MessagesUI = (props: MessagesParams) => {
397
398
  }
398
399
  }
399
400
 
401
+ const onLongPress = (context: any, message: any) => {
402
+ const options = [
403
+ t('COPY_TEXT', 'Copy text'),
404
+ t('CANCEL', 'Cancel'),
405
+ ];
406
+ const cancelButtonIndex = options.length - 1;
407
+ context.actionSheet().showActionSheetWithOptions({
408
+ options,
409
+ cancelButtonIndex
410
+ }, (buttonIndex: any) => buttonIndex === 0 && Clipboard.setString(message.text)
411
+ );
412
+ }
413
+
400
414
  return (
401
415
  <View style={{ height: getViewHeight(), width: '100%', paddingTop: 12, backgroundColor: 'white' }}>
402
416
  <Wrapper>
@@ -473,6 +487,7 @@ const MessagesUI = (props: MessagesParams) => {
473
487
  onSend={onSubmit}
474
488
  onInputTextChanged={onChangeMessage}
475
489
  alignTop
490
+ onLongPress={(context: any, message: any) => onLongPress(context, message)}
476
491
  scrollToBottom
477
492
  renderAvatarOnTop
478
493
  renderUsernameOnMessage
@@ -0,0 +1,63 @@
1
+ import React from 'react'
2
+ import { ChAddress, ChContainer, ChSection, ChUserDetails, DeliveryOptionsContainer } from '../Checkout/styles'
3
+ import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder'
4
+ import { Container } from '../../layouts/Container';
5
+ import { View, StyleSheet } from 'react-native'
6
+ import { useTheme } from 'styled-components/native';
7
+ import { MultiCartCreate } from 'ordering-components/native'
8
+
9
+ export const MultiCartUI = () => {
10
+ const theme = useTheme();
11
+
12
+ const styles = StyleSheet.create({
13
+ pagePadding: {
14
+ paddingHorizontal: 40
15
+ }
16
+ })
17
+
18
+ return (
19
+ <>
20
+ <Container noPadding>
21
+ <ChContainer style={styles.pagePadding}>
22
+ <ChSection>
23
+ <ChUserDetails>
24
+ <Placeholder Animation={Fade}>
25
+ <PlaceholderLine height={20} />
26
+ <PlaceholderLine height={12} />
27
+ <PlaceholderLine height={12} />
28
+ <PlaceholderLine height={12} style={{ marginBottom: 20 }} />
29
+ </Placeholder>
30
+ </ChUserDetails>
31
+ <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginHorizontal: -40 }} />
32
+ </ChSection>
33
+ <DeliveryOptionsContainer>
34
+ <View style={{ height: 110 }}>
35
+ <Placeholder Animation={Fade}>
36
+ <PlaceholderLine height={20} />
37
+ <PlaceholderLine height={40} />
38
+ </Placeholder>
39
+ </View>
40
+ </DeliveryOptionsContainer>
41
+ <ChSection>
42
+ <ChAddress>
43
+ <Placeholder Animation={Fade}>
44
+ <PlaceholderLine height={20} style={{ marginBottom: 50 }} />
45
+ <PlaceholderLine height={100} />
46
+ </Placeholder>
47
+ </ChAddress>
48
+ <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginTop: 13, marginHorizontal: -40 }} />
49
+ </ChSection>
50
+ </ChContainer>
51
+ </Container>
52
+
53
+ </>
54
+ )
55
+ }
56
+
57
+ export const MultiCart = (props : any) => {
58
+ const mulcartProps = {
59
+ ...props,
60
+ UIComponent: MultiCartUI
61
+ }
62
+ return <MultiCartCreate {...mulcartProps} />
63
+ }
@@ -25,7 +25,6 @@ const MultiCartsPaymethodsAndWalletsUI = (props: any) => {
25
25
  businessIds,
26
26
  paymethodsAndWallets,
27
27
  walletsState,
28
- businessPaymethods,
29
28
  paymethodSelected,
30
29
  handleSelectPaymethod,
31
30
  handleSelectWallet,
@@ -77,24 +76,24 @@ const MultiCartsPaymethodsAndWalletsUI = (props: any) => {
77
76
  const renderPaymethods = ({ item }: any) => {
78
77
  return (
79
78
  <TouchableOpacity
80
- onPress={() => handleSelectPaymethod(item)}
79
+ onPress={() => handleSelectPaymethod({ ...item, paymethod: { gateway: item.gateway }, paymethod_id: item?.id })}
81
80
  >
82
81
  <PMItem
83
82
  key={item.id}
84
- isActive={paymethodSelected?.paymethod_id === item.paymethod_id}
83
+ isActive={paymethodSelected?.id === item.id}
85
84
  >
86
85
  <OIcon
87
86
  src={getPayIcon(item.paymethod?.gateway)}
88
87
  width={20}
89
88
  height={20}
90
- color={paymethodSelected?.paymethod_id === item.paymethod_id ? theme.colors.white : theme.colors.backgroundDark}
89
+ color={paymethodSelected?.id === item.id ? theme.colors.white : theme.colors.backgroundDark}
91
90
  />
92
91
  <OText
93
92
  size={10}
94
93
  style={{ margin: 0, marginTop: 4 }}
95
- color={paymethodSelected?.paymethod_id === item.paymethod_id ? theme.colors.white : '#000'}
94
+ color={paymethodSelected?.id === item.id ? theme.colors.white : '#000'}
96
95
  >
97
- {t(item?.paymethod?.gateway.toUpperCase(), item?.paymethod?.name)}
96
+ {t(item?.gateway.toUpperCase(), item?.name)}
98
97
  </OText>
99
98
  </PMItem>
100
99
  </TouchableOpacity>
@@ -124,7 +123,7 @@ const MultiCartsPaymethodsAndWalletsUI = (props: any) => {
124
123
  <FlatList
125
124
  horizontal
126
125
  showsHorizontalScrollIndicator={false}
127
- data={businessPaymethods?.result?.filter((paymethod: any) => paymethodsAndWallets.paymethods.find((item: any) => item.id === paymethod.paymethod_id))}
126
+ data={paymethodsAndWallets.paymethods}
128
127
  renderItem={renderPaymethods}
129
128
  keyExtractor={(paymethod: any) => paymethod?.id?.toString?.()}
130
129
  />
@@ -53,7 +53,8 @@ const MultiCheckoutUI = (props: any) => {
53
53
  paymethodSelected,
54
54
  handleSelectPaymethod,
55
55
  handleSelectWallet,
56
- handlePaymethodDataChange
56
+ handlePaymethodDataChange,
57
+ cartUuid
57
58
  } = props
58
59
 
59
60
  const theme = useTheme();
@@ -78,7 +79,7 @@ const MultiCheckoutUI = (props: any) => {
78
79
  const configTypes = configs?.order_types_allowed?.value.split('|').map((value: any) => Number(value)) || []
79
80
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
80
81
  const maximumCarts = 5
81
- const isDisablePlaceOrderButton = !(paymethodSelected?.paymethod_id || paymethodSelected?.wallet_id) || openCarts.length > maximumCarts
82
+ const isDisablePlaceOrderButton = !(paymethodSelected?.paymethod_id || paymethodSelected?.wallet_id) || openCarts.length > maximumCarts || (paymethodSelected?.paymethod?.gateway === 'stripe' && !paymethodSelected?.paymethod_data)
82
83
  const walletCarts = (Object.values(carts)?.filter((cart: any) => cart?.products && cart?.products?.length && cart?.status !== 2 && cart?.valid_schedule && cart?.valid_products && cart?.valid_address && cart?.valid_maximum && cart?.valid_minimum && cart?.wallets) || null) || []
83
84
 
84
85
  const [isUserDetailsEdit, setIsUserDetailsEdit] = useState(false);
@@ -225,6 +226,7 @@ const MultiCheckoutUI = (props: any) => {
225
226
  handleSelectPaymethod={handleSelectPaymethod}
226
227
  handleSelectWallet={handleSelectWallet}
227
228
  handlePaymethodDataChange={handlePaymethodDataChange}
229
+ cartUuid={cartUuid}
228
230
  />
229
231
  <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginTop: 13, marginHorizontal: -40 }} />
230
232
  </ChSection>
@@ -19,6 +19,7 @@ import {
19
19
  OrdersSummary,
20
20
  BorderLine
21
21
  } from './styles'
22
+ import { NotFoundSource } from '../NotFoundSource'
22
23
 
23
24
  export const MultiOrdersDetailsUI = (props: any) => {
24
25
  const {
@@ -248,6 +249,19 @@ export const MultiOrdersDetailsUI = (props: any) => {
248
249
  ))}
249
250
  </>
250
251
  )}
252
+ {!loading && (error || orders?.length === 0) && (
253
+ error?.includes('ERROR_ACCESS_EXPIRED') ? (
254
+ <NotFoundSource
255
+ content={t(error[0], 'Sorry, the order has expired.')}
256
+ />
257
+ ) : (
258
+ <NotFoundSource
259
+ content={t('NOT_FOUND_ORDER', theme?.defaultLanguages?.NOT_FOUND_ORDER || 'Sorry, we couldn\'t find the requested order.')}
260
+ btnTitle={t('ORDERS_REDIRECT', theme?.defaultLanguages?.ORDERS_REDIRECT || 'Go to Orders')}
261
+ onClickButton={navigation.navigate('BusinessList')}
262
+ />
263
+ )
264
+ )}
251
265
  <Divider />
252
266
  </OrdersDetailsContainer>
253
267
  )
@@ -60,12 +60,42 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
60
60
  const [, { showToast }] = useToast()
61
61
  const { loading, error, orders: values } = orderList
62
62
  const [businessLoading, setBusinessLoading] = useState(true)
63
+ const [orders, setOrders] = useState([])
63
64
 
64
65
  const imageFails = activeOrders
65
66
  ? theme.images.general.emptyActiveOrders
66
67
  : theme.images.general.emptyPastOrders
67
68
 
68
- const orders = customArray || values || []
69
+ const _orders = customArray || values || []
70
+ const uniqueOrders: any = []
71
+
72
+
73
+ useEffect(() => {
74
+ if (loading || error) return
75
+ const orders = _orders.map((order: any) => order?.cart_group_id
76
+ ? _orders
77
+ .filter((_order : any) => _order?.cart_group_id === order?.cart_group_id)
78
+ ?.reduce((orderCompleted : any, currentOrder : any) => ({
79
+ ...orderCompleted,
80
+ total: orderCompleted.summary?.total + currentOrder?.summary?.total,
81
+ business: [orderCompleted.business, currentOrder.business].flat(),
82
+ business_id: [orderCompleted.business_id, currentOrder.business_id].flat(),
83
+ id: [orderCompleted.id, currentOrder.id].flat(),
84
+ review: orderCompleted.review && currentOrder.review,
85
+ user_review: orderCompleted.user_review && currentOrder.user_review,
86
+ products: [orderCompleted.products, currentOrder.products].flat()
87
+ }))
88
+ : order)
89
+ .filter((order: any) => {
90
+ const isDuplicate = uniqueOrders.includes(order?.cart_group_id)
91
+ if (!isDuplicate) {
92
+ uniqueOrders.push(order?.cart_group_id)
93
+ return true
94
+ }
95
+ return false
96
+ })
97
+ setOrders(orders)
98
+ }, [JSON.stringify(_orders)])
69
99
 
70
100
  const getOrderStatus = (s: string) => {
71
101
  const status = parseInt(s)
@@ -219,7 +249,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
219
249
  )}
220
250
  </>
221
251
  )}
222
- {isBusiness && !!businessesSearchList && businesses?.loading && (
252
+ {isBusiness && !!businessesSearchList && businesses?.loading && (
223
253
  <ScrollView horizontal>
224
254
  <BusinessControllerSkeletons paginationProps={businessPaginationProps} />
225
255
  </ScrollView>