ordering-ui-react-native 0.15.31 → 0.15.33-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 (178) hide show
  1. package/package.json +4 -2
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/BusinessController/index.tsx +8 -2
  4. package/src/components/BusinessTypeFilter/index.tsx +4 -1
  5. package/src/components/BusinessesListing/index.tsx +1 -1
  6. package/src/components/Checkout/index.tsx +23 -3
  7. package/src/components/DriverTips/index.tsx +11 -6
  8. package/src/components/LanguageSelector/index.tsx +7 -2
  9. package/src/components/LoginForm/index.tsx +3 -1
  10. package/src/components/OrderDetails/index.tsx +2 -2
  11. package/src/components/PaymentOptions/index.tsx +9 -16
  12. package/src/components/PaymentOptionsWebView/index.tsx +123 -124
  13. package/src/components/SignupForm/index.tsx +3 -1
  14. package/src/components/SingleProductCard/index.tsx +16 -4
  15. package/src/components/StripeElementsForm/index.tsx +27 -48
  16. package/src/components/UpsellingProducts/index.tsx +1 -1
  17. package/src/components/UserProfileForm/index.tsx +63 -6
  18. package/src/components/UserProfileForm/styles.tsx +8 -0
  19. package/src/components/VerifyPhone/styles.tsx +1 -2
  20. package/src/components/shared/OModal.tsx +1 -1
  21. package/src/config.json +0 -2
  22. package/src/hooks/useCountdownTimer.tsx +26 -0
  23. package/src/navigators/HomeNavigator.tsx +6 -0
  24. package/src/pages/BusinessProductsList.tsx +1 -0
  25. package/src/pages/BusinessesListing.tsx +1 -1
  26. package/src/pages/Checkout.tsx +1 -1
  27. package/src/pages/Sessions.tsx +22 -0
  28. package/src/types/index.tsx +5 -11
  29. package/src/utils/index.tsx +68 -1
  30. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +103 -15
  31. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -0
  32. package/themes/business/src/components/Chat/index.tsx +38 -86
  33. package/themes/business/src/components/DriverMap/index.tsx +6 -5
  34. package/themes/business/src/components/Home/index.tsx +128 -55
  35. package/themes/business/src/components/Home/styles.tsx +8 -1
  36. package/themes/business/src/components/LoginForm/index.tsx +89 -2
  37. package/themes/business/src/components/LoginForm/styles.tsx +6 -0
  38. package/themes/business/src/components/LogoutButton/index.tsx +1 -1
  39. package/themes/business/src/components/NewOrderNotification/index.tsx +79 -105
  40. package/themes/business/src/components/OrderDetails/Business.tsx +1 -1
  41. package/themes/business/src/components/OrderDetails/Delivery.tsx +32 -15
  42. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +157 -89
  43. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +6 -0
  44. package/themes/business/src/components/OrderDetails/styles.tsx +7 -0
  45. package/themes/business/src/components/OrdersListManager/index.tsx +52 -49
  46. package/themes/business/src/components/OrdersOption/index.tsx +57 -50
  47. package/themes/business/src/components/PreviousOrders/index.tsx +50 -14
  48. package/themes/business/src/components/shared/OModal.tsx +1 -1
  49. package/themes/business/src/types/index.tsx +5 -1
  50. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  51. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  52. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  53. package/themes/kiosk/src/components/Cart/index.tsx +98 -24
  54. package/themes/kiosk/src/components/Cart/styles.tsx +6 -0
  55. package/themes/kiosk/src/components/CartBottomSheet/index.tsx +1 -1
  56. package/themes/kiosk/src/components/CartBottomSheet/styles.tsx +1 -1
  57. package/themes/kiosk/src/components/CartContent/index.tsx +13 -3
  58. package/themes/kiosk/src/components/CartItem/index.tsx +20 -8
  59. package/themes/kiosk/src/components/Checkout/index.tsx +34 -22
  60. package/themes/kiosk/src/components/CustomerName/index.tsx +7 -8
  61. package/themes/kiosk/src/components/Intro/index.tsx +13 -13
  62. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  63. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  64. package/themes/kiosk/src/components/OrderDetails/index.tsx +167 -67
  65. package/themes/kiosk/src/components/OrderDetails/styles.tsx +5 -0
  66. package/themes/kiosk/src/components/OrderSummary/index.tsx +1 -1
  67. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +10 -12
  68. package/themes/kiosk/src/components/PaymentOptions/index.tsx +1 -1
  69. package/themes/kiosk/src/components/ProductForm/index.tsx +174 -125
  70. package/themes/kiosk/src/components/ProductForm/styles.tsx +1 -1
  71. package/themes/kiosk/src/components/ProductOption/index.tsx +1 -0
  72. package/themes/kiosk/src/components/ProductOption/styles.tsx +1 -0
  73. package/themes/kiosk/src/components/UpsellingProducts/index.tsx +48 -34
  74. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  75. package/themes/kiosk/src/types/index.d.ts +2 -0
  76. package/themes/original/index.tsx +184 -1
  77. package/themes/original/src/components/ActiveOrders/index.tsx +15 -132
  78. package/themes/original/src/components/ActiveOrders/styles.tsx +0 -54
  79. package/themes/original/src/components/AddressForm/index.tsx +15 -10
  80. package/themes/original/src/components/AddressList/index.tsx +56 -18
  81. package/themes/original/src/components/AppleLogin/index.tsx +117 -78
  82. package/themes/original/src/components/BusinessBasicInformation/index.tsx +96 -45
  83. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +28 -1
  84. package/themes/original/src/components/BusinessController/index.tsx +77 -29
  85. package/themes/original/src/components/BusinessController/styles.tsx +27 -0
  86. package/themes/original/src/components/BusinessFeaturedController/index.tsx +20 -1
  87. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +23 -0
  88. package/themes/original/src/components/BusinessListingSearch/index.tsx +125 -7
  89. package/themes/original/src/components/BusinessListingSearch/styles.tsx +14 -1
  90. package/themes/original/src/components/BusinessMenuList/index.tsx +11 -4
  91. package/themes/original/src/components/BusinessPreorder/index.tsx +142 -122
  92. package/themes/original/src/components/BusinessProductsCategories/index.tsx +9 -7
  93. package/themes/original/src/components/BusinessProductsList/CategoryDescription/index.tsx +44 -0
  94. package/themes/original/src/components/BusinessProductsList/index.tsx +140 -37
  95. package/themes/original/src/components/BusinessProductsList/styles.tsx +29 -2
  96. package/themes/original/src/components/BusinessProductsListing/index.tsx +112 -14
  97. package/themes/original/src/components/BusinessProductsListing/styles.tsx +22 -0
  98. package/themes/original/src/components/BusinessReviews/index.tsx +4 -25
  99. package/themes/original/src/components/BusinessTypeFilter/index.tsx +1 -2
  100. package/themes/original/src/components/BusinessesListing/index.tsx +98 -72
  101. package/themes/original/src/components/Cart/index.tsx +21 -17
  102. package/themes/original/src/components/CartContent/index.tsx +2 -2
  103. package/themes/original/src/components/Checkout/index.tsx +59 -48
  104. package/themes/original/src/components/DriverTips/index.tsx +17 -12
  105. package/themes/original/src/components/Favorite/index.tsx +91 -0
  106. package/themes/original/src/components/Favorite/styles.tsx +22 -0
  107. package/themes/original/src/components/FavoriteList/index.tsx +287 -0
  108. package/themes/original/src/components/FavoriteList/styles.tsx +5 -0
  109. package/themes/original/src/components/ForgotPasswordForm/index.tsx +84 -4
  110. package/themes/original/src/components/GPSButton/index.tsx +15 -8
  111. package/themes/original/src/components/GoogleMap/index.tsx +1 -0
  112. package/themes/original/src/components/Help/index.tsx +21 -4
  113. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +115 -90
  114. package/themes/original/src/components/Home/index.tsx +1 -1
  115. package/themes/original/src/components/LastOrders/index.tsx +12 -1
  116. package/themes/original/src/components/LoginForm/Otp/index.tsx +90 -0
  117. package/themes/original/src/components/LoginForm/Otp/styles.tsx +7 -0
  118. package/themes/original/src/components/LoginForm/index.tsx +394 -155
  119. package/themes/original/src/components/LoginForm/styles.tsx +7 -4
  120. package/themes/original/src/components/LogoutButton/index.tsx +7 -1
  121. package/themes/original/src/components/MessageListing/index.tsx +10 -1
  122. package/themes/original/src/components/Messages/index.tsx +34 -25
  123. package/themes/original/src/components/Messages/styles.tsx +1 -3
  124. package/themes/original/src/components/MomentOption/index.tsx +10 -1
  125. package/themes/original/src/components/MomentOption/styles.tsx +1 -1
  126. package/themes/original/src/components/OrderDetails/index.tsx +56 -33
  127. package/themes/original/src/components/OrderDetails/styles.tsx +1 -2
  128. package/themes/original/src/components/OrderProgress/index.tsx +4 -4
  129. package/themes/original/src/components/OrderProgress/styles.tsx +1 -0
  130. package/themes/original/src/components/OrderSummary/index.tsx +3 -3
  131. package/themes/original/src/components/OrderTypeSelector/index.tsx +4 -2
  132. package/themes/original/src/components/OrdersOption/index.tsx +59 -58
  133. package/themes/original/src/components/OrdersOption/styles.tsx +0 -6
  134. package/themes/original/src/components/PaymentOptionCash/index.tsx +2 -2
  135. package/themes/original/src/components/PaymentOptionWallet/index.tsx +22 -24
  136. package/themes/original/src/components/PaymentOptionWallet/styles.tsx +1 -1
  137. package/themes/original/src/components/PaymentOptions/index.tsx +9 -21
  138. package/themes/original/src/components/PhoneInputNumber/index.tsx +1 -1
  139. package/themes/original/src/components/PreviousOrders/index.tsx +18 -145
  140. package/themes/original/src/components/ProductForm/index.tsx +76 -61
  141. package/themes/original/src/components/ProductForm/styles.tsx +2 -2
  142. package/themes/original/src/components/ProductItemAccordion/index.tsx +2 -2
  143. package/themes/original/src/components/ProductOptionSubOption/index.tsx +18 -12
  144. package/themes/original/src/components/Promotions/index.tsx +250 -0
  145. package/themes/original/src/components/Promotions/styles.tsx +60 -0
  146. package/themes/original/src/components/ReviewOrder/index.tsx +10 -9
  147. package/themes/original/src/components/ReviewProducts/index.tsx +1 -1
  148. package/themes/original/src/components/SearchBar/index.tsx +4 -1
  149. package/themes/original/src/components/Sessions/index.tsx +160 -0
  150. package/themes/original/src/components/Sessions/styles.tsx +15 -0
  151. package/themes/original/src/components/SignupForm/index.tsx +9 -4
  152. package/themes/original/src/components/SingleOrderCard/index.tsx +282 -0
  153. package/themes/original/src/components/SingleOrderCard/styles.tsx +54 -0
  154. package/themes/original/src/components/SingleProductCard/index.tsx +82 -30
  155. package/themes/original/src/components/SingleProductCard/styles.tsx +28 -1
  156. package/themes/original/src/components/StripeElementsForm/index.tsx +55 -74
  157. package/themes/original/src/components/TaxInformation/index.tsx +10 -4
  158. package/themes/original/src/components/UpsellingProducts/index.tsx +86 -74
  159. package/themes/original/src/components/UserDetails/index.tsx +4 -95
  160. package/themes/original/src/components/UserFormDetails/index.tsx +34 -24
  161. package/themes/original/src/components/UserProfile/index.tsx +66 -14
  162. package/themes/original/src/components/UserProfileForm/index.tsx +20 -18
  163. package/themes/original/src/components/UserVerification/index.tsx +178 -192
  164. package/themes/original/src/components/VerifyPhone/index.tsx +10 -7
  165. package/themes/original/src/components/VerifyPhone/styles.tsx +2 -1
  166. package/themes/original/src/components/Wallets/index.tsx +76 -9
  167. package/themes/original/src/components/Wallets/styles.tsx +21 -0
  168. package/themes/original/src/components/shared/HeaderTitle.tsx +21 -0
  169. package/themes/original/src/components/shared/OModal.tsx +4 -2
  170. package/themes/original/src/components/shared/index.tsx +2 -0
  171. package/themes/original/src/config/constants.tsx +6 -6
  172. package/themes/original/src/types/index.tsx +115 -9
  173. package/themes/original/src/utils/index.tsx +28 -2
  174. package/themes/single-business/src/components/AddressList/index.tsx +1 -1
  175. package/themes/single-business/src/components/OrderTypeSelector/index.tsx +6 -6
  176. package/themes/single-business/src/components/UserProfile/index.tsx +1 -1
  177. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
  178. package/src/components/StripeMethodForm/index.tsx +0 -174
