ordering-ui-react-native 0.15.56 → 0.15.58-release

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 (186) hide show
  1. package/package.json +5 -3
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/AddressForm/index.tsx +18 -2
  4. package/src/components/BusinessController/index.tsx +16 -8
  5. package/src/components/BusinessTypeFilter/index.tsx +3 -1
  6. package/src/components/BusinessesListing/index.tsx +1 -1
  7. package/src/components/Checkout/index.tsx +23 -2
  8. package/src/components/DriverTips/index.tsx +11 -6
  9. package/src/components/LanguageSelector/index.tsx +7 -2
  10. package/src/components/LoginForm/index.tsx +120 -30
  11. package/src/components/LoginForm/styles.tsx +6 -0
  12. package/src/components/OrderDetails/index.tsx +7 -21
  13. package/src/components/PaymentOptions/index.tsx +67 -50
  14. package/src/components/PaymentOptionsWebView/index.tsx +123 -124
  15. package/src/components/SignupForm/index.tsx +145 -61
  16. package/src/components/SingleProductCard/index.tsx +16 -4
  17. package/src/components/StripeMethodForm/index.tsx +1 -2
  18. package/src/components/UpsellingProducts/index.tsx +1 -1
  19. package/src/components/UserProfileForm/index.tsx +63 -6
  20. package/src/components/UserProfileForm/styles.tsx +8 -0
  21. package/src/components/VerifyPhone/styles.tsx +1 -2
  22. package/src/components/shared/OModal.tsx +1 -1
  23. package/src/hooks/useCountdownTimer.tsx +26 -0
  24. package/src/navigators/CheckoutNavigator.tsx +6 -0
  25. package/src/navigators/HomeNavigator.tsx +12 -0
  26. package/src/pages/BusinessesListing.tsx +1 -1
  27. package/src/pages/MultiCheckout.tsx +31 -0
  28. package/src/pages/MultiOrdersDetails.tsx +27 -0
  29. package/src/pages/Sessions.tsx +22 -0
  30. package/src/theme.json +0 -1
  31. package/src/types/index.tsx +18 -11
  32. package/src/utils/index.tsx +68 -1
  33. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +103 -15
  34. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -0
  35. package/themes/business/src/components/Chat/index.tsx +42 -90
  36. package/themes/business/src/components/DriverMap/index.tsx +6 -5
  37. package/themes/business/src/components/LoginForm/index.tsx +89 -2
  38. package/themes/business/src/components/LoginForm/styles.tsx +6 -0
  39. package/themes/business/src/components/LogoutButton/index.tsx +1 -1
  40. package/themes/business/src/components/NewOrderNotification/index.tsx +79 -105
  41. package/themes/business/src/components/OrderDetails/Business.tsx +2 -2
  42. package/themes/business/src/components/OrderDetails/Delivery.tsx +28 -11
  43. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +41 -7
  44. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +6 -0
  45. package/themes/business/src/components/OrdersListManager/index.tsx +1 -1
  46. package/themes/business/src/components/OrdersOption/index.tsx +5 -2
  47. package/themes/business/src/components/PreviousOrders/index.tsx +2 -2
  48. package/themes/business/src/components/ProductItemAccordion/index.tsx +2 -2
  49. package/themes/business/src/components/UserFormDetails/index.tsx +5 -2
  50. package/themes/business/src/components/UserProfileForm/index.tsx +2 -0
  51. package/themes/business/src/components/shared/OModal.tsx +1 -1
  52. package/themes/business/src/types/index.tsx +6 -1
  53. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  54. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  55. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  56. package/themes/kiosk/src/components/BusinessMenu/index.tsx +39 -28
  57. package/themes/kiosk/src/components/BusinessesListing/index.tsx +2 -3
  58. package/themes/kiosk/src/components/Cart/index.tsx +11 -12
  59. package/themes/kiosk/src/components/CartBottomSheet/index.tsx +9 -2
  60. package/themes/kiosk/src/components/CartContent/index.tsx +0 -11
  61. package/themes/kiosk/src/components/CartItem/index.tsx +4 -3
  62. package/themes/kiosk/src/components/CategoriesMenu/index.tsx +107 -62
  63. package/themes/kiosk/src/components/Checkout/index.tsx +40 -22
  64. package/themes/kiosk/src/components/CustomerName/index.tsx +0 -6
  65. package/themes/kiosk/src/components/DrawerView/index.tsx +1 -0
  66. package/themes/kiosk/src/components/DrawerView/styles.tsx +2 -2
  67. package/themes/kiosk/src/components/NavBar/index.tsx +29 -20
  68. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  69. package/themes/kiosk/src/components/OrderDetails/index.tsx +32 -27
  70. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +9 -11
  71. package/themes/kiosk/src/components/PaymentOptions/index.tsx +56 -54
  72. package/themes/kiosk/src/components/ProductForm/index.tsx +7 -8
  73. package/themes/kiosk/src/components/ProductItemAccordion/index.tsx +2 -2
  74. package/themes/kiosk/src/components/ProductOption/index.tsx +1 -1
  75. package/themes/kiosk/src/components/ProductOptionSubOption/index.tsx +3 -1
  76. package/themes/kiosk/src/components/UpsellingProducts/index.tsx +16 -5
  77. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  78. package/themes/kiosk/src/types/index.d.ts +1 -0
  79. package/themes/original/index.tsx +169 -4
  80. package/themes/original/src/components/ActiveOrders/index.tsx +15 -132
  81. package/themes/original/src/components/ActiveOrders/styles.tsx +0 -54
  82. package/themes/original/src/components/AddressForm/index.tsx +7 -6
  83. package/themes/original/src/components/AddressList/index.tsx +30 -18
  84. package/themes/original/src/components/AppleLogin/index.tsx +9 -13
  85. package/themes/original/src/components/BusinessBasicInformation/index.tsx +136 -45
  86. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +4 -0
  87. package/themes/original/src/components/BusinessController/index.tsx +48 -11
  88. package/themes/original/src/components/BusinessController/styles.tsx +27 -0
  89. package/themes/original/src/components/BusinessFeaturedController/index.tsx +20 -1
  90. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +23 -0
  91. package/themes/original/src/components/BusinessItemAccordion/index.tsx +8 -5
  92. package/themes/original/src/components/BusinessItemAccordion/styles.tsx +3 -1
  93. package/themes/original/src/components/BusinessListingSearch/index.tsx +196 -58
  94. package/themes/original/src/components/BusinessListingSearch/styles.tsx +22 -2
  95. package/themes/original/src/components/BusinessPreorder/index.tsx +1 -1
  96. package/themes/original/src/components/BusinessProductsCategories/index.tsx +2 -2
  97. package/themes/original/src/components/BusinessProductsList/CategoryDescription/index.tsx +44 -0
  98. package/themes/original/src/components/BusinessProductsList/index.tsx +119 -35
  99. package/themes/original/src/components/BusinessProductsList/styles.tsx +12 -4
  100. package/themes/original/src/components/BusinessProductsListing/index.tsx +109 -21
  101. package/themes/original/src/components/BusinessProductsListing/styles.tsx +22 -0
  102. package/themes/original/src/components/BusinessReviews/index.tsx +6 -1
  103. package/themes/original/src/components/BusinessTypeFilter/index.tsx +1 -2
  104. package/themes/original/src/components/BusinessesListing/index.tsx +127 -66
  105. package/themes/original/src/components/BusinessesListing/styles.tsx +11 -3
  106. package/themes/original/src/components/Cart/index.tsx +60 -41
  107. package/themes/original/src/components/Checkout/index.tsx +48 -32
  108. package/themes/original/src/components/DriverTips/index.tsx +17 -12
  109. package/themes/original/src/components/Favorite/index.tsx +92 -0
  110. package/themes/original/src/components/Favorite/styles.tsx +22 -0
  111. package/themes/original/src/components/FavoriteList/index.tsx +298 -0
  112. package/themes/original/src/components/FavoriteList/styles.tsx +5 -0
  113. package/themes/original/src/components/ForgotPasswordForm/index.tsx +84 -4
  114. package/themes/original/src/components/GPSButton/index.tsx +15 -8
  115. package/themes/original/src/components/GoogleMap/index.tsx +11 -11
  116. package/themes/original/src/components/Help/index.tsx +21 -4
  117. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +18 -1
  118. package/themes/original/src/components/Home/index.tsx +1 -1
  119. package/themes/original/src/components/LastOrders/index.tsx +12 -1
  120. package/themes/original/src/components/LoginForm/Otp/index.tsx +91 -0
  121. package/themes/original/src/components/LoginForm/Otp/styles.tsx +7 -0
  122. package/themes/original/src/components/LoginForm/index.tsx +332 -164
  123. package/themes/original/src/components/LoginForm/styles.tsx +1 -3
  124. package/themes/original/src/components/MessageListing/index.tsx +10 -1
  125. package/themes/original/src/components/Messages/index.tsx +1 -1
  126. package/themes/original/src/components/MomentOption/index.tsx +10 -1
  127. package/themes/original/src/components/MomentOption/styles.tsx +1 -1
  128. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +243 -0
  129. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/styles.tsx +46 -0
  130. package/themes/original/src/components/MultiCheckout/index.tsx +298 -0
  131. package/themes/original/src/components/MultiCheckout/styles.tsx +59 -0
  132. package/themes/original/src/components/MultiOrdersDetails/SingleOrderCard.tsx +372 -0
  133. package/themes/original/src/components/MultiOrdersDetails/index.tsx +258 -0
  134. package/themes/original/src/components/MultiOrdersDetails/styles.tsx +50 -0
  135. package/themes/original/src/components/MyOrders/index.tsx +120 -32
  136. package/themes/original/src/components/MyOrders/styles.tsx +8 -1
  137. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +167 -0
  138. package/themes/original/src/components/OrderDetails/index.tsx +135 -49
  139. package/themes/original/src/components/OrderDetails/styles.tsx +1 -2
  140. package/themes/original/src/components/OrderSummary/index.tsx +2 -2
  141. package/themes/original/src/components/OrderTypeSelector/index.tsx +4 -2
  142. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +153 -0
  143. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/styles.tsx +6 -0
  144. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/index.tsx +53 -0
  145. package/themes/original/src/components/OrdersOption/PreviousProductsOrdered/styles.tsx +6 -0
  146. package/themes/original/src/components/OrdersOption/index.tsx +130 -38
  147. package/themes/original/src/components/OrdersOption/styles.tsx +4 -1
  148. package/themes/original/src/components/PaymentOptionCash/index.tsx +2 -2
  149. package/themes/original/src/components/PaymentOptionWallet/index.tsx +17 -23
  150. package/themes/original/src/components/PaymentOptionWallet/styles.tsx +1 -1
  151. package/themes/original/src/components/PaymentOptions/index.tsx +57 -36
  152. package/themes/original/src/components/PhoneInputNumber/index.tsx +1 -1
  153. package/themes/original/src/components/PreviousOrders/index.tsx +18 -147
  154. package/themes/original/src/components/ProductForm/index.tsx +70 -62
  155. package/themes/original/src/components/ProductForm/styles.tsx +0 -1
  156. package/themes/original/src/components/ProductItemAccordion/index.tsx +2 -2
  157. package/themes/original/src/components/ProductOptionSubOption/index.tsx +18 -12
  158. package/themes/original/src/components/Promotions/index.tsx +151 -133
  159. package/themes/original/src/components/Promotions/styles.tsx +3 -23
  160. package/themes/original/src/components/SearchBar/index.tsx +10 -4
  161. package/themes/original/src/components/Sessions/index.tsx +160 -0
  162. package/themes/original/src/components/Sessions/styles.tsx +15 -0
  163. package/themes/original/src/components/SignupForm/index.tsx +269 -130
  164. package/themes/original/src/components/SingleOrderCard/index.tsx +282 -0
  165. package/themes/original/src/components/SingleOrderCard/styles.tsx +54 -0
  166. package/themes/original/src/components/SingleProductCard/index.tsx +59 -17
  167. package/themes/original/src/components/StripeElementsForm/index.tsx +16 -8
  168. package/themes/original/src/components/StripeElementsForm/naked.tsx +2 -2
  169. package/themes/original/src/components/UpsellingProducts/index.tsx +86 -74
  170. package/themes/original/src/components/UserDetails/index.tsx +5 -96
  171. package/themes/original/src/components/UserFormDetails/index.tsx +34 -24
  172. package/themes/original/src/components/UserProfile/index.tsx +53 -6
  173. package/themes/original/src/components/UserProfileForm/index.tsx +20 -18
  174. package/themes/original/src/components/UserVerification/index.tsx +178 -192
  175. package/themes/original/src/components/VerifyPhone/index.tsx +10 -7
  176. package/themes/original/src/components/VerifyPhone/styles.tsx +2 -1
  177. package/themes/original/src/components/Wallets/index.tsx +76 -9
  178. package/themes/original/src/components/Wallets/styles.tsx +21 -0
  179. package/themes/original/src/components/shared/OModal.tsx +4 -2
  180. package/themes/original/src/config/constants.tsx +6 -6
  181. package/themes/original/src/types/index.tsx +192 -33
  182. package/themes/original/src/utils/index.tsx +85 -2
  183. package/themes/single-business/src/components/AddressList/index.tsx +1 -1
  184. package/themes/single-business/src/components/OrderTypeSelector/index.tsx +1 -1
  185. package/themes/single-business/src/components/UserProfile/index.tsx +1 -1
  186. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
