ordering-ui-react-native 0.9.2 → 0.9.6

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.
Files changed (37) hide show
  1. package/package.json +1 -1
  2. package/src/DeliveryApp.tsx +2 -1
  3. package/src/components/OrdersOption/test.tsx +410 -0
  4. package/src/components/PreviousOrders/index.tsx +14 -1
  5. package/src/components/ReviewDriver/index.tsx +313 -0
  6. package/src/components/ReviewDriver/styles.tsx +38 -0
  7. package/src/components/ReviewOrder/index.tsx +231 -103
  8. package/src/components/ReviewOrder/styles.tsx +24 -11
  9. package/src/components/ReviewProducts/index.tsx +113 -0
  10. package/src/components/ReviewProducts/styles.tsx +16 -0
  11. package/src/components/SingleProductReview/index.tsx +166 -0
  12. package/src/components/SingleProductReview/styles.tsx +26 -0
  13. package/src/components/shared/OButton.tsx +0 -1
  14. package/src/index.tsx +9 -0
  15. package/src/layouts/FloatingBottomContainer.tsx +26 -0
  16. package/src/navigators/HomeNavigator.tsx +12 -0
  17. package/src/pages/ReviewDriver.tsx +30 -0
  18. package/src/pages/ReviewOrder.tsx +5 -4
  19. package/src/pages/ReviewProducts.tsx +30 -0
  20. package/src/theme.json +2 -1
  21. package/src/types/index.tsx +27 -2
  22. package/themes/business/src/components/Chat/index.tsx +1 -0
  23. package/themes/business/src/components/DriverMap/index.tsx +31 -6
  24. package/themes/business/src/components/OrderDetails/index.tsx +39 -13
  25. package/themes/business/src/components/OrderDetailsDelivery/index.tsx +17 -4
  26. package/themes/business/src/components/OrdersOption/index.tsx +24 -12
  27. package/themes/business/src/components/PreviousOrders/index.tsx +54 -53
  28. package/themes/business/src/components/StoresList/index.tsx +3 -6
  29. package/themes/business/src/components/UserFormDetails/index.tsx +5 -4
  30. package/themes/business/src/components/UserProfileForm/index.tsx +9 -8
  31. package/themes/business/src/hooks/useLocation.tsx +1 -1
  32. package/themes/business/src/types/index.tsx +6 -0
  33. package/themes/doordash/src/components/PreviousOrders/index.tsx +14 -1
  34. package/themes/instacart/src/components/PreviousOrders/index.tsx +14 -1
  35. package/themes/original/src/components/PreviousOrders/index.tsx +4 -0
  36. package/themes/uber-eats/src/components/AddressForm/index.tsx +2 -0
  37. package/themes/uber-eats/src/components/PreviousOrders/index.tsx +14 -1
