ordering-ui-react-native 0.22.75 → 0.22.76-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 (137) hide show
  1. package/package.json +5 -7
  2. package/src/components/BusinessesListing/index.tsx +1 -1
  3. package/src/components/Checkout/index.tsx +40 -39
  4. package/src/components/VerifyPhone/styles.tsx +1 -2
  5. package/src/context/OfflineActions/index.tsx +236 -0
  6. package/src/providers/AlertProvider.tsx +3 -1
  7. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +5 -3
  8. package/themes/business/src/components/AcceptOrRejectOrder/styles.tsx +1 -0
  9. package/themes/business/src/components/BusinessController/index.tsx +8 -3
  10. package/themes/business/src/components/BusinessProductList/index.tsx +3 -2
  11. package/themes/business/src/components/Chat/index.tsx +15 -3
  12. package/themes/business/src/components/DriverMap/index.tsx +44 -33
  13. package/themes/business/src/components/FloatingButton/index.tsx +3 -2
  14. package/themes/business/src/components/LanguageSelector/index.tsx +1 -1
  15. package/themes/business/src/components/LoginForm/index.tsx +123 -98
  16. package/themes/business/src/components/LogoutButton/index.tsx +13 -4
  17. package/themes/business/src/components/MapView/RenderMarker.tsx +146 -0
  18. package/themes/business/src/components/MapView/index.tsx +68 -142
  19. package/themes/business/src/components/NewOrderNotification/index.tsx +38 -54
  20. package/themes/business/src/components/OrderDetails/Business.tsx +56 -20
  21. package/themes/business/src/components/OrderDetails/Delivery.tsx +111 -42
  22. package/themes/business/src/components/OrderDetails/OrderContentComponent.tsx +146 -36
  23. package/themes/business/src/components/OrderDetails/OrderHeaderComponent.tsx +51 -28
  24. package/themes/business/src/components/OrderDetails/styles.tsx +39 -3
  25. package/themes/business/src/components/OrderDetails/usePrinterCommands.tsx +17 -16
  26. package/themes/business/src/components/OrderDetailsLogistic/index.tsx +3 -2
  27. package/themes/business/src/components/OrderSummary/index.tsx +271 -176
  28. package/themes/business/src/components/OrdersListManager/index.tsx +13 -1
  29. package/themes/business/src/components/OrdersOption/index.tsx +207 -144
  30. package/themes/business/src/components/OrdersOption/styles.tsx +14 -0
  31. package/themes/business/src/components/PreviousMessages/index.tsx +26 -3
  32. package/themes/business/src/components/PreviousOrders/OrderItem.tsx +20 -8
  33. package/themes/business/src/components/PreviousOrders/index.tsx +74 -66
  34. package/themes/business/src/components/PreviousOrders/styles.tsx +2 -1
  35. package/themes/business/src/components/PrinterEdition/MessageAlert.tsx +33 -0
  36. package/themes/business/src/components/PrinterEdition/index.tsx +143 -75
  37. package/themes/business/src/components/PrinterEdition/printerList.tsx +23 -0
  38. package/themes/business/src/components/PrinterSettings/index.tsx +1 -1
  39. package/themes/business/src/components/ProductItemAccordion/index.tsx +15 -16
  40. package/themes/business/src/components/ReviewCustomer/index.tsx +2 -0
  41. package/themes/business/src/components/StoresList/index.tsx +2 -2
  42. package/themes/business/src/components/UserProfileForm/index.tsx +48 -10
  43. package/themes/business/src/components/UserProfileForm/styles.tsx +7 -0
  44. package/themes/business/src/components/WebsocketStatus/index.tsx +2 -2
  45. package/themes/business/src/config/currency.tsx +1010 -0
  46. package/themes/business/src/hooks/useLocation.tsx +16 -12
  47. package/themes/business/src/layouts/SafeAreaContainer.tsx +35 -19
  48. package/themes/business/src/types/index.tsx +26 -4
  49. package/themes/business/src/utils/index.tsx +26 -2
  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/Checkout/index.tsx +9 -5
  54. package/themes/kiosk/src/components/CustomerName/index.tsx +1 -1
  55. package/themes/kiosk/src/components/NavBar/index.tsx +14 -14
  56. package/themes/kiosk/src/components/OptionCard/index.tsx +1 -1
  57. package/themes/kiosk/src/components/OrderTypeCardSelector/index.tsx +8 -10
  58. package/themes/kiosk/src/components/PaymentOptions/index.tsx +121 -57
  59. package/themes/kiosk/src/components/shared/OButton.tsx +5 -18
  60. package/themes/original/index.tsx +223 -219
  61. package/themes/original/src/components/AddressForm/index.tsx +56 -17
  62. package/themes/original/src/components/AppleLogin/index.tsx +3 -4
  63. package/themes/original/src/components/BusinessController/index.tsx +4 -2
  64. package/themes/original/src/components/BusinessItemAccordion/index.tsx +8 -3
  65. package/themes/original/src/components/BusinessListingSearch/BusinessSearchFooter.tsx +102 -90
  66. package/themes/original/src/components/BusinessListingSearch/BusinessSearchHeader.tsx +7 -3
  67. package/themes/original/src/components/BusinessListingSearch/index.tsx +8 -13
  68. package/themes/original/src/components/BusinessPreorder/index.tsx +30 -17
  69. package/themes/original/src/components/BusinessProductsList/SubcategoriesComponent/index.tsx +72 -69
  70. package/themes/original/src/components/BusinessProductsList/index.tsx +4 -5
  71. package/themes/original/src/components/BusinessProductsList/styles.tsx +0 -3
  72. package/themes/original/src/components/BusinessProductsListing/index.tsx +5 -4
  73. package/themes/original/src/components/BusinessesListing/Layout/Appointment/styles.tsx +1 -0
  74. package/themes/original/src/components/BusinessesListing/Layout/Original/styles.tsx +2 -1
  75. package/themes/original/src/components/Cart/index.tsx +43 -12
  76. package/themes/original/src/components/Checkout/index.tsx +126 -98
  77. package/themes/original/src/components/FloatingButton/index.tsx +1 -1
  78. package/themes/original/src/components/GPSButton/index.tsx +2 -1
  79. package/themes/original/src/components/GoogleMap/index.tsx +3 -2
  80. package/themes/original/src/components/Help/functions.tsx +76 -0
  81. package/themes/original/src/components/Help/index.tsx +74 -29
  82. package/themes/original/src/components/Help/styles.tsx +4 -1
  83. package/themes/original/src/components/HelpOptions/index.tsx +53 -0
  84. package/themes/original/src/components/HighestRatedBusinesses/index.tsx +1 -1
  85. package/themes/original/src/components/Home/index.tsx +36 -11
  86. package/themes/original/src/components/LastOrder/index.tsx +1 -1
  87. package/themes/original/src/components/LoginForm/index.tsx +11 -5
  88. package/themes/original/src/components/MessageListing/index.tsx +1 -1
  89. package/themes/original/src/components/Messages/index.tsx +562 -555
  90. package/themes/original/src/components/MomentOption/TimeListItem.tsx +56 -0
  91. package/themes/original/src/components/MomentOption/index.tsx +141 -61
  92. package/themes/original/src/components/MomentOption/styles.tsx +1 -1
  93. package/themes/original/src/components/MomentSelector/index.tsx +5 -2
  94. package/themes/original/src/components/MultiCheckout/index.tsx +78 -33
  95. package/themes/original/src/components/MultiOrdersDetails/SingleOrderCard.tsx +2 -2
  96. package/themes/original/src/components/MultiOrdersDetails/index.tsx +2 -2
  97. package/themes/original/src/components/NavBar/index.tsx +6 -2
  98. package/themes/original/src/components/NotFoundSource/index.tsx +40 -39
  99. package/themes/original/src/components/NotFoundSource/styles.tsx +18 -9
  100. package/themes/original/src/components/OrderDetails/OrderEta.tsx +4 -3
  101. package/themes/original/src/components/OrderDetails/OrderHistory.tsx +11 -4
  102. package/themes/original/src/components/OrderDetails/index.tsx +44 -20
  103. package/themes/original/src/components/OrderDetails/styles.tsx +0 -1
  104. package/themes/original/src/components/OrderProgress/index.tsx +5 -4
  105. package/themes/original/src/components/OrderSummary/index.tsx +32 -11
  106. package/themes/original/src/components/OrderTypeSelector/index.tsx +120 -120
  107. package/themes/original/src/components/OrdersOption/index.tsx +325 -325
  108. package/themes/original/src/components/PaymentOptionWallet/index.tsx +1 -0
  109. package/themes/original/src/components/PaymentOptions/index.tsx +471 -459
  110. package/themes/original/src/components/PhoneInputNumber/index.tsx +92 -7
  111. package/themes/original/src/components/ProductItemAccordion/index.tsx +28 -37
  112. package/themes/original/src/components/ProductOptionSubOption/index.tsx +15 -14
  113. package/themes/original/src/components/ServiceForm/index.tsx +2 -2
  114. package/themes/original/src/components/SignupForm/index.tsx +40 -24
  115. package/themes/original/src/components/SingleOrderCard/index.tsx +8 -5
  116. package/themes/original/src/components/SingleProductCard/index.tsx +2 -1
  117. package/themes/original/src/components/SingleProductCard/styles.tsx +0 -3
  118. package/themes/original/src/components/StripeCardsList/index.tsx +7 -1
  119. package/themes/original/src/components/StripeElementsForm/index.tsx +2 -2
  120. package/themes/original/src/components/TaxInformation/index.tsx +3 -2
  121. package/themes/original/src/components/UpsellingProducts/UpsellingContent.tsx +7 -2
  122. package/themes/original/src/components/UserDetails/index.tsx +17 -16
  123. package/themes/original/src/components/UserFormDetails/index.tsx +109 -67
  124. package/themes/original/src/components/UserVerification/index.tsx +18 -5
  125. package/themes/original/src/components/VerifyPhone/index.tsx +1 -1
  126. package/themes/original/src/components/shared/OInput.tsx +97 -97
  127. package/themes/original/src/components/shared/OModal.tsx +7 -2
  128. package/themes/original/src/providers/AlertProvider.tsx +1 -1
  129. package/themes/original/src/types/index.tsx +700 -695
  130. package/themes/original/src/utils/index.tsx +50 -34
  131. package/themes/uber-eats/src/components/BusinessesListing/index.tsx +1 -1
  132. package/themes/original/src/components/HelpAccountAndPayment/index.tsx +0 -62
  133. package/themes/original/src/components/HelpAccountAndPayment/styles.tsx +0 -12
  134. package/themes/original/src/components/HelpGuide/index.tsx +0 -68
  135. package/themes/original/src/components/HelpGuide/styles.tsx +0 -12
  136. package/themes/original/src/components/HelpOrder/index.tsx +0 -71
  137. package/themes/original/src/components/HelpOrder/styles.tsx +0 -13