@@ -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 } from 'ordering-components/native';
3
+ import { useApi, useSession, useLanguage, useConfig } 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';
@@ -16,12 +16,16 @@ export const AppleLogin = (props: any) => {
16
16
  } = props
17
17
 
18
18
  const [ordering] = useApi();
19
- const [{ auth }] = useSession();
20
- const [, t] = useLanguage();
19
+ const [{ auth }] = useSession();
20
+ const [, t] = useLanguage();
21
+ const [{ configs }] = useConfig();
22
+ const [credentialStateForUser, updateCredentialStateForUser] = useState<any>(-1);
21
23
 
22
- const buttonText = auth
23
- ? t('CONTINUE_WITH_APPLE', 'Logout with Apple')
24
- : t('CONTINUE_WITH_FACEBOOK', 'Continue with Apple');
24
+ let user: any = null
25
+
26
+ const buttonText = auth
27
+ ? t('CONTINUE_WITH_APPLE', 'Logout with Apple')
28
+ : t('CONTINUE_WITH_APPLE', 'Continue with Apple');
25
29
 
26
30
  const performAppleLogin = async (code: string) => {
27
31
  try {
@@ -29,17 +33,19 @@ export const AppleLogin = (props: any) => {
29
33
  method: 'POST',
30
34
  headers: { 'Content-Type': 'application/json' },
31
35
  body: JSON.stringify({
32
- code: code
36
+ code: code,
37
+ platform: Platform.OS === 'ios' ? 'ios' : 'other'
33
38
  })
34
39
  })
35
- if (!response.content.error) {
40
+ const { result, error } = await response.json()
41
+ if (!error) {
36
42
  if (handleSuccessAppleLogin) {
37
- handleSuccessAppleLogin(response.content.result)
43
+ handleSuccessAppleLogin(result)
38
44
  handleLoading && handleLoading(false)
39
45
  }
40
46
  } else {
47
+ handleErrors && handleErrors(result)
41
48
  handleLoading && handleLoading(false)
42
- logoutFromApple()
43
49
  }
44
50
  } catch (err: any) {
45
51
  handleLoading && handleLoading(false)
@@ -47,66 +53,98 @@ export const AppleLogin = (props: any) => {
47
53
  }
48
54
  }
49
55
 
50
- const logoutFromApple = () => {
51
-
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
+ }
52
67
  }
