ordering-ui-react-native 0.17.18 → 0.17.19-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 (209) hide show
  1. package/package.json +5 -7
  2. package/src/DeliveryApp.tsx +43 -1
  3. package/src/components/BusinessesListing/index.tsx +1 -1
  4. package/src/components/OrderCreating/index.tsx +1 -21
  5. package/src/components/PaymentOptionsWebView/index.tsx +119 -120
  6. package/src/components/StripeMethodForm/index.tsx +108 -79
  7. package/src/components/VerifyPhone/styles.tsx +1 -2
  8. package/src/components/shared/OToast.tsx +4 -4
  9. package/src/types/index.tsx +5 -0
  10. package/src/utils/index.tsx +7 -1
  11. package/themes/business/index.tsx +2 -0
  12. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +265 -240
  13. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +6 -4
  14. package/themes/business/src/components/BusinessController/index.tsx +0 -1
  15. package/themes/business/src/components/Chat/index.tsx +118 -107
  16. package/themes/business/src/components/DriverMap/index.tsx +17 -6
  17. package/themes/business/src/components/GoogleMap/index.tsx +58 -57
  18. package/themes/business/src/components/LoginForm/Otp/index.tsx +120 -0
  19. package/themes/business/src/components/LoginForm/Otp/styles.tsx +7 -0
  20. package/themes/business/src/components/LoginForm/index.tsx +238 -80
  21. package/themes/business/src/components/LoginForm/styles.tsx +10 -0
  22. package/themes/business/src/components/MapView/index.tsx +10 -10
  23. package/themes/business/src/components/NewOrderNotification/index.tsx +43 -50
  24. package/themes/business/src/components/OrderDetails/Delivery.tsx +4 -3
  25. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +90 -47
  26. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +59 -62
  27. package/themes/business/src/components/OrderDetailsLogistic/index.tsx +195 -0
  28. package/themes/business/src/components/OrderDetailsLogistic/styles.tsx +5 -0
  29. package/themes/business/src/components/OrderMessage/index.tsx +18 -17
  30. package/themes/business/src/components/OrderSummary/index.tsx +113 -121
  31. package/themes/business/src/components/OrdersOption/index.tsx +32 -75
  32. package/themes/business/src/components/PreviousOrders/OrderItem.tsx +250 -0
  33. package/themes/business/src/components/PreviousOrders/OrdersGroupedItem.tsx +115 -0
  34. package/themes/business/src/components/PreviousOrders/index.tsx +445 -243
  35. package/themes/business/src/components/PreviousOrders/styles.tsx +31 -3
  36. package/themes/business/src/components/ProductItemAccordion/index.tsx +27 -3
  37. package/themes/business/src/components/ReviewCustomer/index.tsx +41 -24
  38. package/themes/business/src/components/StoresList/index.tsx +2 -2
  39. package/themes/business/src/components/shared/OLink.tsx +33 -13
  40. package/themes/business/src/components/shared/OModal.tsx +16 -9
  41. package/themes/business/src/components/shared/OText.tsx +8 -2
  42. package/themes/business/src/types/index.tsx +32 -2
  43. package/themes/business/src/utils/index.tsx +44 -1
  44. package/themes/doordash/src/components/BusinessesListing/index.tsx +1 -1
  45. package/themes/doordash/src/components/LoginForm/index.tsx +1 -2
  46. package/themes/instacart/src/components/BusinessesListing/index.tsx +1 -1
  47. package/themes/kiosk/src/components/BusinessesListing/index.tsx +2 -1
  48. package/themes/kiosk/src/components/Checkout/index.tsx +6 -0
  49. package/themes/kiosk/src/components/LoginForm/Otp/index.tsx +92 -0
  50. package/themes/kiosk/src/components/LoginForm/Otp/styles.tsx +7 -0
  51. package/themes/kiosk/src/components/LoginForm/index.tsx +473 -151
  52. package/themes/kiosk/src/components/LoginForm/styles.tsx +14 -1
  53. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  54. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  55. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +8 -10
  56. package/themes/kiosk/src/components/PhoneInputNumber/index.tsx +3 -2
  57. package/themes/kiosk/src/components/PhoneInputNumber/styles.tsx +1 -3
  58. package/themes/kiosk/src/components/ProductForm/index.tsx +1 -14
  59. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  60. package/themes/kiosk/src/components/shared/OModal.tsx +14 -11
  61. package/themes/kiosk/src/layouts/Container.tsx +7 -1
  62. package/themes/kiosk/src/types/index.d.ts +13 -0
  63. package/themes/kiosk/src/utils/index.tsx +15 -0
  64. package/themes/original/index.tsx +10 -2
  65. package/themes/original/src/components/AddressDetails/index.tsx +29 -11
  66. package/themes/original/src/components/AddressForm/index.tsx +41 -16
  67. package/themes/original/src/components/AddressList/index.tsx +26 -21
  68. package/themes/original/src/components/AddressList/styles.tsx +4 -2
  69. package/themes/original/src/components/AnalyticsSegment/index.tsx +195 -12
  70. package/themes/original/src/components/AppleLogin/index.tsx +4 -4
  71. package/themes/original/src/components/BusinessBasicInformation/index.tsx +166 -89
  72. package/themes/original/src/components/BusinessBasicInformation/styles.tsx +9 -7
  73. package/themes/original/src/components/BusinessController/index.tsx +145 -68
  74. package/themes/original/src/components/BusinessController/styles.tsx +22 -9
  75. package/themes/original/src/components/BusinessFeaturedController/index.tsx +21 -54
  76. package/themes/original/src/components/BusinessFeaturedController/styles.tsx +8 -0
  77. package/themes/original/src/components/BusinessInformation/index.tsx +10 -31
  78. package/themes/original/src/components/BusinessItemAccordion/index.tsx +23 -22
  79. package/themes/original/src/components/BusinessListingSearch/index.tsx +350 -323
  80. package/themes/original/src/components/BusinessPreorder/index.tsx +97 -16
  81. package/themes/original/src/components/BusinessProductsList/index.tsx +20 -11
  82. package/themes/original/src/components/BusinessProductsList/styles.tsx +8 -3
  83. package/themes/original/src/components/BusinessProductsListing/index.tsx +616 -495
  84. package/themes/original/src/components/BusinessProductsListing/styles.tsx +7 -9
  85. package/themes/original/src/components/BusinessReviews/index.tsx +3 -1
  86. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +1 -1
  87. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +105 -78
  88. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +1 -9
  89. package/themes/original/src/components/BusinessesListing/index.tsx +5 -3
  90. package/themes/original/src/components/Cart/index.tsx +88 -43
  91. package/themes/original/src/components/CartContent/index.tsx +110 -19
  92. package/themes/original/src/components/CartContent/styles.tsx +15 -1
  93. package/themes/original/src/components/Checkout/index.tsx +323 -178
  94. package/themes/original/src/components/Checkout/styles.tsx +4 -2
  95. package/themes/original/src/components/CitiesControl/index.tsx +89 -0
  96. package/themes/original/src/components/CitiesControl/styles.tsx +17 -0
  97. package/themes/original/src/components/CouponControl/index.tsx +10 -3
  98. package/themes/original/src/components/DriverTips/index.tsx +49 -34
  99. package/themes/original/src/components/Favorite/index.tsx +7 -4
  100. package/themes/original/src/components/Favorite/styles.tsx +1 -1
  101. package/themes/original/src/components/FavoriteList/index.tsx +51 -80
  102. package/themes/original/src/components/FloatingButton/index.tsx +1 -2
  103. package/themes/original/src/components/FloatingButton/styles.tsx +1 -1
  104. package/themes/original/src/components/GPSButton/styles.ts +3 -3
  105. package/themes/original/src/components/GiftCard/GiftCardUI/index.tsx +96 -0
  106. package/themes/original/src/components/GiftCard/GiftCardUI/styles.tsx +5 -0
  107. package/themes/original/src/components/GiftCard/PurchaseGiftCard/index.tsx +100 -0
  108. package/themes/original/src/components/GiftCard/PurchaseGiftCard/styles.tsx +8 -0
  109. package/themes/original/src/components/GiftCard/RedeemGiftCard/index.tsx +178 -0
  110. package/themes/original/src/components/GiftCard/RedeemGiftCard/styles.tsx +8 -0
  111. package/themes/original/src/components/GiftCard/SendGiftCard/index.tsx +165 -0
  112. package/themes/original/src/components/GiftCard/SendGiftCard/styles.tsx +9 -0
  113. package/themes/original/src/components/Help/index.tsx +8 -8
  114. package/themes/original/src/components/HelpAccountAndPayment/index.tsx +11 -22
  115. package/themes/original/src/components/HelpAccountAndPayment/styles.tsx +6 -0
  116. package/themes/original/src/components/HelpGuide/index.tsx +12 -16
  117. package/themes/original/src/components/HelpGuide/styles.tsx +6 -0
  118. package/themes/original/src/components/HelpOrder/index.tsx +12 -25
  119. package/themes/original/src/components/HelpOrder/styles.tsx +8 -1
  120. package/themes/original/src/components/Home/index.tsx +13 -4
  121. package/themes/original/src/components/LanguageSelector/index.tsx +19 -14
  122. package/themes/original/src/components/LastOrder/index.tsx +1 -34
  123. package/themes/original/src/components/LoginForm/Otp/index.tsx +89 -73
  124. package/themes/original/src/components/LoginForm/Otp/styles.tsx +0 -1
  125. package/themes/original/src/components/LoginForm/index.tsx +59 -22
  126. package/themes/original/src/components/LottieAnimation/index.tsx +78 -0
  127. package/themes/original/src/components/MessageListing/index.tsx +16 -42
  128. package/themes/original/src/components/Messages/index.tsx +32 -10
  129. package/themes/original/src/components/MomentOption/index.tsx +195 -88
  130. package/themes/original/src/components/MultiCart/index.tsx +50 -0
  131. package/themes/original/src/components/MultiCartsPaymethodsAndWallets/index.tsx +197 -116
  132. package/themes/original/src/components/MultiCheckout/index.tsx +264 -85
  133. package/themes/original/src/components/MultiOrdersDetails/SingleOrderCard.tsx +37 -224
  134. package/themes/original/src/components/MultiOrdersDetails/index.tsx +67 -20
  135. package/themes/original/src/components/MultiOrdersDetails/styles.tsx +1 -1
  136. package/themes/original/src/components/MyOrders/index.tsx +55 -51
  137. package/themes/original/src/components/NavBar/index.tsx +6 -11
  138. package/themes/original/src/components/Notifications/index.tsx +144 -0
  139. package/themes/original/src/components/Notifications/styles.tsx +20 -0
  140. package/themes/original/src/components/OrderDetails/OrderEta.tsx +64 -0
  141. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +15 -3
  142. package/themes/original/src/components/OrderDetails/index.tsx +262 -347
  143. package/themes/original/src/components/OrderDetails/styles.tsx +10 -1
  144. package/themes/original/src/components/OrderItAgain/index.tsx +4 -2
  145. package/themes/original/src/components/OrderProgress/index.tsx +74 -112
  146. package/themes/original/src/components/OrderProgress/styles.tsx +5 -0
  147. package/themes/original/src/components/OrderSummary/index.tsx +67 -29
  148. package/themes/original/src/components/OrderTypeSelector/index.tsx +3 -2
  149. package/themes/original/src/components/OrdersOption/PreviousBusinessOrdered/index.tsx +24 -19
  150. package/themes/original/src/components/OrdersOption/index.tsx +96 -88
  151. package/themes/original/src/components/PageBanner/index.tsx +171 -0
  152. package/themes/original/src/components/PageBanner/styles.tsx +11 -0
  153. package/themes/original/src/components/PaymentOptionStripe/styles.tsx +1 -1
  154. package/themes/original/src/components/PaymentOptionWallet/index.tsx +56 -56
  155. package/themes/original/src/components/PaymentOptions/index.tsx +34 -6
  156. package/themes/original/src/components/PhoneInputNumber/index.tsx +3 -3
  157. package/themes/original/src/components/PlaceSpot/index.tsx +12 -6
  158. package/themes/original/src/components/PreviousOrders/index.tsx +3 -2
  159. package/themes/original/src/components/ProductForm/index.tsx +231 -253
  160. package/themes/original/src/components/ProductForm/styles.tsx +4 -7
  161. package/themes/original/src/components/ProductItemAccordion/index.tsx +197 -138
  162. package/themes/original/src/components/ProductOptionSubOption/index.tsx +18 -10
  163. package/themes/original/src/components/ProductOptionSubOption/styles.tsx +1 -2
  164. package/themes/original/src/components/ProfessionalFilter/SingleProfessionalCard/index.tsx +108 -0
  165. package/themes/original/src/components/ProfessionalFilter/index.tsx +20 -50
  166. package/themes/original/src/components/ProfessionalProfile/index.tsx +36 -7
  167. package/themes/original/src/components/Promotions/index.tsx +234 -220
  168. package/themes/original/src/components/Promotions/styles.tsx +10 -3
  169. package/themes/original/src/components/ReviewDriver/index.tsx +3 -3
  170. package/themes/original/src/components/ReviewOrder/index.tsx +26 -9
  171. package/themes/original/src/components/ReviewOrder/styles.tsx +7 -0
  172. package/themes/original/src/components/ReviewProducts/index.tsx +7 -4
  173. package/themes/original/src/components/ReviewTrigger/index.tsx +27 -9
  174. package/themes/original/src/components/ReviewTrigger/styles.tsx +8 -1
  175. package/themes/original/src/components/ScheduleAccordion/index.tsx +68 -0
  176. package/themes/original/src/components/ScheduleAccordion/styles.tsx +14 -0
  177. package/themes/original/src/components/ServiceForm/index.tsx +366 -288
  178. package/themes/original/src/components/Sessions/index.tsx +11 -8
  179. package/themes/original/src/components/Sessions/styles.tsx +5 -0
  180. package/themes/original/src/components/SignupForm/index.tsx +82 -67
  181. package/themes/original/src/components/SingleOrderCard/index.tsx +148 -62
  182. package/themes/original/src/components/SingleOrderCard/styles.tsx +11 -9
  183. package/themes/original/src/components/SingleProductCard/index.tsx +99 -55
  184. package/themes/original/src/components/SingleProductCard/styles.tsx +27 -13
  185. package/themes/original/src/components/SingleProductReview/index.tsx +8 -2
  186. package/themes/original/src/components/SingleProductReview/styles.tsx +1 -1
  187. package/themes/original/src/components/StripeCardsList/index.tsx +9 -2
  188. package/themes/original/src/components/StripeElementsForm/index.tsx +28 -15
  189. package/themes/original/src/components/UpsellingProducts/index.tsx +238 -224
  190. package/themes/original/src/components/UpsellingProducts/styles.tsx +12 -1
  191. package/themes/original/src/components/UserDetails/index.tsx +8 -4
  192. package/themes/original/src/components/UserFormDetails/index.tsx +53 -54
  193. package/themes/original/src/components/UserProfile/index.tsx +57 -41
  194. package/themes/original/src/components/UserProfile/styles.ts +17 -0
  195. package/themes/original/src/components/UserProfileForm/index.tsx +21 -28
  196. package/themes/original/src/components/UserProfileForm/styles.tsx +7 -0
  197. package/themes/original/src/components/Wallets/index.tsx +31 -17
  198. package/themes/original/src/components/Wallets/styles.tsx +2 -0
  199. package/themes/original/src/components/shared/CardAnimation.tsx +47 -0
  200. package/themes/original/src/components/shared/HeaderTitle.tsx +8 -3
  201. package/themes/original/src/components/shared/OBottomPopup.tsx +1 -1
  202. package/themes/original/src/components/shared/OButton.tsx +6 -2
  203. package/themes/original/src/components/shared/OIcon.tsx +8 -1
  204. package/themes/original/src/components/shared/OInput.tsx +10 -1
  205. package/themes/original/src/components/shared/OModal.tsx +3 -3
  206. package/themes/original/src/layouts/Container.tsx +13 -9
  207. package/themes/original/src/types/index.tsx +41 -10
  208. package/themes/original/src/utils/index.tsx +375 -58
  209. 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: {
@@ -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,304 +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')}
297
- </OText>
298
- <OText
299
- size={10}
300
- weight={'400'}
301
- color={theme.colors?.danger5}
302
- >
303
- {t('REQUIRED', 'Required')}
328
+ {product?.name}
304
329
  </OText>
305
- </View>
306
- <TouchableOpacity
307
- style={styles.professionalSelect}
308
- onPress={() => setIsOpen(true)}
309
- >
310
- {!!currentProfessional ? (
311
- <>
312
- <View style={{ flexDirection: 'row' }}>
313
- {!!currentProfessional?.photo ? (
314
- <FastImage
315
- style={styles.photoStyle}
316
- source={{
317
- uri: optimizeImage(currentProfessional?.photo, 'h_250,c_limit'),
318
- priority: FastImage.priority.normal,
319
- }}
320
- resizeMode={FastImage.resizeMode.cover}
321
- />
322
- ) : (
323
- <OIcon
324
- src={theme?.images?.general?.user}
325
- cover={false}
326
- style={styles.photoStyle}
327
- />
328
- )}
329
- <View style={{ marginLeft: 14 }}>
330
- <OText
331
- size={14}
332
- weight={'400'}
333
- lineHeight={22}
334
- >
335
- {currentProfessional?.name} {currentProfessional?.lastname}
336
- </OText>
337
- <OText
338
- size={12}
339
- weight={'400'}
340
- lineHeight={17}
341
- color={isBusyTime(currentProfessional) ? theme.colors.danger5 : theme.colors.success500}
342
- >
343
- {isBusyTime(currentProfessional)
344
- ? t('BUSY_ON_SELECTED_TIME', 'Busy on selected time')
345
- : t('AVAILABLE', 'Available')
346
- }
347
- </OText>
348
- </View>
349
- </View>
350
- </>
351
- ) : (
352
- <OText size={12}>{t('SELECT_PROFESSIONAL', 'Select professional')}</OText>
353
- )}
354
- <View style={{ marginLeft: 5 }}>
355
- <IconAntDesign
356
- name='down'
357
- color={theme.colors.textThird}
358
- size={12}
359
- />
360
- </View>
361
- </TouchableOpacity>
362
- </ProfessionalWrapper>
363
- <ScheduleWrapper>
364
- <View
365
- style={{
366
- flexDirection: 'row',
367
- justifyContent: 'space-between',
368
- alignItems: 'center',
369
- marginBottom: 23
370
- }}
371
- >
372
330
  <OText
373
331
  size={16}
374
- weight={Platform.OS === 'ios' ? '600' : 'bold'}
332
+ style={{ marginBottom: 10 }}
333
+ weight={'400'}
375
334
  >
376
- {t('SCHEDULE', 'Schedule')}
335
+ {parsePrice(product?.price)} • {product?.duration}min
377
336
  </OText>
378
337
  <OText
379
- size={10}
338
+ size={14}
380
339
  weight={'400'}
381
- color={theme.colors?.danger5}
340
+ color={theme?.colors?.disabled}
382
341
  >
383
- {t('REQUIRED', 'Required')}
342
+ {product?.description}
384
343
  </OText>
385
- </View>
386
- {!!currentProfessional?.schedule ? (
387
- <CalendarWrapper>
388
- {(timeList?.length > 0 && isEnabled) ? (
389
- <SelectDropdown
390
- ref={dropdownRef}
391
- defaultValue={timeSelected}
392
- data={timeList}
393
- onSelect={(selectedItem, index) => {
394
- setTimeSelected(selectedItem?.value)
395
- }}
396
- buttonTextAfterSelection={(selectedItem, index) => {
397
- return selectedItem?.text
398
- }}
399
- rowTextForSelection={(item, index) => {
400
- return item.text
401
- }}
402
- buttonStyle={{borderRadius: 7.6, ...styles.selectOption}}
403
- buttonTextStyle={{
404
- color: theme.colors.disabled,
405
- fontSize: 14,
406
- textAlign: 'left',
407
- marginHorizontal: 0
408
- }}
409
- dropdownStyle={{
410
- borderRadius: 8,
411
- borderColor: theme.colors.lightGray,
412
- marginTop: Platform.OS === 'ios' ? 12 : -top
413
- }}
414
- rowStyle={{
415
- borderBottomColor: theme.colors.backgroundGray100,
416
- backgroundColor: theme.colors.backgroundGray100,
417
- height: 30,
418
- flexDirection: 'column',
419
- alignItems: 'flex-start',
420
- paddingTop: 8,
421
- paddingHorizontal: 12
422
- }}
423
- rowTextStyle={{
424
- color: theme.colors.disabled,
425
- fontSize: 14,
426
- marginHorizontal: 0
427
- }}
428
- renderDropdownIcon={() => dropDownIcon()}
429
- dropdownOverlayColor='transparent'
430
- />
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>
369
+ <TouchableOpacity
370
+ style={styles.professionalSelect}
371
+ onPress={() => setIsOpen(true)}
372
+ >
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
+ </>
431
414
  ) : (
432
- <OText
433
- size={12}
434
- style={{ marginBottom: 30 }}
435
- weight={'400'}
436
- color={theme.colors?.danger5}
437
- >
438
- {t('PROFESSIONAL_NOT_AVAILABLE', 'Professional is not available at the moment')}
439
- </OText>
415
+ <OText size={12}>{t('SELECT_PROFESSIONAL', 'Select professional')}</OText>
440
416
  )}
441
- <CalendarPicker
442
- previousComponent={
443
- <FeatherIcon
444
- name='chevron-left'
445
- color={theme.colors.disabled}
446
- size={24}
447
- style={{ marginHorizontal: 4 }}
448
- />
449
- }
450
- nextComponent={
451
- <FeatherIcon
452
- name='chevron-right'
453
- color={theme.colors.disabled}
454
- size={24}
455
- style={{ marginHorizontal: 4 }}
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)
458
+ }}
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'
456
495
  />
457
- }
458
- width={screenWidth - 110}
459
- selectedDayTextColor={theme.colors.white}
460
- selectedDayColor={theme.colors.primary}
461
- todayBackgroundColor={theme.colors.border}
462
- dayLabelsWrapper={{ borderColor: theme.colors.clear }}
463
- onDateChange={onDateChange}
464
- minDate={new Date()}
465
- customDayHeaderStyles={customDayHeaderStylesCallback}
466
- selectedStartDate={selectDate}
467
- />
468
- </CalendarWrapper>
469
- ) : (
496
+ ) : (
497
+ <OText
498
+ size={12}
499
+ style={{ marginBottom: 30 }}
500
+ weight={'400'}
501
+ color={theme.colors?.danger5}
502
+ >
503
+ {t('PROFESSIONAL_NOT_AVAILABLE', 'Professional is not available at the moment')}
504
+ </OText>
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}
532
+ />
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>
470
546
  <OText
