ordering-ui-react-native 0.15.16 → 0.15.19

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.16",
3
+ "version": "0.15.19",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -378,7 +378,7 @@ const styles = StyleSheet.create({
378
378
  borderBottomLeftRadius: 10,
379
379
  borderBottomRightRadius: 10,
380
380
  borderColor: '#DBDCDB',
381
- height: 100,
381
+ height: 160,
382
382
  alignItems: 'flex-start',
383
383
  },
384
384
  quantityControl: {
@@ -66,6 +66,7 @@ export const WrapperSubOption = styled.View`
66
66
  `
67
67
 
68
68
  export const ProductComment = styled.View`
69
+ height: 160px;
69
70
  `
70
71
 
71
72
  export const ProductActions = styled.View`
@@ -25,6 +25,7 @@ import { ReviewProducts } from './src/components/ReviewProducts';
25
25
  import { ReviewDriver } from './src/components/ReviewDriver';
26
26
  import { UserProfile } from './src/components/UserProfile';
27
27
  import { MessageListing } from './src/components/MessageListing';
28
+ import { Messages } from './src/components/Messages';
28
29
  import { Help } from './src/components/Help';
29
30
  import { HelpAccountAndPayment } from './src/components/HelpAccountAndPayment';
30
31
  import { HelpGuide } from './src/components/HelpGuide';
@@ -93,6 +94,7 @@ export {
93
94
  BusinessMenuList,
94
95
  UserProfile,
95
96
  MessageListing,
97
+ Messages,
96
98
  Help,
97
99
  HelpAccountAndPayment,
98
100
  HelpGuide,
@@ -6,7 +6,7 @@ import { BusinessProductsListParams } from '../../types';
6
6
  import { OButton, OIcon, OModal, OText } from '../shared';
7
7
  import { ProductsContainer, ErrorMessage, WrapperNotFound } from './styles';
8
8
  import { Fade, Placeholder, PlaceholderLine } from 'rn-placeholder';
9
- import { View } from 'react-native';
9
+ import { View, ScrollView } from 'react-native';
10
10
  import { StyleSheet } from 'react-native';
11
11
  import { useTheme } from 'styled-components/native';
12
12
 
@@ -220,7 +220,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
220
220
  title={openDescription?.name}
221
221
  onClose={() => setOpenDescription(null)}
222
222
  >
223
- <View style={{ padding: 20 }}>
223
+ <ScrollView style={{ padding: 20 }}>
224
224
  {!!openDescription?.image && (
225
225
  <OIcon
226
226
  url={optimizeImage(openDescription?.image, 'h_100,c_limit')}
@@ -230,7 +230,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
230
230
  />
231
231
  )}
232
232
  <OText>{openDescription?.description}</OText>
233
- </View>
233
+ </ScrollView>
234
234
  </OModal>
235
235
  </ProductsContainer>
236
236
  );
@@ -168,7 +168,7 @@ const BusinessesListingUI = (props: BusinessesListingParams) => {
168
168
 
169
169
  useEffect(() => {
170
170
  if (businessesList.businesses.length > 0) {
171
- const fb = businessesList.businesses.filter((b) => b.featured == true);
171
+ const fb = businessesList.businesses.filter((b) => b.featured === true && b?.open);
172
172
  const ary = [];
173
173
  while (fb.length > 0) {
174
174
  ary.push(fb.splice(0, 2));
@@ -24,6 +24,7 @@ import AntIcon from 'react-native-vector-icons/AntDesign'
24
24
  import { TaxInformation } from '../TaxInformation';
25
25
  import { CartStoresListing } from '../CartStoresListing';
26
26
  import { OAlert } from '../../../../../src/components/shared'
27
+ import { PlaceSpot } from '../PlaceSpot'
27
28
 
28
29
  const CartUI = (props: any) => {
29
30
  const {
@@ -54,12 +55,14 @@ const CartUI = (props: any) => {
54
55
  const [canOpenUpselling, setCanOpenUpselling] = useState(false)
55
56
  const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null, type: '' })
56
57
  const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
58
+ const [openPlaceModal, setOpenPlaceModal] = useState(false)
57
59
 
58
60
  const isCartPending = cart?.status === 2
59
61
  const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled
60
62
 
61
63
  const business: any = (orderState?.carts && Object.values(orderState.carts).find((_cart: any) => _cart?.uuid === props.cartuuid)) ?? {}
62
64
  const businessId = business?.business_id ?? null
65
+ const placeSpotTypes = [3, 4]
63
66
 
64
67
  const momentFormatted = !orderState?.option?.moment
65
68
  ? t('RIGHT_NOW', 'Right Now')
@@ -353,6 +356,24 @@ const CartUI = (props: any) => {
353
356
  </OText>
354
357
  </OSTable>
355
358
  </OSTotal>
359
+ {placeSpotTypes.includes(orderState?.options?.type) && (
360
+ <OSTable style={{ marginTop: 15 }}>
361
+ <OText size={14} lineHeight={21} weight={'600'}>
362
+ {t('SPOT', 'Spot')}: {cart?.place?.name || t('NO_SELECTED', 'No selected')}
363
+ </OText>
364
+ <TouchableOpacity onPress={() => setOpenPlaceModal(true)}>
365
+ <OText
366
+ size={14}
367
+ lineHeight={21}
368
+ weight={'600'}
369
+ color={theme.colors.primary}
370
+ style={{ textDecorationLine: 'underline' }}
371
+ >
372
+ {t('EDIT', 'Edit')}
373
+ </OText>
374
+ </TouchableOpacity>
375
+ </OSTable>
376
+ )}
356
377
  {cart?.status !== 2 && (
357
378
  <OSTable>
358
379
  <View style={{ width: '100%', marginTop: 20 }}>
@@ -434,14 +455,26 @@ const CartUI = (props: any) => {
434
455
  products={cart?.products}
435
456
  />
436
457
  </OModal>
437
- <OAlert
438
- open={confirm.open}
439
- title={confirm.title}
440
- content={confirm.content}
441
- onAccept={confirm.handleOnAccept}
442
- onCancel={() => setConfirm({ ...confirm, open: false, title: null })}
443
- onClose={() => setConfirm({ ...confirm, open: false, title: null })}
458
+ <OModal
459
+ open={openPlaceModal}
460
+ title={t('CHOOSE_YOUR_SPOT', 'Choose your spot')}
461
+ onClose={() => setOpenPlaceModal(false)}
462
+ entireModal
463
+ >
464
+ <PlaceSpot
465
+ cart={cart}
466
+ isOpenPlaceSpot={openPlaceModal}
467
+ setOpenPlaceModal={setOpenPlaceModal}
444
468
  />
469
+ </OModal>
470
+ <OAlert
471
+ open={confirm.open}
472
+ title={confirm.title}
473
+ content={confirm.content}
474
+ onAccept={confirm.handleOnAccept}
475
+ onCancel={() => setConfirm({ ...confirm, open: false, title: null })}
476
+ onClose={() => setConfirm({ ...confirm, open: false, title: null })}
477
+ />
445
478
  </CContainer>
446
479
  )
447
480
  }
@@ -132,10 +132,11 @@ const CheckoutUI = (props: any) => {
132
132
  const [isDeliveryOptionModalVisible, setIsDeliveryOptionModalVisible] = useState(false)
133
133
  const [showGateway, setShowGateway] = useState<any>({ closedByUsed: false, open: false });
134
134
  const [webviewPaymethod, setWebviewPaymethod] = useState<any>(null)
135
-
136
-
135
+
136
+ const placeSpotTypes = [3, 4]
137
137
  const isWalletEnabled = configs?.wallet_enabled?.value === '1' && (configs?.wallet_cash_enabled?.value === '1' || configs?.wallet_credit_point_enabled?.value === '1')
138
138
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
139
+ const isDisabledButtonPlace = loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) || placing || errorCash || cart?.subtotal < cart?.minimum || (placeSpotTypes.includes(options?.type) && !cart?.place)
139
140
 
140
141
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
141
142
  ? JSON.parse(configs?.driver_tip_options?.value) || []
@@ -156,7 +157,7 @@ const CheckoutUI = (props: any) => {
156
157
  navigation.navigate('MomentOption')
157
158
  }
158
159
  }
159
-
160
+
160
161
  const handlePlaceOrder = () => {
161
162
  if (!userErrors.length) {
162
163
  handlerClickPlaceOrder && handlerClickPlaceOrder()
@@ -201,8 +202,8 @@ const CheckoutUI = (props: any) => {
201
202
  if (
202
203
  !user?.cellphone &&
203
204
  ((validationFields?.fields?.checkout?.cellphone?.enabled &&
204
- validationFields?.fields?.checkout?.cellphone?.required) ||
205
- configs?.verification_phone_required?.value === '1')
205
+ validationFields?.fields?.checkout?.cellphone?.required) ||
206
+ configs?.verification_phone_required?.value === '1')
206
207
  ) {
207
208
  errors.push(t('VALIDATION_ERROR_MOBILE_PHONE_REQUIRED', 'The field Phone number is required'))
208
209
  }
@@ -268,15 +269,15 @@ const CheckoutUI = (props: any) => {
268
269
  />
269
270
  </CHMomentWrapper>
270
271
  <CHMomentWrapper
271
- onPress={() => handleMomentClick()}
272
- disabled={loading}
272
+ onPress={() => handleMomentClick()}
273
+ disabled={loading}
273
274
  >
274
275
  <OText size={12} numberOfLines={1} ellipsizeMode='tail' color={theme.colors.textSecondary}>
275
276
  {options?.moment
276
277
  ? parseDate(options?.moment, { outputFormat: configs?.dates_moment_format?.value })
277
278
  : t('ASAP_ABBREVIATION', 'ASAP')}
278
279
  </OText>
279
- { isPreOrder && (
280
+ {isPreOrder && (
280
281
  <OIcon
281
282
  src={theme.images.general.arrow_down}
282
283
  width={10}
@@ -648,6 +649,14 @@ const CheckoutUI = (props: any) => {
648
649
  {t('WARNING_INVALID_PRODUCTS', 'Some products are invalid, please check them.')}
649
650
  </OText>
650
651
  )}
652
+ {placeSpotTypes.includes(options?.type) && !cart?.place && (
653
+ <OText
654
+ color={theme.colors.error}
655
+ size={12}
656
+ >
657
+ {t('WARNING_PLACE_SPOT', 'Please, select your spot to place order.')}
658
+ </OText>
659
+ )}
651
660
  </ChErrors>
652
661
  </View>
653
662
  )}
@@ -667,8 +676,8 @@ const CheckoutUI = (props: any) => {
667
676
  {!cartState.loading && cart && cart?.status !== 2 && (
668
677
  <FloatingButton
669
678
  handleClick={() => handlePlaceOrder()}
670
- isSecondaryBtn={loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) || placing || errorCash || cart?.subtotal < cart?.minimum}
671
- disabled={loading || !cart?.valid || (!paymethodSelected && cart?.balance > 0) || placing || errorCash || cart?.subtotal < cart?.minimum}
679
+ isSecondaryBtn={isDisabledButtonPlace}
680
+ disabled={isDisabledButtonPlace}
672
681
  btnText={cart?.subtotal >= cart?.minimum
673
682
  ? (
674
683
  placing
@@ -63,7 +63,7 @@ const DriverTipsUI = (props: any) => {
63
63
  return (
64
64
  <DTContainer>
65
65
  <DTWrapperTips>
66
- {driverTipsOptions.map((option: any, i: number) => (
66
+ {driverTipsOptions.map((option: any, i: number) => (
67
67
  <TouchableOpacity
68
68
  key={i}
69
69
  onPress={() => handlerChangeOption(option)}
@@ -98,27 +98,17 @@ const MessagesUI = (props: MessagesParams) => {
98
98
 
99
99
  const handleImagePicker = () => {
100
100
  launchImageLibrary({ mediaType: 'photo', maxHeight: 2048, maxWidth: 2048, includeBase64: true }, (response: any) => {
101
- if (response.didCancel) {
102
- console.log('User cancelled image picker');
103
- } else if (response.errorMessage) {
104
- console.log('ImagePicker Error: ', response.errorMessage);
101
+ if (response?.didCancel) {
102
+ showToast(ToastType.Error, t('IMAGE_CANCELLED', 'User cancelled image picker'));
103
+ } else if (response?.errorMessage) {
105
104
  showToast(ToastType.Error, response.errorMessage);
106
105
  } else {
107
- if (Platform.OS === 'ios') {
108
- if (response.uri) {
109
- const url = `data:${response.type};base64,${response.base64}`
110
- setImage && setImage(url);
111
- } else {
112
- showToast(ToastType.Error, t('IMAGE_NOT_FOUND', 'Image not found'));
113
- }
106
+ if (response?.assets?.length > 0) {
107
+ const image = response?.assets[0]
108
+ const url = `data:${image.type};base64,${image.base64}`
109
+ setImage && setImage(url);
114
110
  } else {
115
- if (response?.assets?.length > 0) {
116
- const image = response?.assets[0]
117
- const url = `data:${image.type};base64,${image.base64}`
118
- setImage && setImage(url);
119
- } else {
120
- showToast(ToastType.Error, t('IMAGE_NOT_FOUND', 'Image not found'));
121
- }
111
+ showToast(ToastType.Error, t('IMAGE_NOT_FOUND', 'Image not found'));
122
112
  }
123
113
  }
124
114
  });
@@ -237,7 +227,7 @@ const MessagesUI = (props: MessagesParams) => {
237
227
  {image && (
238
228
  <TouchableOpacity
239
229
  style={{ position: 'absolute', top: -5, right: -5, borderColor: theme.colors.backgroundDark, backgroundColor: theme.colors.white, borderRadius: 25 }}
240
- onPress={() => removeImage()}
230
+ onPress={removeImage}
241
231
  >
242
232
  <MaterialCommunityIcon name='close-circle-outline' color={theme.colors.backgroundDark} size={24} />
243
233
  </TouchableOpacity>
@@ -545,9 +535,15 @@ const styles = StyleSheet.create({
545
535
  })
546
536
 
547
537
  export const Messages = (props: MessagesParams) => {
538
+ const [allMessages, setAllMessages] = useState(props.messages)
548
539
  const MessagesProps = {
549
540
  ...props,
550
- UIComponent: MessagesUI
541
+ UIComponent: MessagesUI,
542
+ messages: allMessages,
543
+ setMessages: (values: any) => {
544
+ props.setMessages && props.setMessages(values)
545
+ setAllMessages(values)
546
+ }
551
547
  }
552
548
  return <MessagesController {...MessagesProps} />
553
549
  }
@@ -1,14 +1,11 @@
1
1
  import React, { useState, useEffect } from 'react';
2
- import { View, StyleSheet, BackHandler, KeyboardAvoidingView, Platform, Linking } from 'react-native';
3
- import Spinner from 'react-native-loading-spinner-overlay';
2
+ import { View, StyleSheet, BackHandler, Platform, Linking } from 'react-native';
4
3
  import LinearGradient from 'react-native-linear-gradient';
5
- import { Messages } from '../Messages';
6
4
  import {
7
5
  useLanguage,
8
6
  OrderDetails as OrderDetailsConTableoller,
9
7
  useUtils,
10
8
  useConfig,
11
- useSession,
12
9
  } from 'ordering-components/native';
13
10
  import { useTheme } from 'styled-components/native';
14
11
  import {
@@ -16,14 +13,10 @@ import {
16
13
  Header,
17
14
  OrderContent,
18
15
  OrderBusiness,
19
- Logo,
20
16
  OrderData,
21
17
  OrderInfo,
22
- OrderStatus,
23
18
  StaturBar,
24
- StatusImage,
25
19
  OrderCustomer,
26
- CustomerPhoto,
27
20
  InfoBlock,
28
21
  HeaderInfo,
29
22
  Customer,
@@ -31,7 +24,6 @@ import {
31
24
  Table,
32
25
  OrderBill,
33
26
  Total,
34
- NavBack,
35
27
  Icons,
36
28
  OrderDriver,
37
29
  Map,
@@ -41,7 +33,6 @@ import { OButton, OIcon, OModal, OText } from '../shared';
41
33
  import { ProductItemAccordion } from '../ProductItemAccordion';
42
34
  import { TouchableOpacity } from 'react-native-gesture-handler';
43
35
  import { OrderDetailsParams } from '../../types';
44
- import { USER_TYPE } from '../../config/constants';
45
36
  import { GoogleMap } from '../GoogleMap';
46
37
  import { verifyDecimals } from '../../utils';
47
38
  import { OSRow } from '../OrderSummary/styles';
@@ -55,7 +46,6 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
55
46
  messages,
56
47
  setMessages,
57
48
  readMessages,
58
- messagesReadList,
59
49
  isFromCheckout,
60
50
  driverLocation,
61
51
  } = props;
@@ -92,19 +82,12 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
92
82
 
93
83
  const [, t] = useLanguage();
94
84
  const [{ parsePrice, parseNumber, parseDate }] = useUtils();
95
- const [{ user }] = useSession();
96
85
  const [{ configs }] = useConfig();
97
86
 
98
- const [openModalForBusiness, setOpenModalForBusiness] = useState(false);
99
- const [openModalForDriver, setOpenModalForDriver] = useState(false);
100
87
  const [isReviewed, setIsReviewed] = useState(false)
101
- const [unreadAlert, setUnreadAlert] = useState({
102
- business: false,
103
- driver: false,
104
- });
105
88
  const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, tax: null, type: '' })
106
89
 
107
- const { order, businessData } = props.order;
90
+ const { order } = props.order;
108
91
 
109
92
  const walletName: any = {
110
93
  cash: {
@@ -293,18 +276,18 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
293
276
  percentage: 95,
294
277
  image: theme.images.order.status7,
295
278
  },
296
- {
297
- key: 22,
298
- value: t('ORDER_LOOKING_FOR_DRIVER', 'Looking for driver'),
299
- slug: 'ORDER_LOOKING_FOR_DRIVER',
300
- percentage: 35,
301
- image: theme.images.order.status8
279
+ {
280
+ key: 22,
281
+ value: t('ORDER_LOOKING_FOR_DRIVER', 'Looking for driver'),
282
+ slug: 'ORDER_LOOKING_FOR_DRIVER',
283
+ percentage: 35,
284
+ image: theme.images.order.status8
302
285
  },
303
- {
304
- key: 23,
305
- value: t('ORDER_DRIVER_ON_WAY', 'Driver on way'),
306
- slug: 'ORDER_DRIVER_ON_WAY',
307
- percentage: 45,
286
+ {
287
+ key: 23,
288
+ value: t('ORDER_DRIVER_ON_WAY', 'Driver on way'),
289
+ slug: 'ORDER_DRIVER_ON_WAY',
290
+ percentage: 45,
308
291
  image: theme.images.order.status8
309
292
  }
310
293
  ];
@@ -314,38 +297,24 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
314
297
  return objectStatus && objectStatus;
315
298
  };
316
299
 
317
- const handleOpenMessagesForBusiness = () => {
318
- setOpenModalForBusiness(true);
319
- readMessages && readMessages();
320
- setUnreadAlert({ ...unreadAlert, business: false });
321
- };
322
-
323
- const handleOpenMessagesForDriver = () => {
324
- setOpenModalForDriver(true);
300
+ const handleGoToMessages = (type: string) => {
325
301
  readMessages && readMessages();
326
- setUnreadAlert({ ...unreadAlert, driver: false });
327
- };
328
-
329
- const unreadMessages = () => {
330
- const length = messages?.messages.length;
331
- const unreadLength = order?.unread_count;
332
- const unreadedMessages = messages.messages.slice(
333
- length - unreadLength,
334
- length,
335
- );
336
- const business = unreadedMessages.some((message: any) =>
337
- message?.can_see?.includes(2),
338
- );
339
- const driver = unreadedMessages.some((message: any) =>
340
- message?.can_see?.includes(4),
341
- );
342
- setUnreadAlert({ business, driver });
343
- };
344
-
345
- const handleCloseModal = () => {
346
- setOpenModalForBusiness(false);
347
- setOpenModalForDriver(false);
348
- };
302
+ navigation.navigate(
303
+ 'MessageDetails',
304
+ {
305
+ type,
306
+ order,
307
+ messages,
308
+ setMessages,
309
+ orderId: order?.id,
310
+ business: type === 'business',
311
+ driver: type === 'driver',
312
+ onClose: () => navigation?.canGoBack()
313
+ ? navigation.goBack()
314
+ : navigation.navigate('BottomTab', { screen: 'MyOrders' }),
315
+ }
316
+ )
317
+ }
349
318
 
350
319
  const handleArrowBack: any = () => {
351
320
  if (!isFromCheckout) {
@@ -394,14 +363,6 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
394
363
  };
395
364
  }, []);
396
365
 
397
- useEffect(() => {
398
- if (messagesReadList?.length) {
399
- openModalForBusiness
400
- ? setUnreadAlert({ ...unreadAlert, business: false })
401
- : setUnreadAlert({ ...unreadAlert, driver: false });
402
- }
403
- }, [messagesReadList]);
404
-
405
366
  const locations = [
406
367
  {
407
368
  ...order?.driver?.location,
@@ -430,10 +391,6 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
430
391
  }
431
392
  }, [driverLocation]);
432
393
 
433
- useEffect(() => {
434
- console.log('order: ', order)
435
- }, [order]);
436
-
437
394
  return (
438
395
  <OrderDetailsContainer keyboardShouldPersistTaps="handled">
439
396
  {(!order || Object.keys(order).length === 0) && (
@@ -481,7 +438,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
481
438
  <PlaceholderLine width={65} height={10} />
482
439
  <PlaceholderLine width={80} height={10} />
483
440
  <PlaceholderLine width={70} height={10} />
484
- <View style={{marginTop: 10}}>
441
+ <View style={{ marginTop: 10 }}>
485
442
  <PlaceholderLine width={60} height={20} />
486
443
  <PlaceholderLine width={40} height={10} />
487
444
  </View>
@@ -610,7 +567,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
610
567
  )}
611
568
  <TouchableOpacity
612
569
  style={{ paddingStart: 5 }}
613
- onPress={() => handleOpenMessagesForBusiness()}>
570
+ onPress={() => handleGoToMessages('business')}>
614
571
  <OIcon
615
572
  src={theme.images.general.chat}
616
573
  width={16}
@@ -739,7 +696,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
739
696
  </OText>
740
697
  <Icons>
741
698
  <TouchableOpacity
742
- onPress={() => handleOpenMessagesForDriver()}>
699
+ onPress={() => handleGoToMessages('driver')}>
743
700
  <OIcon
744
701
  src={theme.images.general.chat}
745
702
  width={16}
@@ -1022,22 +979,6 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
1022
979
  </OrderContent>
1023
980
  </>
1024
981
  )}
1025
- <OModal
1026
- open={openModalForBusiness || openModalForDriver}
1027
- entireModal
1028
- customClose
1029
- onClose={() => handleCloseModal()}>
1030
- <Messages
1031
- type={openModalForBusiness ? USER_TYPE.BUSINESS : USER_TYPE.DRIVER}
1032
- orderId={order?.id}
1033
- messages={messages}
1034
- order={order}
1035
- business={openModalForBusiness}
1036
- driver={openModalForDriver}
1037
- setMessages={setMessages}
1038
- onClose={handleCloseModal}
1039
- />
1040
- </OModal>
1041
982
  <OModal
1042
983
  open={openTaxModal.open}
1043
984
  onClose={() => setOpenTaxModal({ open: false, data: null, type: '' })}
@@ -26,6 +26,7 @@ import AntIcon from 'react-native-vector-icons/AntDesign'
26
26
  import { TaxInformation } from '../TaxInformation';
27
27
  import { TouchableOpacity } from 'react-native';
28
28
  import { OAlert } from '../../../../../src/components/shared'
29
+ import { PlaceSpot } from '../PlaceSpot'
29
30
 
30
31
  const OrderSummaryUI = (props: any) => {
31
32
  const {
@@ -49,7 +50,9 @@ const OrderSummaryUI = (props: any) => {
49
50
  const [validationFields] = useValidationFields();
50
51
  const [openTaxModal, setOpenTaxModal] = useState<any>({ open: false, data: null, type: '' })
51
52
  const [confirm, setConfirm] = useState<any>({ open: false, content: null, handleOnAccept: null, id: null, title: null })
53
+ const [openPlaceModal, setOpenPlaceModal] = useState(false)
52
54
  const isCouponEnabled = validationFields?.fields?.checkout?.coupon?.enabled;
55
+ const placeSpotTypes = [3, 4]
53
56
 
54
57
  const handleDeleteClick = (product: any) => {
55
58
  removeProduct(product, cart)
@@ -301,6 +304,24 @@ const OrderSummaryUI = (props: any) => {
301
304
  </OSTable>
302
305
  </View>
303
306
  )}
307
+ {placeSpotTypes.includes(orderState?.options?.type) && (
308
+ <OSTable style={{ marginTop: 15 }}>
309
+ <OText size={14} lineHeight={21} weight={'600'}>
310
+ {t('SPOT', 'Spot')}: {cart?.place?.name || t('NO_SELECTED', 'No selected')}
311
+ </OText>
312
+ <TouchableOpacity onPress={() => setOpenPlaceModal(true)}>
313
+ <OText
314
+ size={14}
315
+ lineHeight={21}
316
+ weight={'600'}
317
+ color={theme.colors.primary}
318
+ style={{ textDecorationLine: 'underline' }}
319
+ >
320
+ {t('EDIT', 'Edit')}
321
+ </OText>
322
+ </TouchableOpacity>
323
+ </OSTable>
324
+ )}
304
325
  {cart?.status !== 2 && (
305
326
  <OSTable>
306
327
  <View style={{ width: '100%', marginTop: 20 }}>
@@ -349,6 +370,18 @@ const OrderSummaryUI = (props: any) => {
349
370
  products={cart?.products}
350
371
  />
351
372
  </OModal>
373
+ <OModal
374
+ open={openPlaceModal}
375
+ title={t('CHOOSE_YOUR_SPOT', 'Choose your spot')}
376
+ onClose={() => setOpenPlaceModal(false)}
377
+ entireModal
378
+ >
379
+ <PlaceSpot
380
+ cart={cart}
381
+ isOpenPlaceSpot={openPlaceModal}
382
+ setOpenPlaceModal={setOpenPlaceModal}
383
+ />
384
+ </OModal>
352
385
  <OAlert
353
386
  open={confirm.open}
354
387
  title={confirm.title}
@@ -0,0 +1,114 @@
1
+ import React, { useEffect, useState } from 'react'
2
+ import { View } from 'react-native'
3
+ import { PlaceSpot as PlaceSpotController, useLanguage } from 'ordering-components/native'
4
+ import { PlaceGroupContainer, PlaceSpotContainer } from './styles'
5
+ import { NotFoundSource } from '../NotFoundSource'
6
+ import { OText, ODropDown } from '../shared'
7
+ import { Placeholder, PlaceholderLine } from 'rn-placeholder'
8
+ import { PlaceSpotParams } from '../../types'
9
+
10
+ const PlaceSpotUI = (props: PlaceSpotParams) => {
11
+ const {
12
+ isOpenPlaceSpot,
13
+ cart,
14
+ placesState,
15
+ handleChangePlace,
16
+ getPlacesList,
17
+ setOpenPlaceModal
18
+ } = props
19
+
20
+ const [, t] = useLanguage()
21
+ const [placeGroupSelected, setPlaceGroupSelected] = useState<any>(null)
22
+
23
+ const getPlacesGroups = () => {
24
+ const groups = placesState.placeGroups?.filter((group: any) => group?.enabled && placesState?.places?.find((place: any) => place?.enabled && place?.place_group_id === group?.id))
25
+ return groups.map((group: any) => ({
26
+ value: group,
27
+ content: group?.name,
28
+ showOnSelected: group?.name
29
+ }))
30
+ }
31
+
32
+ const getPlaces = () => {
33
+ const places = placeGroupSelected && placesState?.places?.filter((place: any) => place?.enabled && place?.place_group_id === placeGroupSelected?.id)
34
+ return places.map((place: any) => ({
35
+ value: place,
36
+ content: place.name,
37
+ showOnSelected: place.name
38
+ }))
39
+ }
40
+
41
+ const handlerChangePlace = (place: any) => {
42
+ setOpenPlaceModal(false)
43
+ handleChangePlace(place)
44
+ }
45
+
46
+
47
+ useEffect(() => {
48
+ if (!placesState?.loading) {
49
+ const placeGroupOnCart = placesState?.placeGroups.find((group: any) => group?.id === cart?.place?.place_group_id)
50
+ setPlaceGroupSelected(placeGroupOnCart)
51
+ }
52
+ }, [placesState])
53
+
54
+ useEffect(() => {
55
+ getPlacesList()
56
+ }, [isOpenPlaceSpot])
57
+
58
+ return (
59
+ <PlaceSpotContainer>
60
+ {(placesState.error || placesState?.placeGroups?.length === 0) && !placesState?.loading && (
61
+ <NotFoundSource
62
+ content={t('NO_PLACES_THIS_BUSINESS', 'There are not places for this business')}
63
+ />
64
+ )}
65
+ {placesState?.loading && (
66
+ <Placeholder>
67
+ <PlaceGroupContainer>
68
+ <PlaceholderLine width={100} height={25} />
69
+ <PlaceholderLine height={30} />
70
+ </PlaceGroupContainer>
71
+ <View>
72
+ <PlaceholderLine width={120} height={25} />
73
+ <PlaceholderLine height={30} />
74
+ </View>
75
+ </Placeholder>
76
+ )}
77
+ {!(placesState.error || placesState?.placeGroups?.length === 0) && !placesState?.loading && (
78
+ <>
79
+ <PlaceGroupContainer>
80
+ <OText size={16} mBottom={10}>{t('PLACE_GROUP', 'Place group')}</OText>
81
+ <ODropDown
82
+ placeholder={t('PLACE_GROUP', 'Place group')}
83
+ options={getPlacesGroups()}
84
+ onSelect={(group: any) => setPlaceGroupSelected(group)}
85
+ defaultValue={placeGroupSelected ?? cart?.place}
86
+ isModal
87
+ />
88
+ </PlaceGroupContainer>
89
+ {placeGroupSelected && (
90
+ <View>
91
+ <OText size={16} mBottom={10}>{t('SELECT_YOUR_SPOT', 'Select your spot')}</OText>
92
+ <ODropDown
93
+ onSelect={(place: any) => handlerChangePlace(place)}
94
+ placeholder={t('SELECT_YOUR_SPOT', 'Select your spot')}
95
+ options={getPlaces()}
96
+ defaultValue={placesState?.places?.find((place : any) => place?.id === cart?.place_id)}
97
+ isModal
98
+ />
99
+ </View>
100
+ )}
101
+ </>
102
+ )}
103
+ </PlaceSpotContainer>
104
+ )
105
+ }
106
+
107
+ export const PlaceSpot = (props: PlaceSpotParams) => {
108
+ const placeSpotProps = {
109
+ ...props,
110
+ UIComponent: PlaceSpotUI
111
+ }
112
+
113
+ return <PlaceSpotController {...placeSpotProps} />
114
+ }
@@ -0,0 +1,11 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const PlaceSpotContainer = styled.View`
4
+ min-height: 300px;
5
+ padding: 20px;
6
+ `
7
+
8
+ export const PlaceGroupContainer = styled.View`
9
+ margin-bottom: 40px;
10
+ margin-top: 20px;
11
+ `
@@ -887,7 +887,6 @@ export const ProductOptionsUI = (props: any) => {
887
887
  <OIcon
888
888
  src={theme.images.general.minus}
889
889
  width={16}
890
- style={{ borderWidth: 1, borderColor: 'red' }}
891
890
  color={
892
891
  productCart.quantity === 1 || isSoldOut
893
892
  ? theme.colors.backgroundGray
@@ -931,7 +930,6 @@ export const ProductOptionsUI = (props: any) => {
931
930
  <OIcon
932
931
  src={theme.images.general.plus}
933
932
  width={16}
934
- style={{ borderWidth: 1, borderColor: 'red' }}
935
933
  color={
936
934
  maxProductQuantity <= 0 ||
937
935
  productCart.quantity >= maxProductQuantity ||
@@ -16,6 +16,7 @@ import { LogoutButton } from '../LogoutButton'
16
16
  import { LanguageSelector } from '../LanguageSelector'
17
17
  import MessageCircle from 'react-native-vector-icons/AntDesign'
18
18
  import Ionicons from 'react-native-vector-icons/Ionicons'
19
+ import FastImage from 'react-native-fast-image'
19
20
 
20
21
  import {
21
22
  OIcon,
@@ -142,12 +143,13 @@ const ProfileListUI = (props: ProfileParams) => {
142
143
  <CenterView style={styles.pagePadding}>
143
144
  <View style={styles.photo}>
144
145
  {user?.photo ? (
145
- <OIcon
146
- url={user?.photo}
147
- cover
148
- width={60}
149
- height={60}
150
- borderRadius={8}
146
+ <FastImage
147
+ style={{ height: 60, width: 60, borderRadius: 8 }}
148
+ source={{
149
+ uri: user?.photo,
150
+ priority: FastImage.priority.normal,
151
+ }}
152
+ resizeMode={FastImage.resizeMode.cover}
151
153
  />
152
154
  ) : (
153
155
  <Ionicons name='person-outline' size={50} style={{ marginRight: 10 }} />
@@ -21,6 +21,7 @@ import NavBar from '../NavBar';
21
21
  import { Container } from '../../layouts/Container';
22
22
  import { VerifyPhone } from '../VerifyPhone'
23
23
  import Ionicons from 'react-native-vector-icons/Ionicons'
24
+ import FastImage from 'react-native-fast-image'
24
25
 
25
26
  const ProfileUI = (props: ProfileParams) => {
26
27
  const {
@@ -288,12 +289,13 @@ const ProfileUI = (props: ProfileParams) => {
288
289
  <CenterView style={styles.pagePadding}>
289
290
  <View style={styles.photo}>
290
291
  {user?.photo ? (
291
- <OIcon
292
- url={user?.photo}
293
- cover
294
- width={60}
295
- height={60}
296
- borderRadius={8}
292
+ <FastImage
293
+ style={{ height: 60, width: 80, borderRadius: 8 }}
294
+ source={{
295
+ uri: user?.photo,
296
+ priority: FastImage.priority.normal,
297
+ }}
298
+ resizeMode={FastImage.resizeMode.cover}
297
299
  />
298
300
  ) : (
299
301
  <Ionicons name='person-outline' size={50} />
@@ -383,7 +383,7 @@ export interface MessagesParams {
383
383
  handleSend?: () => {},
384
384
  setImage?: (image: string | null) => {},
385
385
  setMessage?: (comment: string) => {},
386
- setMessages?: () => {},
386
+ setMessages?: (image: any | null) => {},
387
387
  readMessages?: () => {},
388
388
  onClose?: () => void,
389
389
  isMeesageListing?: boolean,
@@ -546,3 +546,12 @@ export interface BusinessSearchParams {
546
546
  export interface NoNetworkParams {
547
547
  image?: any,
548
548
  }
549
+
550
+ export interface PlaceSpotParams {
551
+ isOpenPlaceSpot?: boolean,
552
+ cart?: any ,
553
+ placesState?: any,
554
+ handleChangePlace?: any,
555
+ getPlacesList?: any,
556
+ setOpenPlaceModal?: any
557
+ }