53
68
 
54
- const onIOSButtonPress = async () => {
55
-
56
- const appleAuthRequestResponse = await appleAuth.performRequest({
57
- requestedOperation: appleAuth.Operation.LOGIN,
58
- requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],
59
- });
60
-
61
- // get current authentication state for user
62
- // /!\ This method must be tested on a real device. On the iOS simulator it always throws an error.
63
- const credentialState = await appleAuth.getCredentialStateForUser(appleAuthRequestResponse.user);
64
-
65
- // use credentialState response to ensure the user is authenticated
66
- if (credentialState === appleAuth.State.AUTHORIZED) {
67
- // user is authenticated
68
- if (appleAuthRequestResponse.authorizationCode) {
69
- performAppleLogin(appleAuthRequestResponse.authorizationCode)
69
+ const onIOSButtonPress = async (updateCredentialStateForUser: any) => {
70
+ try {
71
+ const appleAuthRequestResponse = await appleAuth.performRequest({
72
+ requestedOperation: appleAuth.Operation.LOGIN,
73
+ requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],
74
+ });
75
+
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
+ performAppleLogin(authorizationCode)
91
+ } else {
92
+ handleErrors && handleErrors('UNABLE_LOGIN_TOKEN', 'Unable to login, no token found')
70
93
  }
71
- }
72
94
 
95
+ } catch (err: any) {
96
+ handleLoading && handleLoading(false)
97
+ handleErrors && handleErrors(err.message)
98
+ }
73
99
  }