471
- size={16}
472
- style={{ marginBottom: 30, textAlign: 'center' }}
473
- color={theme?.colors?.disabled}
547
+ size={14}
474
548
  weight={Platform.OS === 'ios' ? '600' : 'bold'}
475
549
  >
476
- {t('NO_SCHEDULE', 'No schedule')}
550
+ {dateSelected && moment(dateSelected).format('hh:mm A')}
477
551
  </OText>
478
- )}
479
- </ScheduleWrapper>
480
- <ButtonWrapper>
481
- <OText
482
- size={14}
483
- weight={Platform.OS === 'ios' ? '600' : 'bold'}
484
- >
485
- {dateSelected && moment(dateSelected).format('hh:mm A')}
486
- </OText>
487
- {((productCart &&
488
- auth &&
489
- orderState.options?.address_id)) && (
490
- <OButton
491
- bgColor={theme.colors.primary}
492
- onClick={() => handleSaveService()}
493
- text={orderState.loading
494
- ? t('LOADING', 'Loading')
495
- : ((isSoldOut || maxProductQuantity <= 0)
496
- ? t('SOLD_OUT', 'Sold out')
497
- : t('BOOK', 'Book'))}
498
- style={styles.buttonStyle}
499
- isDisabled={isSoldOut || maxProductQuantity <= 0 || !currentProfessional?.id || !dateSelected}
500
- textStyle={{ fontSize: 14, color: theme.colors.white }}
501
- />
502
- )}
503
- {auth &&
504
- !orderState.options?.address_id &&
505
- (orderState.loading ? (
506
- <OButton
507
- isDisabled
508
- text={t('LOADING', 'Loading')}
509
- imgRightSrc=""
510
- textStyle={{ fontSize: 10 }}
511
- />
512
- ) : (
513
- <OButton onClick={() => addressRedirect()} />
514
- ))}
515
- {!auth && (
516
- <OButton
517
- isDisabled={isSoldOut || maxProductQuantity <= 0}
518
- onClick={() => handleRedirectLogin()}
519
- text={
520
- isSoldOut || maxProductQuantity <= 0
521
- ? t('SOLD_OUT', 'Sold out')
522
- : t('LOGIN_SIGNUP', 'Login / Sign Up')
523
- }
524
- imgRightSrc=""
525
- textStyle={{ color: theme.colors.primary, fontSize: 14 }}
526
- style={{
527
- height: 44,
528
- borderColor: theme.colors.primary,
529
- backgroundColor: theme.colors.white,
530
- }}
531
- />
532
- )}
533
- </ButtonWrapper>
534
- </Container>
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 }}
576
+ />
577
+ ) : (
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
+ />
597
+ )}
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
+
535
613
  <OModal
536
614
  open={isOpen}
537
615
  onClose={() => setIsOpen(false)}
@@ -546,7 +624,7 @@ const ServiceFormUI = (props: ServiceFormParams) => {
546
624
  {t('ANY_OROFESSIONAL_MEMBER', 'Any professional member')}
547
625
  </OText>
548
626
  </View>
549
- {professionalList?.map((professional: any) => (
627
+ {professionalListState?.professionals?.map((professional: any) => (
550
628
  <TouchableOpacity
551
629
  key={professional?.id}
552
630
  style={styles.professionalItem}
@@ -581,9 +659,9 @@ const ServiceFormUI = (props: ServiceFormParams) => {
581
659
  size={12}
582
660
  weight={'400'}
583
661
  lineHeight={17}
584
- color={isBusyTime(professional) ? theme.colors.danger5 : theme.colors.success500}
662
+ color={isBusyTime(professional, dateSelected) ? theme.colors.danger5 : theme.colors.success500}
585
663
  >
586
- {isBusyTime(professional)
664
+ {isBusyTime(professional, dateSelected)
587
665
  ? t('BUSY_ON_SELECTED_TIME', 'Busy on selected time')
588
666
  : t('AVAILABLE', 'Available')
589
667
  }