@@ -0,0 +1,313 @@
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, Button } 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
+ paddingTop={0}
195
+ />
196
+ <DriverPhotoContainer>
197
+ <View
198
+ style={{
199
+ ...styles.photoWrapper,
200
+ backgroundColor: theme.colors.white,
201
+ padding: !order?.driver?.photo ? 5 : 0
202
+ }}
203
+ >
204
+ <OIcon
205
+ url={order?.driver?.photo}
206
+ src={!order?.driver?.photo && theme.images.general.user}
207
+ cover={order?.driver?.photo ? true: false}
208
+ width={80}
209
+ height={80}
210
+ />
211
+ </View>
212
+ <OText weight={500} style={{ marginVertical: 10 }}>{order?.driver?.name} {order?.driver?.lastname}</OText>
213
+ </DriverPhotoContainer>
214
+
215
+ <View style={{flex: 1, justifyContent: 'flex-end'}}>
216
+ <FormReviews>
217
+ <OText mBottom={13}>{t('HOW_WAS_YOUR_DRIVER', 'How was your driver?')}</OText>
218
+ <RatingBarContainer>
219
+ <LinearGradient
220
+ start={{ x: 0.0, y: 0.0 }}
221
+ end={{ x: qualificationList[dirverReviews?.qualification - 1]?.percent || 0, y: 0 }}
222
+ locations={[.9999, .9999]}
223
+ colors={[theme.colors.primary, theme.colors.lightGray]}
224
+ style={styles.statusBar}
225
+ />
226
+ <RatingTextContainer>
227
+ {qualificationList.map((qualification: any) => (
228
+ <View
229
+ key={qualification.key}
230
+ style={{ ...qualification.parentStyle, ...styles.ratingItemContainer }}
231
+ >
232
+ <TouchableOpacity
233
+ style={qualification.isInnerStyle && styles.ratingItem}
234
+ onPress={() => handleChangeQualification(qualification.key)}
235
+ >
236
+ <View
237
+ style={{
238
+ ...styles.ratingLineStyle,
239
+ backgroundColor: (qualification.pointerColor && !(dirverReviews?.qualification >= qualification.key)) ? theme.colors.dusk : 'transparent'
240
+ }}
241
+ />
242
+ <OText size={12} color={dirverReviews?.qualification === qualification.key ? theme.colors.black : theme.colors.lightGray}>{qualification.text}</OText>
243
+ </TouchableOpacity>
244
+ </View>
245
+ ))}
246
+ </RatingTextContainer>
247
+ </RatingBarContainer>
248
+
249
+ <OText style={{ marginTop: 30 }}>{t('COMMENTS', 'Comments')}</OText>
250
+ <CommentsButtonGroup>
251
+ {commentsList.map(commentItem => (
252
+ <OButton
253
+ key={commentItem.key}
254
+ text={commentItem.content}
255
+ bgColor={isSelectedComment(commentItem.key) ? theme.colors.primary : theme.colors.lightGray}
256
+ borderColor={isSelectedComment(commentItem.key) ? theme.colors.primary : theme.colors.lightGray}
257
+ textStyle={{
258
+ color: isSelectedComment(commentItem.key) ? theme.colors.white : theme.colors.black,
259
+ fontSize: 13,
260
+ paddingRight: isSelectedComment(commentItem.key) ? 15 : 0
261
+ }}
262
+ style={{ height: 35, paddingLeft: 5, paddingRight: 5, marginHorizontal: 3, marginVertical: 10 }}
263
+ imgRightSrc={isSelectedComment(commentItem.key) ? theme.images.general.close : null}
264
+ imgRightStyle={{ tintColor: theme.colors.white, right: 5, margin: 5 }}
265
+ onClick={() => handleChangeComment(commentItem) }
266
+ />
267
+ ))}
268
+ </CommentsButtonGroup>
269
+
270
+ <OText style={{ marginTop: 30 }}>{t('REVIEW_COMMENT_QUESTION', 'Do you want to add something?')}</OText>
271
+ <Controller
272
+ control={control}
273
+ defaultValue=''
274
+ name='comments'
275
+ render={({ onChange }: any) => (
276
+ <OInput
277
+ name='comments'
278
+ onChange={(val: any) => {
279
+ onChange(val)
280
+ setExtraComment(val.target.value)
281
+ }}
282
+ style={styles.inputTextArea}
283
+ multiline
284
+ />
285
+ )}
286
+ />
287
+ </FormReviews>
288
+ </View>
289
+ </ReviewDriverContainer>
290
+ <Spinner visible={formState.loading} />
291
+ <FloatingBottomContainer>
292
+ <ActionContainer>
293
+ <OButton
294
+ textStyle={{ color: theme.colors.white, paddingRight: 10 }}
295
+ text={t('SEND_REVIEW', 'Send Review')}
296
+ style={{ borderRadius: 8 }}
297
+ imgRightStyle={{ tintColor: theme.colors.white, right: 5, margin: 5 }}
298
+ onClick={handleSubmit(handleSendReviewClick)}
299
+ />
300
+ </ActionContainer>
301
+ </FloatingBottomContainer>
302
+ </>
303
+ )
304
+ }
305
+
306
+ export const ReviewDriver = (props: any) => {
307
+ const reviewDriverProps = {
308
+ ...props,
309
+ UIComponent: ReviewDriverUI,
310
+ isToast: true
311
+ }
312
+ return <ReviewDriverController {...reviewDriverProps} />
313
+ }
@@ -0,0 +1,38 @@
1
+ import styled from 'styled-components/native'
2
+
3
+ export const ReviewDriverContainer = styled.ScrollView`
4
+ padding: 20px;
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 10px;
38
+ `