@@ -0,0 +1,56 @@
1
+ import React from 'react'
2
+ import { Pressable } from 'react-native'
3
+ import {
4
+ TimeItem,
5
+ } from './styles'
6
+ import { OIcon, OText } from '../shared'
7
+ import { useTheme } from 'styled-components/native'
8
+
9
+ const timeListItemPropsAreEqual = (prevProps: any, nextProps: any) => {
10
+ return JSON.stringify(prevProps.time) === JSON.stringify(nextProps.time) &&
11
+ JSON.stringify(prevProps.selectedTime) === JSON.stringify(nextProps.selectedTime) &&
12
+ JSON.stringify(prevProps.cateringPreorder) === JSON.stringify(nextProps.cateringPreorder)
13
+ }
14
+ export const TimeListItem = React.memo((props : any) => {
15
+ const {
16
+ time,
17
+ selectedTime,
18
+ handleChangeTimeSelected,
19
+ cateringPreorder
20
+ } = props
21
+ const theme = useTheme()
22
+
23
+ return (
24
+ <Pressable onPress={() => handleChangeTimeSelected(time.value)}>
25
+ <TimeItem
26
+ active={selectedTime === time.value}
27
+ cateringPreorder={cateringPreorder}
28
+ >
29
+ {cateringPreorder && (
30
+ <>
31
+ {selectedTime === time.value ? (
32
+ <OIcon
33
+ src={theme.images.general.option_checked}
34
+ width={18}
35
+ style={{ marginEnd: 24, bottom: 2 }}
36
+ />
37
+ ) : (
38
+ <OIcon
39
+ src={theme.images.general.option_normal}
40
+ width={18}
41
+ style={{ marginEnd: 24, bottom: 2 }}
42
+ />
43
+ )}
44
+ </>
45
+ )}
46
+ <OText
47
+ size={cateringPreorder ? 18 : 16}
48
+ color={selectedTime === time.value ? theme.colors.primary : theme.colors.textNormal}
49
+ style={{
50
+ lineHeight: 24
51
+ }}
52
+ >{time.text} {cateringPreorder && `- ${time.endText}`}</OText>
53
+ </TimeItem>
54
+ </Pressable>
55
+ )
56
+ }, timeListItemPropsAreEqual)
@@ -30,6 +30,7 @@ import {
30
30
  } from './styles';
