ordering-ui-react-native 0.12.27 → 0.12.31

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.12.27",
3
+ "version": "0.12.31",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -84,6 +84,7 @@
84
84
  "react-native-lightbox": "^0.8.1",
85
85
  "react-native-linear-gradient": "^2.5.6",
86
86
  "react-native-loading-spinner-overlay": "^2.0.0",
87
+ "react-native-map-link": "^2.8.2",
87
88
  "react-native-maps": "^0.28.0",
88
89
  "react-native-modal-dropdown": "^1.0.1",
89
90
  "react-native-onesignal": "^4.1.1",
@@ -27,6 +27,7 @@ import { PhoneInputNumber } from './src/components/PhoneInputNumber';
27
27
  import { PreviousMessages } from './src/components/PreviousMessages';
28
28
  import { PreviousOrders } from './src/components/PreviousOrders';
29
29
  import { ProductItemAccordion } from './src/components/ProductItemAccordion';
30
+ import { ReviewCustomer } from './src/components/ReviewCustomer'
30
31
  import { SearchBar } from './src/components/SearchBar';
31
32
  import { SignupForm } from './src/components/SignupForm';
32
33
  import { StoresList } from './src/components/StoresList';
@@ -91,6 +92,7 @@ export {
91
92
  PreviousMessages,
92
93
  PreviousOrders,
93
94
  ProductItemAccordion,
95
+ ReviewCustomer,
94
96
  SafeAreaContainerLayout,
95
97
  SearchBar,
96
98
  SignupForm,
@@ -4,16 +4,15 @@ import MapView, {
4
4
  PROVIDER_GOOGLE,
5
5
  Marker
6
6
  } from 'react-native-maps';
7
- import Geocoder from 'react-native-geocoding';
8
7
  import { useLanguage, useConfig, useUtils } from 'ordering-components/native';
9
8
  import { GoogleMapsParams } from '../../types';
10
9
  import Alert from '../../providers/AlertProvider';
11
- import { OIconButton, OIcon, OFab, OText, OLink } from '../shared';
10
+ import { OIconButton, OIcon, OFab, OText, OButton } from '../shared';
12
11
  import Icon from 'react-native-vector-icons/FontAwesome5';
13
12
  import { useTheme } from 'styled-components/native';
14
13
  import { useLocation } from '../../hooks/useLocation';
15
- // import MapViewDirections from 'react-native-maps-directions';
16
14
  import { FloatingButton } from '../FloatingButton';
15
+ import { showLocation } from 'react-native-map-link';
17
16
 
18
17
  export const DriverMap = (props: GoogleMapsParams) => {
19
18
  const {
@@ -90,11 +89,11 @@ export const DriverMap = (props: GoogleMapsParams) => {
90
89
  content: !(errKey === 'ERROR_MAX_LIMIT_LOCATION_TO')
91
90
  ? [t(errKey, mapErrors[errKey])]
92
91
  : [
93
- `${t(errKey, mapErrors[errKey])} ${maxLimitLocation} ${t(
94
- 'METTERS',
95
- 'meters',
96
- )}`,
97
- ],
92
+ `${t(errKey, mapErrors[errKey])} ${maxLimitLocation} ${t(
93
+ 'METTERS',
94
+ 'meters',
95
+ )}`,
96
+ ],
98
97
  key: errKey,
99
98
  });
100
99
  };
@@ -322,6 +321,17 @@ export const DriverMap = (props: GoogleMapsParams) => {
322
321
  arrowDistance: {
323
322
  borderWidth: 0,
324
323
  },
324
+ buttonContainer: {
325
+ width: '100%',
326
+ alignItems: 'center',
327
+ justifyContent: 'center',
328
+ paddingVertical: 10,
329
+ paddingHorizontal: 80,
330
+ },
331
+ showButton: {
332
+ alignSelf: 'center',
333
+ borderRadius: 10,
334
+ }
325
335
  });
326
336
 
