ordering-ui-react-native 0.11.54 → 0.11.58
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 +1 -1
- package/src/components/OrderCreating/index.tsx +8 -4
- package/src/config.json +1 -1
- package/themes/instacart/index.tsx +4 -0
- package/themes/instacart/src/components/BusinessItemAccordion/index.tsx +16 -41
- package/themes/instacart/src/components/BusinessItemAccordion/styles.tsx +4 -6
- package/themes/instacart/src/components/BusinessesListing/index.tsx +2 -2
- package/themes/instacart/src/components/Cart/index.tsx +8 -5
- package/themes/instacart/src/components/Cart/styles.tsx +11 -0
- package/themes/instacart/src/components/CartContent/index.tsx +2 -1
- package/themes/instacart/src/components/NavBar/index.tsx +4 -2
- package/themes/instacart/src/components/PreviousOrders/index.tsx +1 -1
- package/themes/instacart/src/components/ReviewDriver/index.tsx +221 -0
- package/themes/instacart/src/components/ReviewDriver/styles.tsx +46 -0
- package/themes/instacart/src/components/ReviewOrder/index.tsx +304 -185
- package/themes/instacart/src/components/ReviewOrder/styles.tsx +18 -3
- package/themes/instacart/src/components/ReviewProduct/index.tsx +275 -0
- package/themes/instacart/src/components/ReviewProduct/styles.tsx +53 -0
- package/themes/instacart/src/components/SingleProductCard/index.tsx +8 -8
- package/themes/instacart/src/components/SingleProductCard/styles.tsx +4 -5
- package/themes/instacart/src/components/TagSelector/index.tsx +94 -0
- package/themes/instacart/src/components/TagSelector/styles.ts +0 -0
- package/themes/instacart/src/components/shared/OBottomStickBar.tsx +62 -0
- package/themes/instacart/src/config/constants.tsx +25 -1
- package/themes/instacart/src/types/index.tsx +25 -2
- package/themes/original/src/components/AddressForm/index.tsx +6 -2
- package/themes/original/src/components/FloatingButton/index.tsx +3 -2
- package/themes/original/src/components/FloatingButton/styles.tsx +2 -2
- package/themes/original/src/components/LoginForm/index.tsx +7 -2
- package/themes/original/src/components/ProductForm/index.tsx +5 -1
- package/themes/original/src/components/ProductForm/styles.tsx +3 -1
- package/themes/original/src/components/SignupForm/index.tsx +7 -2
- package/themes/original/src/components/UserDetails/index.tsx +3 -2
- package/themes/original/src/components/UserFormDetails/styles.tsx +0 -1
- package/themes/original/src/components/shared/OInput.tsx +1 -0
- package/themes/original/src/layouts/Container.tsx +4 -1
- package/themes/single-business/src/components/Checkout/index.tsx +2 -2
- package/themes/single-business/src/components/ForgotPasswordForm/index.tsx +2 -2
- package/themes/single-business/src/components/LastOrder/index.tsx +1 -1
- package/themes/single-business/src/components/LoginForm/index.tsx +1 -1
- package/themes/single-business/src/components/ReviewOrder/index.tsx +1 -1
- package/themes/single-business/src/components/SignupForm/index.tsx +1 -1
- package/themes/single-business/src/components/StripeRedirectForm/index.tsx +1 -1
- package/themes/single-business/src/components/UserFormDetails/index.tsx +1 -1
- package/themes/single-business/src/components/UserProfile/index.tsx +1 -1
- package/themes/single-business/src/components/UserProfileForm/index.tsx +1 -1
- package/themes/single-business/src/components/shared/OToast.tsx +1 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import React, { useState, useEffect, useCallback } from 'react'
|
|
2
|
+
import { ReviewProduct as ReviewProductController, useLanguage, ToastType, useToast } from 'ordering-components/native'
|
|
3
|
+
import { useTheme } from 'styled-components/native';
|
|
4
|
+
import { useForm, Controller } from 'react-hook-form'
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ReviewOrderContainer,
|
|
8
|
+
BusinessLogo,
|
|
9
|
+
FormReviews,
|
|
10
|
+
Category,
|
|
11
|
+
Stars,
|
|
12
|
+
BlockWrap,
|
|
13
|
+
CommentItem,
|
|
14
|
+
IconBtn,
|
|
15
|
+
HWrapper
|
|
16
|
+
} from './styles'
|
|
17
|
+
import { OButton, OIcon, OInput, OText } from '../shared'
|
|
18
|
+
import { TouchableOpacity, StyleSheet, View } from 'react-native';
|
|
19
|
+
import NavBar from '../NavBar'
|
|
20
|
+
import Spinner from 'react-native-loading-spinner-overlay'
|
|
21
|
+
|
|
22
|
+
import { ReviewProductParams } from '../../types'
|
|
23
|
+
import { REVIEW_PRODUCT_COMMENTS } from '../../config/constants';
|
|
24
|
+
import TagSelector from '../TagSelector';
|
|
25
|
+
import OBottomStickBar from '../shared/OBottomStickBar';
|
|
26
|
+
import { Container } from '../../..';
|
|
27
|
+
|
|
28
|
+
const SingleProduct = (props: any) => {
|
|
29
|
+
const {
|
|
30
|
+
handleChangeFormState,
|
|
31
|
+
formState,
|
|
32
|
+
product
|
|
33
|
+
} = props;
|
|
34
|
+
const {id, name} = product;
|
|
35
|
+
|
|
36
|
+
const theme = useTheme();
|
|
37
|
+
const [, t] = useLanguage();
|
|
38
|
+
const { control, errors } = useForm()
|
|
39
|
+
|
|
40
|
+
const [suggests] = useState(REVIEW_PRODUCT_COMMENTS.map(({key, value}) => t(key, value)));
|
|
41
|
+
const [comments, setComments] = useState([])
|
|
42
|
+
const [extraComment, setExtraComment] = useState('')
|
|
43
|
+
const [isExtra, setShowExtra] = useState(false);
|
|
44
|
+
const [isLike, setLike] = useState(0);
|
|
45
|
+
|
|
46
|
+
const singleStyle = StyleSheet.create({
|
|
47
|
+
hWrapper: {
|
|
48
|
+
flexDirection: 'row',
|
|
49
|
+
alignItems: 'center'
|
|
50
|
+
},
|
|
51
|
+
inputTextArea: {
|
|
52
|
+
borderColor: theme.colors.border,
|
|
53
|
+
borderRadius: 7.6,
|
|
54
|
+
marginVertical: 10,
|
|
55
|
+
height: 100,
|
|
56
|
+
alignItems: 'flex-start',
|
|
57
|
+
paddingVertical: 12,
|
|
58
|
+
fontSize: 10,
|
|
59
|
+
marginBottom: 30
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const onSuggestUpdate = useCallback((items) => {
|
|
64
|
+
if (items.length > 0) {
|
|
65
|
+
let selected: Array<never> = [];
|
|
66
|
+
items.map(({label, checked}: never) => {
|
|
67
|
+
if (checked === true) {
|
|
68
|
+
selected.push(label);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
setComments(selected);
|
|
72
|
+
}
|
|
73
|
+
}, []);
|
|
74
|
+
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (comments?.length === 0 && !extraComment && formState.changes?.length === 0 && isLike) return
|
|
77
|
+
let _comments = ''
|
|
78
|
+
if (comments.length > 0) {
|
|
79
|
+
comments.map(comment => (_comments += comment + '. '))
|
|
80
|
+
}
|
|
81
|
+
const _comment = _comments + extraComment
|
|
82
|
+
let found = false
|
|
83
|
+
const _changes = formState.changes.map((item: any) => {
|
|
84
|
+
if (item?.id === product?.id) {
|
|
85
|
+
found = true
|
|
86
|
+
return {
|
|
87
|
+
id: product?.id,
|
|
88
|
+
comment: _comment,
|
|
89
|
+
qualification: isLike ? 5 : 1
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return item
|
|
93
|
+
})
|
|
94
|
+
if (!found) {
|
|
95
|
+
_changes.push({
|
|
96
|
+
product_id: product?.id,
|
|
97
|
+
comment: _comment,
|
|
98
|
+
qualification: isLike ? 5 : 1
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
handleChangeFormState && handleChangeFormState(_changes)
|
|
102
|
+
}, [comments, extraComment, isLike])
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<BlockWrap key={id}>
|
|
107
|
+
<HWrapper style={{justifyContent: 'space-between', marginBottom: 14}}>
|
|
108
|
+
<OText size={12} lineHeight={18}>{name}</OText>
|
|
109
|
+
<HWrapper>
|
|
110
|
+
<IconBtn onPress={() => setLike(5)}>
|
|
111
|
+
<OIcon src={theme.images.general.thumbs_up} width={16} color={isLike == 5 ? theme.colors.primary : theme.colors.textSecondary} />
|
|
112
|
+
</IconBtn>
|
|
113
|
+
<IconBtn onPress={() => setLike(1)}>
|
|
114
|
+
<OIcon src={theme.images.general.thumbs_up} width={16} color={isLike == 1 ? theme.colors.primary : theme.colors.textSecondary} style={{transform: [{rotate: '180deg'}]}} />
|
|
115
|
+
</IconBtn>
|
|
116
|
+
</HWrapper>
|
|
117
|
+
</HWrapper>
|
|
118
|
+
<View style={{flexShrink: 1}}>
|
|
119
|
+
<TagSelector
|
|
120
|
+
items={suggests}
|
|
121
|
+
activeColor={theme.colors.primary} normalColor={'#E9ECEF'}
|
|
122
|
+
onUpdated={onSuggestUpdate}
|
|
123
|
+
/>
|
|
124
|
+
</View>
|
|
125
|
+
<TouchableOpacity onPress={() => setShowExtra(!isExtra)} style={{marginBottom: 16}}>
|
|
126
|
+
<OText size={10} lineHeight={15}
|
|
127
|
+
style={{textDecorationLine: 'underline', alignSelf: 'center'}}
|
|
128
|
+
color={isExtra ? theme.colors.primary : theme.colors.textSecondary}
|
|
129
|
+
>
|
|
130
|
+
{t('ADDITIONAL_COMMENTS', 'Additional comments')}
|
|
131
|
+
</OText>
|
|
132
|
+
</TouchableOpacity>
|
|
133
|
+
{isExtra &&
|
|
134
|
+
<FormReviews>
|
|
135
|
+
<OText size={12} lineHeight={18}>{t('DO_YOU_WANT_TO_ADD_SOMETHING', 'Do you want to add something?')}</OText>
|
|
136
|
+
<Controller
|
|
137
|
+
control={control}
|
|
138
|
+
defaultValue=''
|
|
139
|
+
name='comments'
|
|
140
|
+
render={({ onChange }: any) => (
|
|
141
|
+
<OInput
|
|
142
|
+
name='comments'
|
|
143
|
+
placeholder={t('COMMENTS', 'Comments')}
|
|
144
|
+
onChange={(val: string) => {
|
|
145
|
+
onChange(val)
|
|
146
|
+
setExtraComment(val)
|
|
147
|
+
}}
|
|
148
|
+
style={singleStyle.inputTextArea}
|
|
149
|
+
multiline
|
|
150
|
+
inputStyle={{fontSize: 12}}
|
|
151
|
+
/>
|
|
152
|
+
)}
|
|
153
|
+
/>
|
|
154
|
+
</FormReviews>
|
|
155
|
+
}
|
|
156
|
+
</BlockWrap>
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export const ReviewProductUI = (props: ReviewProductParams) => {
|
|
161
|
+
const {
|
|
162
|
+
order,
|
|
163
|
+
products,
|
|
164
|
+
formState,
|
|
165
|
+
closeReviewProduct,
|
|
166
|
+
handleSendProductReview,
|
|
167
|
+
setIsProductReviewed,
|
|
168
|
+
handleChangeFormState,
|
|
169
|
+
navigation
|
|
170
|
+
} = props
|
|
171
|
+
|
|
172
|
+
const sorted = products?.map((p: any) => {
|
|
173
|
+
return {
|
|
174
|
+
...p,
|
|
175
|
+
like: 0,
|
|
176
|
+
showExtra: false,
|
|
177
|
+
comments: ''
|
|
178
|
+
}
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
const theme = useTheme();
|
|
182
|
+
|
|
183
|
+
const [, t] = useLanguage()
|
|
184
|
+
const [, { showToast }] = useToast()
|
|
185
|
+
const { handleSubmit, control, errors } = useForm()
|
|
186
|
+
|
|
187
|
+
const [alertState, setAlertState] = useState<{ open: boolean, content: Array<any>, success?: boolean }>({ open: false, content: [], success: false })
|
|
188
|
+
|
|
189
|
+
const [curVal, setReviewVal] = useState(-1);
|
|
190
|
+
|
|
191
|
+
const [allProducts, setAllProducts] = useState(sorted);
|
|
192
|
+
|
|
193
|
+
const onSubmit = () => {
|
|
194
|
+
// if (Object.values(stars).some(value => value === 0)) {
|
|
195
|
+
// setAlertState({
|
|
196
|
+
// open: true,
|
|
197
|
+
// content: Object.values(categories).map((category, i) => stars[category.name] === 0 ? `- ${t('CATEGORY_ATLEAST_ONE', `${category.show} must be at least one point`).replace('CATEGORY', category.name.toUpperCase())} ${i !== 3 && '\n'}` : ' ')
|
|
198
|
+
// })
|
|
199
|
+
// return
|
|
200
|
+
// }
|
|
201
|
+
handleSendProductReview()
|
|
202
|
+
setAlertState({ ...alertState, success: true })
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
useEffect(() => {
|
|
206
|
+
if (formState.error && !formState?.loading) {
|
|
207
|
+
showToast(ToastType.Error, formState.result)
|
|
208
|
+
}
|
|
209
|
+
if (!formState.loading && !formState.error && alertState.success) {
|
|
210
|
+
showToast(ToastType.Success, t('REVIEW_SUCCESS_CONTENT', 'Thank you, Review successfully submitted!'))
|
|
211
|
+
navigation?.navigate('ReviewDriver', { order: order });
|
|
212
|
+
}
|
|
213
|
+
}, [formState.result])
|
|
214
|
+
|
|
215
|
+
useEffect(() => {
|
|
216
|
+
if (Object.keys(errors).length > 0) {
|
|
217
|
+
// Convert all errors in one string to show in toast provider
|
|
218
|
+
const list = Object.values(errors);
|
|
219
|
+
let stringError = '';
|
|
220
|
+
list.map((item: any, i: number) => {
|
|
221
|
+
stringError +=
|
|
222
|
+
i + 1 === list.length ? `- ${item.message}` : `- ${item.message}\n`;
|
|
223
|
+
});
|
|
224
|
+
showToast(ToastType.Error, stringError);
|
|
225
|
+
}
|
|
226
|
+
}, [errors]);
|
|
227
|
+
|
|
228
|
+
useEffect(() => {
|
|
229
|
+
if (alertState.open) {
|
|
230
|
+
alertState.content && showToast(
|
|
231
|
+
ToastType.Error,
|
|
232
|
+
alertState.content
|
|
233
|
+
)
|
|
234
|
+
}
|
|
235
|
+
}, [alertState.content])
|
|
236
|
+
|
|
237
|
+
return (
|
|
238
|
+
<>
|
|
239
|
+
<Container>
|
|
240
|
+
<ReviewOrderContainer>
|
|
241
|
+
<NavBar
|
|
242
|
+
title={t('REVIEW_PRODUCT', 'Review product')}
|
|
243
|
+
onActionLeft={() => navigation?.canGoBack() && navigation.goBack()}
|
|
244
|
+
showCall={false}
|
|
245
|
+
btnStyle={{ paddingLeft: 0 }}
|
|
246
|
+
paddingTop={0}
|
|
247
|
+
isVertical
|
|
248
|
+
leftImg={theme.images.general.close}
|
|
249
|
+
leftImageStyle={{width: 16}}
|
|
250
|
+
/>
|
|
251
|
+
<View style={{ paddingBottom: 30 }}>
|
|
252
|
+
{allProducts && allProducts.map((p: any) =>
|
|
253
|
+
<SingleProduct key={p.id} {...props} product={p} />
|
|
254
|
+
)}
|
|
255
|
+
</View>
|
|
256
|
+
<Spinner visible={formState.loading} />
|
|
257
|
+
</ReviewOrderContainer>
|
|
258
|
+
</Container>
|
|
259
|
+
<OBottomStickBar
|
|
260
|
+
rightBtnStyle={{borderRadius: 7.6, height: 44}}
|
|
261
|
+
rightAction={handleSubmit(onSubmit)}
|
|
262
|
+
leftAction={() => navigation?.navigate('ReviewDriver', { order: order })}
|
|
263
|
+
/>
|
|
264
|
+
</>
|
|
265
|
+
)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
export const ReviewProduct = (props: ReviewProductParams) => {
|
|
270
|
+
const reviewProductProps = {
|
|
271
|
+
...props,
|
|
272
|
+
UIComponent: ReviewProductUI
|
|
273
|
+
}
|
|
274
|
+
return <ReviewProductController {...reviewProductProps} />
|
|
275
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import styled from 'styled-components/native'
|
|
2
|
+
|
|
3
|
+
export const ReviewOrderContainer = styled.View`
|
|
4
|
+
width: 100%;
|
|
5
|
+
flex: 1;
|
|
6
|
+
`
|
|
7
|
+
export const ReviewOrderTitle = styled.View`
|
|
8
|
+
|
|
9
|
+
`
|
|
10
|
+
|
|
11
|
+
export const BusinessLogo = styled.View`
|
|
12
|
+
margin-vertical: 5px;
|
|
13
|
+
align-items: center;
|
|
14
|
+
box-shadow: 0 1px 2px #ddd;
|
|
15
|
+
border-radius: 7.6px;
|
|
16
|
+
margin-bottom: 20px;
|
|
17
|
+
`
|
|
18
|
+
|
|
19
|
+
export const FormReviews = styled.View`
|
|
20
|
+
flex: 1;
|
|
21
|
+
`
|
|
22
|
+
|
|
23
|
+
export const Category = styled.View`
|
|
24
|
+
padding: 10px;
|
|
25
|
+
border-width: 1px;
|
|
26
|
+
border-color: ${(props: any) => props.theme.colors.secundaryContrast};
|
|
27
|
+
flex-direction: row;
|
|
28
|
+
justify-content: space-between;
|
|
29
|
+
margin-vertical: 5px;
|
|
30
|
+
border-radius: 10px;
|
|
31
|
+
`
|
|
32
|
+
|
|
33
|
+
export const Stars = styled.View`
|
|
34
|
+
flex-direction: row;
|
|
35
|
+
`
|
|
36
|
+
export const HWrapper = styled.View`
|
|
37
|
+
flex-direction: row;
|
|
38
|
+
align-items: center;
|
|
39
|
+
`
|
|
40
|
+
|
|
41
|
+
export const BlockWrap = styled.View`
|
|
42
|
+
margin-vertical: 16px;
|
|
43
|
+
padding-bottom: 20px;
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
export const CommentItem = styled.TouchableOpacity`
|
|
47
|
+
padding: 3px 10px;
|
|
48
|
+
border-radius: 20px;
|
|
49
|
+
min-height: 24px;
|
|
50
|
+
`;
|
|
51
|
+
export const IconBtn = styled.TouchableOpacity`
|
|
52
|
+
padding-horizontal: 7px;
|
|
53
|
+
`;
|
|
@@ -27,17 +27,17 @@ export const SingleProductCard = (props: SingleProductCardParams) => {
|
|
|
27
27
|
textStyle: {
|
|
28
28
|
flex: 1,
|
|
29
29
|
},
|
|
30
|
-
soldOutBackgroundStyle: {
|
|
31
|
-
backgroundColor: '#B8B8B8',
|
|
32
|
-
},
|
|
33
30
|
soldOutTextStyle : {
|
|
34
|
-
textTransform: '
|
|
31
|
+
textTransform: 'capitalize',
|
|
32
|
+
color: 'white',
|
|
33
|
+
fontSize: 12,
|
|
34
|
+
lineHeight: 18
|
|
35
35
|
},
|
|
36
36
|
productStyle: {
|
|
37
37
|
width: 100,
|
|
38
38
|
height: 100,
|
|
39
39
|
borderRadius: 3,
|
|
40
|
-
|
|
40
|
+
marginTop: 5
|
|
41
41
|
},
|
|
42
42
|
addBtn: {
|
|
43
43
|
position: 'absolute',
|
|
@@ -72,13 +72,13 @@ export const SingleProductCard = (props: SingleProductCardParams) => {
|
|
|
72
72
|
}, [product]);
|
|
73
73
|
|
|
74
74
|
return (
|
|
75
|
-
<CardContainer style={
|
|
75
|
+
<CardContainer style={styles.container}
|
|
76
76
|
onPress={() => onProductClick(product)}
|
|
77
77
|
activeOpacity={0.8}
|
|
78
78
|
>
|
|
79
79
|
<OIcon
|
|
80
80
|
url={optimizeImage(product?.images, 'h_200,c_limit')}
|
|
81
|
-
style={styles.productStyle}
|
|
81
|
+
style={{...styles.productStyle, opacity: (isSoldOut || maxProductQuantity <= 0) ? 0.4 : 1}}
|
|
82
82
|
/>
|
|
83
83
|
<CardInfo>
|
|
84
84
|
<OText color={theme.colors.textPrimary} style={{...theme.labels.normal, marginTop: 9}}>{parsePrice(product?.price)}</OText>
|
|
@@ -92,7 +92,7 @@ export const SingleProductCard = (props: SingleProductCardParams) => {
|
|
|
92
92
|
|
|
93
93
|
{(isSoldOut || maxProductQuantity <= 0) && (
|
|
94
94
|
<SoldOut>
|
|
95
|
-
<OText size={10}
|
|
95
|
+
<OText size={10} style={styles.soldOutTextStyle}>{t('SOLD_OUT', 'SOLD OUT')}</OText>
|
|
96
96
|
</SoldOut>
|
|
97
97
|
)}
|
|
98
98
|
</CardContainer>
|
|
@@ -17,9 +17,8 @@ export const CardInfo = styled.View`
|
|
|
17
17
|
`
|
|
18
18
|
export const SoldOut = styled.View`
|
|
19
19
|
position: absolute;
|
|
20
|
-
background: ${(props: any) => props.theme.colors.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
right: 6px;
|
|
20
|
+
background: ${(props: any) => props.theme.colors.black} 0% 0% no-repeat padding-box;
|
|
21
|
+
padding: 3px 9px;
|
|
22
|
+
top: 91px;
|
|
23
|
+
left: 10px;
|
|
25
24
|
`
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
|
+
import { StyleSheet, Text, View, TouchableOpacity, Image } from 'react-native';
|
|
3
|
+
import { useTheme } from 'styled-components/native';
|
|
4
|
+
// import { TouchableOpacity } from 'react-native-gesture-handler';
|
|
5
|
+
|
|
6
|
+
interface TProps {
|
|
7
|
+
items: Array<string>;
|
|
8
|
+
onUpdated?: (items: Array<TItem>) => void;
|
|
9
|
+
activeColor?: string;
|
|
10
|
+
normalColor?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface TItem {
|
|
14
|
+
id: number;
|
|
15
|
+
label: string;
|
|
16
|
+
checked: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const TagSelector = (props: TProps) => {
|
|
20
|
+
const { items, onUpdated, activeColor, normalColor } = props;
|
|
21
|
+
const theme = useTheme();
|
|
22
|
+
const [tags, setTags] = useState<TItem[]>([]);
|
|
23
|
+
|
|
24
|
+
const onCheck = (tag: TItem, remove?: boolean) => {
|
|
25
|
+
let temp = [...tags];
|
|
26
|
+
temp[tag.id].checked = remove ? !temp[tag.id].checked : true;
|
|
27
|
+
setTags(temp);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const tagItems = items.map((str, idx) =>
|
|
32
|
+
{
|
|
33
|
+
return {
|
|
34
|
+
id: idx,
|
|
35
|
+
label: str,
|
|
36
|
+
checked: false,
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
setTags(tagItems);
|
|
41
|
+
}, [items]);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (onUpdated) onUpdated(tags);
|
|
45
|
+
}, [tags]);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<View style={tcStyles.wrapper}>
|
|
49
|
+
{tags.map((t, idx) =>
|
|
50
|
+
<TouchableOpacity key={idx} activeOpacity={0.8} onPress={() => onCheck(t)}
|
|
51
|
+
style={{...tcStyles.item, backgroundColor: t.checked === true ? activeColor || 'blue' : normalColor || '#eee'}}>
|
|
52
|
+
<Text style={{fontSize: 10, color: t.checked ? 'white' : 'black'}}>{t.label}</Text>
|
|
53
|
+
{t.checked &&
|
|
54
|
+
<TouchableOpacity onPress={() => onCheck(t, true)} style={tcStyles.remove}>
|
|
55
|
+
<Image source={theme.images.general.close} style={tcStyles.removeIcon} />
|
|
56
|
+
</TouchableOpacity>
|
|
57
|
+
}
|
|
58
|
+
</TouchableOpacity>
|
|
59
|
+
)}
|
|
60
|
+
</View>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const tcStyles = StyleSheet.create({
|
|
65
|
+
wrapper: {
|
|
66
|
+
flexDirection: 'row',
|
|
67
|
+
flexShrink: 1,
|
|
68
|
+
flexWrap: 'wrap'
|
|
69
|
+
},
|
|
70
|
+
item: {
|
|
71
|
+
borderRadius: 20,
|
|
72
|
+
paddingHorizontal: 12,
|
|
73
|
+
paddingVertical: 5,
|
|
74
|
+
marginEnd: 10,
|
|
75
|
+
backgroundColor: '#EEE',
|
|
76
|
+
flexDirection: 'row',
|
|
77
|
+
alignItems: 'center',
|
|
78
|
+
justifyContent: 'space-between',
|
|
79
|
+
marginBottom: 14,
|
|
80
|
+
minHeight: 24
|
|
81
|
+
},
|
|
82
|
+
remove: {
|
|
83
|
+
padding: 2,
|
|
84
|
+
marginStart: 12,
|
|
85
|
+
},
|
|
86
|
+
removeIcon: {
|
|
87
|
+
width: 7,
|
|
88
|
+
height: 7,
|
|
89
|
+
resizeMode: 'contain',
|
|
90
|
+
tintColor: 'white'
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
export default TagSelector;
|
|
File without changes
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled, { useTheme } from 'styled-components/native';
|
|
3
|
+
import { OButton, OText } from '.';
|
|
4
|
+
import { useLanguage } from 'ordering-components/native';
|
|
5
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
6
|
+
import { ViewStyle } from 'react-native';
|
|
7
|
+
|
|
8
|
+
const BWrap = styled.View`
|
|
9
|
+
position: absolute;
|
|
10
|
+
min-height: 69px;
|
|
11
|
+
background-color: white;
|
|
12
|
+
width: 100%;
|
|
13
|
+
flex-direction: row;
|
|
14
|
+
justify-content: space-between;
|
|
15
|
+
align-items: center;
|
|
16
|
+
padding-horizontal: 40px;
|
|
17
|
+
padding-vertical: 12px;
|
|
18
|
+
border-top-width: 1px;
|
|
19
|
+
border-top-color: ${(props: any) => props.theme.colors.border};
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const TxtButton = styled.TouchableOpacity`
|
|
23
|
+
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
interface Props {
|
|
27
|
+
rightText?: string;
|
|
28
|
+
rightAction?: any;
|
|
29
|
+
leftText?: string;
|
|
30
|
+
leftAction?: any;
|
|
31
|
+
customLeftView?: any;
|
|
32
|
+
customRightView?: any;
|
|
33
|
+
rightBtnStyle?: ViewStyle;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const OBottomStickBar = (props: Props) => {
|
|
37
|
+
const [, t] = useLanguage();
|
|
38
|
+
const { rightText, rightAction, customRightView, leftText, leftAction, customLeftView, rightBtnStyle } = props;
|
|
39
|
+
const { bottom } = useSafeAreaInsets();
|
|
40
|
+
const theme = useTheme();
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<BWrap style={{bottom: 0, paddingBottom: bottom}}>
|
|
44
|
+
{customLeftView ? customLeftView :
|
|
45
|
+
<TxtButton onPress={leftAction ? leftAction : () => {}}>
|
|
46
|
+
<OText size={16} weight={'bold'} color={theme.colors.textSecondary}>{leftText || t('SKIP', 'Skip')}</OText>
|
|
47
|
+
</TxtButton>
|
|
48
|
+
}
|
|
49
|
+
{customRightView ? customRightView :
|
|
50
|
+
<OButton
|
|
51
|
+
onClick={rightAction ? rightAction : () => {}}
|
|
52
|
+
text={rightText || t('CONTINUE', 'Continue')} textStyle={{fontSize: 14, color: 'white', marginEnd: 32}}
|
|
53
|
+
style={{paddingStart: 10, paddingEnd: 10, ...rightBtnStyle}}
|
|
54
|
+
imgRightSrc={theme.images.general.arrow_left}
|
|
55
|
+
imgRightStyle={{tintColor: 'white', transform: [{ rotate: '180deg' }]}}
|
|
56
|
+
/>
|
|
57
|
+
}
|
|
58
|
+
</BWrap>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default OBottomStickBar;
|
|
@@ -2,4 +2,28 @@ export const USER_TYPE = {
|
|
|
2
2
|
BUSINESS: 'business',
|
|
3
3
|
CUSTOMER: 'customer',
|
|
4
4
|
DRIVER: 'driver'
|
|
5
|
-
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const REVIEW_ORDER_COMMENTS = [
|
|
8
|
+
{ key: 'IT_WASNT_TASTY', value: 'It wasn\'t tasty' },
|
|
9
|
+
{ key: 'IT_DOESNT_PACK_WELL', value: 'It doesn\'t pack well' },
|
|
10
|
+
{ key: 'IT_ISNT_WORTH_WHAT_IT_COASTS', value: 'It isn\'t worth what it coasts' },
|
|
11
|
+
{ key: 'TO_SLOW', value: 'To slow' },
|
|
12
|
+
{ key: 'SUSTAINABLE_PACKAGING_WASNT_USED', value: 'Sustainable packaging wasn\'t used' },
|
|
13
|
+
{ key: 'THEY_DID_NOT_FOLLOW_THE_ORDER_NOTES', value: 'They didn\'t follow the order notes' }
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
export const REVIEW_PRODUCT_COMMENTS = [
|
|
17
|
+
{ key: 'IT_WASNT_TASTY', value: 'It wasn\'t tasty'},
|
|
18
|
+
{ key: 'SMALL_PORTION', value: 'Small portion'},
|
|
19
|
+
{ key: 'WET_OR_LEAKY', value: 'Wet or leaky'},
|
|
20
|
+
{ key: 'SLOPPY_PRESENTATION', value: 'Sloppy presentation'},
|
|
21
|
+
{ key: 'COLD_OR_MELTED', value: 'Cold or melted'}
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
export const REVIEW_DRIVER_COMMENTS = [
|
|
25
|
+
{ key: 'FAST_AND_EFFICIENT', value: 'Fast and efficient'},
|
|
26
|
+
{ key: 'DELIVERY_PERFECT', value: 'Delivery perfect'},
|
|
27
|
+
{ key: 'EXCELLENT_COMMUNICATION', value: 'Excellent communication'},
|
|
28
|
+
{ key: 'CORDIAL_SERVICE', value: 'Cordial service'},
|
|
29
|
+
]
|
|
@@ -296,13 +296,36 @@ export interface ProductItemAccordionParams {
|
|
|
296
296
|
isExpanded?: boolean,
|
|
297
297
|
}
|
|
298
298
|
export interface ReviewOrderParams {
|
|
299
|
-
order?: { orderId: number, businessId: number, logo: string },
|
|
299
|
+
order?: { orderId: number, businessId: number, logo: string, products: Array<{id: number, name: string}> },
|
|
300
300
|
stars?: any,
|
|
301
301
|
handleChangeInput?: any,
|
|
302
302
|
handleChangeRating?: any,
|
|
303
303
|
handleSendReview?: any,
|
|
304
304
|
formState?: any,
|
|
305
|
-
navigation?: any
|
|
305
|
+
navigation?: any,
|
|
306
|
+
route?: any,
|
|
307
|
+
orderComments?: any,
|
|
308
|
+
setStars?: any
|
|
309
|
+
}
|
|
310
|
+
export interface ReviewProductParams {
|
|
311
|
+
order?: any,
|
|
312
|
+
products?: Array<{id: number, name: string}>,
|
|
313
|
+
formState?: any,
|
|
314
|
+
navigation?: any,
|
|
315
|
+
handleChangeFormState?: any,
|
|
316
|
+
closeReviewProduct?: any,
|
|
317
|
+
handleSendProductReview?: any,
|
|
318
|
+
setIsProductReviewed?: any
|
|
319
|
+
}
|
|
320
|
+
export interface ReviewDriverParams {
|
|
321
|
+
dirverReviews?: any,
|
|
322
|
+
order?: any,
|
|
323
|
+
formState?: any,
|
|
324
|
+
setDriverReviews?: any,
|
|
325
|
+
closeReviewDriver?: any,
|
|
326
|
+
setIsDriverReviewed?: any,
|
|
327
|
+
handleSendDriverReview?: any,
|
|
328
|
+
navigation?: any,
|
|
306
329
|
}
|
|
307
330
|
export interface MessagesParams {
|
|
308
331
|
type?: string,
|
|
@@ -90,6 +90,7 @@ const AddressFormUI = (props: AddressFormParams) => {
|
|
|
90
90
|
height: 50,
|
|
91
91
|
maxHeight: 50,
|
|
92
92
|
minHeight: 50,
|
|
93
|
+
flex: 1,
|
|
93
94
|
},
|
|
94
95
|
textAreaStyles: {
|
|
95
96
|
borderColor: theme.colors.border,
|
|
@@ -495,7 +496,10 @@ const AddressFormUI = (props: AddressFormParams) => {
|
|
|
495
496
|
}, [orderState.loading]);
|
|
496
497
|
|
|
497
498
|
return (
|
|
498
|
-
<ScrollView
|
|
499
|
+
<ScrollView
|
|
500
|
+
keyboardShouldPersistTaps='always'
|
|
501
|
+
listViewDisplayed={false}
|
|
502
|
+
>
|
|
499
503
|
<NavBar
|
|
500
504
|
title={t('WHERE_DO_WE_DELIVERY', 'Where do we delivery?')}
|
|
501
505
|
titleAlign={'center'}
|
|
@@ -504,7 +508,7 @@ const AddressFormUI = (props: AddressFormParams) => {
|
|
|
504
508
|
paddingTop={20}
|
|
505
509
|
btnStyle={{ paddingLeft: 40 }}
|
|
506
510
|
titleStyle={{ fontSize: 14 }}
|
|
507
|
-
titleWrapStyle={{
|
|
511
|
+
titleWrapStyle={{ paddingHorizontal: 0 }}
|
|
508
512
|
/>
|
|
509
513
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
|
510
514
|
<AddressFormContainer style={{ height: 600, overflow: 'scroll' }}>
|
|
@@ -60,8 +60,9 @@ const FloatingButtonUI = (props: FloatingButtonParams) => {
|
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
62
|
<Container
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
style={{
|
|
64
|
+
paddingBottom: Platform.OS === 'ios' ? 0 : bottom + 16
|
|
65
|
+
}}>
|
|
65
66
|
|
|
66
67
|
<View style={styles.infoCont}>
|
|
67
68
|
<OText color={theme.colors.textNormal} size={16} lineHeight={24} weight={'600'} mRight={20}>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import styled
|
|
1
|
+
import styled from 'styled-components/native'
|
|
2
2
|
|
|
3
3
|
export const Container = styled.View`
|
|
4
4
|
position: absolute;
|
|
@@ -21,6 +21,6 @@ export const Button = styled.TouchableOpacity`
|
|
|
21
21
|
align-items: center;
|
|
22
22
|
border-radius: 7.6px;
|
|
23
23
|
height: 44px;
|
|
24
|
-
max-height
|
|
24
|
+
max-height: 44px;
|
|
25
25
|
padding-horizontal: 20px;
|
|
26
26
|
`
|