ordering-ui-react-native 0.17.11 → 0.17.12-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 (215) hide show
  1. package/package.json +5 -5
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/BusinessInformation/index.tsx +11 -4
  4. package/src/components/BusinessInformation/styles.tsx +2 -2
  5. package/src/components/BusinessesListing/index.tsx +1 -1
  6. package/src/components/OrderCreating/index.tsx +1 -21
  7. package/src/components/PaymentOptionsWebView/index.tsx +119 -120
  8. package/src/components/SingleProductReview/index.tsx +0 -24
  9. package/src/components/SingleProductReview/styles.tsx +0 -12
  10. package/src/components/StripeMethodForm/index.tsx +108 -77
  11. package/src/components/VerifyPhone/styles.tsx +1 -2
  12. package/src/components/shared/OToast.tsx +4 -4
  13. package/src/types/index.tsx +5 -0
  14. package/src/utils/index.tsx +7 -1
  15. package/themes/business/index.tsx +2 -0
  16. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +265 -240
  17. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -4
  18. package/themes/business/src/components/BusinessController/index.tsx +0 -1
  19. package/themes/business/src/components/Chat/index.tsx +118 -107
  20. package/themes/business/src/components/DriverMap/index.tsx +17 -7
  21. package/themes/business/src/components/GoogleMap/index.tsx +58 -57
  22. package/themes/business/src/components/LoginForm/Otp/index.tsx +120 -0
  23. package/themes/business/src/components/LoginForm/Otp/styles.tsx +7 -0
  24. package/themes/business/src/components/LoginForm/index.tsx +238 -80
  25. package/themes/business/src/components/LoginForm/styles.tsx +10 -0
  26. package/themes/business/src/components/MapView/index.tsx +18 -7
  27. package/themes/business/src/components/NewOrderNotification/index.tsx +43 -50
  28. package/themes/business/src/components/OrderDetails/Delivery.tsx +4 -3
  29. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +98 -50
  30. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +59 -62
  31. package/themes/business/src/components/OrderDetailsLogistic/index.tsx +195 -0
  32. package/themes/business/src/components/OrderDetailsLogistic/styles.tsx +5 -0
  33. package/themes/business/src/components/OrderMessage/index.tsx +18 -17
  34. package/themes/business/src/components/OrderSummary/index.tsx +113 -121
  35. package/themes/business/src/components/OrdersOption/index.tsx +32 -75
  36. package/themes/business/src/components/PreviousOrders/OrderItem.tsx +250 -0
  37. package/themes/business/src/components/PreviousOrders/OrdersGroupedItem.tsx +115 -0
  38. package/themes/business/src/components/PreviousOrders/index.tsx +445 -243
  39. package/themes/business/src/components/PreviousOrders/styles.tsx +31 -3
  40. package/themes/business/src/components/ProductItemAccordion/index.tsx +27 -3
  41. package/themes/business/src/components/ReviewCustomer/index.tsx +41 -24
  42. package/themes/business/src/components/StoresList/index.tsx +2 -2
  43. package/themes/business/src/components/shared/OLink.tsx +33 -13
  44. package/themes/business/src/components/shared/OModal.tsx +16 -9
  45. package/themes/business/src/components/shared/OText.tsx +8 -2
  46. package/themes/business/src/types/index.tsx +33 -2
  47. package/themes/business/src/utils/index.tsx +44 -1
  48. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  49. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  50. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  51. package/themes/kiosk/src/components/BusinessesListing/index.tsx +2 -1
  52. package/themes/kiosk/src/components/Checkout/index.tsx +6 -0
  53. package/themes/kiosk/src/components/LoginForm/Otp/index.tsx +92 -0
  54. package/themes/kiosk/src/components/LoginForm/Otp/styles.tsx +7 -0
  55. package/themes/kiosk/src/components/LoginForm/index.tsx +473 -151
  56. package/themes/kiosk/src/components/LoginForm/styles.tsx +14 -1
  57. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  58. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  59. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +8 -10
  60. package/themes/kiosk/src/components/PhoneInputNumber/index.tsx +3 -2
  61. package/themes/kiosk/src/components/PhoneInputNumber/styles.tsx +1 -3
  62. package/themes/kiosk/src/components/ProductForm/index.tsx +1 -14
  63. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  64. package/themes/kiosk/src/components/shared/OModal.tsx +14 -11
  65. package/themes/kiosk/src/layouts/Container.tsx +7 -1
  66. package/themes/kiosk/src/types/index.d.ts +13 -0
  67. package/themes/kiosk/src/utils/index.tsx +15 -0
  68. package/themes/original/index.tsx +8 -0
  69. package/themes/original/src/components/AddressDetails/index.tsx +29 -11
  70. package/themes/original/src/components/AddressForm/index.tsx +41 -16
  71. package/themes/original/src/components/AddressList/index.tsx +26 -21
  72. package/themes/original/src/components/AddressList/styles.tsx +4 -2
  73. package/themes/original/src/components/AnalyticsSegment/index.tsx +189 -9
  74. package/themes/original/src/components/AppleLogin/index.tsx +4 -4
  75. package/themes/original/src/components/BusinessBasicInformation/index.tsx +125 -82
  76. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +9 -4
  77. package/themes/original/src/components/BusinessController/index.tsx +145 -68
  78. package/themes/original/src/components/BusinessController/styles.tsx +22 -9
  79. package/themes/original/src/components/BusinessFeaturedController/index.tsx +21 -54
  80. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +8 -0
  81. package/themes/original/src/components/BusinessInformation/index.tsx +10 -31
  82. package/themes/original/src/components/BusinessItemAccordion/index.tsx +23 -22
  83. package/themes/original/src/components/BusinessListingSearch/index.tsx +350 -323
  84. package/themes/original/src/components/BusinessPreorder/index.tsx +97 -16
  85. package/themes/original/src/components/BusinessProductsList/index.tsx +20 -11
  86. package/themes/original/src/components/BusinessProductsList/styles.tsx +8 -3
  87. package/themes/original/src/components/BusinessProductsListing/index.tsx +617 -492
  88. package/themes/original/src/components/BusinessProductsListing/styles.tsx +7 -13
  89. package/themes/original/src/components/BusinessReviews/index.tsx +3 -1
  90. package/themes/original/src/components/BusinessTypeFilter/index.tsx +3 -3
  91. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +1 -1
  92. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +98 -78
  93. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +1 -9
  94. package/themes/original/src/components/BusinessesListing/index.tsx +5 -3
  95. package/themes/original/src/components/Cart/index.tsx +88 -43
  96. package/themes/original/src/components/CartContent/index.tsx +110 -19
  97. package/themes/original/src/components/CartContent/styles.tsx +15 -1
  98. package/themes/original/src/components/Checkout/index.tsx +323 -178
  99. package/themes/original/src/components/Checkout/styles.tsx +4 -2
  100. package/themes/original/src/components/CitiesControl/index.tsx +89 -0
  101. package/themes/original/src/components/CitiesControl/styles.tsx +17 -0
  102. package/themes/original/src/components/CouponControl/index.tsx +10 -3
  103. package/themes/original/src/components/DriverTips/index.tsx +52 -37
  104. package/themes/original/src/components/DriverTips/styles.tsx +2 -1
  105. package/themes/original/src/components/Favorite/index.tsx +7 -4
  106. package/themes/original/src/components/Favorite/styles.tsx +1 -1
  107. package/themes/original/src/components/FavoriteList/index.tsx +51 -80
  108. package/themes/original/src/components/FloatingButton/index.tsx +1 -2
  109. package/themes/original/src/components/FloatingButton/styles.tsx +1 -1
  110. package/themes/original/src/components/GPSButton/styles.ts +3 -3
  111. package/themes/original/src/components/GiftCard/GiftCardUI/index.tsx +96 -0
  112. package/themes/original/src/components/GiftCard/GiftCardUI/styles.tsx +5 -0
  113. package/themes/original/src/components/GiftCard/PurchaseGiftCard/index.tsx +100 -0
  114. package/themes/original/src/components/GiftCard/PurchaseGiftCard/styles.tsx +8 -0
  115. package/themes/original/src/components/GiftCard/RedeemGiftCard/index.tsx +178 -0
  116. package/themes/original/src/components/GiftCard/RedeemGiftCard/styles.tsx +8 -0
  117. package/themes/original/src/components/GiftCard/SendGiftCard/index.tsx +165 -0
  118. package/themes/original/src/components/GiftCard/SendGiftCard/styles.tsx +9 -0
  119. package/themes/original/src/components/Help/index.tsx +8 -8
  120. package/themes/original/src/components/HelpAccountAndPayment/index.tsx +11 -22
  121. package/themes/original/src/components/HelpAccountAndPayment/styles.tsx +6 -0
  122. package/themes/original/src/components/HelpGuide/index.tsx +12 -16
  123. package/themes/original/src/components/HelpGuide/styles.tsx +6 -0
  124. package/themes/original/src/components/HelpOrder/index.tsx +12 -25
  125. package/themes/original/src/components/HelpOrder/styles.tsx +8 -1
  126. package/themes/original/src/components/Home/index.tsx +13 -4
  127. package/themes/original/src/components/LanguageSelector/index.tsx +19 -14
  128. package/themes/original/src/components/LastOrder/index.tsx +1 -34
  129. package/themes/original/src/components/LoginForm/Otp/index.tsx +89 -73
  130. package/themes/original/src/components/LoginForm/Otp/styles.tsx +0 -1
  131. package/themes/original/src/components/LoginForm/index.tsx +48 -19
  132. package/themes/original/src/components/LottieAnimation/index.tsx +78 -0
  133. package/themes/original/src/components/MessageListing/index.tsx +16 -42
  134. package/themes/original/src/components/Messages/index.tsx +32 -10
  135. package/themes/original/src/components/MomentOption/index.tsx +195 -88
  136. package/themes/original/src/components/MultiCart/index.tsx +50 -0
  137. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +195 -116
  138. package/themes/original/src/components/MultiCheckout/index.tsx +262 -83
  139. package/themes/original/src/components/MultiOrdersDetails/SingleOrderCard.tsx +37 -224
  140. package/themes/original/src/components/MultiOrdersDetails/index.tsx +67 -20
  141. package/themes/original/src/components/MultiOrdersDetails/styles.tsx +1 -1
  142. package/themes/original/src/components/MyOrders/index.tsx +66 -17
  143. package/themes/original/src/components/NavBar/index.tsx +6 -11
  144. package/themes/original/src/components/Notifications/index.tsx +144 -0
  145. package/themes/original/src/components/Notifications/styles.tsx +20 -0
  146. package/themes/original/src/components/OrderDetails/OrderEta.tsx +61 -0
  147. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +10 -3
  148. package/themes/original/src/components/OrderDetails/index.tsx +262 -347
  149. package/themes/original/src/components/OrderDetails/styles.tsx +10 -1
  150. package/themes/original/src/components/OrderItAgain/index.tsx +47 -43
  151. package/themes/original/src/components/OrderProgress/index.tsx +74 -112
  152. package/themes/original/src/components/OrderProgress/styles.tsx +5 -0
  153. package/themes/original/src/components/OrderSummary/index.tsx +67 -29
  154. package/themes/original/src/components/OrderTypeSelector/index.tsx +3 -2
  155. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +28 -19
  156. package/themes/original/src/components/OrdersOption/index.tsx +99 -89
  157. package/themes/original/src/components/PageBanner/index.tsx +171 -0
  158. package/themes/original/src/components/PageBanner/styles.tsx +11 -0
  159. package/themes/original/src/components/PaymentOptionStripe/styles.tsx +1 -1
  160. package/themes/original/src/components/PaymentOptionWallet/index.tsx +56 -56
  161. package/themes/original/src/components/PaymentOptions/index.tsx +34 -6
  162. package/themes/original/src/components/PhoneInputNumber/index.tsx +3 -3
  163. package/themes/original/src/components/PlaceSpot/index.tsx +12 -6
  164. package/themes/original/src/components/PreviousOrders/index.tsx +3 -2
  165. package/themes/original/src/components/ProductForm/index.tsx +231 -253
  166. package/themes/original/src/components/ProductForm/styles.tsx +4 -7
  167. package/themes/original/src/components/ProductItemAccordion/index.tsx +197 -138
  168. package/themes/original/src/components/ProductOptionSubOption/index.tsx +18 -10
  169. package/themes/original/src/components/ProductOptionSubOption/styles.tsx +1 -2
  170. package/themes/original/src/components/ProfessionalFilter/SingleProfessionalCard/index.tsx +108 -0
  171. package/themes/original/src/components/ProfessionalFilter/index.tsx +20 -50
  172. package/themes/original/src/components/ProfessionalProfile/index.tsx +36 -7
  173. package/themes/original/src/components/Promotions/index.tsx +234 -220
  174. package/themes/original/src/components/Promotions/styles.tsx +10 -3
  175. package/themes/original/src/components/ReviewDriver/index.tsx +3 -3
  176. package/themes/original/src/components/ReviewOrder/index.tsx +26 -9
  177. package/themes/original/src/components/ReviewOrder/styles.tsx +7 -0
  178. package/themes/original/src/components/ReviewProducts/index.tsx +7 -4
  179. package/themes/original/src/components/ReviewTrigger/index.tsx +27 -9
  180. package/themes/original/src/components/ReviewTrigger/styles.tsx +8 -1
  181. package/themes/original/src/components/ScheduleAccordion/index.tsx +68 -0
  182. package/themes/original/src/components/ScheduleAccordion/styles.tsx +14 -0
  183. package/themes/original/src/components/ServiceForm/index.tsx +358 -275
  184. package/themes/original/src/components/Sessions/index.tsx +11 -8
  185. package/themes/original/src/components/Sessions/styles.tsx +5 -0
  186. package/themes/original/src/components/SignupForm/index.tsx +82 -67
  187. package/themes/original/src/components/SingleOrderCard/index.tsx +148 -62
  188. package/themes/original/src/components/SingleOrderCard/styles.tsx +11 -9
  189. package/themes/original/src/components/SingleProductCard/index.tsx +99 -55
  190. package/themes/original/src/components/SingleProductCard/styles.tsx +27 -13
  191. package/themes/original/src/components/SingleProductReview/index.tsx +38 -5
  192. package/themes/original/src/components/SingleProductReview/styles.tsx +12 -0
  193. package/themes/original/src/components/StripeCardsList/index.tsx +9 -2
  194. package/themes/original/src/components/StripeElementsForm/index.tsx +28 -15
  195. package/themes/original/src/components/UpsellingProducts/index.tsx +238 -218
  196. package/themes/original/src/components/UpsellingProducts/styles.tsx +12 -1
  197. package/themes/original/src/components/UserDetails/index.tsx +8 -4
  198. package/themes/original/src/components/UserFormDetails/index.tsx +53 -54
  199. package/themes/original/src/components/UserProfile/index.tsx +58 -35
  200. package/themes/original/src/components/UserProfile/styles.ts +17 -0
  201. package/themes/original/src/components/UserProfileForm/index.tsx +21 -28
  202. package/themes/original/src/components/UserProfileForm/styles.tsx +7 -0
  203. package/themes/original/src/components/Wallets/index.tsx +31 -17
  204. package/themes/original/src/components/Wallets/styles.tsx +2 -0
  205. package/themes/original/src/components/shared/CardAnimation.tsx +47 -0
  206. package/themes/original/src/components/shared/HeaderTitle.tsx +8 -3
  207. package/themes/original/src/components/shared/OBottomPopup.tsx +1 -1
  208. package/themes/original/src/components/shared/OButton.tsx +6 -2
  209. package/themes/original/src/components/shared/OIcon.tsx +8 -1
  210. package/themes/original/src/components/shared/OInput.tsx +10 -1
  211. package/themes/original/src/components/shared/OModal.tsx +3 -3
  212. package/themes/original/src/layouts/Container.tsx +13 -9
  213. package/themes/original/src/types/index.tsx +43 -9
  214. package/themes/original/src/utils/index.tsx +375 -58
  215. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
