ordering-ui-react-native 0.14.86 → 0.14.87

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.14.86",
3
+ "version": "0.14.87",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -191,3 +191,71 @@ export const transformCountryCode = (countryCode : number) => {
191
191
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
192
192
  return R * c
193
193
  }
194
+
195
+ /**
196
+ * function to manage review comment list
197
+ * @param {number} param0 type of reviews to return
198
+ * @returns object with reviews dictionary
199
+ */
200
+ export const reviewCommentList = (type: string) => {
201
+ const [, t] = useLanguage()
202
+
203
+ const reviews: any = {
204
+ customer: {
205
+ 1: {
206
+ title: t('CUSTOMER_QUICK_COMMENT_TITLE_1', "What went wrong?"),
207
+ list: [
208
+ { key: 0, content: t('CUSTOMER_QUICK_COMMENT_1_0', "Poor communication") },
209
+ { key: 1, content: t('CUSTOMER_QUICK_COMMENT_1_1', "Wrong address") },
210
+ { key: 2, content: t('CUSTOMER_QUICK_COMMENT_1_2', "COVID-19 issue") },
211
+ { key: 3, content: t('CUSTOMER_QUICK_COMMENT_1_3', "Didn't follow instructions") },
212
+ { key: 4, content: t('CUSTOMER_QUICK_COMMENT_1_4', "Rude") },
213
+ { key: 5, content: t('CUSTOMER_QUICK_COMMENT_1_5', "Not on-time") },
214
+ ]
215
+ },
216
+ 2: {
217
+ title: t('CUSTOMER_QUICK_COMMENT_TITLE_2', "What went wrong?"),
218
+ list: [
219
+ { key: 0, content: t('CUSTOMER_QUICK_COMMENT_2_0', "Poor communication") },
220
+ { key: 1, content: t('CUSTOMER_QUICK_COMMENT_2_1', "Wrong address") },
221
+ { key: 2, content: t('CUSTOMER_QUICK_COMMENT_2_2', "COVID-19 issue") },
222
+ { key: 3, content: t('CUSTOMER_QUICK_COMMENT_2_3', "Didn't follow instructions") },
223
+ { key: 4, content: t('CUSTOMER_QUICK_COMMENT_2_4', "Rude") },
224
+ { key: 5, content: t('CUSTOMER_QUICK_COMMENT_2_5', "Not on-time") },
225
+ ]
226
+ },
227
+ 3: {
228
+ title: t('CUSTOMER_QUICK_COMMENT_TITLE_3', "What could have been better?"),
229
+ list: [
230
+ { key: 0, content: t('CUSTOMER_QUICK_COMMENT_3_0', "Poor communication") },
231
+ { key: 1, content: t('CUSTOMER_QUICK_COMMENT_3_1', "Wrong address") },
232
+ { key: 2, content: t('CUSTOMER_QUICK_COMMENT_3_2', "COVID-19 issue") },
233
+ { key: 3, content: t('CUSTOMER_QUICK_COMMENT_3_3', "Didn't follow instructions") },
234
+ { key: 4, content: t('CUSTOMER_QUICK_COMMENT_3_4', "Rude") },
235
+ { key: 5, content: t('CUSTOMER_QUICK_COMMENT_3_5', "Not on-time") },
236
+ ]
237
+ },
238
+ 4: {
239
+ title: t('CUSTOMER_QUICK_COMMENT_TITLE_4', " Tell us more"),
240
+ list: [
241
+ { key: 0, content: t('CUSTOMER_QUICK_COMMENT_4_0', "Poor communication") },
242
+ { key: 1, content: t('CUSTOMER_QUICK_COMMENT_4_1', "Wrong address") },
243
+ { key: 2, content: t('CUSTOMER_QUICK_COMMENT_4_2', "COVID-19 issue") },
244
+ { key: 3, content: t('CUSTOMER_QUICK_COMMENT_4_3', "Didn't follow instructions") },
245
+ { key: 4, content: t('CUSTOMER_QUICK_COMMENT_4_4', "Rude") },
246
+ { key: 5, content: t('CUSTOMER_QUICK_COMMENT_4_5', "Not on-time") },
247
+ ]
248
+ },
249
+ 5: {
250
+ title: t('CUSTOMER_QUICK_COMMENT_TITLE_5', "What went well?"),
251
+ list: [
252
+ { key: 0, content: t('CUSTOMER_QUICK_COMMENT_5_0', "Good communication") },
253
+ { key: 1, content: t('CUSTOMER_QUICK_COMMENT_5_1', "Friendly") },
254
+ { key: 2, content: t('CUSTOMER_QUICK_COMMENT_5_2', "Above and beyond") },
255
+ ]
256
+ },
257
+ }
258
+ }
259
+
260
+ return reviews[type]
261
+ }
@@ -20,6 +20,8 @@ import { FloatingButton } from '../FloatingButton'
20
20
  import LinearGradient from 'react-native-linear-gradient'