31
31
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
32
32
  import { monthsEnum, setLocalMoment } from '../../utils';
33
+ import { TimeListItem } from './TimeListItem';
33
34
 
34
35
  const MomentOptionUI = (props: MomentOptionParams) => {
35
36
  const {
@@ -161,6 +162,9 @@ const MomentOptionUI = (props: MomentOptionParams) => {
161
162
  const [datesWhitelist, setDateWhitelist] = useState<any>([{ start: null, end: null }])
162
163
  const [selectDate, setSelectedDate] = useState<any>(dateSelected)
163
164
  const [timeList, setTimeList] = useState<any>(hoursList)
165
+ const [nextTime, setNextTime] = useState(null)
166
+ const [isEnabled, setIsEnabled] = useState(false)
167
+
164
168
  const goToBack = () => navigation?.canGoBack() && navigation.goBack();
165
169
 
166
170
  const _handleAsap = () => {
@@ -177,6 +181,60 @@ const MomentOptionUI = (props: MomentOptionParams) => {
177
181
  handleChangeTime(time ?? selectedTime);
178
182
  };
179
183
 
184
+ const validateSelectedDate = (curdate: any, menu: any) => {
185
+ const day = moment(curdate).format('d')
186
+ setIsEnabled(menu?.schedule?.[day]?.enabled || false)
187
+ }
188
+
189
+ const getTimes = (curdate: any, menu: any) => {
190
+ validateSelectedDate(curdate, menu)
191
+ const date = new Date()
192
+ var dateSeleted = new Date(curdate)
193
+ var times = []
194
+ for (var k = 0; k < menu.schedule[dateSeleted.getDay()].lapses.length; k++) {
195
+ var open = {
196
+ hour: menu.schedule[dateSeleted.getDay()].lapses[k].open.hour,
197
+ minute: menu.schedule[dateSeleted.getDay()].lapses[k].open.minute
198
+ }
199
+ var close = {
200
+ hour: menu.schedule[dateSeleted.getDay()].lapses[k].close.hour,
201
+ minute: menu.schedule[dateSeleted.getDay()].lapses[k].close.minute
202
+ }
203
+ for (var i = open.hour; i <= close.hour; i++) {
204
+ if (date.getDate() !== dateSeleted.getDate() || i >= date.getHours()) {
205
+ let hour = ''
206
+ let meridian = ''
207
+ if (is12hours) {
208
+ if (i === 0) {
209
+ hour = '12'
210
+ meridian = ' ' + t('AM', 'AM')
211
+ } else if (i > 0 && i < 12) {
212
+ hour = (i < 10 ? '0' + i : i)
213
+ meridian = ' ' + t('AM', 'AM')
214
+ } else if (i === 12) {
215
+ hour = '12'
216
+ meridian = ' ' + t('PM', 'PM')
217
+ } else {
218
+ hour = ((i - 12 < 10) ? '0' + (i - 12) : `${(i - 12)}`)
219
+ meridian = ' ' + t('PM', 'PM')
220
+ }
221
+ } else {
222
+ hour = i < 10 ? '0' + i : i
223
+ }
224
+ for (let j = (i === open.hour ? open.minute : 0); j <= (i === close.hour ? close.minute : 59); j += 15) {
225
+ if (i !== date.getHours() || j >= date.getMinutes() || date.getDate() !== dateSeleted.getDate()) {
226
+ times.push({
227
+ text: hour + ':' + (j < 10 ? '0' + j : j) + meridian,
228
+ value: (i < 10 ? '0' + i : i) + ':' + (j < 10 ? '0' + j : j)
229
+ })
230
+ }
231
+ }
232
+ }
233
+ }
234
+ }
235
+ return times
236
+ }
237
+
180
238
  const momento = moment(
181
239
  `${dateSelected} ${timeSelected}`,
182
240
  'YYYY-MM-DD HH:mm',
@@ -256,7 +314,7 @@ const MomentOptionUI = (props: MomentOptionParams) => {
256
314
  setDateWhitelist([{ start: _minDate, end: _maxDate }])
257
315
  }
258
316
  }
259
- }, [JSON.stringify(datesList), preorderMinimumDays, preorderMaximumDays, cateringPreorder])
317
+ }, [JSON.stringify(datesList), preorderMinimumDays, preorderMaximumDays])
260
318
 
