ordering-ui-react-native 0.15.87 → 0.15.90

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.15.87",
3
+ "version": "0.15.90",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -408,49 +408,49 @@ export const orderCommentList = (value: string) => {
408
408
 
409
409
  const messages: any = {
410
410
  6: [// on reject order
411
- 'Very far away',
412
- 'Driver/ vehicle incident',
413
- 'Destination unreachable',
414
- 'Unavailable driver',
415
- 'Other'
411
+ 'very_far_away',
412
+ 'driver_vehicle_incident',
413
+ 'destination_unreacheable',
414
+ 'unavailable_driver',
415
+ 'other'
416
416
  ],
417
417
  9: [// on force pickup status
418
- 'I forgot to complete it in the location',
419
- 'I didn\'t have internet connection',
420
- 'Other'
418
+ 'forgot_complete_location',
419
+ 'not_internet_conection',
420
+ 'other'
421
421
  ],
422
422
  10: [// on pickup failed by driver
423
- 'Very far away',
424
- 'Driver/ vehicle incident',
425
- 'Destination unreachable',
426
- 'Store closed',
427
- 'Unavailable driver',
428
- 'Other'
423
+ 'very_far_away',
424
+ 'driver_vehicle_incident',
425
+ 'destination_unreacheable',
426
+ 'store_closed',
427
+ 'unavailable_driver',
428
+ 'other'
429
429
  ],
430
430
  11: [// on force delivery status
431
- 'I forgot to complete it in the location',
432
- 'I didn\'t have internet connection',
433
- 'Other'
431
+ 'forgot_complete_location',
432
+ 'not_internet_conection',
433
+ 'other'
434
434
  ],
435
435
  12: [// on delivery failed by driver
436
- 'Very far away',
437
- 'Driver/ vehicle incident',
438
- 'Destination unreachable',
439
- 'Recipient unavailable',
440
- 'Refused- incorrect/ missing items',
441
- 'Refused- damage',
442
- 'Other'
436
+ 'very_far_away',
437
+ 'driver_vehicle_incident',
438
+ 'destination_unreacheable',
439
+ 'recipient_unavailable',
440
+ 'incorrect_missing_items',
441
+ 'refused_damage',
442
+ 'other'
443
443
  ],
444
444
  14: [// on order not ready
445
- 'Store didn\'t receive the order on time',
446
- 'Store very busy',
447
- 'Other'
445
+ 'store_recieve_order_late',
446
+ 'store_busy',
447
+ 'other'
448
448
  ]
449
449
  }
450
450
 
451
451
  if (!messages[status]) return null
452
452
 
453
- const list = messages[status].map((val: any, i: number) => ({ key: i, content: t(`ORDER_STATUS_${status}_QUICK_COMMENT_${i}`, val) }))
453
+ const list = messages[status].map((val: any, i: number) => ({ key: i, value: val, content: t(`REJECT_REASON_${val.toUpperCase()}`, val.replaceAll('_', ' ')) }))
454
454
 
455
455
  return { list }
456
456
  }
@@ -1,14 +1,17 @@
1
1
  import React, { useState, useEffect, useRef } from 'react';
2
+ import FeatherIcon from 'react-native-vector-icons/Feather';
2
3
  import {
3
4
  Linking,
4
5
  Keyboard,
5
6
  Platform,
6
7
  View,
7
8
  KeyboardAvoidingView,
8
- TextInput
9
+ TextInput,
10
+ StyleSheet
9
11
  } from 'react-native';
10
12
  import { useTheme } from 'styled-components/native';
11
- import { useLanguage } from 'ordering-components/native';
13
+ import SelectDropdown from 'react-native-select-dropdown'
14
+ import { useLanguage, useSession } from 'ordering-components/native';
12
15
  import { Content, Timer, TimeField, Header, Action, Comments, CommentsButtonGroup } from './styles';
13
16
  import { FloatingButton } from '../FloatingButton';
14
17
  import { OText, OButton, OTextarea, OIconButton } from '../shared';
@@ -32,6 +35,7 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
32
35
  } = props;
33
36
 
34
37
  const [, t] = useLanguage();