74
100
 
75
101
  const onAndroidButtonPress = async () => {
76
- // Generate secure, random values for state and nonce
77
- const rawNonce: any = uuid.v4();
78
- const state: any = uuid.v4();
79
-
80
- // Configure the request
81
- appleAuthAndroid.configure({
82
- clientId: 'com.example.client-android',
83
- // Return URL added to your Apple dev console. We intercept this redirect, but it must still match
84
- // the URL you provided to Apple. It can be an empty route on your backend as it's never called.
85
- redirectUri: 'https://example.com/auth/callback',
86
- responseType: appleAuthAndroid.ResponseType.ALL,
87
- scope: appleAuthAndroid.Scope.ALL,
88
- // Random nonce value that will be SHA256 hashed before sending to Apple.
89
- nonce: rawNonce,
90
- state,
91
- });
92
-
93
- // Open the browser window for user sign in
94
- const response = await appleAuthAndroid.signIn();
95
-
96
102
  try {
103
+ // Generate secure, random values for state and nonce
104
+ const rawNonce: any = uuid.v4();
105
+ const state: any = uuid.v4();
106
+
107
+ // Configure the request
108
+ appleAuthAndroid.configure({
109
+ // The Service ID you registered with Apple
110
+ clientId: configs?.apple_login_client_id?.value,
111
+ // Return URL added to your Apple dev console. We intercept this redirect, but it must still match
112
+ // the URL you provided to Apple. It can be an empty route on your backend as it's never called.
113
+ redirectUri: 'https://example.com/auth/callback',
114
+ responseType: appleAuthAndroid.ResponseType.ALL,
115
+ scope: appleAuthAndroid.Scope.ALL,
116
+ // Random nonce value that will be SHA256 hashed before sending to Apple.
117
+ nonce: rawNonce,
118
+ state,
119
+ });
120
+
121
+ // Open the browser window for user sign in
122
+ const response = await appleAuthAndroid.signIn();
97
123
  if (response.code) {
98
124
  performAppleLogin(response.code)
99
125
  }
100
126
  } catch (err: any) {
101
-
127
+ handleLoading && handleLoading(false)
128
+ handleErrors && handleErrors(err.message)
102
129
  }
130
+
103
131
  }
104
132
 
105
133
  useEffect(() => {
106
- if (Platform.OS == 'android') return;
107
- // onCredentialRevoked returns a function that will remove the event listener. useEffect will call this function when the component unmounts
134
+ if (!appleAuth.isSupported || Platform.OS === 'android') return;
135
+
136
+ fetchAndUpdateCredentialState(updateCredentialStateForUser).catch(error =>
137
+ updateCredentialStateForUser(`Error: ${error.code}`),
138
+ );
139
+ }, []);
140
+
141
+ useEffect(() => {
142
+ if (!appleAuth.isSupported || Platform.OS === 'android') return;
143
+
108
144
  return appleAuth.onCredentialRevoked(async () => {
109
- console.warn('If this function executes, User Credentials have been Revoked');
145
+ fetchAndUpdateCredentialState(updateCredentialStateForUser).catch(error =>
146
+ updateCredentialStateForUser(`Error: ${error.code}`),
147
+ );
110
148
  });
111
149
  }, []);
112
150
 
@@ -115,35 +153,36 @@ export const AppleLogin = (props: any) => {
115
153
  if (Platform.OS === 'android') return appleAuthAndroid.isSupported;
116
154
  return false;
117
155
  }