327
337
  return (
@@ -453,7 +463,6 @@ export const DriverMap = (props: GoogleMapsParams) => {
453
463
  </OText>
454
464
  </View>
455
465
  </View>
456
-
457
466
  <View style={styles.facDistance}>
458
467
  <View
459
468
  style={{
@@ -475,22 +484,31 @@ export const DriverMap = (props: GoogleMapsParams) => {
475
484
  size={13}
476
485
  numberOfLines={2}
477
486
  adjustsFontSizeToFit>
478
- {`${travelTime.toFixed(2)} - ${
479
- isMin ? t('MINNUTES', 'mins') : t('HOURS', 'hours')
480
- } ${distancesFromTwoPlacesKm.toFixed(2)} km`}
487
+ {`${travelTime.toFixed(2)} - ${isMin ? t('MINNUTES', 'mins') : t('HOURS', 'hours')
488
+ } ${distancesFromTwoPlacesKm.toFixed(2)} km`}
481
489
  </OText>
482
490
  </View>
483
491
  </View>
484
492
  </View>
485
- <View>
486
- <OLink
487
- PressStyle={{paddingHorizontal: 80, paddingVertical: 10,bottom: showAcceptOrReject ? 80 : 0}}
488
- hasButton
489
- url={Platform.select({
490
- ios: `maps:0,0?q=${destination.latitude},${destination.longitude}`,
491
- android: `geo:0,0?q=${destination.latitude},${destination.longitude}`,
493
+ <View style={styles.buttonContainer}>
494
+ <OButton
495
+ imgRightSrc=''
496
+ textStyle={{ color: theme.colors.white }}
497
+ style={{
498
+ ...styles.showButton,
499
+ bottom: showAcceptOrReject ? 80 : 0
500
+ }}
501
+ onClick={() => showLocation({
502
+ latitude: destination.latitude,
503
+ longitude: destination.longitude,
504
+ sourceLatitude: userLocation.latitude,
505
+ sourceLongitude: userLocation.longitude,
506
+ naverCallerName: 'com.deliveryapp',
507
+ dialogTitle: t('SHOW_IN_OTHER_MAPS', 'Show in other maps'),
508
+ dialogMessage: t('WHAT_APP_WOULD_YOU_USE', 'What app would you like to use?'),
509
+ cancelText: t('CANCEL', 'Cancel'),
492
510
  })}
493
- shorcut={t('SHOW_IN_OTHER_MAPS', 'Show in other maps')}
511
+ text={t('SHOW_IN_OTHER_MAPS', 'Show in other maps')}
494
512
  />
495
513
  </View>
496
514
  {showAcceptOrReject && (
@@ -442,6 +442,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
442
442
  style={{
443
443
  backgroundColor: theme.colors.inputChat,
444
444
  borderRadius: 7.5,
445
+ marginBottom: 20
445
446
  }}>
446
447
  <CountryPicker
447
448
  // @ts-ignore
@@ -1,8 +1,8 @@
1
- import React from 'react'
1
+ import React, { useState } from 'react'
2
2
 
3
3
  import { Platform, StyleSheet, View } from 'react-native';
4
4
 
5
- import { OText, OLink } from '../shared'
5
+ import { OButton, OText, OLink, OModal } from '../shared'
6
6
  import {
7
7
  OrderContent,
8
8
  OrderBusiness,
@@ -23,7 +23,7 @@ import {
23
23
  useConfig,
24
24
  } from 'ordering-components/native';
25
25
  import { useTheme } from 'styled-components/native';
26
-
26
+ import { ReviewCustomer } from '../ReviewCustomer'
27
27
 
28
28
  interface OrderContent {
29
29
  order: any
@@ -37,6 +37,10 @@ export const OrderContentComponent = (props: OrderContent) => {
37
37
 
38
38
  const [{ parsePrice, parseNumber }] = useUtils();
39
39
  const [{ configs }] = useConfig();
40
+ const [openReviewModal, setOpenReviewModal] = useState(false)
41
+ const [isCustomerReviewed, setIsCustomerReviewed] = useState(false)
42
+
43
+ const pastOrderStatuses = [1, 2, 5, 6, 10, 11, 12, 16, 17]
40
44
 
41
45
  const styles = StyleSheet.create({
42
46
  linkWithIcons: {
@@ -51,8 +55,18 @@ export const OrderContentComponent = (props: OrderContent) => {
51
55
  },
52
56
  textLink: {
53
57
  color: '#365CC7'
58
+ },
59
+ btnReview: {
60
+ borderWidth: 0,
61
+ backgroundColor: theme.colors.primary,
62
+ borderRadius: 8,
54
63
  }
55
64
  })
65
+
66
+ const handleSuccessReviewed = () => {
67
+ setOpenReviewModal(false)
68
+ setIsCustomerReviewed(true)
69
+ }
56
70
  return (
57
71
  <OrderContent>
58
72
  <OrderBusiness>
@@ -232,6 +246,16 @@ export const OrderContentComponent = (props: OrderContent) => {
232
246
  {order?.customer?.zipcode}
233
247
  </OText>
234
248
  )}
249
+
250
+ {!order?.user_review && pastOrderStatuses.includes(order?.status) && !isCustomerReviewed && (
251
+ <OButton
252
+ style={styles.btnReview}
253
+ textStyle={{ color: theme.colors.white }}
254
+ text={t('REVIEW_CUSTOMER', 'Review customer')}
255
+ imgRightSrc={false}
256
+ onClick={() => setOpenReviewModal(true)}
257
+ />
258
+ )}
235
259
  </OrderCustomer>
236
260
 
237
261
  <OrderProducts>
@@ -386,6 +410,19 @@ export const OrderContentComponent = (props: OrderContent) => {
386
410
  </Table>
387
411
  </Total>
388
412
  </OrderBill>
413
+
414
+ <OModal
415
+ open={openReviewModal}
416
+ onClose={() => setOpenReviewModal(false)}
417
+ entireModal
418
+ customClose
419
+ >
420
+ <ReviewCustomer
421
+ order={order}
422
+ closeModal={() => setOpenReviewModal(false)}
423
+ onClose={() => handleSuccessReviewed()}
424
+ />
425
+ </OModal>
389
426
  </OrderContent>
390
427
  )
391
428
  }
@@ -5,7 +5,7 @@ export const OrderDetailsContainer = styled.ScrollView`
5
5
  `;
6
6
 
7
7
  export const Pickup = styled.View`
8
- padding-vertical: 10px;
8
+ padding-vertical: 20px;
9
9
  margin-bottom: 20px;
10
10
  `;
11
11
 
@@ -309,25 +309,6 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
309
309
  />
310
310
  </IconWrapper>
311
311
  </View>
312
- {isBusinessApp && (
313
- <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'flex-start', maxHeight: 40 }}>
314
- <OIcon
315
- src={theme.images.general.information}
316
- width={12}
317
- height={12}
318
- color={theme.colors.skyBlue}
319
- style={{ marginRight: 5 }}
320
- />
321
- <OText size={12}>
322
- {t('MORE_SETTINGS_GO_TO', 'For more settings go to ')}
323
- </OText>
324
- <TouchableOpacity onPress={() => { Linking.openURL('https://new-admin.tryordering.com/') }}>
325
- <OText size={12} color={theme.colors.skyBlue}>
326
- {t('LINK_MORE_SETTINGS_GO_TO', 'new-admin.ordering.co')}
327
- </OText>
328
- </TouchableOpacity>
329
- </View>
330
- )}
331
312
  <FiltersTab>
332
313
  <ScrollView
333
314
  ref={scrollRefTab}
@@ -524,85 +505,82 @@ const OrdersOptionUI = (props: OrdersOptionParams) => {
524
505
  {/* </GestureRecognizer> */}
525
506
 
526
507
  <NewOrderNotification />
527
- <OModal open={openModal} entireModal customClose>
528
- <ModalContainer
529
- nestedScrollEnabled={true}
530
- >
531
- <OIconButton
532
- icon={theme.images.general.arrow_left}
533
- borderColor={theme.colors.clear}
534
- iconColor={theme.colors.backArrow}
535
- iconStyle={{ width: 20, height: 13 }}
536
- style={{
537
- maxWidth: 40,
538
- height: 35,
539
- justifyContent: 'flex-end',
540
- marginBottom: 30,
541
- marginTop: 30
542
- }}
543
- onClick={() => setOpenModal(false)}
544
- />
545
- <ModalTitle>{t('SEARCH_ORDERS', 'Search orders')}</ModalTitle>
546
- <OInput
547
- value={search.id}
548
- onChange={(value: any) => setSearch({ ...search, id: value })}
549
- style={styles.inputStyle}
550
- placeholder={t('ORDER_NUMBER', 'Order number')}
551
- autoCorrect={false}
552
- />
553
- <OrdersOptionDate
554
- {...props}
555
- search={search}
556
- onSearch={setSearch}
557
- />
558
- <OrdersOptionStatus
559
- {...props}
560
- search={search}
561
- onSearch={setSearch}
562
- />
563
- <OrdersOptionCity
564
- {...props}
565
- search={search}
566
- onSearch={setSearch}
567
- />
568
- <OrdersOptionBusiness
569
- {...props}
570
- search={search}
571
- onSearch={setSearch}
572
- />
573
- {isBusinessApp && (
574
- <>
575
- <OrdersOptionDelivery
576
- {...props}
577
- search={search}
578
- onSearch={setSearch}
579
- />
580
- <OrdersOptionDriver
581
- {...props}
582
- search={search}
583
- onSearch={setSearch}
584
- />
585
- <OrdersOptionPaymethod
586
- {...props}
587
- search={search}
588
- onSearch={setSearch}
589
- />
590
- </>
591
- )}
592
- <OButton
593
- text={t('SEARCH', 'Search')}
594
- textStyle={{ color: theme.colors.white }}
595
- imgRightSrc={null}
596
- style={{
597
- borderRadius: 7.6,
598
- marginBottom: 70,
599
- marginTop: 60,
600
- zIndex: 12
601
- }}
602
- onClick={applyFilters}
603
- />
604
- </ModalContainer>
605
- </OModal>
508
+ {openModal && (
509
+ <OModal open={openModal} entireModal customClose>
510
+ <ModalContainer
511
+ nestedScrollEnabled={true}
512
+ >
513
+ <OIconButton
514
+ icon={theme.images.general.arrow_left}
515
+ borderColor={theme.colors.clear}
516
+ iconColor={theme.colors.backArrow}
517
+ iconStyle={{ width: 20, height: 13 }}
518
+ style={{
519
+ maxWidth: 40,
520
+ height: 35,
521
+ justifyContent: 'flex-end',
522
+ marginBottom: 30,
523
+ marginTop: 30
524
+ }}
525
+ onClick={() => setOpenModal(false)}
526
+ />
527
+ <ModalTitle>{t('SEARCH_ORDERS', 'Search orders')}</ModalTitle>
528
+ <OInput
529
+ value={search.id}
530
+ onChange={(value: any) => setSearch({ ...search, id: value })}
531
+ style={styles.inputStyle}
532
+ placeholder={t('ORDER_NUMBER', 'Order number')}
533
+ autoCorrect={false}
534
+ />
535
+ <OrdersOptionDate
536
+ {...props}
537
+ search={search}
538
+ onSearch={setSearch}
539
+ />
540
+ <OrdersOptionCity
541
+ {...props}
542
+ search={search}
543
+ onSearch={setSearch}
544
+ />
545
+ {isBusinessApp && (
546
+ <>
547
+ <OrdersOptionBusiness
548
+ {...props}
549
+ search={search}
550
+ onSearch={setSearch}
551
+ />
552
+ <OrdersOptionDelivery
553
+ {...props}
554
+ search={search}
555
+ onSearch={setSearch}
556
+ />
557
+ <OrdersOptionDriver
558
+ {...props}
559
+ search={search}
560
+ onSearch={setSearch}
561
+ />
562
+ <OrdersOptionPaymethod
563
+ {...props}
564
+ search={search}
565
+ onSearch={setSearch}
566
+ />
567
+ </>
568
+ )}
569
+ <OButton
570
+ text={t('SEARCH', 'Search')}
571
+ textStyle={{ color: theme.colors.white }}
572
+ imgRightSrc={null}
573
+ style={{
574
+ borderRadius: 7.6,
575
+ marginBottom: 70,
576
+ marginTop: 60,
577
+ zIndex: 12
578
+ }}
579
+ onClick={applyFilters}
580
+ />
581
+ </ModalContainer>
582
+ </OModal>
583
+ )}
606
584
  </>
607
585
  );
608
586
  };
@@ -0,0 +1,314 @@
1
+ import React, { useState, useEffect } from 'react'
2
+ import {
3
+ useLanguage,
4
+ useUtils,
5
+ ReviewCustomer as ReviewCustomerController
6
+ } from 'ordering-components/native'
7
+ import {
8
+ KeyboardAvoidingView,
9
+ Platform,
10
+ View,
11
+ StyleSheet,
12
+ I18nManager,
13
+ TouchableOpacity
14
+ } from 'react-native'
15
+ import { useTheme } from 'styled-components/native'
16
+ import { ReviewCustomerParams } from '../../types'
17
+ import { OButton, OText, OIconButton, OIcon, OInput } from '../shared'
18
+ import { useSafeAreaInsets } from 'react-native-safe-area-context'
19
+ import { FloatingButton } from '../FloatingButton'
20
+ import LinearGradient from 'react-native-linear-gradient'
21
+ import Alert from '../../providers/AlertProvider'
22
+
23
+ import {
24
+ Content,
25
+ ActionButtonWrapper,
26
+ CustomerInfoContainer,
27
+ RatingBarContainer,
28
+ RatingTextContainer,
29
+ CommentsButtonGroup
30
+ } from './styles'
31
+
32
+ const ReviewCustomerUI = (props: ReviewCustomerParams) => {
33
+ const {
34
+ order,
35
+ closeModal,
36
+ reviewState,
37
+ setReviewState,
38
+ actionState,
39
+ handleChangeQualification,
40
+ handleSendCustomerReview
41
+ } = props
42
+
43
+ const theme = useTheme()
44
+ const [, t] = useLanguage()
45
+ const [{ optimizeImage }] = useUtils()
46
+ const [alertState, setAlertState] = useState<{
47
+ open: boolean;
48
+ content: Array<string>;
49
+ key?: string | null;
50
+ }>({ open: false, content: [] })
51
+ const { top, bottom } = useSafeAreaInsets()
52
+ const [comments, setComments] = useState<Array<any>>([])
53
+ const [extraComment, setExtraComment] = useState('')
54
+
55
+ const styles = StyleSheet.create({
56
+ photoWrapper: {
57
+ shadowColor: theme.colors.black,
58
+ shadowRadius: 3,
59
+ shadowOffset: {width: 1, height: 4},
60
+ elevation: 3,
61
+ borderRadius: 8,
62
+ shadowOpacity: 0.1,
63
+ overflow: 'hidden'
64
+ },
65
+ statusBar: {
66
+ transform: [{ scaleX: I18nManager.isRTL ? -1 : 1 }],
67
+ height: 8,
68
+ borderRadius: 5,
69
+ marginTop: 5
70
+ },
71
+ ratingItemContainer: {
72
+ position: 'absolute',
73
+ top: -18
74
+ },
75
+ ratingItem: {
76
+ left: '-50%',
77
+ flexDirection: 'column',
78
+ alignItems: 'center'
79
+ },
80
+ ratingLineStyle: {
81
+ height: 8,
82
+ width: 1,
83
+ marginBottom: 10,
84
+ backgroundColor: theme.colors.lightGray
85
+ },
86
+ inputTextArea: {
87
+ borderColor: theme.colors.lightGray,
88
+ borderRadius: 8,
89
+ marginTop: 10,
90
+ marginBottom: 40,
91
+ height: 100,
92
+ alignItems: 'flex-start'
93
+ }
94
+ })
95
+
96
+ const qualificationList = [
97
+ { key: 1, text: t('TERRIBLE', 'Terrible'), percent: 0, parentStyle: { left: '0%' }, isInnerStyle: false, pointerColor: false },
98
+ { key: 2, text: t('BAD', 'Bad'), percent: 0.25, parentStyle: { left: '25%' }, isInnerStyle: true, pointerColor: true },
99
+ { key: 3, text: t('OKAY', 'Okay'), percent: 0.5, parentStyle: { left: '50%' }, isInnerStyle: true, pointerColor: true },
100
+ { key: 4, text: t('GOOD', 'Good'), percent: 0.75, parentStyle: { left: '75%' }, isInnerStyle: true, pointerColor: true },
101
+ { key: 5, text: t('GREAT', 'Great'), percent: 1, parentStyle: { right: '0%' }, isInnerStyle: false, pointerColor: false }
102
+ ]
103
+
104
+ const commentsList = [
105
+ { key: 0, content: t('RESPECTFUL', 'Respectful') },
106
+ { key: 1, content: t('EXCELLENT_COMMUNICATION', "Excellent communication") },
107
+ { key: 2, content: t('CORDIAL_SERVICE', 'Cordial service') }
108
+ ]
109
+ const isSelectedComment = (commentKey: number) => {
110
+ const found = comments.find((comment: any) => comment?.key === commentKey)
111
+ return found
112
+ }
113
+
114
+ const handleChangeComment = (commentItem: any) => {
115
+ const found = comments.find((comment: any) => comment?.key === commentItem.key)
116
+ if (found) {
117
+ const _comments = comments.filter((comment: any) => comment?.key !== commentItem.key)
118
+ setComments(_comments)
119
+ } else {
120
+ setComments([...comments, commentItem])
121
+ }
122
+ }
123
+
124
+ useEffect(() => {
125
+ let _comments = ''
126
+ if (comments.length > 0) {
127
+ comments.map((comment: any) => (_comments += comment.content + '. '))
128
+ }
129
+ const _comment = _comments + extraComment
130
+ setReviewState({ ...reviewState, comment: _comment })
131
+ }, [comments, extraComment])
132
+
133
+ useEffect(() => {
134
+ if (!actionState.error) return
135
+ setAlertState({
136
+ open: true,
137
+ content: actionState.error
138
+ })
139
+
140
+ }, [actionState.error])
141
+
142
+ return (
143
+ <KeyboardAvoidingView
144
+ enabled
145
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
146
+ style={{
147
+ flex: 1,
148
+ paddingHorizontal: 30,
149
+ paddingTop: 28,
150
+ marginTop: top,
151
+ marginBottom: bottom,
152
+ justifyContent: 'space-between'
153
+ }}
154
+ >
155
+ <View>
156
+ <OIconButton
157
+ icon={theme.images.general.arrow_left}
158
+ borderColor={theme.colors.clear}
159
+ iconStyle={{ width: 20, height: 16 }}
160
+ style={{
161
+ maxWidth: 40,
162
+ height: 20,
163
+ justifyContent: 'flex-end',
164
+ marginBottom: 20,
165
+ }}
166
+ onClick={() => closeModal()}
167
+ />
168
+ <OText
169
+ size={20}
170
+ weight="600"
171
+ >
172
+ {t('REVIEW_CUSTOMER', 'Review customer')}
173
+ </OText>
174
+ </View>
175
+
176
+ <Content
177
+ showsVerticalScrollIndicator={false}
178
+ contentContainerStyle={{ paddingBottom: 30 }}
179
+ >
180
+ <CustomerInfoContainer>
181
+ <View
182
+ style={{
183
+ ...styles.photoWrapper,
184
+ backgroundColor: theme.colors.white,
185
+ padding: !order?.customer?.photo ? 5 : 0
186
+ }}
187
+ >
188
+ <OIcon
189
+ url={optimizeImage(order?.customer?.photo, 'h_100,c_limit')}
190
+ src={!order?.customer?.photo && theme.images.general.user}
191
+ width={72}
192
+ height={72}
193
+ style={{ borderRadius: 7.6 }}
194
+ />
195
+ </View>
196
+ <OText
197
+ size={14}
198
+ weight="500"
199
+ style={{
200
+ marginTop: 16
201
+ }}
202
+ >
203
+ {order?.customer?.name} {order?.customer?.middle_name} {order?.customer?.lastname} {order?.customer?.second_lastname}
204
+ </OText>
205
+ </CustomerInfoContainer>
206
+ <OText
207
+ size={12}
208
+ >
209
+ {t('HOW_WAS_YOUR_CUSTOMER', 'How was your experience with _name_?').replace('_name_', `${order?.customer?.name} ${order?.customer?.middle_name} ${order?.customer?.lastname} ${order?.customer?.second_lastname}`)}
210
+ </OText>
211
+ <RatingBarContainer>
212
+ <LinearGradient
213
+ start={{ x: 0.0, y: 0.0 }}
214
+ end={{ x: qualificationList[reviewState?.qualification - 1]?.percent || 0, y: 0 }}
215
+ locations={[.9999, .9999]}
216
+ colors={[theme.colors.primary, theme.colors.tabBar]}
217
+ style={styles.statusBar}
218
+ />
219
+ <RatingTextContainer>
220
+ {qualificationList.map((qualification: any) => (
221
+ <View
222
+ key={qualification.key}
223
+ style={{ ...qualification.parentStyle, ...styles.ratingItemContainer }}
224
+ >
225
+ <TouchableOpacity
226
+ style={qualification.isInnerStyle && styles.ratingItem}
227
+ onPress={() => handleChangeQualification(qualification.key)}
228
+ >
229
+ <View
230
+ style={{
231
+ ...styles.ratingLineStyle,
232
+ backgroundColor: (qualification.pointerColor && !(reviewState?.qualification >= qualification.key)) ? theme.colors.dusk : 'transparent'
233
+ }}
234
+ />
235
+ <OText
236
+ size={12}
237
+ color={
238
+ reviewState?.qualification === qualification.key
239
+ ? theme.colors.darkText
240
+ : theme.colors.lightGray
241
+ }
242
+ >
243
+ {qualification.text}
244
+ </OText>
245
+ </TouchableOpacity>
246
+ </View>
247
+ ))}
248
+ </RatingTextContainer>
249
+ </RatingBarContainer>
250
+ <OText
251
+ size={12}
252
+ style={{ marginTop: 30 }}
253
+ >
254
+ {t('COMMENTS', 'Comments')}
255
+ </OText>
256
+ <CommentsButtonGroup>
257
+ {commentsList.map(commentItem => (
258
+ <OButton
259
+ key={commentItem.key}
260
+ text={commentItem.content}
261
+ bgColor={isSelectedComment(commentItem.key) ? theme.colors.primary : theme.colors.tabBar}
262
+ borderColor={isSelectedComment(commentItem.key) ? theme.colors.primary : theme.colors.tabBar}
263
+ textStyle={{
264
+ color: isSelectedComment(commentItem.key) ? theme.colors.white : theme.colors.darkText,
265
+ fontSize: 12,
266
+ paddingRight: isSelectedComment(commentItem.key) ? 15 : 0
267
+ }}
268
+ style={{ height: 35, paddingLeft: 5, paddingRight: 5, marginHorizontal: 3, marginVertical: 10 }}
269
+ imgRightSrc={isSelectedComment(commentItem.key) ? theme.images.general.close : null}
270
+ imgRightStyle={{ tintColor: theme.colors.white, right: 5, margin: 5 }}
271
+ onClick={() => handleChangeComment(commentItem) }
272
+ />
273
+ ))}
274
+ </CommentsButtonGroup>
275
+ <OText
276
+ size={12}
277
+ style={{ marginTop: 30 }}
278
+ >
279
+ {t('REVIEW_COMMENT_QUESTION', 'Do you want to add something?')}
280
+ </OText>
281
+ <OInput
282
+ name='comments'
283
+ onChange={(val: any) => setExtraComment(val.target.value)}
284
+ style={styles.inputTextArea}
285
+ multiline
286
+ />
287
+ </Content>
288
+
289
+ <ActionButtonWrapper>
290
+ <FloatingButton
291
+ firstButtonClick={() => handleSendCustomerReview()}
292
+ btnText={actionState.loading ? t('LOADING', 'Loading') : t('SEND_REVIEW', 'Send Review')}
293
+ color={theme.colors.primary}
294
+ widthButton={'100%'}
295
+ />
296
+ </ActionButtonWrapper>
297
+ <Alert
298
+ open={alertState.open}
299
+ onAccept={() => setAlertState({ open: false, content: [] })}
300
+ onClose={() => setAlertState({ open: false, content: [] })}
301
+ content={alertState.content}
302
+ title={t('ERROR', 'Error')}
303
+ />
304
+ </KeyboardAvoidingView>
305
+ )
306
+ }
307
+
308
+ export const ReviewCustomer = (props: any) => {
309
+ const reviewCustomerProps = {
310
+ ...props,
311
+ UIComponent: ReviewCustomerUI
312
+ }
313
+ return <ReviewCustomerController {...reviewCustomerProps} />
314
+ }
@@ -0,0 +1,28 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const Content = styled.ScrollView`
4
+ background-color: ${(props: any) => props.theme.colors.white};
5
+ margin-bottom: 30px;
6
+ `;
7
+ export const ActionButtonWrapper = styled.View`
8
+ margin-bottom: 10px;
9
+ `
10
+ export const CustomerInfoContainer = styled.View`
11
+ flex-direction: column;
12
+ align-items: center;
13
+ margin: 25px 0;
14
+ `
15
+ export const RatingBarContainer = styled.View`
16
+ margin-top: 13px;
17
+ margin-bottom: 25px;
18
+ `
19
+ export const RatingTextContainer = styled.View`
20
+ flex-direction: row;
21
+ align-items: center;
22
+ justify-content: space-between;
23
+ margin-top: 10px;
24
+ `
25
+ export const CommentsButtonGroup = styled.View`
26
+ flex-direction: row;
27
+ flex-wrap: wrap;
28
+ `
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect, useState } from 'react';
2
- import { View, StyleSheet, Dimensions } from 'react-native';
3
- import { ScrollView } from 'react-native-gesture-handler';
2
+ import { View, StyleSheet, Dimensions, Linking } from 'react-native';
3
+ import { ScrollView, TouchableOpacity } from 'react-native-gesture-handler';
4
4
  import { Placeholder, PlaceholderLine, Fade } from 'rn-placeholder';
5
5
  import NetInfo from '@react-native-community/netinfo';
6
6
  import { useTheme } from 'styled-components/native';
@@ -14,7 +14,7 @@ import {
14
14
  import { NotFoundSource } from '../NotFoundSource';
15
15
  import { SearchBar } from '../SearchBar';
16
16
  import { BusinessController } from '../BusinessController';
17
- import { OText } from '../shared';
17
+ import { OIcon, OText } from '../shared';
18
18
  import { BusinessesListingParams } from '../../types';
19
19
 
20
20
  const StoresListUI = (props: BusinessesListingParams) => {
@@ -154,7 +154,23 @@ const StoresListUI = (props: BusinessesListingParams) => {
154
154
  conditioned={false}
155
155
  />
156
156
  )}
157
-
157
+ <View style={{ flex: 1, flexDirection: 'row', justifyContent: 'flex-start', maxHeight: 40 }}>
158
+ <OIcon
159
+ src={theme.images.general.information}
160
+ width={12}
161
+ height={12}
162
+ color={theme.colors.skyBlue}
163
+ style={{ marginRight: 5 }}
164
+ />
165
+ <OText size={12}>
166
+ {t('MORE_SETTINGS_GO_TO', 'For more settings go to ')}
167
+ </OText>
168
+ <TouchableOpacity onPress={() => { Linking.openURL(t('LINK_MORE_SETTINGS_GO_TO', 'https://app.ordering.co')) }}>
169
+ <OText size={12} color={theme.colors.skyBlue}>
170
+ {t('LINK_MORE_SETTINGS_GO_TO', 'https://app.ordering.co')}
171
+ </OText>
172
+ </TouchableOpacity>
173
+ </View>
158
174
  {!error &&
159
175
  businesses?.map((business: any) => (
160
176
  <BusinessController
@@ -556,3 +556,13 @@ export interface MapViewParams {
556
556
  alertState: { open: boolean, content: Array<string>, key?: string | null },
557
557
  setAlertState: ({open, content, key} : { open: boolean, content: Array<string>, key?: string | null }) => void
558
558
  }
559
+
560
+ export interface ReviewCustomerParams {
561
+ order?: any,
562
+ closeModal?: any,
563
+ reviewState?: any,
564
+ setReviewState?: any,
565
+ actionState?: any,
566
+ handleChangeQualification?: any,
567
+ handleSendCustomerReview?: any,
568
+ }
@@ -0,0 +1 @@
1
+ declare module 'react-native-map-link'