38
+ const [{ user }] = useSession();
35
39
  const theme = useTheme();
36
40
  const scrollViewRef = useRef<any>(null);
37
41
  const viewRef = useRef<any>(null);
@@ -41,10 +45,12 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
41
45
  const [min, setMin] = useState('00');
42
46
  const [time, setTime] = useState('');
43
47
  const [comments, setComments] = useState('');
44
- const [commentList, setCommentList] = useState<any>([]);
48
+ const [rejectReason, setRejectReason] = useState(null);
45
49
  const [isKeyboardShow, setIsKeyboardShow] = useState(false);
46
50
  const { top, bottom } = useSafeAreaInsets()
47
51
 
52
+ const isDriverApp = appTitle?.key === 'DELIVERY_APP'
53
+
48
54
  const orderCommentsList = orderCommentList(action)
49
55
 
50
56
  let codeNumberPhone, numberPhone, numberToShow;
@@ -53,20 +59,41 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
53
59
  const buttonText = t(orderTitle[action]?.btnKey, orderTitle[action]?.btnText)
54
60
  const showTextArea = ['reject', 'deliveryFailed', 'pickupFailed', 'notReady', 'forcePickUp', 'forceDelivery'].includes(action)
55
61
 
56
- const isSelectedComment = (commentKey: number) => {
57
- const found = commentList.find((comment: any) => comment?.key === commentKey)
58
- return found
59
- }
60
-
61
- const handleChangeComments = (commentItem: any) => {
62
- const found = commentList.find((comment: any) => comment?.key === commentItem.key)
63
- if (found) {
64
- const _comments = commentList.filter((comment: any) => comment?.key !== commentItem.key)
65
- setCommentList(_comments)
66
- } else {
67
- setCommentList([...commentList, commentItem])
68
- }
69
- }
62
+ const styles = StyleSheet.create({
63
+ selectOption: {
64
+ alignItems: 'center',
65
+ justifyContent: 'space-between',
66
+ minHeight: 40,
67
+ width: '100%',
68
+ paddingHorizontal: 15,
69
+ backgroundColor: theme.colors.inputChat,
70
+ borderRadius: 7.6,
71
+ },
72
+ buttonTextStyle: {
73
+ textAlign: 'left',
74
+ marginHorizontal: 0,
75
+ fontSize: 16,
76
+ lineHeight: 24,
77
+ color: '#748194',
78
+ textTransform: 'capitalize'
79
+ },
80
+ dropdownStyle: {
81
+ borderWidth: 1,
82
+ borderRadius: 8,
83
+ paddingTop: 5,
84
+ backgroundColor: '#fff',
85
+ borderColor: theme.colors.lightGray,
86
+ overflow: 'hidden',
87
+ minHeight: 155
88
+ },
89
+ rowStyle: {
90
+ display: 'flex',
91
+ borderBottomWidth: 0,
92
+ height: 36,
93
+ alignItems: 'center',
94
+ paddingHorizontal: 10
95
+ },
96
+ })
70
97
 
71
98
  const handleFocus = () => {
72
99
  viewRef?.current?.measure((x: any, y: any) => {
@@ -74,12 +101,6 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
74
101
  });
75
102
  };
76
103
 