21
21
  import Alert from '../../providers/AlertProvider'
22
22
 
23
+ import { reviewCommentList } from '../../../../../src/utils'
24
+
23
25
  import {
24
26
  Content,
25
27
  ActionButtonWrapper,
@@ -101,11 +103,8 @@ const ReviewCustomerUI = (props: ReviewCustomerParams) => {
101
103
  { key: 5, text: t('GREAT', 'Great'), percent: 1, parentStyle: { right: '0%' }, isInnerStyle: false, pointerColor: false }
102
104
  ]
103
105
 
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
- ]
106
+ const commentsList = reviewCommentList('customer')
107
+
109
108
  const isSelectedComment = (commentKey: number) => {
110
109
  const found = comments.find((comment: any) => comment?.key === commentKey)
111
110
  return found
@@ -251,10 +250,10 @@ const ReviewCustomerUI = (props: ReviewCustomerParams) => {
251
250
  size={12}
252
251
  style={{ marginTop: 30 }}
253
252
  >
254
- {t('COMMENTS', 'Comments')}
253
+ {commentsList[reviewState?.qualification || 1]?.title}
255
254
  </OText>
256
255
  <CommentsButtonGroup>
257
- {commentsList.map(commentItem => (
256
+ {commentsList[reviewState?.qualification || 1]?.list?.map(commentItem => (
258
257
  <OButton
259
258
  key={commentItem.key}
260
259
  text={commentItem.content}
@@ -20,6 +20,8 @@ import { BusinessPreorder } from './src/components/BusinessPreorder';
20
20
  import { BusinessMenuList } from './src/components/BusinessMenuList';
21
21
  import { UserProfileForm } from './src/components/UserProfileForm';
22
22
  import { ReviewOrder } from './src/components/ReviewOrder';
23
+ import { ReviewProducts } from './src/components/ReviewProducts';
24
+ import { ReviewDriver } from './src/components/ReviewDriver';
23
25
  import { UserProfile } from './src/components/UserProfile';
24
26
  import { MessageListing } from './src/components/MessageListing';
25
27
  import { Help } from './src/components/Help';
@@ -82,6 +84,8 @@ export {
82
84
  BusinessPreorder,
83
85
  UserProfileForm,
84
86
  ReviewOrder,
87
+ ReviewProducts,
88
+ ReviewDriver,
85
89
  BusinessMenuList,
86
90
  UserProfile,
87
91
  MessageListing,
@@ -0,0 +1,315 @@
1
+ import React, { useState, useEffect } from 'react'
2
+ import { useLanguage, useToast, ToastType, ReviewDriver as ReviewDriverController } from 'ordering-components/native'
3
+ import { StyleSheet, View, I18nManager, TouchableOpacity } from 'react-native'
4
+ import { ReviewDriverParams } from '../../types'
5
+ import { useTheme } from 'styled-components/native'
6
+ import { useForm, Controller } from 'react-hook-form'
7
+ import { OText, OIcon, OButton, OInput } from '../shared'
8
+ import NavBar from '../NavBar'
9
+ import LinearGradient from 'react-native-linear-gradient'
10
+ import { FloatingBottomContainer } from '../../layouts/FloatingBottomContainer'
11
+ import Spinner from 'react-native-loading-spinner-overlay'
12
+
13
+ import {
14
+ ReviewDriverContainer,
15
+ DriverPhotoContainer,
16
+ FormReviews,
17
+ RatingBarContainer,
18
+ RatingTextContainer,
19
+ CommentsButtonGroup,
20
+ ActionContainer,
21
+ } from './styles'
22
+
23
+ const ReviewDriverUI = (props: ReviewDriverParams) => {
24
+ const {
25
+ order,
26
+ navigation,
27
+ formState,
28
+ dirverReviews,
29
+ setDriverReviews,
30
+ handleSendDriverReview,
31
+ onNavigationRedirect
32
+ } = props
33
+
34
+ const [, t] = useLanguage()
35
+ const theme = useTheme()
36
+ const { handleSubmit, control, errors } = useForm()
37
+ const [, { showToast }] = useToast()
38
+
39
+ const [isDriverReviewed, setIsDriverReviewed] = useState(false)
40
+
41
+ const styles = StyleSheet.create({
42
+ photoWrapper: {
43
+ shadowColor: theme.colors.black,
44
+ shadowRadius: 3,
45
+ shadowOffset: {width: 1, height: 4},
46
+ elevation: 3,
47
+ borderRadius: 8,
48
+ shadowOpacity: 0.1,
49
+ overflow: 'hidden'
50
+ },
51
+ inputTextArea: {
52
+ borderColor: theme.colors.lightGray,
53
+ borderRadius: 8,
54
+ marginTop: 10,
55
+ marginBottom: 40,
56
+ height: 100,
57
+ alignItems: 'flex-start'
58
+ },
59
+ statusBar: {
60
+ transform: [{ scaleX: I18nManager.isRTL ? -1 : 1 }],
61
+ height: 10,
62
+ borderRadius: 5,
63
+ marginTop: 5
64
+ },
65
+ ratingItemContainer: {
66
+ position: 'absolute',
67
+ top: -20
68
+ },
69
+ ratingItem: {
70
+ left: '-50%',
71
+ flexDirection: 'column',
72
+ alignItems: 'center'
73
+ },
74
+ ratingLineStyle: {
75
+ height: 10,
76
+ width: 1,
77
+ marginBottom: 10,
78
+ backgroundColor: theme.colors.dusk
79
+ }
80
+ })
81
+
82
+ const [comments, setComments] = useState<Array<any>>([])
83
+ const [extraComment, setExtraComment] = useState('')
84
+ const [alertState, setAlertState] = useState<{ open: boolean, content: Array<any>, success?: boolean }>({ open: false, content: [], success: false })
85
+
86
+ const qualificationList = [
87
+ { key: 1, text: t('TERRIBLE', 'Terrible'), percent: 0, parentStyle: { left: '0%' }, isInnerStyle: false, pointerColor: false },
88
+ { key: 2, text: t('BAD', 'Bad'), percent: 0.25, parentStyle: { left: '25%' }, isInnerStyle: true, pointerColor: true },
89
+ { key: 3, text: t('OKAY', 'Okay'), percent: 0.5, parentStyle: { left: '50%' }, isInnerStyle: true, pointerColor: true },
90
+ { key: 4, text: t('GOOD', 'Good'), percent: 0.75, parentStyle: { left: '75%' }, isInnerStyle: true, pointerColor: true },
91
+ { key: 5, text: t('GREAT', 'Great'), percent: 1, parentStyle: { right: '0%' }, isInnerStyle: false, pointerColor: false }
92
+ ]
93
+
94
+ const commentsList = [
95
+ { key: 0, content: t('FAST_AND_EFFICIENT', "Fast and efficient") },
96
+ { key: 1, content: t('DELIVERY_PERFECT', "Delivery perfect") },
97
+ { key: 2, content: t('EXCELLENT_COMMUNICATION', "Excellent communication") },
98
+ { key: 3, content: t('CORDIAL_SERVICE', 'Cordial service') }
99
+ ]
100
+
101
+ const onSubmit = () => {
102
+ if (dirverReviews?.qualification === 0) {
103
+ setAlertState({
104
+ open: true,
105
+ content: dirverReviews?.qualification === 0 ? [`${t('REVIEW_QUALIFICATION_REQUIRED', 'Review qualification is required')}`] : []
106
+ })
107
+ return
108
+ }
109
+ handleSendDriverReview()
110
+ setAlertState({ ...alertState, success: true })
111
+ }
112
+
113
+ const isSelectedComment = (commentKey: number) => {
114
+ const found = comments.find((comment: any) => comment?.key === commentKey)
115
+ return found
116
+ }
117
+
118
+ const handleChangeComment = (commentItem: any) => {
119
+ const found = comments.find((comment: any) => comment?.key === commentItem.key)
120
+ if (found) {
121
+ const _comments = comments.filter((comment: any) => comment?.key !== commentItem.key)
122
+ setComments(_comments)
123
+ } else {
124
+ setComments([...comments, commentItem])
125
+ }
126
+ }
127
+
128
+ const handleChangeQualification = (qualification: number) => {
129
+ if (qualification) setDriverReviews({ ...dirverReviews, qualification: qualification })
130
+ }
131
+
132
+ const handleSendReviewClick = () => {
133
+ if (!order?.user_review && !isDriverReviewed) {
134
+ onSubmit()
135
+ } else {
136
+ onNavigationRedirect && onNavigationRedirect('MyOrders')
137
+ }
138
+ }
139
+
140
+ useEffect(() => {
141
+ if (!formState.loading && formState.result?.error) {
142
+ setAlertState({
143
+ open: true,
144
+ success: false,
145
+ content: formState.result?.result || [t('ERROR', 'Error')]
146
+ })
147
+ }
148
+ if (!formState.loading && !formState.result?.error && alertState.success) {
149
+ setIsDriverReviewed && setIsDriverReviewed(true)
150
+ onNavigationRedirect('MyOrders')
151
+ }
152
+ }, [formState])
153
+
154
+ useEffect(() => {
155
+ if (Object.keys(errors).length > 0) {
156
+ // Convert all errors in one string to show in toast provider
157
+ const list = Object.values(errors);
158
+ let stringError = '';
159
+ list.map((item: any, i: number) => {
160
+ stringError +=
161
+ i + 1 === list.length ? `- ${item.message}` : `- ${item.message}\n`;
162
+ });
163
+ showToast(ToastType.Error, stringError);
164
+ }
165
+ }, [errors])
166
+
167
+ useEffect(() => {
168
+ if (alertState.open) {
169
+ alertState.content && showToast(
170
+ ToastType.Error,
171
+ alertState.content
172
+ )
173
+ }
174
+ }, [alertState.content])
175
+
176
+ useEffect(() => {
177
+ let _comments = ''
178
+ if (comments.length > 0) {
179
+ comments.map((comment: any) => (_comments += comment.content + '. '))
180
+ }
181
+ const _comment = _comments + extraComment
182
+ setDriverReviews({ ...dirverReviews, comment: _comment })
183
+ }, [comments, extraComment])
184
+
185
+ return (
186
+ <>
187
+ <ReviewDriverContainer>
188
+ <NavBar
189
+ title={t('REVIEW_DRIVER', 'Review driver')}
190
+ titleAlign={'center'}
191
+ onActionLeft={() => navigation?.canGoBack() && navigation.goBack()}
192
+ showCall={false}
193
+ btnStyle={{ paddingLeft: 0 }}
194
+ style={{ flexDirection: 'column', alignItems: 'flex-start' }}
195
+ titleWrapStyle={{ paddingHorizontal: 0 }}
196
+ titleStyle={{ marginRight: 0, marginLeft: 0 }}
197
+ />
198
+ <DriverPhotoContainer>
199
+ <View
200
+ style={{
201
+ ...styles.photoWrapper,
202
+ backgroundColor: theme.colors.white,
203
+ padding: !order?.driver?.photo ? 5 : 0
204
+ }}
205
+ >
206
+ <OIcon
207
+ url={order?.driver?.photo}
208
+ src={!order?.driver?.photo && theme.images.general.user}
209
+ cover={order?.driver?.photo ? true: false}
210
+ width={80}
211
+ height={80}
212
+ />
213
+ </View>
214
+ <OText weight={500} style={{ marginVertical: 10 }} color={theme.colors.textNormal}>{order?.driver?.name} {order?.driver?.lastname}</OText>
215
+ </DriverPhotoContainer>
216
+
217
+ <View style={{flex: 1, justifyContent: 'flex-end'}}>
218
+ <FormReviews>
219
+ <OText mBottom={13} color={theme.colors.textNormal}>{t('HOW_WAS_YOUR_DRIVER', 'How was your driver?')}</OText>
220
+ <RatingBarContainer>
221
+ <LinearGradient
222
+ start={{ x: 0.0, y: 0.0 }}
223
+ end={{ x: qualificationList[dirverReviews?.qualification - 1]?.percent || 0, y: 0 }}
224
+ locations={[.9999, .9999]}
225
+ colors={[theme.colors.primary, theme.colors.backgroundGray200]}
226
+ style={styles.statusBar}
227
+ />
228
+ <RatingTextContainer>
229
+ {qualificationList.map((qualification: any) => (
230
+ <View
231
+ key={qualification.key}
232
+ style={{ ...qualification.parentStyle, ...styles.ratingItemContainer }}
233
+ >
234
+ <TouchableOpacity
235
+ style={qualification.isInnerStyle && styles.ratingItem}
236
+ onPress={() => handleChangeQualification(qualification.key)}
237
+ >
238
+ <View
239
+ style={{
240
+ ...styles.ratingLineStyle,
241
+ backgroundColor: (qualification.pointerColor && !(dirverReviews?.qualification >= qualification.key)) ? theme.colors.dusk : 'transparent'
242
+ }}
243
+ />
244
+ <OText size={12} color={dirverReviews?.qualification === qualification.key ? theme.colors.black : theme.colors.lightGray}>{qualification.text}</OText>
245
+ </TouchableOpacity>
246
+ </View>
247
+ ))}
248
+ </RatingTextContainer>
249
+ </RatingBarContainer>
250
+
251
+ <OText style={{ marginTop: 30 }} color={theme.colors.textNormal}>{t('COMMENTS', 'Comments')}</OText>
252
+ <CommentsButtonGroup>
253
+ {commentsList.map(commentItem => (
254
+ <OButton
255
+ key={commentItem.key}
256
+ text={commentItem.content}
257
+ bgColor={isSelectedComment(commentItem.key) ? theme.colors.primary : theme.colors.backgroundGray200}
258
+ borderColor={isSelectedComment(commentItem.key) ? theme.colors.primary : theme.colors.backgroundGray200}
259
+ textStyle={{
260
+ color: isSelectedComment(commentItem.key) ? theme.colors.white : theme.colors.textNormal,
261
+ fontSize: 13,
262
+ paddingRight: isSelectedComment(commentItem.key) ? 15 : 0
263
+ }}
264
+ style={{ height: 35, paddingLeft: 5, paddingRight: 5, marginHorizontal: 3, marginVertical: 10 }}
265
+ imgRightSrc={isSelectedComment(commentItem.key) ? theme.images.general.close : null}
266
+ imgRightStyle={{ tintColor: theme.colors.white, right: 5, margin: 5 }}
267
+ onClick={() => handleChangeComment(commentItem) }
268
+ />
269
+ ))}
270
+ </CommentsButtonGroup>
271
+
272
+ <OText style={{ marginTop: 30 }} color={theme.colors.textNormal}>{t('REVIEW_COMMENT_QUESTION', 'Do you want to add something?')}</OText>
273
+ <Controller
274
+ control={control}
275
+ defaultValue=''
276
+ name='comments'
277
+ render={({ onChange }: any) => (
278
+ <OInput
279
+ name='comments'
280
+ onChange={(val: any) => {
281
+ onChange(val)
282
+ setExtraComment(val.target.value)
283
+ }}
284
+ style={styles.inputTextArea}
285
+ multiline
286
+ />
287
+ )}
288
+ />
289
+ </FormReviews>
290
+ </View>
291
+ </ReviewDriverContainer>
292
+ <Spinner visible={formState.loading} />
293
+ <FloatingBottomContainer>
294
+ <ActionContainer>
295
+ <OButton
296
+ textStyle={{ color: theme.colors.white, paddingRight: 10 }}
297
+ text={t('SEND_REVIEW', 'Send Review')}
298
+ style={{ borderRadius: 8 }}
299
+ imgRightStyle={{ tintColor: theme.colors.white, right: 5, margin: 5 }}
300
+ onClick={handleSubmit(handleSendReviewClick)}
301
+ />
302
+ </ActionContainer>
303
+ </FloatingBottomContainer>
304
+ </>
305
+ )
306
+ }
307
+
308
+ export const ReviewDriver = (props: any) => {
309
+ const reviewDriverProps = {
310
+ ...props,
311
+ UIComponent: ReviewDriverUI,
312
+ isToast: true
313
+ }
314
+ return <ReviewDriverController {...reviewDriverProps} />
315
+ }
@@ -0,0 +1,38 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const ReviewDriverContainer = styled.ScrollView`
4
+ padding: 20px 40px;
5
+ margin-bottom: 100px;
6
+ `
7
+
8
+ export const DriverPhotoContainer = styled.View`
9
+ margin-vertical: 5px;
10
+ flex-direction: column;
11
+ align-items: center;
12
+ `
13
+
14
+ export const FormReviews = styled.View`
15
+ flex: 1;
16
+ height: 100%;
17
+ margin-top: 30px;
18
+ `
19
+
20
+ export const RatingBarContainer = styled.View`
21
+ margin-top: 10px;
22
+ margin-bottom: 25px;
23
+ `
24
+
25
+ export const RatingTextContainer = styled.View`
26
+ flex-direction: row;
27
+ align-items: center;
28
+ justify-content: space-between;
29
+ margin-top: 10px;
30
+ `
31
+ export const CommentsButtonGroup = styled.View`
32
+ flex-direction: row;
33
+ flex-wrap: wrap;
34
+ `
35
+
36
+ export const ActionContainer = styled.View`
37
+ padding: 3px 30px;
38
+ `