156
+
118
157
  return (
119
158
  <Container>
120
- {canShowButton() &&
121
- <AppleButton
122
- onPress={() => Platform.OS == 'android' ? onAndroidButtonPress() : onIOSButtonPress()}
123
- >
124
- <Icon
125
- name="apple"
126
- size={20}
127
- color={'black'}
128
- style={style.fbBtn}
129
- />
130
- <Text style={style.textBtn}>
131
- {buttonText}
132
- </Text>
133
- </AppleButton>
159
+ {canShowButton() &&
160
+ <AppleButton
161
+ onPress={() => Platform.OS == 'android' ? onAndroidButtonPress() : onIOSButtonPress(updateCredentialStateForUser)}
162
+ >
163
+ <Icon
164
+ name="apple"
165
+ size={20}
166
+ color={'black'}
167
+ style={style.fbBtn}
168
+ />
169
+ <Text style={style.textBtn}>
170
+ {buttonText}
171
+ </Text>
172
+ </AppleButton>
134
173
  }
135
174
  </Container>
136
175
  );
137
176
  }
138
177
 
139
178
  const style = StyleSheet.create({
140
- fbBtn: {
141
- position: 'absolute',
142
- left: 0,
143
- marginHorizontal: 16
144
- },
145
- textBtn: {
146
- fontSize: 14,
147
- color: '#000000'
148
- }
149
- })
179
+ fbBtn: {
180
+ position: 'absolute',
181
+ left: 0,
182
+ marginHorizontal: 16
183
+ },
184
+ textBtn: {
185
+ fontSize: 14,
186
+ color: '#000000'
187
+ }
188
+ })
@@ -4,9 +4,7 @@ import { useUtils, useOrder, useLanguage } from 'ordering-components/native';
4
4
  import { useTheme } from 'styled-components/native';
5
5
  import { OIcon, OText, OModal } from '../shared';
6
6
  import { BusinessBasicInformationParams } from '../../types';
7
- import { convertHoursToMinutes } from '../../utils';
8
- import { BusinessInformation } from '../BusinessInformation';
9
- import { BusinessReviews } from '../BusinessReviews';
7
+ import { convertHoursToMinutes, shape } from '../../utils';
10
8
  import dayjs from 'dayjs';
11
9
  import timezone from 'dayjs/plugin/timezone';
12
10
  import isBetween from 'dayjs/plugin/isBetween';
@@ -22,10 +20,15 @@ import {
22
20
  BusinessInfoItem,
23
21
  WrapReviews,
24
22
  WrapBusinessInfo,
23
+ TitleWrapper,
24
+ RibbonBox
25
25
  } from './styles';
26
26
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
27
27
  const types = ['food', 'laundry', 'alcohol', 'groceries'];
28
28
 
29
+ let BusinessInformation: null | React.ElementType = null
30
+ let BusinessReviews: null | React.ElementType = null
31
+
29
32
  export const BusinessBasicInformation = (
30
33
  props: BusinessBasicInformationParams,
31
34
  ) => {
@@ -38,6 +41,25 @@ export const BusinessBasicInformation = (
38
41
  const [{ parsePrice, parseDistance, optimizeImage }] = useUtils();
39
42
  const [openBusinessInformation, setOpenBusinessInformation] = useState(false);
40
43
  const [openBusinessReviews, setOpenBusinessReviews] = useState(false);
44
+ const [businessInformationObtained, setBusinessInformationObtained] = useState(false)
45
+ const [businessReviewsObtained, setBusinessReviewsObtainedbtained] = useState(false)
46
+
47
+ const handleClickBusinessInformation = () => {
48
+ if (!businessInformationObtained) {
49
+ BusinessInformation = require('../BusinessInformation').BusinessInformation
50
+ setBusinessInformationObtained(true)
51
+ }
52
+ setOpenBusinessInformation(true)
53
+ }
54
+
55
+ const handleClickBusinessReviews = () => {
56
+ if (!businessReviewsObtained) {
57
+ BusinessReviews = require('../BusinessReviews').BusinessReviews
58
+ setBusinessReviewsObtainedbtained(true)
59
+ }
60
+ setOpenBusinessReviews(true)
61
+ }
62
+
41
63
  const getBusinessType = () => {
42
64
  if (Object.keys(business).length <= 0) return t('GENERAL', 'General');
43
65
  const _types: any = [];
@@ -51,7 +73,7 @@ export const BusinessBasicInformation = (
51
73
  return _types.join(', ');
52
74
  };
53
75
 
54
-
76
+
55
77
  useEffect(() => {
56
78
  if (businessState?.loading) return
57
79
  let timeout: any = null
@@ -65,16 +87,16 @@ export const BusinessBasicInformation = (
65
87
  })
66
88
  }
67
89
  if (lapse) {
68
- const to = currentDate.hour(lapse.close.hour).minute(lapse.close.minute)
69
- const timeToClose = (to.unix() - currentDate.unix()) * 1000
70
- timeout = setTimeout(() => {
71
- navigation.navigate('BusinessPreorder', { business: businessState?.business, handleBusinessClick: () => navigation?.goBack() })
72
- }, timeToClose)
90
+ const to = currentDate.hour(lapse.close.hour).minute(lapse.close.minute)
91
+ const timeToClose = (to.unix() - currentDate.unix()) * 1000
92
+ timeout = setTimeout(() => {
93
+ navigation.navigate('BusinessPreorder', { business: businessState?.business, handleBusinessClick: () => navigation?.goBack() })
94
+ }, timeToClose)
73
95
  }
74
96
  return () => {
75
- timeout && clearTimeout(timeout)
97
+ timeout && clearTimeout(timeout)
76
98
  }
77
- }, [businessState?.business])
99
+ }, [businessState?.business])
78
100
 