77
- const handleFocusTimer = () => {
78
- timerRef?.current?.measure((x: any, y: any) => {
79
- scrollViewRef?.current?.scrollTo({ x: 0, y });
80
- });
81
- };
82
-
83
104
  useEffect(() => {
84
105
  const keyboardDidShowListener = Keyboard.addListener(
85
106
  'keyboardDidShow',
@@ -171,13 +192,6 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
171
192
 
172
193
  const handleAcceptOrReject = () => {
173
194
  handleFixTime();
174
-
175
- let _comments = ''
176
- if (commentList.length > 0) {
177
- commentList.map((comment: any) => (_comments += comment.content + '. '))
178
- }
179
- const _comment = _comments + comments
180
-
181
195
  let minsToSend = min;
182
196
 
183
197
  if (min > '60') minsToSend = '59';
@@ -191,7 +205,7 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
191
205
  status: 7,
192
206
  },
193
207
  rejectByBusiness: {
194
- comment: _comment,
208
+ comment: comments,
195
209
  status: 5,
196
210
  },
197
211
  acceptByDriver: {
@@ -199,28 +213,34 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
199
213
  status: 8,
200
214
  },
201
215
  rejectByDriver: {
202
- comment: _comment,
216
+ comment: comments,
203
217
  status: 6,
218
+ reject_reason: rejectReason
204
219
  },
205
220
  pickupFailedByDriver: {
206
- comment: _comment,
207
- status: 10
221
+ comment: comments,
222
+ status: 10,
223
+ reject_reason: rejectReason
208
224
  },
209
225
  deliveryFailedByDriver: {
210
- comment: _comment,
211
- status: 12
226
+ comment: comments,
227
+ status: 12,
228
+ reject_reason: rejectReason
212
229
  },
213
230
  orderNotReady: {
214
- comment: _comment,
215
- status: 14
231
+ comment: comments,
232
+ status: 14,
233
+ reject_reason: rejectReason
216
234
  },
217
235
  forcePickUp: {
218
- reasons: _comment,
219
- status: 9
236
+ reasons: comments,
237
+ status: 9,
238
+ reject_reason: rejectReason
220
239
  },
221
240
  forceDelivery: {
222
- reasons: _comment,
223
- status: 11
241
+ reasons: comments,
242
+ status: 11,
243
+ reject_reason: rejectReason
224
244
  }
225
245
  };
226
246
 
@@ -413,25 +433,45 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
413
433
  onBlur={() => actions && action === 'accept' && timerRef?.current?.focus?.()}
414
434
  />
415
435
 
416
- {orderCommentsList && (
436
+ {orderCommentsList && isDriverApp && (
417
437
  <CommentsButtonGroup>
418
- {orderCommentsList?.list?.map((comment: any) => (
419
- <OButton
420
- key={comment.key}
421
- text={comment.content}
422
- bgColor={isSelectedComment(comment.key) ? theme.colors.primary : theme.colors.tabBar}
423
- borderColor={isSelectedComment(comment.key) ? theme.colors.primary : theme.colors.tabBar}
424
- textStyle={{
425
- color: isSelectedComment(comment.key) ? theme.colors.white : theme.colors.darkText,
426
- fontSize: 12,
427
- paddingRight: isSelectedComment(comment.key) ? 15 : 0
428
- }}
429
- style={{ height: 35, paddingLeft: 5, paddingRight: 5, marginHorizontal: 3, marginVertical: 10 }}
430
- imgRightSrc={isSelectedComment(comment.key) ? theme.images.general.close : null}
431
- imgRightStyle={{ tintColor: theme.colors.white, right: 5, margin: 5 }}
432
- onClick={() => handleChangeComments(comment) }
433
- />
434
- ))}
438
+ <SelectDropdown
439
+ defaultButtonText={t('REJECT_REASONS_OPTIONS', 'Reject reasons')}
440
+ data={orderCommentsList?.list}
441
+ onSelect={(selectedItem) => {
442
+ setRejectReason(selectedItem?.value)
443
+ }}
444
+ buttonTextAfterSelection={(selectedItem) => selectedItem.content}
445
+ rowTextForSelection={(item) => item.key}
446
+ buttonStyle={styles.selectOption}
447
+ buttonTextStyle={styles.buttonTextStyle}
448
+ renderDropdownIcon={isOpened => {
449
+ return <FeatherIcon name={isOpened ? 'chevron-up' : 'chevron-down'} color={'#444'} size={18} />;
450
+ }}
451
+ dropdownStyle={styles.dropdownStyle}
452
+ dropdownOverlayColor='transparent'
453
+ rowStyle={styles.rowStyle}
454
+ renderCustomizedRowChild={(item) => {
455
+ return (
456
+ <View
457
+ style={{
458
+ flexDirection: 'row',
459
+ alignItems: 'center'
460
+ }}
461
+ >
462
+ <View>
463
+ <OText
464
+ size={14}
465
+ color={'#748194'}
466
+ style={{ textTransform: 'capitalize' }}
467
+ >
468
+ {item?.content}
469
+ </OText>
470
+ </View>
471
+ </View>
472
+ );
473
+ }}
474
+ />
435
475
  </CommentsButtonGroup>
436
476
  )}
437
477
 
@@ -39,4 +39,5 @@ export const Comments = styled.View`
39
39
  export const CommentsButtonGroup = styled.View`
40
40
  flex-direction: row;
41
41
  flex-wrap: wrap;
42
+ margin-top: 15px;
42
43
  `
@@ -14,7 +14,8 @@ Sound.setCategory('Playback')
14
14
 
15
15
  const windowWidth = Dimensions.get('screen').width
16
16
 
17
- const NewOrderNotificationUI = () => {
17
+ const NewOrderNotificationUI = (props: any) => {
18
+ const { isBusinessApp } = props
18
19
  const [events] = useEvent()
19
20
  const theme = useTheme()
20
21
  const [, t] = useLanguage()
@@ -76,13 +77,14 @@ const NewOrderNotificationUI = () => {
76
77
  headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }
77
78
  })
78
79
  const assignedTimeDiff = moment.utc(value?.driver?.last_order_assigned_at).local().fromNow()
79
- if (assignedTimeDiff === 'a few seconds ago') {
80
+ if (assignedTimeDiff === 'a few seconds ago' && !isBusinessApp) {
80
81
  handlePlayNotificationSound()
81
82
  clearInterval(soundTimeout)
82
83
  setCurrentEvent({ evt: 2, orderId: value?.id })
83
84
  }
84
85
  return
85
86
  }
87
+ if (evtType === 3) return
86
88
  handlePlayNotificationSound()
87
89
  clearInterval(soundTimeout)
88
90
  setCurrentEvent({
@@ -617,7 +617,7 @@ const OrdersListManagerUI = (props: OrdersOptionParams) => {
617
617
  </RightSide>
618
618
  </Sides>
619
619
 
620
- <NewOrderNotification />
620
+ <NewOrderNotification isBusinessApp={isBusinessApp} />
621
621
  {(openSearchModal || openSLASettingModal) && (
622
622
  <OModal open={openSearchModal || openSLASettingModal} entireModal customClose>
623
623
  <ModalContainer
@@ -726,7 +726,7 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
726
726
  </View>
727
727
  {/* </GestureRecognizer> */}
728
728
 
729
- <NewOrderNotification />
729
+ <NewOrderNotification isBusinessApp={isBusinessApp} />
730
730
  {(openSearchModal || openSLASettingModal) && (
731
731
  <OModal open={openSearchModal || openSLASettingModal} entireModal customClose>
732
732
  <ModalContainer
@@ -438,7 +438,7 @@ const CartUI = (props: any) => {
438
438
  </BusinessItemAccordion>
439
439
 
440
440
  <OModal
441
- open={openChangeStore && props.isFranchiseApp}
441
+ open={openChangeStore}
442
442
  entireModal
443
443
  customClose
444
444
  onClose={() => setOpenChangeStore(false)}
@@ -135,7 +135,11 @@ const CheckoutUI = (props: any) => {
135
135
  const [webviewPaymethod, setWebviewPaymethod] = useState<any>(null)
136
136
 
137
137
  const placeSpotTypes = [3, 4]
138
- const isWalletEnabled = configs?.wallet_enabled?.value === '1' && (configs?.wallet_cash_enabled?.value === '1' || configs?.wallet_credit_point_enabled?.value === '1')
138
+ const businessConfigs = businessDetails?.business?.configs ?? []
139
+ const isWalletCashEnabled = businessConfigs.find((config: any) => config.key === 'wallet_cash_enabled')?.value === '1'
140
+ const isWalletCreditPointsEnabled = businessConfigs.find((config: any) => config.key === 'wallet_credit_point_enabled')?.value === '1'
141
+ const isWalletEnabled = configs?.cash_wallet?.value && configs?.wallet_enabled?.value === '1' && (isWalletCashEnabled || isWalletCreditPointsEnabled)
142
+
139
143
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
140
144
  const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) || placing || errorCash ||
141
145
  cart?.subtotal < cart?.minimum || (placeSpotTypes.includes(options?.type) && !cart?.place) ||
@@ -244,7 +248,7 @@ const CheckoutUI = (props: any) => {
244
248
 
245
249
  useEffect(() => {
246
250
  if (cart?.products?.length === 0) {
247
- onNavigationRedirect('Business', { store: cart?.business?.slug })
251
+ onNavigationRedirect('Business', { store: cart?.business?.slug, header: null, logo: null })
248
252
  }
249
253
  }, [cart?.products])
250
254
 
@@ -25,7 +25,8 @@ const ForgotPasswordUI = (props: any) => {
25
25
  formState,
26
26
  handleButtonForgotPasswordClick,
27
27
  handleReCaptcha,
28
- enableReCaptcha
28
+ enableReCaptcha,
29
+ reCaptchaValue
29
30
  } = props;
30
31
  const [, t] = useLanguage();
31
32
  const [, { showToast }] = useToast();
@@ -58,9 +59,12 @@ const ForgotPasswordUI = (props: any) => {
58
59
  onChange(value.toLowerCase().replace(/[&,()%";:ç?<>{}\\[\]\s]/g, ''))
59
60
  }
60
61
 
61
- const handleOpenRecaptcha = () => {
62
+ const handleOpenRecaptcha = () => {
62
63
  setRecaptchaVerified(false)
63
- if (!recaptchaConfig?.siteKey) {
64
+ handleReCaptcha(null)
65
+ if (reCaptchaValue) return
66
+
67
+ if (!recaptchaConfig?.siteKey) {
64
68
  showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
65
69
  return
66
70
  }
@@ -76,6 +80,11 @@ const ForgotPasswordUI = (props: any) => {
76
80
  handleReCaptcha(token)
77
81
  }
78
82
 
83
+ const handleRecaptchaExpire = () => {
84
+ setRecaptchaVerified(false)
85
+ handleReCaptcha(null)
86
+ }
87
+
79
88
  useEffect(() => {
80
89
  if (!formState.loading && emailSent) {
81
90
  if (formState.result?.error) {
@@ -192,7 +201,7 @@ const ForgotPasswordUI = (props: any) => {
192
201
  siteKey={recaptchaConfig?.siteKey}
193
202
  baseUrl={recaptchaConfig?.baseUrl}
194
203
  onVerify={onRecaptchaVerify}
195
- onExpire={() => setRecaptchaVerified(false)}
204
+ onExpire={handleRecaptchaExpire}
196
205
  />
197
206
  </>
198
207
  )}
@@ -109,7 +109,7 @@ const ProfileListUI = (props: ProfileParams) => {
109
109
 
110
110
  const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
111
111
 
112
- const isWalletEnabled = configs?.wallet_enabled?.value === '1' && (configs?.wallet_cash_enabled?.value === '1' || configs?.wallet_credit_point_enabled?.value === '1')
112
+ const isWalletEnabled = configs?.cash_wallet?.value && configs?.wallet_enabled?.value === '1' && (configs?.wallet_cash_enabled?.value === '1' || configs?.wallet_credit_point_enabled?.value === '1')
113
113
  const IsPromotionsEnabled = configs?.advanced_offers_module?.value === '1' || configs?.advanced_offers_module?.value === true
114
114
  const onRedirect = (route: string, params?: any) => {
115
115
  navigation.navigate(route, params)
@@ -61,7 +61,7 @@ const WalletsUI = (props: any) => {
61
61
 
62
62
  const [tabSelected, setTabSelected] = useState(isWalletCashEnabled ? 'cash' : 'credit_point')
63
63
 
64
- const isWalletEnabled = configs?.wallet_enabled?.value === '1' && (isWalletCashEnabled || isWalletPointsEnabled)
64
+ const isWalletEnabled = configs?.cash_wallet?.value && configs?.wallet_enabled?.value === '1' && (isWalletCashEnabled || isWalletPointsEnabled)
65
65
 
66
66
  const currentWalletSelected = (walletList.wallets?.length > 0 && walletList.wallets?.find((w: any) => w.type === tabSelected)) ?? null
67
67