@@ -1,6 +1,6 @@
1
1
  import React, { useState, useEffect, useRef } from 'react'
2
2
  import { useTheme } from 'styled-components/native'
3
- import { Platform, View, StyleSheet, Dimensions, ScrollView, TouchableOpacity } from 'react-native'
3
+ import { Platform, View, StyleSheet, Dimensions, ScrollView, TouchableOpacity, Text } from 'react-native'
4
4
  import { OText, OButton, OModal, OIcon } from '../shared'
5
5
  import FastImage from 'react-native-fast-image'
6
6
  import IconAntDesign from 'react-native-vector-icons/AntDesign'
@@ -10,6 +10,10 @@ import CalendarPicker from 'react-native-calendar-picker'
10
10
  import FeatherIcon from 'react-native-vector-icons/Feather';
11
11
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
12
12
  import { ServiceFormParams } from '../../types'
13
+ import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
14
+ import uuid from 'react-native-uuid';
15
+ import { orderTypeList } from '../../utils'
16
+
13
17
  import {
14
18
  ProductForm as ProductFormController,
15
19
  useUtils,
@@ -35,14 +39,17 @@ const screenWidth = Dimensions.get('window').width
35
39
  const ServiceFormUI = (props: ServiceFormParams) => {
36
40
  const {
37
41
  professionalSelected,
38
- product,
42
+ productObject,
39
43
  handleSave,
40
44
  productCart,
41
45
  navigation,
42
46
  isSoldOut,
43
47
  maxProductQuantity,
44
48
  onClose,
45
- professionalList
49
+ professionalListState,
50
+ isCartProduct,
51
+ actionStatus,
52
+ handleCreateGuestUser
46
53
  } = props
47
54
 
48
55
  const theme = useTheme()
@@ -52,15 +59,19 @@ const ServiceFormUI = (props: ServiceFormParams) => {
52
59
  const [{ configs }] = useConfig()
53
60
  const [orderState] = useOrder()
54
61
  const [{ auth }] = useSession()
62
+ const { product, loading, error } = productObject;
55
63
 
56
64
  const [selectDate, setSelectedDate] = useState<any>(new Date())
57
65
  const [timeList, setTimeList] = useState<any>([])
58
66
  const [isEnabled, setIsEnabled] = useState(false)
59
- const [timeSelected, setTimeSelected] = useState(null)
67
+ const [timeSelected, setTimeSelected] = useState<string | null>(null)
60
68
  const [dateSelected, setDateSelected] = useState<any>(null)
61
69
  const [isOpen, setIsOpen] = useState(false)
62
70
  const [currentProfessional, setCurrentProfessional] = useState<any>(null)
63
71
 
72
+ const guestCheckoutEnabled = configs?.guest_checkout_enabled?.value === '1'
73
+ const orderTypeEnabled = !orderTypeList[orderState?.options?.type - 1] || configs?.allowed_order_types_guest_checkout?.value?.includes(orderTypeList[orderState?.options?.type - 1])
74
+
64
75
  const dropdownRef = useRef<any>(null)
65
76
 
66
77
  const styles = StyleSheet.create({
@@ -99,17 +110,41 @@ const ServiceFormUI = (props: ServiceFormParams) => {
99
110
  height: 40,
100
111
  marginBottom: 30
101
112
  },
113
+ dropDownRow: {
114
+ color: theme.colors.primary,
115
+ fontSize: 14,
116
+ marginHorizontal: 0
117
+ },
102
118
  professionalList: {
103
119
  paddingHorizontal: 40,
104
- paddingVertical: 30
120
+ paddingVertical: 30,
105
121
  }
106
122
  })
107
123
 
108
- const isBusyTime = (professional: any) => {
109
- if (professional?.busy_times?.length === 0 || !dateSelected) return false
110
- const valid = professional?.busy_times.some((item: any) => {
111
- return moment(item?.start).valueOf() <= moment(dateSelected).valueOf() &&
112
- moment(dateSelected).valueOf() <= moment(item?.end).valueOf()
124
+ const getMomentTime = (time) => {
125
+ const _moment = moment(`${moment(selectDate).format('YYYY-MM-DD')} ${time}`, 'YYYY-MM-DD HH:mm').toDate()
126
+ return _moment
127
+ }
128
+
129
+ const isBusyTime = (professional, selectedMoment) => {
130
+ if (!selectedMoment) return false
131
+ const startDay = moment(selectedMoment).utc().format('d')
132
+ const isStartScheduleEnabled = professional?.schedule?.[startDay]?.enabled
133
+ const duration = product?.duration ?? 0
134
+ const endDay = moment(selectedMoment).add(duration - 1, 'minutes').utc().format('d')
135
+ const isEndScheduleEnabled = professional?.schedule?.[endDay]?.enabled
136
+ if (!isStartScheduleEnabled || !isEndScheduleEnabled) return true
137
+
138
+ if (professional?.busy_times?.length === 0) return false
139
+
140
+ const busyTimes = isCartProduct
141
+ ? professional?.busy_times.filter(item => !(item.start === productCart?.calendar_event?.start && item.end === productCart?.calendar_event?.end))
142
+ : [...professional?.busy_times]
143
+ const valid = busyTimes.some(item => {
144
+ return (moment.utc(item?.start).local().valueOf() <= moment(selectedMoment).valueOf() &&
145
+ moment(selectedMoment).valueOf() < moment.utc(item?.end).local().valueOf()) ||
146
+ (moment.utc(item?.start).local().valueOf() < moment(selectedMoment).add(duration, 'minutes').valueOf() &&
147
+ moment(selectedMoment).add(duration, 'minutes').valueOf() < moment.utc(item?.end).local().valueOf())
113
148
  })
114
149
  return valid
115
150
  }
@@ -130,6 +165,11 @@ const ServiceFormUI = (props: ServiceFormParams) => {
130
165
  )
131
166
  }
132
167
 
168
+ const handleUpdateGuest = () => {
169
+ const guestToken = uuid.v4()
170
+ if (guestToken) handleCreateGuestUser({ guest_token: guestToken })
171
+ }
172
+
133
173
  const customDayHeaderStylesCallback = () => {
134
174
  return {
135
175
  textStyle: {
@@ -141,7 +181,7 @@ const ServiceFormUI = (props: ServiceFormParams) => {
141
181
 
142
182
  const handleSaveService = () => {
143
183
  const updated = {
144
- serviceTime: dateSelected,
184
+ serviceTime: moment(dateSelected).utc().format('YYYY-MM-DD HH:mm:00'),
145
185
  professional: currentProfessional
146
186
  }
147
187
  handleSave && handleSave(updated)
@@ -153,7 +193,7 @@ const ServiceFormUI = (props: ServiceFormParams) => {
153
193
  }
154
194
 
155
195
  const handleRedirectLogin = () => {
156
- navigation.navigate('Login', {
196
+ navigation && navigation.navigate('Login', {
157
197
  store_slug: props.businessSlug
158
198
  });
159
199
  onClose && onClose()
@@ -209,7 +249,7 @@ const ServiceFormUI = (props: ServiceFormParams) => {
209
249
  }
210
250
 
211
251
  const addressRedirect = () => {
212
- navigation.navigate('AddressList')
252
+ navigation && navigation.navigate('AddressList')
213
253
  onClose && onClose()
214
254
  }
215
255
 
@@ -234,299 +274,342 @@ const ServiceFormUI = (props: ServiceFormParams) => {
234
274
  }, [selectDate, timeSelected])
235
275
 
236
276
  useEffect(() => {
237
- if (!professionalSelected) return
277
+ if (!professionalSelected?.schedule) return
238
278
  setCurrentProfessional(professionalSelected)
239
279
  }, [professionalSelected])
280
+
281
+ useEffect(() => {
282
+ if (isCartProduct && professionalListState?.professionals?.length > 0) {
283
+ const professional = professionalListState?.professionals?.find((item: any) => item.id === professionalSelected?.id)
284
+ setCurrentProfessional(professional)
285
+ }
286
+ }, [isCartProduct, professionalListState?.professionals])
287
+
288
+ useEffect(() => {
289
+ if (!productCart?.calendar_event?.start) return
290
+ setSelectedDate(moment.utc(productCart?.calendar_event?.start).local())
291
+ setTimeSelected(moment.utc(productCart?.calendar_event?.start).local().format('HH:mm'))
292
+ }, [productCart])
240
293
 
241
294
  return (
242
295
  <>
243
- <Container>
244
- {!!product?.images ? (
245
- <ProfessionalPhoto
246
- source={{
247
- uri: product?.images
248
- }}
249
- />
250
- ) : (
251
- <OIcon
252
- src={theme?.images?.dummies?.product}
253
- cover={false}
254
- style={{ alignSelf: 'center' }}
255
- width={200}
256
- height={200}
296
+ {loading && !error && (
297
+ <Placeholder Animation={Fade}>
298
+ <PlaceholderLine
299
+ height={258}
300
+ style={{ borderRadius: 0 }}
301
+ width={screenWidth}
257
302
  />
258
- )}
259
- <InfoWrapper>
260
- <OText
261
- size={20}
262
- style={{ marginBottom: 4 }}
263
- weight={Platform.OS === 'ios' ? '600' : 'bold'}
264
- >
265
- {product?.name}
266
- </OText>
267
- <OText
268
- size={16}
269
- style={{ marginBottom: 10 }}
270
- weight={'400'}
271
- >
272
- {parsePrice(product?.price)} {product?.duration}min
273
- </OText>
274
- <OText
275
- size={14}
276
- weight={'400'}
277
- color={theme?.colors?.disabled}
278
- >
279
- {product?.description}
280
- </OText>
281
- </InfoWrapper>
282
- <Divider />
283
- <ProfessionalWrapper>
284
- <View
285
- style={{
286
- flexDirection: 'row',
287
- justifyContent: 'space-between',
288
- alignItems: 'center',
289
- marginBottom: 23
290
- }}
291
- >
303
+ </Placeholder>
304
+ )}
305
+ {!loading && !error && (
306
+ <Container>
307
+ {!!product?.images ? (
308
+ <ProfessionalPhoto
309
+ source={{
310
+ uri: product?.images
311
+ }}
312
+ />
313
+ ) : (
314
+ <OIcon
315
+ src={theme?.images?.dummies?.product}
316
+ cover={false}
317
+ style={{ alignSelf: 'center' }}
318
+ width={200}
319
+ height={200}
320
+ />
321
+ )}
322
+ <InfoWrapper>
292
323
  <OText
293
- size={16}
324
+ size={20}
325
+ style={{ marginBottom: 4 }}
294
326
  weight={Platform.OS === 'ios' ? '600' : 'bold'}
295
327
  >
296
- {t('PROFESSIONAL', 'Professional')}
328
+ {product?.name}
297
329
  </OText>
298
330
  <OText
299
- size={10}
331
+ size={16}
332
+ style={{ marginBottom: 10 }}
300
333
  weight={'400'}
301
- color={theme.colors?.danger5}
302
334
  >
303
- {t('REQUIRED', 'Required')}
335
+ {parsePrice(product?.price)} • {product?.duration}min
304
336
  </OText>
305
- </View>
306
- {currentProfessional && (
337
+ <OText
338
+ size={14}
339
+ weight={'400'}
340
+ color={theme?.colors?.disabled}
341
+ >
342
+ {product?.description}
343
+ </OText>
344
+ </InfoWrapper>
345
+ <Divider />
346
+ <ProfessionalWrapper>
347
+ <View
348
+ style={{
349
+ flexDirection: 'row',
350
+ justifyContent: 'space-between',
351
+ alignItems: 'center',
352
+ marginBottom: 23
353
+ }}
354
+ >
355
+ <OText
356
+ size={16}
357
+ weight={Platform.OS === 'ios' ? '600' : 'bold'}
358
+ >
359
+ {t('PROFESSIONAL', 'Professional')}
360
+ </OText>
361
+ <OText
362
+ size={10}
363
+ weight={'400'}
364
+ color={theme.colors?.danger5}
365
+ >
366
+ {t('REQUIRED', 'Required')}
367
+ </OText>
368
+ </View>
307
369
  <TouchableOpacity
308
370
  style={styles.professionalSelect}
309
371
  onPress={() => setIsOpen(true)}
310
372
  >
311
- <View style={{ flexDirection: 'row' }}>
312
- {!!currentProfessional?.photo ? (
313
- <FastImage
314
- style={styles.photoStyle}
315
- source={{
316
- uri: optimizeImage(currentProfessional?.photo, 'h_250,c_limit'),
317
- priority: FastImage.priority.normal,
373
+ {!!currentProfessional ? (
374
+ <>
375
+ <View style={{ flexDirection: 'row' }}>
376
+ {!!currentProfessional?.photo ? (
377
+ <FastImage
378
+ style={styles.photoStyle}
379
+ source={{
380
+ uri: optimizeImage(currentProfessional?.photo, 'h_250,c_limit'),
381
+ priority: FastImage.priority.normal,
382
+ }}
383
+ resizeMode={FastImage.resizeMode.cover}
384
+ />
385
+ ) : (
386
+ <OIcon
387
+ src={theme?.images?.general?.user}
388
+ cover={false}
389
+ style={styles.photoStyle}
390
+ />
391
+ )}
392
+ <View style={{ marginLeft: 14 }}>
393
+ <OText
394
+ size={14}
395
+ weight={'400'}
396
+ lineHeight={22}
397
+ >
398
+ {currentProfessional?.name} {currentProfessional?.lastname}
399
+ </OText>
400
+ <OText
401
+ size={12}
402
+ weight={'400'}
403
+ lineHeight={17}
404
+ color={isBusyTime(currentProfessional, dateSelected) ? theme.colors.danger5 : theme.colors.success500}
405
+ >
406
+ {isBusyTime(currentProfessional, dateSelected)
407
+ ? t('BUSY_ON_SELECTED_TIME', 'Busy on selected time')
408
+ : t('AVAILABLE', 'Available')
409
+ }
410
+ </OText>
411
+ </View>
412
+ </View>
413
+ </>
414
+ ) : (
415
+ <OText size={12}>{t('SELECT_PROFESSIONAL', 'Select professional')}</OText>
416
+ )}
417
+ <View style={{ marginLeft: 5 }}>
418
+ <IconAntDesign
419
+ name='down'
420
+ color={theme.colors.textThird}
421
+ size={12}
422
+ />
423
+ </View>
424
+ </TouchableOpacity>
425
+ </ProfessionalWrapper>
426
+ <ScheduleWrapper>
427
+ <View
428
+ style={{
429
+ flexDirection: 'row',
430
+ justifyContent: 'space-between',
431
+ alignItems: 'center',
432
+ marginBottom: 23
433
+ }}
434
+ >
435
+ <OText
436
+ size={16}
437
+ weight={Platform.OS === 'ios' ? '600' : 'bold'}
438
+ >
439
+ {t('SCHEDULE', 'Schedule')}
440
+ </OText>
441
+ <OText
442
+ size={10}
443
+ weight={'400'}
444
+ color={theme.colors?.danger5}
445
+ >
446
+ {t('REQUIRED', 'Required')}
447
+ </OText>
448
+ </View>
449
+ {!!currentProfessional?.schedule ? (
450
+ <CalendarWrapper>
451
+ {(timeList?.length > 0 && isEnabled) ? (
452
+ <SelectDropdown
453
+ ref={dropdownRef}
454
+ defaultValueByIndex={timeList.findIndex((item: any) => item.value === timeSelected)}
455
+ data={timeList}
456
+ onSelect={(selectedItem, index) => {
457
+ setTimeSelected(selectedItem?.value)
318
458
  }}
319
- resizeMode={FastImage.resizeMode.cover}
459
+ buttonTextAfterSelection={(selectedItem, index) => {
460
+ return selectedItem?.text
461
+ }}
462
+ rowTextForSelection={(item, index) => {
463
+ return item.text
464
+ }}
465
+ buttonStyle={{borderRadius: 7.6, ...styles.selectOption}}
466
+ buttonTextStyle={{
467
+ color: theme.colors.disabled,
468
+ fontSize: 14,
469
+ textAlign: 'left',
470
+ marginHorizontal: 0
471
+ }}
472
+ dropdownStyle={{
473
+ borderRadius: 8,
474
+ borderColor: theme.colors.lightGray,
475
+ marginTop: Platform.OS === 'ios' ? 12 : -top
476
+ }}
477
+ rowStyle={{
478
+ borderBottomColor: theme.colors.backgroundGray100,
479
+ backgroundColor: theme.colors.backgroundGray100,
480
+ height: 30,
481
+ flexDirection: 'column',
482
+ alignItems: 'flex-start',
483
+ paddingTop: 8,
484
+ paddingHorizontal: 12
485
+ }}
486
+ renderCustomizedRowChild={(item, index) => {
487
+ return (
488
+ <Text style={[styles.dropDownRow, { color: isBusyTime(currentProfessional, getMomentTime(item.value)) ? theme.colors.lightGray : theme.colors.primary } ]}>
489
+ {item.text}
490
+ </Text>
491
+ )
492
+ }}
493
+ renderDropdownIcon={() => dropDownIcon()}
494
+ dropdownOverlayColor='transparent'
320
495
  />
321
496
  ) : (
322
- <OIcon
323
- src={theme?.images?.general?.user}
324
- cover={false}
325
- style={styles.photoStyle}
326
- />
327
- )}
328
- <View style={{ marginLeft: 14 }}>
329
- <OText
330
- size={14}
331
- weight={'400'}
332
- lineHeight={22}
333
- >
334
- {currentProfessional?.name} {currentProfessional?.lastname}
335
- </OText>
336
497
  <OText
337
498
  size={12}
499
+ style={{ marginBottom: 30 }}
338
500
  weight={'400'}
339
- lineHeight={17}
340
- color={isBusyTime(currentProfessional) ? theme.colors.danger5 : theme.colors.success500}
501
+ color={theme.colors?.danger5}
341
502
  >
342
- {isBusyTime(currentProfessional)
343
- ? t('BUSY_ON_SELECTED_TIME', 'Busy on selected time')
344
- : t('AVAILABLE', 'Available')
345
- }
503
+ {t('PROFESSIONAL_NOT_AVAILABLE', 'Professional is not available at the moment')}
346
504
  </OText>
347
- </View>
348
- </View>
349
- <View style={{ marginLeft: 5 }}>
350
- <IconAntDesign
351
- name='down'
352
- color={theme.colors.textThird}
353
- size={12}
505
+ )}
506
+ <CalendarPicker
507
+ previousComponent={
508
+ <FeatherIcon
509
+ name='chevron-left'
510
+ color={theme.colors.disabled}
511
+ size={24}
512
+ style={{ marginHorizontal: 4 }}
513
+ />
514
+ }
515
+ nextComponent={
516
+ <FeatherIcon
517
+ name='chevron-right'
518
+ color={theme.colors.disabled}
519
+ size={24}
520
+ style={{ marginHorizontal: 4 }}
521
+ />
522
+ }
523
+ width={screenWidth - 110}
524
+ selectedDayTextColor={theme.colors.white}
525
+ selectedDayColor={theme.colors.primary}
526
+ todayBackgroundColor={theme.colors.border}
527
+ dayLabelsWrapper={{ borderColor: theme.colors.clear }}
528
+ onDateChange={onDateChange}
529
+ minDate={new Date()}
530
+ customDayHeaderStyles={customDayHeaderStylesCallback}
531
+ selectedStartDate={selectDate}
354
532
  />
355
- </View>
356
- </TouchableOpacity>
357
- )}
358
- </ProfessionalWrapper>
359
- <ScheduleWrapper>
360
- <View
361
- style={{
362
- flexDirection: 'row',
363
- justifyContent: 'space-between',
364
- alignItems: 'center',
365
- marginBottom: 23
366
- }}
367
- >
533
+ </CalendarWrapper>
534
+ ) : (
535
+ <OText
536
+ size={16}
537
+ style={{ marginBottom: 30, textAlign: 'center' }}
538
+ color={theme?.colors?.disabled}
539
+ weight={Platform.OS === 'ios' ? '600' : 'bold'}
540
+ >
541
+ {t('NO_SCHEDULE', 'No schedule')}
542
+ </OText>
543
+ )}
544
+ </ScheduleWrapper>
545
+ <ButtonWrapper>
368
546
  <OText
369
- size={16}
547
+ size={14}
370
548
  weight={Platform.OS === 'ios' ? '600' : 'bold'}
371
549
  >
372
- {t('SCHEDULE', 'Schedule')}
373
- </OText>
374
- <OText
375
- size={10}
376
- weight={'400'}
377
- color={theme.colors?.danger5}
378
- >
379
- {t('REQUIRED', 'Required')}
550
+ {dateSelected && moment(dateSelected).format('hh:mm A')}
380
551
  </OText>
381
- </View>
382
- {!!currentProfessional?.schedule ? (
383
- <CalendarWrapper>
384
- {(timeList?.length > 0 && isEnabled) ? (
385
- <SelectDropdown
386
- ref={dropdownRef}
387
- defaultValue={timeSelected}
388
- data={timeList}
389
- onSelect={(selectedItem, index) => {
390
- setTimeSelected(selectedItem?.value)
391
- }}
392
- buttonTextAfterSelection={(selectedItem, index) => {
393
- return selectedItem?.text
394
- }}
395
- rowTextForSelection={(item, index) => {
396
- return item.text
397
- }}
398
- buttonStyle={{borderRadius: 7.6, ...styles.selectOption}}
399
- buttonTextStyle={{
400
- color: theme.colors.disabled,
401
- fontSize: 14,
402
- textAlign: 'left',
403
- marginHorizontal: 0
404
- }}
405
- dropdownStyle={{
406
- borderRadius: 8,
407
- borderColor: theme.colors.lightGray,
408
- marginTop: Platform.OS === 'ios' ? 12 : -top
409
- }}
410
- rowStyle={{
411
- borderBottomColor: theme.colors.backgroundGray100,
412
- backgroundColor: theme.colors.backgroundGray100,
413
- height: 30,
414
- flexDirection: 'column',
415
- alignItems: 'flex-start',
416
- paddingTop: 8,
417
- paddingHorizontal: 12
418
- }}
419
- rowTextStyle={{
420
- color: theme.colors.disabled,
421
- fontSize: 14,
422
- marginHorizontal: 0
423
- }}
424
- renderDropdownIcon={() => dropDownIcon()}
425
- dropdownOverlayColor='transparent'
552
+ {((productCart &&
553
+ auth &&
554
+ orderState.options?.address_id)) && (
555
+ <OButton
556
+ bgColor={theme.colors.primary}
557
+ onClick={() => handleSaveService()}
558
+ text={orderState.loading
559
+ ? t('LOADING', 'Loading')
560
+ : ((isSoldOut || maxProductQuantity <= 0)
561
+ ? t('SOLD_OUT', 'Sold out')
562
+ : t('BOOK', 'Book'))}
563
+ style={styles.buttonStyle}
564
+ isDisabled={isSoldOut || maxProductQuantity <= 0 || !currentProfessional?.id || !dateSelected || isBusyTime(currentProfessional, dateSelected)}
565
+ textStyle={{ fontSize: 14, color: theme.colors.white }}
566
+ />
567
+ )}
568
+ {auth &&
569
+ !orderState.options?.address_id &&
570
+ (orderState.loading ? (
571
+ <OButton
572
+ isDisabled
573
+ text={t('LOADING', 'Loading')}
574
+ imgRightSrc=""
575
+ textStyle={{ fontSize: 10 }}
426
576
  />
427
577
  ) : (
428
- <OText
429
- size={12}
430
- style={{ marginBottom: 30 }}
431
- weight={'400'}
432
- color={theme.colors?.danger5}
433
- >
434
- {t('PROFESSIONAL_NOT_AVAILABLE', 'Professional is not available at the moment')}
435
- </OText>
578
+ <OButton onClick={() => addressRedirect()} />
579
+ ))}
580
+ {!auth && (
581
+ <OButton
582
+ isDisabled={isSoldOut || maxProductQuantity <= 0}
583
+ onClick={() => handleRedirectLogin()}
584
+ text={
585
+ isSoldOut || maxProductQuantity <= 0
586
+ ? t('SOLD_OUT', 'Sold out')
587
+ : t('LOGIN_SIGNUP', 'Login / Sign Up')
588
+ }
589
+ imgRightSrc=""
590
+ textStyle={{ color: theme.colors.primary, fontSize: 14 }}
591
+ style={{
592
+ height: 44,
593
+ borderColor: theme.colors.primary,
594
+ backgroundColor: theme.colors.white,
595
+ }}
596
+ />
436
597
  )}
437
- <CalendarPicker
438
- previousComponent={
439
- <FeatherIcon
440
- name='chevron-left'
441
- color={theme.colors.disabled}
442
- size={24}
443
- style={{ marginHorizontal: 4 }}
444
- />
445
- }
446
- nextComponent={
447
- <FeatherIcon
448
- name='chevron-right'
449
- color={theme.colors.disabled}
450
- size={24}
451
- style={{ marginHorizontal: 4 }}
452
- />
453
- }
454
- width={screenWidth - 110}
455
- selectedDayTextColor={theme.colors.white}
456
- selectedDayColor={theme.colors.primary}
457
- todayBackgroundColor={theme.colors.border}
458
- dayLabelsWrapper={{ borderColor: theme.colors.clear }}
459
- onDateChange={onDateChange}
460
- minDate={new Date()}
461
- customDayHeaderStyles={customDayHeaderStylesCallback}
462
- selectedStartDate={selectDate}
463
- />
464
- </CalendarWrapper>
465
- ) : (
466
- <OText
467
- size={20}
468
- style={{ marginBottom: 30 }}
469
- weight={Platform.OS === 'ios' ? '600' : 'bold'}
470
- >
471
- {t('NO_SCHEDULE', 'No schedule')}
472
- </OText>
473
- )}
474
- </ScheduleWrapper>
475
- <ButtonWrapper>
476
- <OText
477
- size={14}
478
- weight={Platform.OS === 'ios' ? '600' : 'bold'}
479
- >
480
- {dateSelected && moment(dateSelected).format('hh:mm A')}
481
- </OText>
482
- {((productCart &&
483
- auth &&
484
- orderState.options?.address_id)) && (
485
- <OButton
486
- bgColor={theme.colors.primary}
487
- onClick={() => handleSaveService()}
488
- text={orderState.loading
489
- ? t('LOADING', 'Loading')
490
- : ((isSoldOut || maxProductQuantity <= 0)
491
- ? t('SOLD_OUT', 'Sold out')
492
- : t('BOOK', 'Book'))}
493
- style={styles.buttonStyle}
494
- isDisabled={isSoldOut || maxProductQuantity <= 0 || !currentProfessional?.id || !dateSelected}
495
- textStyle={{ fontSize: 14, color: theme.colors.white }}
496
- />
497
- )}
498
- {auth &&
499
- !orderState.options?.address_id &&
500
- (orderState.loading ? (
501
- <OButton
502
- isDisabled
503
- text={t('LOADING', 'Loading')}
504
- imgRightSrc=""
505
- textStyle={{ fontSize: 10 }}
506
- />
507
- ) : (
508
- <OButton onClick={() => addressRedirect()} />
509
- ))}
510
- {!auth && (
511
- <OButton
512
- isDisabled={isSoldOut || maxProductQuantity <= 0}
513
- onClick={() => handleRedirectLogin()}
514
- text={
515
- isSoldOut || maxProductQuantity <= 0
516
- ? t('SOLD_OUT', 'Sold out')
517
- : t('LOGIN_SIGNUP', 'Login / Sign Up')
518
- }
519
- imgRightSrc=""
520
- textStyle={{ color: theme.colors.primary, fontSize: 14 }}
521
- style={{
522
- height: 44,
523
- borderColor: theme.colors.primary,
524
- backgroundColor: theme.colors.white,
525
- }}
526
- />
527
- )}
528
- </ButtonWrapper>
529
- </Container>
598
+ {!auth && guestCheckoutEnabled && orderTypeEnabled && (
599
+ <TouchableOpacity style={{ marginTop: 10 }} onPress={handleUpdateGuest}>
600
+ {actionStatus?.loading ? (
601
+ <Placeholder Animation={Fade}>
602
+ <PlaceholderLine width={60} height={20} />
603
+ </Placeholder>
604
+ ) : (
605
+ <OText color={theme.colors.primary} size={13}>{t('WITH_GUEST_USER', 'With Guest user')}</OText>
606
+ )}
607
+ </TouchableOpacity>
608
+ )}
609
+ </ButtonWrapper>
610
+ </Container>
611
+ )}
612
+
530
613
  <OModal
531
614
  open={isOpen}
532
615
  onClose={() => setIsOpen(false)}
@@ -541,7 +624,7 @@ const ServiceFormUI = (props: ServiceFormParams) => {
541
624
  {t('ANY_OROFESSIONAL_MEMBER', 'Any professional member')}
542
625
  </OText>
543
626
  </View>
544
- {professionalList?.map((professional: any) => professional?.products?.includes(product?.id) && (
627
+ {professionalListState?.professionals?.map((professional: any) => (
545
628
  <TouchableOpacity
546
629
  key={professional?.id}
547
630
  style={styles.professionalItem}
@@ -576,9 +659,9 @@ const ServiceFormUI = (props: ServiceFormParams) => {
576
659
  size={12}
577
660
  weight={'400'}
578
661
  lineHeight={17}
579
- color={isBusyTime(professional) ? theme.colors.danger5 : theme.colors.success500}
662
+ color={isBusyTime(professional, dateSelected) ? theme.colors.danger5 : theme.colors.success500}
580
663
  >
581
- {isBusyTime(professional)
664
+ {isBusyTime(professional, dateSelected)
582
665
  ? t('BUSY_ON_SELECTED_TIME', 'Busy on selected time')
583
666
  : t('AVAILABLE', 'Available')
584
667
  }