79
101
  return (
80
102
  <BusinessContainer>
@@ -90,7 +112,7 @@ export const BusinessBasicInformation = (
90
112
  optimizeImage(businessState?.business?.header, 'h_250,c_limit'),
91
113
  }}>
92
114
  {!isBusinessInfoShow && (
93
- <WrapBusinessInfo onPress={() => setOpenBusinessInformation(true)}>
115
+ <WrapBusinessInfo onPress={() => handleClickBusinessInformation()}>
94
116
  <OIcon src={theme.images.general.info} width={24} />
95
117
  </WrapBusinessInfo>
96
118
  )}
@@ -121,9 +143,29 @@ export const BusinessBasicInformation = (
121
143
  <PlaceholderLine height={30} width={20} />
122
144
  </Placeholder>
123
145
  ) : (
124
- <OText size={24} weight={'600'}>
125
- {business?.name}
126
- </OText>
146
+ <TitleWrapper>
147
+ <OText size={24} weight={'600'}>
148
+ {business?.name}
149
+ </OText>
150
+ {business?.ribbon?.enabled && (
151
+ <RibbonBox
152
+ bgColor={business?.ribbon?.color}
153
+ isRoundRect={business?.ribbon?.shape === shape?.rectangleRound}
154
+ isCapsule={business?.ribbon?.shape === shape?.capsuleShape}
155
+ >
156
+ <OText
157
+ size={10}
158
+ weight={'400'}
159
+ color={theme.colors.white}
160
+ numberOfLines={2}
161
+ ellipsizeMode='tail'
162
+ lineHeight={13}
163
+ >
164
+ {business?.ribbon?.text}
165
+ </OText>
166
+ </RibbonBox>
167
+ )}
168
+ </TitleWrapper>
127
169
  )}
128
170
  </BusinessInfoItem>