261
319
  useEffect(() => {
262
320
  if (dateSelected) {
@@ -278,13 +336,21 @@ const MomentOptionUI = (props: MomentOptionParams) => {
278
336
  let _timeLists = []
279
337
  const schedule = business && getActualSchedule()
280
338
  if (!schedule && business) {
339
+ setTimeList([])
281
340
  return
282
341
  }
283
342
  _timeLists = hoursList
284
- .filter(hour => (!business || schedule?.lapses?.some((lapse: any) =>
285
- moment(dateSelected + ` ${hour.startTime}`) >= moment(dateSelected + ` ${lapse.open.hour}:${lapse.open.minute}`).add(preorderLeadTime, 'minutes') && moment(dateSelected + ` ${hour.endTime}`) <= moment(dateSelected + ` ${lapse.close.hour}:${lapse.close.minute}`))) &&
286
- moment(dateSelected + ` ${hour.startTime}`) < moment(dateSelected + ` ${hour.endTime}`) &&
287
- (moment().add(preorderLeadTime, 'minutes') < moment(dateSelected + ` ${hour.startTime}`) || !cateringPreorder))
343
+ .filter(hour => {
344
+ return (Object.keys(business || {})?.length === 0 || schedule?.lapses?.some((lapse: any) => {
345
+ const openHour = lapse.open.hour < 10 ? `0${lapse.open.hour}` : lapse.open.hour
346
+ const openMinute = lapse.open.minute < 10 ? `0${lapse.open.minute}` : lapse.open.minute
347
+ const closeHour = lapse.close.hour < 10 ? `0${lapse.close.hour}` : lapse.close.hour
348
+ const closeMinute = lapse.close.minute < 10 ? `0${lapse.close.minute}` : lapse.close.minute
349
+ return moment(dateSelected + ` ${hour.startTime}`) >= moment(dateSelected + ` ${openHour}:${openMinute}`).add(preorderLeadTime, 'minutes') && moment(dateSelected + ` ${hour.endTime}`) <= moment(dateSelected + ` ${closeHour}:${closeMinute}`)
350
+ })) &&
351
+ (moment(dateSelected + ` ${hour.startTime}`) < moment(dateSelected + ` ${hour.endTime}`)) &&
352
+ (moment().add(preorderLeadTime, 'minutes') < moment(dateSelected + ` ${hour.startTime}`) || !cateringPreorder)
353
+ })
288
354
  .map(hour => {
289
355
  return {
290
356
  value: hour.startTime,
@@ -308,25 +374,49 @@ const MomentOptionUI = (props: MomentOptionParams) => {
308
374
  setTimeList(_timeLists)
309
375
  }
310
376
  } else {
311
- setTimeList(hoursList.map(hour => {
312
- return {
313
- value: hour.startTime,
314
- text: is12hours ? (
315
- hour.startTime.includes('12')
316
- ? `${hour.startTime}PM`
317
- : parseTime(moment(hour.startTime, 'HH:mm'), { outputFormat: 'hh:mma' })
318
- ) : (
319
- parseTime(moment(hour.startTime, 'HH:mm'), { outputFormat: 'HH:mm' })
320
- )
321
- }
322
- }))
377
+ let _times: any = []
378
+ if (business) {
379
+ _times = getTimes(selectDate, business)
380
+ } else {
381
+ _times = hoursList.map(hour => {
382
+ return {
383
+ value: hour.startTime,
384
+ text: is12hours ? (
385
+ hour.startTime.includes('12')
386
+ ? `${hour.startTime}PM`
387
+ : parseTime(moment(hour.startTime, 'HH:mm'), { outputFormat: 'hh:mma' })
388
+ ) : (
389
+ parseTime(moment(hour.startTime, 'HH:mm'), { outputFormat: 'HH:mm' })
390
+ )
391
+ }
392
+ })
393
+ setIsEnabled(true)
394
+ }
395
+ setTimeList(_times)
323
396
  }
324
- }, [dateSelected, JSON.stringify(hoursList), JSON.stringify(datesWhitelist), cateringPreorder, JSON.stringify(business)])
397
+ }, [dateSelected, hoursList?.length, JSON.stringify(datesWhitelist), JSON.stringify(business)])
325
398
 
326
399
  useEffect(() => {
327
400
  setLocalMoment(moment, t)
328
401
  }, [])
329
402
 
403
+ useEffect(() => {
404
+ if (preorderMinimumDays === 0 && preorderLeadTime === 0) return
405
+ const isToday = dateSelected === moment().format('YYYY-MM-DD')
406
+ if (isCart && isToday && !orderState?.loading && timeList?.length > 0) {
407
+ setNextTime(timeList?.[0] ?? null)
408
+ }
409
+ }, [timeList?.length])
410
+
411
+ useEffect(() => {
412
+ if (nextTime?.value && timeList?.length > 0 && isCart && !orderState?.loading && !(preorderMinimumDays === 0 && preorderLeadTime === 0)) {
413
+ const notime = timeList?.filter((_: any, i: number) => i !== 0)?.find?.((time: any) => time?.value === timeSelected)
414
+ if (!notime) {
415
+ handleChangeTime(nextTime?.value)
416
+ }
417
+ }
418
+ }, [nextTime?.value])
419
+
330
420
  return (
331
421
  <>
332
422
  <Container
@@ -349,7 +439,7 @@ const MomentOptionUI = (props: MomentOptionParams) => {
349
439
  titleWrapStyle={{ paddingHorizontal: 0 }}
350
440
  />
351
441
  )}
352
- {(preorderMinimumDays === 0 && preorderLeadTime === 0) || !cateringPreorder && (
442
+ {((preorderMinimumDays === 0 && preorderLeadTime === 0) || !cateringPreorder) && (
353
443
  <WrapSelectOption
354
444
  onPress={() => _handleAsap()}
355
445
  disabled={orderState.loading} style={{ alignItems: 'flex-start' }}>
@@ -402,23 +492,23 @@ const MomentOptionUI = (props: MomentOptionParams) => {
402
492
  style={styles.calendar}
403
493
  calendarHeaderContainerStyle={styles.calendarHeaderContainer}
404
494
  calendarHeaderStyle={styles.calendarHeader}
405
- dateNumberStyle={styles.dateNumber}
406
- dateNameStyle={styles.dateName}
407
495
  iconContainer={{ flex: 0.1 }}
408
- highlightDateNameStyle={styles.highlightDateName}
409
- highlightDateNumberStyle={styles.highlightDateNumber}
410
496
  dayContainerStyle={{ height: '100%' }}
411
497
  highlightDateContainerStyle={{ height: '100%' }}
412
498
  calendarHeaderFormat='MMMM, YYYY'
413
499
  iconStyle={{ borderWidth: 1 }}
414
500
  selectedDate={dateSelected}
415
501
  datesWhitelist={datesWhitelist}
502
+ highlightDateNumberStyle={styles.highlightDateNumber}
503
+ highlightDateNameStyle={styles.highlightDateName}
416
504
  minDate={moment()}
417
505
  maxDate={cateringPreorder ? moment().add(preorderMaximumDays, 'days') : undefined}
418
506
  disabledDateNameStyle={styles.disabledDateName}
419
507
  disabledDateNumberStyle={styles.disabledDateNumber}
420
508
  disabledDateOpacity={0.6}
421
- onDateSelected={(date) => onSelectDate(date)}
509
+ dateNumberStyle={styles.dateNumber}
510
+ dateNameStyle={styles.dateName}
511
+ onDateSelected={(date: any) => onSelectDate(date)}
422
512
  leftSelector={<LeftSelector />}
423
513
  rightSelector={<RightSelector />}
424
514
  />
@@ -426,44 +516,34 @@ const MomentOptionUI = (props: MomentOptionParams) => {
426
516
  </View>
427
517
  )}
428
518
  <TimeListWrapper nestedScrollEnabled={true} cateringPreorder={cateringPreorder}>
429
- <TimeContentWrapper>
430
- {timeList.map((time: any, i: number) => (
431
- <Pressable key={i} onPress={() => handleChangeTimeSelected(time.value)}>
432
- <TimeItem
433
- active={selectedTime === time.value}
519
+ {isEnabled && timeList?.length > 0 ? (
520
+ <TimeContentWrapper>
521
+ {timeList.map((time: any, i: number) => (
522
+ <TimeListItem
523
+ key={i}
524
+ time={time}
525
+ selectedTime={selectedTime}
526
+ handleChangeTimeSelected={handleChangeTimeSelected}
434
527
  cateringPreorder={cateringPreorder}
435
- >
436
- {cateringPreorder && (
437
- <>
438
- {selectedTime === time.value ? (
439
- <OIcon
440
- src={theme.images.general.option_checked}
441
- width={18}
442
- style={{ marginEnd: 24, bottom: 2 }}
443
- />
444
- ) : (
445
- <OIcon
446
- src={theme.images.general.option_normal}
447
- width={18}
448
- style={{ marginEnd: 24, bottom: 2 }}
449
- />
450
- )}
451
- </>
452
- )}
453
- <OText
454
- size={cateringPreorder ? 18 : 16}
455
- color={selectedTime === time.value ? theme.colors.primary : theme.colors.textNormal}
456
- style={{
457
- lineHeight: 24
458
- }}
459
- >{time.text} {cateringPreorder && `- ${time.endText}`}</OText>
460
- </TimeItem>
461
- </Pressable>
462
- ))}
463
- {timeList.length % 3 === 2 && (
464
- <TimeItem style={{ backgroundColor: 'transparent' }} />
465
- )}
466
- </TimeContentWrapper>
528
+ />
529
+ ))}
530
+ {timeList.length % 3 === 2 && (
531
+ <TimeItem style={{ backgroundColor: 'transparent' }} />
532
+ )}
533
+ </TimeContentWrapper>
534
+ ) : (
535
+ <OText
536
+ size={16}
537
+ style={{
538
+ fontWeight: '600',
539
+ lineHeight: 24,
540
+ marginBottom: 12,
541
+ textAlign: 'center'
542
+ }}
543
+ >
544
+ {t('ERROR_ADD_PRODUCT_BUSINESS_CLOSED', 'The business is closed at the moment')}
545
+ </OText>
546
+ )}
467
547
  </TimeListWrapper>
468
548
  </OrderTimeWrapper>
469
549
  )}
@@ -40,7 +40,7 @@ export const TimeItem = styled.View`
40
40
  border-radius: 7.6px;
41
41
  justify-content: center;
42
42
  align-items: center;
43
- margin: 10px 0px;
43
+ margin: 10px 5px;
44
44
  ${({ cateringPreorder }: any) => cateringPreorder && css`
45
45
  background: #fff;
46
46
  width: 100%;
@@ -5,7 +5,8 @@ import { useTheme } from 'styled-components/native'
5
5
  import {
6
6
  MomentOption as MomentOptionController,
7
7
  useConfig,
8
- useUtils
8
+ useUtils,
9
+ useLanguage
9
10
  } from 'ordering-components/native'
10
11
  import { useSafeAreaInsets } from 'react-native-safe-area-context'
11
12
  import IconAntDesign from 'react-native-vector-icons/AntDesign'
@@ -26,6 +27,7 @@ const MomentSelectorUI = (props: any) => {
26
27
  const { top } = useSafeAreaInsets()
27
28
  const [{ configs }] = useConfig()
28
29
  const [{ parseTime }] = useUtils()
30
+ const [, t] = useLanguage()
29
31
 
30
32
  const [customizedDateList, setCustomizedDateList] = useState([])
31
33
  const [customizedTimeList, setCustomizedTimeList] = useState([])
@@ -130,6 +132,7 @@ const MomentSelectorUI = (props: any) => {
130
132
  <View style={styles.selectWrapper}>
131
133
  <SelectDropdown
132
134
  defaultValue={customizedTimeList?.find((item: any) => item.key === timeSelected)}
135
+ defaultButtonText={t('SELECT_A_TIME_OPTION', 'Select an option')}
133
136
  data={customizedTimeList}
134
137
  onSelect={(selectedItem, index) => {
135
138
  handleChangeTime(selectedItem.key)
@@ -194,4 +197,4 @@ export const MomentSelector = (props: any) => {
194
197
  maxDate: currentDate
195
198
  }
196
199
  return <MomentOptionController {...businessPreorderProps} />
197
- }
200
+ }
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useCallback } from 'react'
1
+ import React, { useState, useEffect, useCallback, useMemo } from 'react'
2
2
  import {
3
3
  useLanguage,
4
4
  useConfig,
@@ -70,7 +70,8 @@ const MultiCheckoutUI = (props: any) => {
70
70
  walletState,
71
71
  onNavigationRedirectReplace,
72
72
  merchantId,
73
- cartsInvalid
73
+ cartsInvalid,
74
+ checkoutFieldsState
74
75
  } = props
75
76
 
76
77
  const theme = useTheme();
@@ -96,11 +97,14 @@ const MultiCheckoutUI = (props: any) => {
96
97
  const [{ parsePrice, parseDate }] = useUtils();
97
98
  const [{ options, carts, loading }, { confirmCart }] = useOrder();
98
99
  const [validationFields] = useValidationFields();
99
- const [{ user }, { login }] = useSession()
100
+ const [{ user, loading: userLoading }, { login }] = useSession()
100
101
 
102
+ const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes', 'comments']
101
103
  const configTypes = configs?.order_types_allowed?.value.split('|').map((value: any) => Number(value)) || []
102
104
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
103
105
  const isMultiDriverTips = configs?.checkout_multi_business_enabled?.value === '1'
106
+ const allowDriverTipPickup = configs?.driver_tip_allowed_at_pickup?.value === '1' && options?.type === 2
107
+ const isGuestCheckoutEnabled = configs?.guest_checkout_enabled?.value === '1'
104
108
  const walletCarts = (Object.values(carts)?.filter((cart: any) => cart?.products && cart?.products?.length && cart?.status !== 2 && cart?.valid_schedule && cart?.valid_products && cart?.valid_address && cart?.valid_maximum && cart?.valid_minimum && cart?.wallets) || null) || []
105
109
  const isChewLayout = theme?.header?.components?.layout?.type?.toLowerCase() === 'chew'
106
110
  const cartsToShow = openCarts?.length > 0 ? openCarts : cartsInvalid
@@ -121,6 +125,7 @@ const MultiCheckoutUI = (props: any) => {
121
125
 
122
126
  const creditPointGeneralPlan = loyaltyPlansState?.result?.find((loyal: any) => loyal.type === 'credit_point')
123
127
  const loyalBusinessAvailable = creditPointGeneralPlan?.businesses?.filter((b: any) => b.accumulates) ?? []
128
+ const checkoutFields = useMemo(() => checkoutFieldsState?.fields?.filter((field: any) => field.order_type_id === options?.type), [checkoutFieldsState, options])
124
129
 
125
130
  const accumulationRateBusiness = (businessId: number) => {
126
131
  const value = loyalBusinessAvailable?.find((loyal: any) => loyal.business_id === businessId)?.accumulation_rate ?? 0
@@ -159,7 +164,8 @@ const MultiCheckoutUI = (props: any) => {
159
164
  const isDisablePlaceOrderButton = cartGroup?.loading || placing || (!(paymethodSelected?.paymethod_id || paymethodSelected?.wallet_id) && cartGroup?.result?.balance > 0) ||
160
165
  (paymethodSelected?.paymethod?.gateway === 'stripe' && !paymethodSelected?.paymethod_data) ||
161
166
  walletCarts.length > 0
162
- || (methodsPay.includes(paymethodSelected?.gateway) && (!methodPaySupported.enabled || methodPaySupported.loading)) || openCarts?.length === 0
167
+ || (methodsPay.includes(paymethodSelected?.gateway) && (!methodPaySupported.enabled || methodPaySupported.loading)) || openCarts?.length === 0 ||
168
+ (!isGuestCheckoutEnabled && !!user?.guest_id)
163
169
 
164
170
  const handleMomentClick = () => {
165
171
  if (isPreOrder) {
@@ -169,35 +175,55 @@ const MultiCheckoutUI = (props: any) => {
169
175
 
170
176
  const checkValidationFields = () => {
171
177
  setUserErrors([])
172
- const errors = []
173
- const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes']
174
- const _requiredFields: any = []
175
-
176
- Object.values(validationFields?.fields?.checkout).map((field: any) => {
177
- if (field?.required && !notFields.includes(field.code)) {
178
- if (!user[field?.code]) {
179
- _requiredFields.push(field?.code)
178
+ const errors: Array<string> = []
179
+ const userSelected = user
180
+ const _requiredFields: Array<string> = []
181
+ Object.values(checkoutFieldsState?.fields).map((field: any) => {
182
+ if (options?.type === field?.order_type_id &&
183
+ field?.enabled &&
184
+ field?.required &&
185
+ !notFields.includes(field?.validation_field?.code)
186
+ ) {
187
+ if (userSelected && !userSelected[field?.validation_field?.code]) {
188
+ _requiredFields.push(field?.validation_field?.code)
180
189
  }
181
190
  }
182
191
  })
183
-
192
+ const mobilePhoneField: any = Object.values(checkoutFieldsState?.fields)?.find((field: any) => field?.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
184
193
  if (
185
- !user?.cellphone &&
186
- ((validationFields?.fields?.checkout?.cellphone?.enabled &&
187
- validationFields?.fields?.checkout?.cellphone?.required) ||
194
+ userSelected &&
195
+ !userSelected?.cellphone &&
196
+ ((mobilePhoneField?.enabled &&
197
+ mobilePhoneField?.required) ||
188
198
  configs?.verification_phone_required?.value === '1')
189
199
  ) {
190
200
  _requiredFields.push('cellphone')
191
201
  }
192
202
  setRequiredFields(_requiredFields)
193
203
 
194
- if (phoneUpdate) {
195
- errors.push(t('NECESSARY_UPDATE_COUNTRY_PHONE_CODE', 'It is necessary to update your phone number'))
196
- }
197
-
198
204
  setUserErrors(errors)
199
205
  }
200
206
 
207
+ const checkGuestValidationFields = () => {
208
+ const userSelected = user
209
+ const _requiredFields = checkoutFieldsState?.fields
210
+ .filter((field) => (field?.order_type_id === options?.type) && field?.enabled && field?.required_with_guest &&
211
+ !notFields.includes(field?.validation_field?.code) &&
212
+ userSelected && !userSelected[field?.validation_field?.code])
213
+ const requiredFieldsCode = _requiredFields.map((item) => item?.validation_field?.code)
214
+ const guestCheckoutCellPhone = checkoutFieldsState?.fields?.find((field) => field.order_type_id === options?.type && field?.validation_field?.code === 'mobile_phone')
215
+ if (
216
+ userSelected &&
217
+ !userSelected?.cellphone &&
218
+ ((guestCheckoutCellPhone?.enabled &&
219
+ guestCheckoutCellPhone?.required_with_guest) ||
220
+ configs?.verification_phone_required?.value === '1')
221
+ ) {
222
+ requiredFieldsCode.push('cellphone')
223
+ }
224
+ setRequiredFields(requiredFieldsCode)
225
+ }
226
+
201
227
  const togglePhoneUpdate = (val: boolean) => {
202
228
  setPhoneUpdate(val)
203
229
  }
@@ -208,7 +234,7 @@ const MultiCheckoutUI = (props: any) => {
208
234
  return
209
235
  }
210
236
 
211
- if (!userErrors.length && (!requiredFields?.length || allowedGuest)) {
237
+ if (!userErrors.length && !requiredFields?.length) {
212
238
  handleGroupPlaceOrder && handleGroupPlaceOrder(confirmPayment)
213
239
  return
214
240
  }
@@ -255,10 +281,13 @@ const MultiCheckoutUI = (props: any) => {
255
281
  }
256
282
 
257
283
  useEffect(() => {
258
- if (validationFields && validationFields?.fields?.checkout) {
284
+ if (checkoutFieldsState?.loading || userLoading) return
285
+ if (user?.guest_id) {
286
+ checkGuestValidationFields()
287
+ } else {
259
288
  checkValidationFields()
260
289
  }
261
- }, [validationFields, user])
290
+ }, [checkoutFieldsState, user, options?.type])
262
291
 
263
292
  useEffect(() => {
264
293
  if (cartsToShow?.length === 1) {
@@ -402,14 +431,16 @@ const MultiCheckoutUI = (props: any) => {
402
431
  style={{ borderRadius: 7.6, marginTop: 20 }}
403
432
  onClick={() => setOpenModal({ ...openModal, login: true })}
404
433
  />
405
- <OButton
406
- text={t('CONTINUE_AS_GUEST', 'Continue as guest')}
407
- textStyle={{ color: theme.colors.black }}
408
- bgColor={theme.colors.white}
409
- borderColor={theme.colors.black}
410
- style={{ borderRadius: 7.6, marginTop: 20 }}
411
- onClick={() => setAllowedGuest(true)}
412
- />
434
+ {isGuestCheckoutEnabled && (
435
+ <OButton
436
+ text={t('CONTINUE_AS_GUEST', 'Continue as guest')}
437
+ textStyle={{ color: theme.colors.black }}
438
+ bgColor={theme.colors.white}
439
+ borderColor={theme.colors.black}
440
+ style={{ borderRadius: 7.6, marginTop: 20 }}
441
+ onClick={() => setAllowedGuest(true)}
442
+ />
443
+ )}
413
444
  </View>
414
445
  ) : (
415
446
  <UserDetails
@@ -420,6 +451,9 @@ const MultiCheckoutUI = (props: any) => {
420
451
  isCheckout
421
452
  phoneUpdate={phoneUpdate}
422
453
  togglePhoneUpdate={togglePhoneUpdate}
454
+ isOrderTypeValidationField
455
+ requiredFields={requiredFields}
456
+ checkoutFields={checkoutFields}
423
457
  />
424
458
  )}
425
459
  </ChUserDetails>
@@ -461,7 +495,7 @@ const MultiCheckoutUI = (props: any) => {
461
495
  )}
462
496
  {
463
497
  isMultiDriverTips &&
464
- options?.type === 1 &&
498
+ (options?.type === 1 || allowDriverTipPickup) &&
465
499
  validationFields?.fields?.checkout?.driver_tip?.enabled &&
466
500
  openCarts.every((cart: any) => cart.business_id && cart.status !== 2) &&
467
501
  driverTipsOptions && driverTipsOptions?.length > 0 &&
@@ -614,6 +648,14 @@ const MultiCheckoutUI = (props: any) => {
614
648
  {t('WARNING_INVALID_PRODUCTS_CHECKOUT', 'To continue with your checkout, please remove from your cart the products that are not available.')}
615
649
  </OText>
616
650
  )}
651
+ {(!isGuestCheckoutEnabled && !!user?.guest_id) && (
652
+ <OText
653
+ color={theme.colors.error}
654
+ size={12}
655
+ >
656
+ {t('LOGIN_SIGN_UP_COMPLETE_ORDER', 'Login/Sign up to complete your order.')}
657
+ </OText>
658
+ )}
617
659
  </ChContainer>
618
660
  <OModal
619
661
  open={openModal.signup}
@@ -656,9 +698,12 @@ const MultiCheckoutUI = (props: any) => {
656
698
  isEdit
657
699
  phoneUpdate={phoneUpdate}
658
700
  togglePhoneUpdate={togglePhoneUpdate}
659
- requiredFields={requiredFields}
660
701
  hideUpdateButton
661
702
  handlePlaceOrderAsGuest={handlePlaceOrderAsGuest}
703
+ isCheckoutPlace
704
+ isOrderTypeValidationField
705
+ requiredFields={requiredFields}
706
+ checkoutFields={checkoutFields}
662
707
  onClose={() => {
663
708
  setIsOpen(false)
664
709
  handlePlaceOrder()
@@ -143,7 +143,7 @@ const SingleOrderCardUI = (props: any) => {
143
143
  <LinearGradient
144
144
  start={{ x: 0.0, y: 0.0 }}
145
145
  end={{
146
- x: getOrderStatus(order?.status)?.percentage || 0,
146
+ x: getOrderStatus(order?.status, t)?.percentage || 0,
147
147
  y: 0,
148
148
  }}
149
149
  locations={[0.9999, 0.9999]}
@@ -152,7 +152,7 @@ const SingleOrderCardUI = (props: any) => {
152
152
  />
153
153
  </StaturBar>
154
154
  <OText size={12} lineHeight={18} weight={'400'} color={theme.colors.textNormal}>
155
- {getOrderStatus(order?.status)?.value}
155
+ {getOrderStatus(order?.status, t)?.value}
156
156
  </OText>
157
157
  </>
158
158
  )}
@@ -208,7 +208,7 @@ export const MultiOrdersDetailsUI = (props: any) => {
208
208
  <LinearGradient
209
209
  start={{ x: 0.0, y: 0.0 }}
210
210
  end={{
211
- x: getOrderStatus(orders[0]?.status)?.percentage || 0,
211
+ x: getOrderStatus(orders[0]?.status, t)?.percentage || 0,
212
212
  y: 0,
213
213
  }}
214
214
  locations={[0.9999, 0.9999]}
@@ -218,7 +218,7 @@ export const MultiOrdersDetailsUI = (props: any) => {
218
218
  </StaturBar>
219
219
  )}
220
220
  <OText size={14} lineHeight={18} weight={'400'} color={theme.colors.textNormal} mBottom={10}>
221
- {getOrderStatus(orders[0]?.status)?.value}
221
+ {getOrderStatus(orders[0]?.status, t)?.value}
222
222
  </OText>
223
223
  {orders.map((order: any) => (
224
224
  <Row key={order.id}>
@@ -1,3 +1,6 @@
1
+
2
+
3
+
1
4
  import * as React from 'react'
2
5
  import styled, { useTheme } from 'styled-components/native'
3
6
  import { OButton, OIcon, OText } from '../shared'
@@ -130,8 +133,9 @@ NavBar.defaultProps = {
130
133
  textAlign: 'center'
131
134
  };
132
135
 
133
- const areEqual = (prevProps: { route?: any; }, nextProps: { route?: any; }) => {
134
- return prevProps.route === nextProps.route
136
+ const areEqual = (prevProps: { route?: any, title?: string }, nextProps: { route?: any, title?: string }) => {
137
+ return prevProps.route === nextProps.route &&
138
+ JSON.stringify(prevProps.title) === JSON.stringify(nextProps.title)
135
139
  return true
136
140
  }
137
141