ordering-ui-react-native 0.14.85 → 0.14.88

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.
@@ -0,0 +1,314 @@
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 { reviewCommentList } from '../../../../../src/utils'
14
+
15
+ import {
16
+ ReviewDriverContainer,
17
+ DriverPhotoContainer,
18
+ FormReviews,
19
+ RatingBarContainer,
20
+ RatingTextContainer,
21
+ CommentsButtonGroup,
22
+ ActionContainer,
23
+ } from './styles'
24
+
25
+ const ReviewDriverUI = (props: ReviewDriverParams) => {
26
+ const {
27
+ order,
28
+ navigation,
29
+ formState,
30
+ dirverReviews,
31
+ setDriverReviews,
32
+ handleSendDriverReview,
33
+ onNavigationRedirect
34
+ } = props
35
+
36
+ const [, t] = useLanguage()
37
+ const theme = useTheme()
38
+ const { handleSubmit, control, errors } = useForm()
39
+ const [, { showToast }] = useToast()
40
+
41
+ const [isDriverReviewed, setIsDriverReviewed] = useState(false)
42
+
43
+ const styles = StyleSheet.create({
44
+ photoWrapper: {
45
+ shadowColor: theme.colors.black,
46
+ shadowRadius: 3,
47
+ shadowOffset: {width: 1, height: 4},
48
+ elevation: 3,
49
+ borderRadius: 8,
50
+ shadowOpacity: 0.1,
51
+ overflow: 'hidden'
52
+ },
53
+ inputTextArea: {
54
+ borderColor: theme.colors.lightGray,
55
+ borderRadius: 8,
56
+ marginTop: 10,
57
+ marginBottom: 40,
58
+ height: 100,
59
+ alignItems: 'flex-start'
60
+ },
61
+ statusBar: {
62
+ transform: [{ scaleX: I18nManager.isRTL ? -1 : 1 }],
63
+ height: 10,
64
+ borderRadius: 5,
65
+ marginTop: 5
66
+ },
67
+ ratingItemContainer: {
68
+ position: 'absolute',
69
+ top: -20
70
+ },
71
+ ratingItem: {
72
+ left: '-50%',
73
+ flexDirection: 'column',
74
+ alignItems: 'center'
75
+ },
76
+ ratingLineStyle: {
77
+ height: 10,
78
+ width: 1,
79
+ marginBottom: 10,
80
+ backgroundColor: theme.colors.dusk
81
+ }
82
+ })
83
+
84
+ const [comments, setComments] = useState<Array<any>>([])
85
+ const [extraComment, setExtraComment] = useState('')
86
+ const [alertState, setAlertState] = useState<{ open: boolean, content: Array<any>, success?: boolean }>({ open: false, content: [], success: false })
87
+
88
+ const qualificationList = [
89
+ { key: 1, text: t('TERRIBLE', 'Terrible'), percent: 0, parentStyle: { left: '0%' }, isInnerStyle: false, pointerColor: false },
90
+ { key: 2, text: t('BAD', 'Bad'), percent: 0.25, parentStyle: { left: '25%' }, isInnerStyle: true, pointerColor: true },
91
+ { key: 3, text: t('OKAY', 'Okay'), percent: 0.5, parentStyle: { left: '50%' }, isInnerStyle: true, pointerColor: true },
92
+ { key: 4, text: t('GOOD', 'Good'), percent: 0.75, parentStyle: { left: '75%' }, isInnerStyle: true, pointerColor: true },
93
+ { key: 5, text: t('GREAT', 'Great'), percent: 1, parentStyle: { right: '0%' }, isInnerStyle: false, pointerColor: false }
94
+ ]
95
+
96
+ const commentsList = reviewCommentList('driver')
97
+
98
+ const onSubmit = () => {
99
+ if (dirverReviews?.qualification === 0) {
100
+ setAlertState({
101
+ open: true,
102
+ content: dirverReviews?.qualification === 0 ? [`${t('REVIEW_QUALIFICATION_REQUIRED', 'Review qualification is required')}`] : []
103
+ })
104
+ return
105
+ }
106
+ handleSendDriverReview()
107
+ setAlertState({ ...alertState, success: true })
108
+ }
109
+
110
+ const isSelectedComment = (commentKey: number) => {
111
+ const found = comments.find((comment: any) => comment?.key === commentKey)
112
+ return found
113
+ }
114
+
115
+ const handleChangeComment = (commentItem: any) => {
116
+ const found = comments.find((comment: any) => comment?.key === commentItem.key)
117
+ if (found) {
118
+ const _comments = comments.filter((comment: any) => comment?.key !== commentItem.key)
119
+ setComments(_comments)
120
+ } else {
121
+ setComments([...comments, commentItem])
122
+ }
123
+ }
124
+
125
+ const handleChangeQualification = (qualification: number) => {
126
+ if (qualification) setDriverReviews({ ...dirverReviews, qualification: qualification })
127
+ }
128
+
129
+ const handleSendReviewClick = () => {
130
+ if (!order?.user_review && !isDriverReviewed) {
131
+ onSubmit()
132
+ } else {
133
+ onNavigationRedirect && onNavigationRedirect('MyOrders')
134
+ }
135
+ }
136
+
137
+ useEffect(() => {
138
+ if (!formState.loading && formState.result?.error) {
139
+ setAlertState({
140
+ open: true,
141
+ success: false,
142
+ content: formState.result?.result || [t('ERROR', 'Error')]
143
+ })
144
+ }
145
+ if (!formState.loading && !formState.result?.error && alertState.success) {
146
+ setIsDriverReviewed && setIsDriverReviewed(true)
147
+ onNavigationRedirect('MyOrders')
148
+ }
149
+ }, [formState])
150
+
151
+ useEffect(() => {
152
+ if (Object.keys(errors).length > 0) {
153
+ // Convert all errors in one string to show in toast provider
154
+ const list = Object.values(errors);
155
+ let stringError = '';
156
+ list.map((item: any, i: number) => {
157
+ stringError +=
158
+ i + 1 === list.length ? `- ${item.message}` : `- ${item.message}\n`;
159
+ });
160
+ showToast(ToastType.Error, stringError);
161
+ }
162
+ }, [errors])
163
+
164
+ useEffect(() => {
165
+ if (alertState.open) {
166
+ alertState.content && showToast(
167
+ ToastType.Error,
168
+ alertState.content
169
+ )
170
+ }
171
+ }, [alertState.content])
172
+
173
+ useEffect(() => {
174
+ let _comments = ''
175
+ if (comments.length > 0) {
176
+ comments.map((comment: any) => (_comments += comment.content + '. '))
177
+ }
178
+ const _comment = _comments + extraComment
179
+ setDriverReviews({ ...dirverReviews, comment: _comment })
180
+ }, [comments, extraComment])
181
+
182
+ return (
183
+ <>
184
+ <ReviewDriverContainer>
185
+ <NavBar
186
+ title={t('REVIEW_DRIVER', 'Review driver')}
187
+ titleAlign={'center'}
188
+ onActionLeft={() => navigation?.canGoBack() && navigation.goBack()}
189
+ showCall={false}
190
+ btnStyle={{ paddingLeft: 0 }}
191
+ style={{ flexDirection: 'column', alignItems: 'flex-start' }}
192
+ titleWrapStyle={{ paddingHorizontal: 0 }}
193
+ titleStyle={{ marginRight: 0, marginLeft: 0 }}
194
+ />
195
+ <DriverPhotoContainer>
196
+ <View
197
+ style={{
198
+ ...styles.photoWrapper,
199
+ backgroundColor: theme.colors.white,
200
+ padding: !order?.driver?.photo ? 5 : 0
201
+ }}
202
+ >
203
+ <OIcon
204
+ url={order?.driver?.photo}
205
+ src={!order?.driver?.photo && theme.images.general.user}
206
+ cover={order?.driver?.photo ? true: false}
207
+ width={80}
208
+ height={80}
209
+ />
210
+ </View>
211
+ <OText weight={500} style={{ marginVertical: 10 }} color={theme.colors.textNormal}>{order?.driver?.name} {order?.driver?.lastname}</OText>
212
+ </DriverPhotoContainer>
213
+
214
+ <View style={{flex: 1, justifyContent: 'flex-end'}}>
215
+ <FormReviews>
216
+ <OText mBottom={13} color={theme.colors.textNormal}>{t('HOW_WAS_YOUR_DRIVER', 'How was your driver?')}</OText>
217
+ <RatingBarContainer>
218
+ <LinearGradient
219
+ start={{ x: 0.0, y: 0.0 }}
220
+ end={{ x: qualificationList[dirverReviews?.qualification - 1]?.percent || 0, y: 0 }}
221
+ locations={[.9999, .9999]}
222
+ colors={[theme.colors.primary, theme.colors.backgroundGray200]}
223
+ style={styles.statusBar}
224
+ />
225
+ <RatingTextContainer>
226
+ {qualificationList.map((qualification: any) => (
227
+ <View
228
+ key={qualification.key}
229
+ style={{ ...qualification.parentStyle, ...styles.ratingItemContainer }}
230
+ >
231
+ <TouchableOpacity
232
+ style={qualification.isInnerStyle && styles.ratingItem}
233
+ onPress={() => handleChangeQualification(qualification.key)}
234
+ >
235
+ <View
236
+ style={{
237
+ ...styles.ratingLineStyle,
238
+ backgroundColor: (qualification.pointerColor && !(dirverReviews?.qualification >= qualification.key)) ? theme.colors.dusk : 'transparent'
239
+ }}
240
+ />
241
+ <OText size={12} color={dirverReviews?.qualification === qualification.key ? theme.colors.black : theme.colors.lightGray}>{qualification.text}</OText>
242
+ </TouchableOpacity>
243
+ </View>
244
+ ))}
245
+ </RatingTextContainer>
246
+ </RatingBarContainer>
247
+
248
+ <OText style={{ marginTop: 30 }} color={theme.colors.textNormal}>
249
+ {commentsList[dirverReviews?.qualification || 1]?.title}
250
+ </OText>
251
+ <CommentsButtonGroup>
252
+ {commentsList[dirverReviews?.qualification || 1]?.list?.map(commentItem => (
253
+ <OButton
254
+ key={commentItem.key}
255
+ text={commentItem.content}
256
+ bgColor={isSelectedComment(commentItem.key) ? theme.colors.primary : theme.colors.backgroundGray200}
257
+ borderColor={isSelectedComment(commentItem.key) ? theme.colors.primary : theme.colors.backgroundGray200}
258
+ textStyle={{
259
+ color: isSelectedComment(commentItem.key) ? theme.colors.white : theme.colors.textNormal,
260
+ fontSize: 13,
261
+ paddingRight: isSelectedComment(commentItem.key) ? 15 : 0
262
+ }}
263
+ style={{ height: 35, paddingLeft: 5, paddingRight: 5, marginHorizontal: 3, marginVertical: 10 }}
264
+ imgRightSrc={isSelectedComment(commentItem.key) ? theme.images.general.close : null}
265
+ imgRightStyle={{ tintColor: theme.colors.white, right: 5, margin: 5 }}
266
+ onClick={() => handleChangeComment(commentItem) }
267
+ />
268
+ ))}
269
+ </CommentsButtonGroup>
270
+
271
+ <OText style={{ marginTop: 30 }} color={theme.colors.textNormal}>{t('REVIEW_COMMENT_QUESTION', 'Do you want to add something?')}</OText>
272
+ <Controller
273
+ control={control}
274
+ defaultValue=''
275
+ name='comments'
276
+ render={({ onChange }: any) => (
277
+ <OInput
278
+ name='comments'
279
+ onChange={(val: any) => {
280
+ onChange(val)
281
+ setExtraComment(val.target.value)
282
+ }}
283
+ style={styles.inputTextArea}
284
+ multiline
285
+ />
286
+ )}
287
+ />
288
+ </FormReviews>
289
+ </View>
290
+ </ReviewDriverContainer>
291
+ <Spinner visible={formState.loading} />
292
+ <FloatingBottomContainer>
293
+ <ActionContainer>
294
+ <OButton
295
+ textStyle={{ color: theme.colors.white, paddingRight: 10 }}
296
+ text={t('SEND_REVIEW', 'Send Review')}
297
+ style={{ borderRadius: 8 }}
298
+ imgRightStyle={{ tintColor: theme.colors.white, right: 5, margin: 5 }}
299
+ onClick={handleSubmit(handleSendReviewClick)}
300
+ />
301
+ </ActionContainer>
302
+ </FloatingBottomContainer>
303
+ </>
304
+ )
305
+ }
306
+
307
+ export const ReviewDriver = (props: any) => {
308
+ const reviewDriverProps = {
309
+ ...props,
310
+ UIComponent: ReviewDriverUI,
311
+ isToast: true
312
+ }
313
+ return <ReviewDriverController {...reviewDriverProps} />
314
+ }
@@ -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
+ `