129
171
  {loading ? (
@@ -181,17 +223,17 @@ export const BusinessBasicInformation = (
181
223
  <WrapReviews>
182
224
  {!isBusinessInfoShow && (
183
225
  <>
184
- { isPreOrder && (
226
+ {isPreOrder && (
185
227
  <>
186
- <TouchableOpacity onPress={() => navigation.navigate('BusinessPreorder', { business: businessState?.business, handleBusinessClick: () => navigation?.goBack() })}>
187
- <OText color={theme.colors.textSecondary} style={{ textDecorationLine: 'underline' }}>
188
- {t('PRE_ORDER', 'Preorder')}
189
- </OText>
190
- </TouchableOpacity>
191
- <OText size={12} color={theme.colors.textSecondary}>{' \u2022 '}</OText>
228
+ <TouchableOpacity onPress={() => navigation.navigate('BusinessPreorder', { business: businessState?.business, handleBusinessClick: () => navigation?.goBack() })}>
229
+ <OText color={theme.colors.textSecondary} style={{ textDecorationLine: 'underline' }}>
230
+ {t('PRE_ORDER', 'Preorder')}
231
+ </OText>
232
+ </TouchableOpacity>
233
+ <OText size={12} color={theme.colors.textSecondary}>{' \u2022 '}</OText>
192
234
  </>
193
235
  )}
194
- <TouchableOpacity onPress={() => setOpenBusinessReviews(true)}>
236
+ <TouchableOpacity onPress={() => handleClickBusinessReviews()}>
195
237
  <OText color={theme.colors.textSecondary} style={{ textDecorationLine: 'underline' }}>
196
238
  {t('REVIEWS', 'Reviews')}
197
239
  </OText>
@@ -200,28 +242,37 @@ export const BusinessBasicInformation = (
200
242
  )}
201
243
  </WrapReviews>
202
244
  </BusinessInfo>
203
- <OModal
204
- titleSectionStyle={styles.modalTitleSectionStyle}
205
- open={openBusinessInformation}
206
- onClose={() => setOpenBusinessInformation(false)}
207
- isNotDecoration>
208
- <BusinessInformation
209
- businessState={businessState}
210
- business={business}
211
- />
212
- </OModal>
213
- <OModal
214
- entireModal
215
- titleSectionStyle={styles.modalTitleSectionStyle}
216
- open={openBusinessReviews}
217
- onClose={() => setOpenBusinessReviews(false)}
218
- isNotDecoration>
219
- <BusinessReviews
220
- businessState={businessState}
221
- businessId={business.id}
222
- reviews={business.reviews?.reviews}
223
- />
224
- </OModal>
245
+ {businessInformationObtained ? (
246
+ <OModal
247
+ titleSectionStyle={styles.modalTitleSectionStyle}
248
+ open={openBusinessInformation}
249
+ onClose={() => setOpenBusinessInformation(false)}
250
+ isNotDecoration>
251
+ {BusinessInformation && (
252
+ <BusinessInformation
253
+ businessState={businessState}
254
+ business={business}
255
+ />
256
+ )}
257
+ </OModal>
258
+ ) : null}
259
+ {businessReviewsObtained ? (
260
+ <OModal
261
+ entireModal
262
+ titleSectionStyle={styles.modalTitleSectionStyle}
263
+ open={openBusinessReviews}
264
+ onClose={() => setOpenBusinessReviews(false)}
265
+ isNotDecoration
266
+ >
267
+ {BusinessReviews && (
268
+ <BusinessReviews
269
+ businessState={businessState}
270
+ businessId={business.id}
271
+ reviews={business.reviews?.reviews}
272
+ />
273
+ )}
274
+ </OModal>
275
+ ) : null}
225
276
  </BusinessContainer>
226
277
  );
227
278
  };
@@ -1,4 +1,4 @@
1
- import styled from 'styled-components/native';
1
+ import styled, { css } from 'styled-components/native';
2
2
  import { Platform } from 'react-native';
3
3
 
4
4
  export const BusinessContainer = styled.View`
@@ -41,3 +41,30 @@ export const WrapBusinessInfo = styled.TouchableOpacity`
41
41
  top: 16px;
42
42
  end: 39px;
43
43
  `;
44
+
45
+ export const TitleWrapper = styled.View`
46
+ width: 100%;
47
+ flex-direction: row;
48
+ align-items: center;
49
+ justify-content: space-between;
50
+ `
51
+
52
+ export const RibbonBox = styled.View`
53
+ margin-left: 5px;
54
+ background-color: ${(props: any) => props.theme.colors.primary};
55
+ padding: 2px 8px;
56
+ max-width: 180px;
57
+ align-self: flex-start;
58
+
59
+ ${(props: any) => props.bgColor && css`
60
+ background-color: ${props.bgColor};
61
+ `}
62
+
63
+ ${(props: any) => props.isRoundRect && css`
64
+ border-radius: 7.6px;
65
+ `}
66
+
67
+ ${(props: any) => props.isCapsule && css`
68
+ border-radius: 50px;
69
+ `}
70
+ `
@@ -4,11 +4,12 @@ import {
4
4
  useUtils,
5
5
  useOrder,
6
6
  useLanguage,
7
+ useConfig
7
8
  } from 'ordering-components/native';
8
9
  import { OIcon, OText } from '../shared';
9
- import { StyleSheet, View } from 'react-native';
10
+ import { StyleSheet, TouchableOpacity, View } from 'react-native';
10
11
  import { BusinessControllerParams } from '../../types';
11
- import { convertHoursToMinutes } from '../../utils';
12
+ import { convertHoursToMinutes, shape } from '../../utils';
12
13
  import {
13
14
  Card,
14
15
  BusinessHero,
@@ -19,24 +20,36 @@ import {
19
20
  BusinessState,
20
21
  BusinessLogo,
21
22
  Reviews,
23
+ RibbonBox,
24
+ ReviewAndFavorite
22
25
  } from './styles';
23
26
  import { useTheme } from 'styled-components/native';
24
27
  import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome5';
28
+ import IconAntDesign from 'react-native-vector-icons/AntDesign'
25
29
  import FastImage from 'react-native-fast-image'
26
30
 
27
31
  export const BusinessControllerUI = (props: BusinessControllerParams) => {
28
- const {
29
- business,
30
- handleClick,
31
- navigation,
32
- isBusinessOpen,
33
- style
32
+ const {
33
+ business,
34
+ handleClick,
35
+ navigation,
36
+ isBusinessOpen,
37
+ style,
38
+ businessHeader,
39
+ businessFeatured,
40
+ businessLogo,
41
+ businessReviews,
42
+ businessDeliveryPrice,
43
+ businessDeliveryTime,
44
+ businessPickupTime,
45
+ businessDistance,
46
+ handleFavoriteBusiness
34
47
  } = props;
35
48
  const [{ parsePrice, parseDistance, parseNumber, optimizeImage }] = useUtils();
36
49
  const [orderState] = useOrder();
50
+ const [configState] = useConfig();
37
51
  const [, t] = useLanguage();
38
52
  const theme = useTheme()
39
-
40
53
  const styles = StyleSheet.create({
41
54
  headerStyle: {
42
55
  borderTopLeftRadius: 7.6,
@@ -110,24 +123,46 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
110
123
  }
111
124
  }
112
125
 
126
+ const handleChangeFavorite = () => {
127
+ handleFavoriteBusiness && handleFavoriteBusiness(!business?.favorite)
128
+ }
129
+
113
130
  return (
114
131
  <Card activeOpacity={1} onPress={() => handleBusinessClick(business)} style={style}>
132
+ {business?.ribbon?.enabled && (
133
+ <RibbonBox
134
+ bgColor={business?.ribbon?.color}
135
+ isRoundRect={business?.ribbon?.shape === shape?.rectangleRound}
136
+ isCapsule={business?.ribbon?.shape === shape?.capsuleShape}
137
+ >
138
+ <OText
139
+ size={10}
140
+ weight={'400'}
141
+ color={theme.colors.white}
142
+ numberOfLines={2}
143
+ ellipsizeMode='tail'
144
+ lineHeight={13}
145
+ >
146
+ {business?.ribbon?.text}
147
+ </OText>
148
+ </RibbonBox>
149
+ )}
115
150
  <BusinessHero>
116
151
  <FastImage
117
152
  style={{ height: 120 }}
118
153
  source={{
119
- uri: optimizeImage(business?.header, 'h_500,c_limit'),
120
- priority: FastImage.priority.normal,
154
+ uri: optimizeImage(businessHeader || business?.header, 'h_500,c_limit'),
155
+ priority: FastImage.priority.normal,
121
156
  }}
122
157
  resizeMode={FastImage.resizeMode.cover}
123
158
  />
124
- {business?.featured && (
159
+ {(businessFeatured ?? business?.featured) && (
125
160
  <View style={styles.featured}>
126
161
  <FontAwesomeIcon name="crown" size={26} color="gold" />
127
162
  </View>
128
163
  )}
129
164
  <BusinessState>
130
- {!isBusinessOpen && (
165
+ {!isBusinessOpen && (configState?.configs?.preorder_status_enabled?.value === '1') && (
131
166
  <View style={styles.businessStateView}>
132
167
  <OText
133
168
  color={theme.colors.textThird}
@@ -145,20 +180,31 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
145
180
  <FastImage
146
181
  style={{ width: 56, height: 56 }}
147
182
  source={{
148
- uri: optimizeImage(business?.logo, 'h_150,c_limit'),
149
- priority: FastImage.priority.normal,
183
+ uri: optimizeImage(businessLogo || business?.logo, 'h_150,c_limit'),
184
+ priority: FastImage.priority.normal,
150
185
  }}
151
186
  resizeMode={FastImage.resizeMode.cover}
152
187
  />
153
188
  </BusinessLogo>
154
- {business?.reviews?.total > 0 && (
155
- <Reviews>
156
- <OIcon src={theme.images.general.star} width={12} style={styles.starIcon} />
157
- <OText size={10} style={{ lineHeight: 15 }}>
158
- {parseNumber(business?.reviews?.total, { separator: '.' })}
159
- </OText>
160
- </Reviews>
161
- )}
189
+ <ReviewAndFavorite>
190
+ {(businessReviews?.reviews?.total > 0 ?? business?.reviews?.total > 0) && (
191
+ <Reviews>
192
+ <OIcon src={theme.images.general.star} width={12} style={styles.starIcon} />
193
+ <OText size={10} style={{ lineHeight: 15 }}>
194
+ {parseNumber(businessReviews?.reviews?.total ?? business?.reviews?.total, { separator: '.' })}
195
+ </OText>
196
+ </Reviews>
197
+ )}
198
+ <TouchableOpacity
199
+ onPress={handleChangeFavorite}
200
+ >
201
+ <IconAntDesign
202
+ name={business?.favorite ? 'heart' : 'hearto'}
203
+ color={theme.colors.danger5}
204
+ size={18}
205
+ />
206
+ </TouchableOpacity>
207
+ </ReviewAndFavorite>
162
208
  </BusinessInfo>
163
209
  <OText
164
210
  size={12}
@@ -181,15 +227,17 @@ export const BusinessControllerUI = (props: BusinessControllerParams) => {
181
227
  </View>
182
228
  ) : (
183
229
  <View style={styles.bullet}>
184
- <OText size={10} color={theme.colors.textSecondary}>
185
- {`${t('DELIVERY_FEE', 'Delivery fee')} ${parsePrice(business?.delivery_price) + ' \u2022 '}`}
186
- </OText>
230
+ {orderState?.options?.type === 1 && (
231
+ <OText size={10} color={theme.colors.textSecondary}>
232
+ {`${t('DELIVERY_FEE', 'Delivery fee')} ${parsePrice(businessDeliveryPrice ?? business?.delivery_price) + ' \u2022 '}`}
233
+ </OText>
234
+ )}
187
235
  <OText size={10} color={theme.colors.textSecondary}>{`${convertHoursToMinutes(
188
236
  orderState?.options?.type === 1
189
- ? business?.delivery_time
190
- : business?.pickup_time,
237
+ ? (businessDeliveryTime ?? business?.delivery_time)
238
+ : (businessPickupTime ?? business?.pickup_time),
191
239
  )} \u2022 `}</OText>
192
- <OText size={10} color={theme.colors.textSecondary}>{parseDistance(business?.distance)}</OText>
240
+ <OText size={10} color={theme.colors.textSecondary}>{parseDistance(businessDistance ?? business?.distance)}</OText>
193
241
  </View>
194
242
  )}
195
243
  </Metadata>