@@ -8,6 +8,8 @@ import {
8
8
  ScrollView,
9
9
  } from 'react-native';
10
10
  import { useForm, Controller } from 'react-hook-form';
11
+ import Recaptcha from 'react-native-recaptcha-that-works'
12
+ import { TouchableOpacity } from 'react-native-gesture-handler';
11
13
  import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
12
14
  import {
13
15
  ToastType,
@@ -25,6 +27,7 @@ import {
25
27
  TabsContainer,
26
28
  OrSeparator,
27
29
  LineSeparator,
30
+ RecaptchaButton
28
31
  } from './styles';
29
32
  import { _setStoreData } from '../../providers/StoreUtil'
30
33
  import { OText, OButton, OInput, OIconButton, OModal } from '../shared';
@@ -47,7 +50,10 @@ const LoginFormUI = (props: LoginParams) => {
47
50
  handleCheckPhoneCode,
48
51
  setCheckPhoneCodeState,
49
52
  allowedLevels,
50
- useRootPoint
53
+ useRootPoint,
54
+ notificationState,
55
+ handleReCaptcha,
56
+ enableReCaptcha
51
57
  } = props;
52
58
 
53
59
  const [ordering, { setOrdering }] = useApi();
@@ -61,6 +67,7 @@ const LoginFormUI = (props: LoginParams) => {
61
67
  const inputRef = useRef<any>(null);
62
68
  const inputMailRef = useRef<any>(null);
63
69
 
70
+ const [projectName, setProjectName] = useState({name: '', isFocued: false});
64
71
  const [passwordSee, setPasswordSee] = useState(false);
65
72
  const [isLoadingVerifyModal, setIsLoadingVerifyModal] = useState(false);
66
73
  const [isModalVisible, setIsModalVisible] = useState(false);
@@ -84,6 +91,50 @@ const LoginFormUI = (props: LoginParams) => {
84
91
  const [submitted, setSubmitted] = useState(false);
85
92
  const [formValues, setFormValues] = useState(null);
86
93
 
94
+ const [recaptchaConfig, setRecaptchaConfig] = useState<any>({})
95
+ const [recaptchaVerified, setRecaptchaVerified] = useState(false)
96
+
97
+ const recaptchaRef = useRef<any>({});
98
+
99
+ const handleOpenRecaptcha = () => {
100
+ setRecaptchaVerified(false)
101
+ if (!recaptchaConfig?.siteKey) {
102
+ showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
103
+ return
104
+ }
105
+ if (!recaptchaConfig?.baseUrl) {
106
+ showToast(ToastType.Error, t('NO_RECAPTCHA_BASE_URL', 'The config doesn\'t have recaptcha base url'));
107
+ return
108
+ }
109
+ recaptchaRef.current.open()
110
+ }
111
+
112
+ const onRecaptchaVerify = (token: any) => {
113
+ setRecaptchaVerified(true)
114
+ handleReCaptcha(token)
115
+ }
116
+
117
+ useEffect(() => {
118
+ if (configs && Object.keys(configs).length > 0 && enableReCaptcha) {
119
+ setRecaptchaConfig({
120
+ siteKey: configs?.security_recaptcha_site_key?.value || null,
121
+ baseUrl: configs?.security_recaptcha_base_url?.value || null
122
+ })
123
+ }
124
+ }, [configs, enableReCaptcha])
125
+
126
+ useEffect(() => {
127
+ const projectInputInterval = setInterval(() => {
128
+ if (projectName.name && useRootPoint && projectName.isFocued) {
129
+ setOrdering({
130
+ ...ordering,
131
+ project: projectName.name
132
+ })
133
+ }
134
+ }, 1500)
135
+ return () => clearInterval(projectInputInterval);
136
+ }, [projectName])
137
+
87
138
  const getTraduction = (key: string) => {
88
139
  const keyList: any = {
89
140
  // Add the key and traduction that you need below
@@ -465,6 +516,7 @@ const LoginFormUI = (props: LoginParams) => {
465
516
  icon={theme.images.general.project}
466
517
  iconColor={theme.colors.arrowColor}
467
518
  onChange={(e: any) => {
519
+ setProjectName({name: e?.target?.value, isFocued: true})
468
520
  onChange(e?.target?.value);
469
521
  setSubmitted(false);
470
522
  }}
@@ -493,6 +545,7 @@ const LoginFormUI = (props: LoginParams) => {
493
545
  icon={theme.images.logos.emailInputIcon}
494
546
  iconColor={theme.colors.arrowColor}
495
547
  onChange={(e: any) => {
548
+ setProjectName({...projectName, isFocued: false})
496
549
  handleChangeInputEmail(e, onChange);
497
550
  }}
498
551
  selectionColor={theme.colors.primary}
@@ -590,7 +643,7 @@ const LoginFormUI = (props: LoginParams) => {
590
643
 
591
644
  {onNavigationRedirect && (
592
645
  <Pressable
593
- style={{ marginRight: 'auto', marginBottom: 35 }}
646
+ style={{ marginRight: 'auto', marginBottom: 20 }}
594
647
  onPress={() => onNavigationRedirect('Forgot')}>
595
648
  <OText style={styles.textForgot}>
596
649
  {t('FORGOT_YOUR_PASSWORD', 'Forgot your password?')}
@@ -598,6 +651,39 @@ const LoginFormUI = (props: LoginParams) => {
598
651
  </Pressable>
599
652
  )}
600
653
 
654
+ {enableReCaptcha && (
655
+ <>
656
+ <TouchableOpacity
657
+ style={{ marginBottom: 15 }}
658
+ onPress={handleOpenRecaptcha}
659
+ >
660
+ <RecaptchaButton>
661
+ {recaptchaVerified ? (
662
+ <MaterialCommunityIcons
663
+ name="checkbox-marked"
664
+ size={26}
665
+ color={theme.colors.primary}
666
+ />
667
+ ) : (
668
+ <MaterialCommunityIcons
669
+ name="checkbox-blank-outline"
670
+ size={26}
671
+ color={theme.colors.mediumGray}
672
+ />
673
+ )}
674
+ <OText size={14} mLeft={8}>{t('VERIFY_ReCAPTCHA', 'Verify reCAPTCHA')}</OText>
675
+ </RecaptchaButton>
676
+ </TouchableOpacity>
677
+ <Recaptcha
678
+ ref={recaptchaRef}
679
+ siteKey={recaptchaConfig?.siteKey}
680
+ baseUrl={recaptchaConfig?.baseUrl}
681
+ onVerify={onRecaptchaVerify}
682
+ onExpire={() => setRecaptchaVerified(false)}
683
+ />
684
+ </>
685
+ )}
686
+
601
687
  <OButton
602
688
  onClick={handleLogin}
603
689
  text={t('LOGIN', 'Login')}
@@ -657,6 +743,7 @@ const LoginFormUI = (props: LoginParams) => {
657
743
  export const LoginForm = (props: any) => {
658
744
  const loginProps = {
659
745
  ...props,
746
+ isRecaptchaEnable: true,
660
747
  UIComponent: LoginFormUI,
661
748
  };
662
749
 
@@ -46,3 +46,9 @@ export const LineSeparator = styled.View`
46
46
  height: 1px;
47
47
  background-color: ${(props: any) => props.theme.colors.disabled};
48
48
  `;
49
+
50
+ export const RecaptchaButton = styled.View`
51
+ flex-direction: row;
52
+ align-items: center;
53
+ margin-bottom: 10px;
54
+ `
@@ -15,7 +15,7 @@ const LogoutButtonUI = (props: any) => {
15
15
  const data = await _retrieveStoreData('notification_state');
16
16
  const res = await handleLogoutClick(data);
17
17
  if (res) {
18
- _clearStoreData({ excludedKeys: ['project_name'] });
18
+ _clearStoreData({ excludedKeys: ['isTutorial'] });
19
19
  }
20
20
  };
21
21
 
@@ -1,50 +1,57 @@
1
- import React, { useState, useEffect, useCallback } from 'react'
2
- import { useEvent, useLanguage, useUtils, useSession, useApi, NewOrderNotification as NewOrderNotificationController } from 'ordering-components/native'
1
+ import React, { useState, useEffect } from 'react'
2
+ import moment from 'moment'
3
3
  import { View, Modal, StyleSheet, TouchableOpacity, Dimensions } from 'react-native'
4
- import { OText, OIcon } from '../shared'
5
- import { useTheme } from 'styled-components/native'
4
+ import Sound from 'react-native-sound'
6
5
  import Icon from 'react-native-vector-icons/Feather'
6
+ import { useTheme } from 'styled-components/native'
7
+ import { useEvent, useLanguage, useSession, useApi, NewOrderNotification as NewOrderNotificationController } from 'ordering-components/native'
8
+
9
+ import { OText, OIcon } from '../shared'
7
10
  import { NotificationContainer } from './styles'
8
- import Sound from 'react-native-sound'
9
- import moment from 'moment'
10
11
  import { useLocation } from '../../hooks/useLocation'
11
- import { useFocusEffect } from '@react-navigation/core'
12
+
12
13
  Sound.setCategory('Playback')
13
14
 
14
15
  const windowWidth = Dimensions.get('screen').width
15
16
 
16
17
  const NewOrderNotificationUI = (props: any) => {
18
+ const { isBusinessApp } = props
17
19
  const [events] = useEvent()
18
20
  const theme = useTheme()
19
21
  const [, t] = useLanguage()
20
22
  const [{ user, token }] = useSession()
21
23
  const [ordering] = useApi()
22
- const [{ getTimeAgo }] = useUtils()
23
24
  const { getCurrentLocation } = useLocation();
24
- const [modalOpen, setModalOpen] = useState(false)
25
- const [newOrderId, setNewOrderId] = useState(null)
26
- const [messageOrderId, setMessageOrderId] = useState(null)
27
25
  const [soundTimeout, setSoundTimeout] = useState<any>(null)
28
- const [isFocused, setIsFocused] = useState(false)
29
- const [currentChange, setCurrentChange] = useState(1)
26
+ let [currentEvent, setCurrentEvent] = useState<any>(null)
27
+
28
+ const evtList: any = {
29
+ 1: {
30
+ event: 'messages',
31
+ message: t('NEW_MESSAGES_RECEIVED', 'New messages have been received!'),
32
+ message2: t('ORDER_N_UNREAD_MESSAGES', 'Order #_order_id_ has unread messages.').replace('_order_id_', currentEvent?.orderId),
33
+ },
34
+ 2: {
35
+ event: 'order_added',
36
+ message: t('NEW_ORDERS_RECEIVED', 'New orders have been received!'),
37
+ message2: t('ORDER_N_ORDERED', 'Order #_order_id_ has been ordered.').replace('_order_id_', currentEvent?.orderId),
38
+ },
39
+ 3: {
40
+ event: 'order_updated',
41
+ message: t('NEW_ORDERS_UPDATED', 'New orders have been updated!'),
42
+ message2: t('ORDER_N_UPDATED', 'Order #_order_id_ has been updated.').replace('_order_id_', currentEvent?.orderId),
43
+ },
44
+ }
30
45
 
31
- const notificationSound = new Sound(theme.sounds.notification, error => {
32
- if (error) {
33
- console.log('failed to load the sound', error);
34
- return
35
- }
36
- console.log('loaded successfully');
37
- });
46
+ const notificationSound = new Sound(theme.sounds.notification, (e) => { console.log(e) });
38
47
 
39
48
  const handlePlayNotificationSound = () => {
49
+ if (currentEvent) return
40
50
  let times = 0
41
51
  const _timeout = setInterval(function () {
42
52
  notificationSound.play(success => {
43
53
  if (success) {
44
- console.log('successfully finished playing');
45
54
  times = times + 1
46
- } else {
47
- console.log('playback failed due to audio decoding errors');
48
55
  }
49
56
  })
50
57
  setSoundTimeout(_timeout)
@@ -57,67 +64,57 @@ const NewOrderNotificationUI = (props: any) => {
57
64
 
58
65
  const handleCloseModal = () => {
59
66
  clearInterval(soundTimeout)
60
- setModalOpen(false)
61
- setNewOrderId(null)
62
- setMessageOrderId(null)
67
+ currentEvent = null
68
+ setCurrentEvent({ evt: null })
63
69
  }
64
70
 
65
- const handleNotification = (order: any) => {
66
- setModalOpen(true)
67
- clearInterval(soundTimeout)
68
- setCurrentChange(1)
71
+ const handleEventNotification = async (evtType: number, value: any) => {
72
+ if (value?.driver) {
73
+ try {
74
+ const location = await getCurrentLocation()
75
+ await fetch(`${ordering.root}/users/${user.id}/locations`, {
76
+ method: 'POST',
77
+ body: JSON.stringify({
78
+ location: JSON.stringify({location: `{lat: ${location.latitude}, lng: ${location.longitude}}`})
79
+ }),
80
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }
81
+ })
82
+ } catch (error) {
83
+ console.log(error)
84
+ }
85
+ const duration = moment.duration(moment().diff(moment.utc(value?.last_driver_assigned_at)))
86
+ const assignedSecondsDiff = duration.asSeconds()
87
+ if (assignedSecondsDiff < 5 && !isBusinessApp) {
88
+ handlePlayNotificationSound()
89
+ clearInterval(soundTimeout)
90
+ currentEvent = { evt: 2, orderId: value?.id }
91
+ setCurrentEvent({ evt: 2, orderId: value?.id })
92
+ }
93
+ }
94
+ if (evtType === 3 || value.author_id === user.id) return
69
95
  handlePlayNotificationSound()
70
- setNewOrderId(order.id)
71
- }
72
-
73
- const handleMessageNotification = (message: any) => {
74
- const { order_id: orderId } = message;
75
- if (!modalOpen) setModalOpen(true)
76
96
  clearInterval(soundTimeout)
77
- setCurrentChange(2)
78
- handlePlayNotificationSound()
79
- setMessageOrderId(orderId)
97
+ currentEvent = {
98
+ evt: evtType,
99
+ orderId: evtList[evtType].event === 'messages' ? value?.order_id : value?.id
100
+ }
101
+ setCurrentEvent({
102
+ evt: evtType,
103
+ orderId: evtList[evtType].event === 'messages' ? value?.order_id : value?.id
104
+ })
80
105
  }
81
106
 
82
107
  useEffect(() => {
83
- events.on('order_added_noification', handleNotification)
84
- events.on('message_added_noification', handleMessageNotification)
108
+ events.on('message_added_notification', (o: any) => handleEventNotification(1, o))
109
+ events.on('order_added_notification', (o: any) => handleEventNotification(2, o))
110
+ events.on('order_updated_notification', (o: any) => handleEventNotification(3, o))
85
111
  return () => {
86
- events.off('order_added_noification', handleNotification)
87
- events.off('message_added_noification', handleMessageNotification)
112
+ events.off('message_added_notification', (o: any) => handleEventNotification(1, o))
113
+ events.off('order_added_notification', (o: any) => handleEventNotification(2, o))
114
+ events.off('order_updated_notification', (o: any) => handleEventNotification(3, o))
88
115
  }
89
116
  }, [])
90
117
 
91
- const handleUpdateOrder = useCallback(async (order: any) => {
92
- if (order?.driver) {
93
- const location = await getCurrentLocation()
94
- await fetch(`${ordering.root}/users/${user.id}/locations`, {
95
- method: 'POST',
96
- body: JSON.stringify({
97
- location: JSON.stringify({location: `{lat: ${location.latitude}, lng: ${location.longitude}}`})
98
- }),
99
- headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }
100
- })
101
- const assignedTimeDiff = moment.utc(order?.driver?.last_order_assigned_at).local().fromNow()
102
- if (assignedTimeDiff === 'a few seconds ago') {
103
- clearInterval(soundTimeout)
104
- handlePlayNotificationSound()
105
- setNewOrderId(order.id)
106
- if(isFocused){
107
- setModalOpen(true)
108
- }
109
- }
110
- }
111
- }, [newOrderId, notificationSound, soundTimeout])
112
-
113
- useEffect(() => {
114
- if (user?.level !== 4) return
115
- events.on('order_updated_noification', handleUpdateOrder)
116
- return () => {
117
- events.off('order_updated_noification', handleUpdateOrder)
118
- }
119
- }, [handleUpdateOrder, user])
120
-
121
118
  useEffect(() => {
122
119
  notificationSound.setVolume(1);
123
120
  return () => {
@@ -125,21 +122,12 @@ const NewOrderNotificationUI = (props: any) => {
125
122
  }
126
123
  }, [])
127
124
 
128
- useFocusEffect(
129
- useCallback(() => {
130
- setIsFocused(true)
131
- return () => {
132
- setIsFocused(false)
133
- }
134
- }, [])
135
- )
136
-
137
125
  return (
138
126
  <>
139
127
  <Modal
140
128
  animationType='slide'
141
129
  transparent={true}
142
- visible={modalOpen}
130
+ visible={!!currentEvent?.orderId}
143
131
  >
144
132
  <NotificationContainer>
145
133
  <View style={styles.modalView}>
@@ -147,40 +135,26 @@ const NewOrderNotificationUI = (props: any) => {
147
135
  style={styles.wrapperIcon}
148
136
  onPress={() => handleCloseModal()}
149
137
  >
150
- <Icon
151
- name="x"
152
- size={30}
153
- />
138
+ <Icon name="x" size={30} />
154
139
  </TouchableOpacity>
155
140
  <OText
156
141
  size={18}
157
142
  color={theme.colors.textGray}
158
143
  weight={600}
159
144
  >
160
- {currentChange === 1 ? t('NEW_ORDRES_RECEIVED', 'New orders have been received!') : t('NEW_MESSAGES_RECEIVED', 'New messages have been received!')}
145
+ {evtList[currentEvent?.evt]?.message}
161
146
  </OText>
162
147
  <OIcon
163
148
  src={theme.images.general.newOrder}
164
149
  width={250}
165
150
  height={200}
166
151
  />
167
- {newOrderId !== null && (
168
- <OText
169
- color={theme.colors.textGray}
170
- mBottom={15}
171
- >
172
- {t('ORDER_N_ORDERED', 'Order #_order_id_ has been ordered.').replace('_order_id_', newOrderId)}
173
- </OText>
174
- )}
175
-
176
- {messageOrderId !== null && (
177
- <OText
178
- color={theme.colors.textGray}
179
- mBottom={15}
180
- >
181
- {t('ORDER_N_UNREAD_MESSAGES', 'Order #_order_id_ has unread messages.').replace('_order_id_', messageOrderId)}
182
- </OText>
183
- )}
152
+ <OText
153
+ color={theme.colors.textGray}
154
+ mBottom={15}
155
+ >
156
+ {evtList[currentEvent?.evt]?.message2}
157
+ </OText>
184
158
  </View>
185
159
  </NotificationContainer>
186
160
  </Modal>
@@ -335,7 +335,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
335
335
  addressName: order?.business?.address,
336
336
  zipcode: order?.business?.zipcode
337
337
  },
338
- icon: order?.business?.logo || theme.images.dummies.businessLogo,
338
+ icon: order?.business?.logo || 'https://res.cloudinary.com/demo/image/fetch/c_thumb,g_face,r_max/https://res.cloudinary.com/ordering2/image/upload/v1654619525/hzegwosnplvrbtjkpfi6.png',
339
339
  level: 2,
340
340
  },
341
341
  {
@@ -439,7 +439,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
439
439
  <>
440
440
  <OrderContentComponent order={order} />
441
441
  {(order?.status === 7 || order?.status === 4) &&
442
- order?.delivery_type === 1 && (
442
+ order?.delivery_type === 1 && configs?.assign_driver_enabled?.value === '1' && (
443
443
  <AssignDriver>
444
444
  <OText style={{ marginBottom: 5 }} size={16} weight="600">
445
445
  {t('ASSIGN_DRIVER', 'Assign driver')}
@@ -1,6 +1,6 @@
1
1
  //React & React Native
2
2
  import React, { useState, useEffect } from 'react';
3
- import { StyleSheet, View, Platform, ScrollView } from 'react-native';
3
+ import { StyleSheet, View } from 'react-native';
4
4
 
5
5
  // Thirds
6
6
  import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
@@ -29,7 +29,6 @@ import { NotFoundSource } from '../NotFoundSource';
29
29
  import { getOrderStatus } from '../../utils';
30
30
  import { OrderHeaderComponent } from './OrderHeaderComponent';
31
31
  import { OrderContentComponent } from './OrderContentComponent';
32
-
33
32
  //Styles
34
33
  import { OrderDetailsContainer, Pickup } from './styles';
35
34
 
@@ -51,7 +50,9 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
51
50
  orderTitle,
52
51
  appTitle,
53
52
  handleClickLogisticOrder,
54
- forceUpdate
53
+ forceUpdate,
54
+ getPermissions,
55
+ isGrantedPermissions
55
56
  } = props;
56
57
  const [, { showToast }] = useToast();
57
58
  const { order } = props.order
@@ -72,6 +73,8 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
72
73
  key?: string | null;
73
74
  }>({ open: false, content: [], key: null });
74
75
 
76
+ const validStatusComplete = [9, 19, 23]
77
+
75
78
  const logisticOrderStatus = [4, 6, 7]
76
79
 
77
80
  const showFloatButtonsPickUp: any = {
@@ -101,9 +104,18 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
101
104
  };
102
105
 
103
106
  const handleOpenMapView = async () => {
104
- if (permissions?.locationStatus === 'granted') {
107
+ if (!isGrantedPermissions) {
108
+ navigation.navigate('RequestPermissions')
109
+ return
110
+ }
111
+ const _permissions = await getPermissions()
112
+
113
+ const isBlocked = _permissions.some((_permission: string) => permissions?.locationStatus?.[_permission] === 'blocked')
114
+ const isGranted = _permissions.reduce((allPermissions: boolean, _permission: string) => allPermissions && permissions?.locationStatus?.[_permission] === 'granted', true)
115
+
116
+ if (isGranted) {
105
117
  setOpenModalForMapView(!openModalForMapView);
106
- } else if (permissions?.locationStatus === 'blocked') {
118
+ } else if (isBlocked) {
107
119
  // redirectToSettings();
108
120
  showToast(
109
121
  ToastType.Error,
@@ -114,13 +126,18 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
114
126
  );
115
127
  } else {
116
128
  const response = await askLocationPermission();
117
- if (response === 'granted') {
118
- setOpenModalForMapView(!openModalForMapView);
129
+ const isGranted = _permissions.reduce((allPermissions: boolean, _permission: string) => allPermissions && response?.locationStatus?.[_permission] === 'granted', true)
130
+ if (isGranted) {
131
+ setOpenModalForMapView(true)
119
132
  }
120
133
  }
121
134
  };
122
135
 
123
136
  const handleViewActionOrder = (action: string) => {
137
+ if (!isGrantedPermissions) {
138
+ navigation.navigate('RequestPermissions')
139
+ return
140
+ }
124
141
  if (openModalForMapView) {
125
142
  setOpenModalForMapView(false);
126
143
  }
@@ -230,17 +247,17 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
230
247
  let isToFollow = false;
231
248
  let isBusinessMarker = false;
232
249
 
233
- if (order?.status === 7 || order?.status === 8) {
250
+ if (order?.status === 7 || order?.status === 8 || order?.status === 18) {
234
251
  const markerBusiness = 'Business';
235
252
  isBusinessMarker = true;
236
253
  locationMarker = locations.find(
237
254
  (location: any) => location.type === markerBusiness,
238
255
  );
239
256
 
240
- if (order?.status === 8) {
257
+ if (order?.status === 8 || order?.status === 18) {
241
258
  isToFollow = true;
242
259
  }
243
- } else if (order?.status === 3 || order?.status === 9) {
260
+ } else if (order?.status === 3 || order?.status === 9 || order?.status === 19 || order?.status === 23) {
244
261
  const markerCustomer = 'Customer';
245
262
  isToFollow = true;
246
263
  isBusinessMarker = false;
@@ -378,7 +395,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
378
395
  widthButton={'45%'}
379
396
  />
380
397
  )}
381
- {(order?.status === 9 || order?.status === 19) && (
398
+ {(validStatusComplete.includes(order?.status)) && (
382
399
  <>
383
400
  <FloatingButton
384
401
  disabled={props.order?.loading}
@@ -77,6 +77,7 @@ export const OrderContentComponent = (props: OrderContent) => {
77
77
  })
78
78
 
79
79
  const getIncludedTaxes = () => {
80
+ if (!order?.taxes) return 0
80
81
  if (order?.taxes?.length === 0) {
81
82
  return order.tax_type === 1 ? order?.summary?.tax ?? 0 : 0
82
83
  } else {
@@ -95,6 +96,33 @@ export const OrderContentComponent = (props: OrderContent) => {
95
96
  {isOrderGroup && (
96
97
  <OText size={18}>{t('ORDER', 'Order')} #{isOrderGroup ? order?.order_group_id : order?.id}</OText>
97
98
  )}
99
+
100
+ {order?.metafields?.length > 0 && (
101
+ <OrderBusiness>
102
+ <OText style={{ marginBottom: 5 }} size={16} weight="600">
103
+ {t('CUSTOM_FIELDS', 'Custom fields')}
104
+ </OText>
105
+
106
+ {order.metafields.map((field: any) => (
107
+ <View
108
+ key={field.id}
109
+ style={{
110
+ width: '100%',
111
+ flexDirection: 'row',
112
+ marginBottom: 5
113
+ }}
114
+ >
115
+ <OText style={{ width: '50%' }}>
116
+ {field.key}
117
+ </OText>
118
+ <OText style={{ width: '45%', textAlign: 'right' }}>
119
+ {field.value}
120
+ </OText>
121
+ </View>
122
+ ))}
123
+ </OrderBusiness>
124
+ )}
125
+
98
126
  <OrderBusiness>
99
127
  <OText style={{ marginBottom: 5 }} size={16} weight="600">
100
128
  {t('BUSINESS_DETAILS', 'Business details')}
@@ -246,8 +274,8 @@ export const OrderContentComponent = (props: OrderContent) => {
246
274
  <View style={styles.linkWithIcons}>
247
275
  <OLink
248
276
  PressStyle={styles.linkWithIcons}
249
- url={`tel:${order?.customer?.cellphone}`}
250
- shorcut={order?.customer?.cellphone}
277
+ url={`tel:${!!order?.customer?.country_phone_code ? '+' + order?.customer?.country_phone_code : ''} ${order?.customer?.cellphone}`}
278
+ shorcut={`${!!order?.customer?.country_phone_code ? '+' + order?.customer?.country_phone_code : ''} ${order?.customer?.cellphone}`}
251
279
  TextStyle={styles.textLink}
252
280
  />
253
281
  </View>
@@ -295,6 +323,12 @@ export const OrderContentComponent = (props: OrderContent) => {
295
323
  {order?.customer?.zipcode}
296
324
  </OText>
297
325
  )}
326
+
327
+ {!!order?.on_behalf_of && (
328
+ <OText numberOfLines={1} mBottom={4} ellipsizeMode="tail">
329
+ {t('ON_BEHALF_OF', 'On behalf of')}{': '} {order?.on_behalf_of}
330
+ </OText>
331
+ )}
298
332
  {((order?.delivery_option !== undefined && order?.delivery_type === 1) || !!order?.comment) && (
299
333
  <View style={{ marginTop: 10 }}>
300
334
  {order?.delivery_option !== undefined && order?.delivery_type === 1 && (
@@ -358,7 +392,7 @@ export const OrderContentComponent = (props: OrderContent) => {
358
392
  order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 1)?.map((offer: any) => (
359
393
  <Table key={offer.id}>
360
394
  <OSRow>
361
- <OText numberOfLines={1} mBottom={4}>
395
+ <OText mBottom={4}>
362
396
  {offer.name}
363
397
  {offer.rate_type === 1 && (
364
398
  <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
@@ -404,7 +438,7 @@ export const OrderContentComponent = (props: OrderContent) => {
404
438
  order?.taxes?.length > 0 && order?.taxes?.filter((tax: any) => tax?.type === 2 && tax?.rate !== 0).map((tax: any) => (
405
439
  <Table key={tax.id}>
406
440
  <OSRow>
407
- <OText numberOfLines={1} mBottom={4}>
441
+ <OText mBottom={4}>
408
442
  {tax.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}
409
443
  {`(${verifyDecimals(tax?.rate, parseNumber)}%)`}{' '}
410
444
  </OText>
@@ -417,7 +451,7 @@ export const OrderContentComponent = (props: OrderContent) => {
417
451
  order?.fees?.length > 0 && order?.fees?.filter((fee: any) => !(fee.fixed === 0 && fee.percentage === 0))?.map((fee: any) => (
418
452
  <Table key={fee.id}>
419
453
  <OSRow>
420
- <OText numberOfLines={1} mBottom={4}>
454
+ <OText mBottom={4}>
421
455
  {fee.name || t('INHERIT_FROM_BUSINESS', 'Inherit from business')}
422
456
  ({fee?.fixed > 0 && `${parsePrice(fee?.fixed)} + `}{fee.percentage}%){' '}
423
457
  </OText>
@@ -430,7 +464,7 @@ export const OrderContentComponent = (props: OrderContent) => {
430
464
  order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 3)?.map((offer: any) => (
431
465
  <Table key={offer.id}>
432
466
  <OSRow>
433
- <OText numberOfLines={1} mBottom={4}>
467
+ <OText mBottom={4}>
434
468
  {offer.name}
435
469
  {offer.rate_type === 1 && (
436
470
  <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>
@@ -458,7 +492,7 @@ export const OrderContentComponent = (props: OrderContent) => {
458
492
  order?.offers?.length > 0 && order?.offers?.filter((offer: any) => offer?.target === 2)?.map((offer: any) => (
459
493
  <Table key={offer.id}>
460
494
  <OSRow>
461
- <OText numberOfLines={1} mBottom={4}>
495
+ <OText mBottom={4}>
462
496
  {offer.name}
463
497
  {offer.rate_type === 1 && (
464
498
  <OText>{`(${verifyDecimals(offer?.rate, parsePrice)}%)`}</OText>