ordering-ui-react-native 0.11.58 → 0.12.0

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.11.58",
3
+ "version": "0.12.0",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -34,7 +34,7 @@ import { UserFormDetailsUI } from './src/components/UserFormDetails';
34
34
  import { UserProfileForm } from './src/components/UserProfileForm';
35
35
  import { VerifyPhone } from './src/components/VerifyPhone';
36
36
  import { DriverMap } from './src/components/DriverMap';
37
-
37
+ import { MapViewUI as MapView } from './src/components/MapView'
38
38
  //OComponents
39
39
  import {
40
40
  OText,
@@ -74,6 +74,7 @@ export {
74
74
  LogoutButton,
75
75
  MessagesOption,
76
76
  NotFoundSource,
77
+ MapView,
77
78
  OrderDetailsBusiness,
78
79
  OrderDetailsDelivery,
79
80
  OrderMessage,
@@ -0,0 +1,286 @@
1
+ import React, { useState, useEffect, useRef, useCallback } from 'react';
2
+ import { Dimensions, SafeAreaView, StyleSheet, View } from 'react-native';
3
+ import { useFocusEffect } from '@react-navigation/native'
4
+ import MapView, {
5
+ PROVIDER_GOOGLE,
6
+ Marker,
7
+ Callout
8
+ } from 'react-native-maps';
9
+ import { useLanguage, useSession, MapView as MapViewController } from 'ordering-components/native';
10
+ import { MapViewParams } from '../../types';
11
+ import Alert from '../../providers/AlertProvider';
12
+ import { useTheme } from 'styled-components/native';
13
+ import { useLocation } from '../../hooks/useLocation';
14
+ import Icon from 'react-native-vector-icons/FontAwesome5';
15
+ import { OIcon, OText } from '../shared'
16
+
17
+ const MapViewComponent = (props: MapViewParams) => {
18
+
19
+ const {
20
+ onNavigationRedirect,
21
+ isLoadingBusinessMarkers,
22
+ getBusinessLocations,
23
+ markerGroups,
24
+ customerMarkerGroups
25
+ } = props;
26
+
27
+ const theme = useTheme();
28
+ const [, t] = useLanguage();
29
+ const [{ user }] = useSession()
30
+ const { width, height } = Dimensions.get('window');
31
+ const ASPECT_RATIO = width / height;
32
+ const mapRef = useRef<MapView>(null);
33
+ const following = useRef<boolean>(true);
34
+ const [isFocused, setIsFocused] = useState(false)
35
+ const [locationSelected, setLocationSelected] = useState<any>(null)
36
+ const [alertState, setAlertState] = useState<{
37
+ open: boolean;
38
+ content: Array<string>;
39
+ key?: string | null;
40
+ }>({ open: false, content: [], key: null });
41
+
42
+ const {
43
+ initialPosition,
44
+ userLocation,
45
+ stopFollowUserLocation,
46
+ followUserLocation
47
+ } = useLocation();
48
+
49
+ const location = { lat: userLocation.latitude, lng: userLocation.longitude }
50
+
51
+ const closeAlert = () => {
52
+ setAlertState({
53
+ open: false,
54
+ content: [],
55
+ });
56
+ };
57
+
58
+ const fitCoordinates = (location?: any) => {
59
+ if (mapRef.current) {
60
+ mapRef.current.fitToCoordinates(
61
+ [
62
+ { latitude: location.latitude, longitude: location.longitude },
63
+ {
64
+ latitude: userLocation.latitude,
65
+ longitude: userLocation.longitude,
66
+ },
67
+ ],
68
+ {
69
+ edgePadding: { top: 120, right: 120, bottom: 120, left: 120 },
70
+ },
71
+ );
72
+ }
73
+ };
74
+
75
+ useEffect(() => {
76
+ fitCoordinates(locationSelected || userLocation);
77
+ }, [userLocation, locationSelected]);
78
+
79
+
80
+ useEffect(() => {
81
+ if (isFocused) {
82
+ getBusinessLocations()
83
+ }
84
+ }, [isFocused])
85
+
86
+ useEffect(() => {
87
+ followUserLocation();
88
+
89
+ return () => {
90
+ stopFollowUserLocation();
91
+ };
92
+ }, []);
93
+
94
+
95
+ useFocusEffect(
96
+ useCallback(() => {
97
+ setIsFocused(true)
98
+ return () => {
99
+ stopFollowUserLocation()
100
+ setIsFocused(false)
101
+ setLocationSelected(null)
102
+ }
103
+ }, [])
104
+ )
105
+
106
+ const styles = StyleSheet.create({
107
+ image: {
108
+ borderRadius: 50,
109
+ },
110
+ view: {
111
+ width: 25,
112
+ position: 'absolute',
113
+ top: 6,
114
+ left: 6,
115
+ bottom: 0,
116
+ right: 0,
117
+ },
118
+ });
119
+
120
+ const RenderMarker = ({ marker, customer, orderIds }: { marker: any, customer?: boolean, orderIds?: Array<number> }) => {
121
+ const markerRef = useRef<any>()
122
+ useEffect(() => {
123
+ if (
124
+ markerRef?.current?.props?.coordinate?.latitude === locationSelected?.latitude &&
125
+ markerRef?.current?.props?.coordinate?.longitude === locationSelected?.longitude
126
+ ) {
127
+ markerRef?.current?.showCallout()
128
+ } else {
129
+ markerRef?.current?.hideCallout()
130
+ }
131
+ }, [locationSelected])
132
+
133
+ return (
134
+ <Marker
135
+ key={customer ? marker?.customer?.id : marker?.business?.id}
136
+ coordinate={{
137
+ latitude: customer ? marker?.customer?.location?.lat : marker?.business?.location?.lat,
138
+ longitude: customer ? marker?.customer?.location?.lng : marker?.business?.location?.lng
139
+ }}
140
+ onPress={() =>
141
+ setLocationSelected({
142
+ latitude: customer ? marker?.customer?.location?.lat : marker?.business?.location?.lat,
143
+ longitude: customer ? marker?.customer?.location?.lng : marker?.business?.location?.lng
144
+ })
145
+ }
146
+ ref={(ref) => markerRef.current = ref}
147
+ >
148
+ <Icon
149
+ name="map-marker"
150
+ size={50}
151
+ color={theme.colors.primary}
152
+ />
153
+ <View style={styles.view}>
154
+ <OIcon
155
+ style={styles.image}
156
+ src={{ uri: customer ? marker?.customer?.photo : marker?.business?.logo }}
157
+ width={25}
158
+ height={25}
159
+ />
160
+ </View>
161
+ <Callout
162
+ onPress={() => !!orderIds && orderIds.toString().includes(',') ? onNavigationRedirect('Orders') : onNavigationRedirect('OrderDetails', { order: marker })}
163
+ >
164
+ <View style={{ flex: 1, width: 200, padding: 5 }}>
165
+ <OText weight='bold'>{customer ? `${marker?.customer?.name} ${marker?.customer?.lastname}` : marker?.business?.name}</OText>
166
+ <OText>
167
+ {!!orderIds && orderIds.toString().includes(',') ? (
168
+ <>
169
+ {t('ORDER_NUMBERS', 'Order Numbers')} {orderIds}
170
+ </>
171
+ ) : (
172
+ <>
173
+ {t('ORDER_NUMBER', 'Order No.')} {marker?.id}
174
+ </>
175
+ )}
176
+ </OText>
177
+ <OText>{customer ? marker?.customer?.address : marker?.business?.address}</OText>
178
+ {((customer && marker?.customer?.city?.address_notes) || !customer) && (
179
+ <OText>{customer ? marker?.customer?.city?.address_notes : marker?.business?.city?.name}</OText>
180
+ )}
181
+ {((customer && marker?.business?.zipcode) || (!customer && marker?.business?.zipcode)) && (
182
+ <OText>{customer ? marker?.customer?.zipcode : marker?.business?.zipcode}</OText>
183
+ )}
184
+ {customer && marker?.customer?.internal_number && (
185
+ <OText>{marker?.customer?.internal_number}</OText>
186
+ )}
187
+ <OText textDecorationLine='underline' color={theme.colors.primary}>
188
+ {!!orderIds && orderIds.toString().includes(',') ? (
189
+ <>
190
+ {t('SHOW_ORDERS', 'Show orders')}
191
+ </>
192
+ ) : (
193
+ <>
194
+ {t('MORE_INFO', 'More info')}
195
+ </>
196
+ )}
197
+ </OText>
198
+ </View>
199
+ </Callout>
200
+ </Marker>
201
+ )
202
+ }
203
+ return (
204
+ <SafeAreaView style={{ flex: 1 }}>
205
+ <View style={{ flex: 1 }}>
206
+ <View style={{ flex: 1 }}>
207
+ {typeof initialPosition?.latitude === 'number' && !isLoadingBusinessMarkers && isFocused && (
208
+ <MapView
209
+ ref={mapRef}
210
+ provider={PROVIDER_GOOGLE}
211
+ initialRegion={{
212
+ latitude: initialPosition.latitude,
213
+ longitude: initialPosition.longitude,
214
+ latitudeDelta: 0.01,
215
+ longitudeDelta: 0.01 * ASPECT_RATIO,
216
+ }}
217
+ style={{ flex: 1 }}
218
+ zoomTapEnabled
219
+ zoomEnabled
220
+ zoomControlEnabled
221
+ cacheEnabled
222
+ moveOnMarkerPress
223
+ onTouchStart={() => (following.current = false)}
224
+ >
225
+ <>
226
+ {Object.values(markerGroups).map((marker: any) => (
227
+ <RenderMarker
228
+ key={marker[0]?.business_id}
229
+ marker={marker[0]}
230
+ orderIds={marker.map((order: any) => order.id).join(', ')}
231
+ />
232
+ ))}
233
+ {Object.values(customerMarkerGroups).map((marker: any) => (
234
+ <RenderMarker
235
+ key={marker[0]?.customer_id}
236
+ marker={marker[0]}
237
+ orderIds={marker.map((order: any) => order.id).join(', ')}
238
+ customer
239
+ />
240
+ ))}
241
+ <Marker
242
+ coordinate={{
243
+ latitude: location.lat,
244
+ longitude: location.lng,
245
+ }}
246
+ title={t('YOUR_LOCATION', 'Your Location')}
247
+ >
248
+ <Icon
249
+ name="map-marker"
250
+ size={50}
251
+ color={theme.colors.primary}
252
+ />
253
+ <View style={styles.view}>
254
+ <OIcon
255
+ style={styles.image}
256
+ src={{ uri: user.photo }}
257
+ width={25}
258
+ height={25}
259
+ />
260
+ </View>
261
+ </Marker>
262
+ </>
263
+ </MapView>
264
+ )}
265
+ </View>
266
+ </View>
267
+ <View>
268
+ <Alert
269
+ open={alertState.open}
270
+ onAccept={closeAlert}
271
+ onClose={closeAlert}
272
+ content={alertState.content}
273
+ title={t('ERROR', 'Error')}
274
+ />
275
+ </View>
276
+ </SafeAreaView >
277
+ );
278
+ };
279
+
280
+ export const MapViewUI = (props: any) => {
281
+ const MapViewProps = {
282
+ ...props,
283
+ UIComponent: MapViewComponent
284
+ }
285
+ return <MapViewController {...MapViewProps} />
286
+ }
@@ -23,6 +23,7 @@ const SText = styled.Text`
23
23
  css`
24
24
  flex: ${props.weight ? 1 : 0};
25
25
  `};
26
+ text-decoration: ${(props : any) => props.textDecorationLine};
26
27
  `;
27
28
  interface Props {
28
29
  color?: string;
@@ -39,6 +40,7 @@ interface Props {
39
40
  numberOfLines?: number;
40
41
  ellipsizeMode?: string;
41
42
  adjustsFontSizeToFit?: boolean;
43
+ textDecorationLine?: string
42
44
  }
43
45
 
44
46
  const OText = (props: Props): React.ReactElement => {
@@ -539,3 +539,11 @@ export interface AcceptOrRejectOrderParams {
539
539
  titleReject?: textTranslate;
540
540
  appTitle?: textTranslate;
541
541
  }
542
+
543
+ export interface MapViewParams {
544
+ onNavigationRedirect: (page : string, params ?: any) => void,
545
+ getBusinessLocations: () => void,
546
+ isLoadingBusinessMarkers?: boolean,
547
+ markerGroups: Array<any>,
548
+ customerMarkerGroups: Array<any>
549
+ }
@@ -82,6 +82,7 @@ const BusinessProductsListingUI = (props: BusinessProductsListingParams) => {
82
82
  inactiveSlideOpacity={1}
83
83
  initialScrollIndex={0}
84
84
  onScrollToIndexFailed={(_: any) => {}}
85
+ enableMomentum={true}
85
86
  />
86
87
  </>
87
88
  );
@@ -13,7 +13,8 @@ import {
13
13
  StyledContent,
14
14
  StyledTopBar,
15
15
  } from './styles';
16
- import { OButton, OModal, OText } from '../shared';
16
+ import { OButton, OModal, OText, OIconButton } from '../shared';
17
+ import EvilIcons from 'react-native-vector-icons/EvilIcons';
17
18
  import CartItem from '../CartItem';
18
19
  import { Cart as TypeCart } from '../../types';
19
20
  import { ProductForm } from '../ProductForm';
@@ -109,6 +110,7 @@ const CartBottomSheetUI = (props: CartBottomSheetUIProps): React.ReactElement |
109
110
  {...props}
110
111
  handleClearProducts={handleClearProducts}
111
112
  selectedOrderType={selectedOrderType}
113
+ hideCartBottomSheet={hideCartBottomSheet}
112
114
  />
113
115
 
114
116
  {cart?.products?.length > 0 && cart?.products.map((product: any) => (
@@ -126,13 +128,27 @@ const CartBottomSheetUI = (props: CartBottomSheetUIProps): React.ReactElement |
126
128
  ))}
127
129
 
128
130
  </StyledContent>
129
-
130
- <StyledBottomContent
131
- minHeight={props.height * 0.1}
131
+ <TouchableOpacity
132
+ onPress={handleClearProducts}
133
+ style={{flex:1, justifyContent:'center', alignItems:'center', bottom: 20, paddingTop: 5}}
132
134
  >
135
+ <View>
136
+ <OText
137
+ size={20}
138
+ weight="700"
139
+ color={theme.colors.red}
140
+ >
141
+ {t('CANCEL_ORDER', 'Cancel order')}
142
+ </OText>
143
+ </View>
144
+ </TouchableOpacity>
145
+ <StyledBottomContent
146
+ style={{bottom:10}}
147
+ minHeight={props.height * 0.01}
148
+ >
133
149
  <OButton
134
150
  text={(cart?.subtotal >= cart?.minimum || !cart?.minimum) && cart?.valid_address ? (
135
- !openUpselling !== canOpenUpselling ? `${t('CONFIRM_THIS', 'Confirm this')} ${parsePrice(cart?.total)} ${t('ORDER', 'order')}`: t('LOADING', 'Loading')
151
+ !openUpselling !== canOpenUpselling ? `${t('CHECKOUT', 'Checkout')} ${parsePrice(cart?.total)}`: t('LOADING', 'Loading')
136
152
  ) : !cart?.valid_address ? (
137
153
  `${t('OUT_OF_COVERAGE', 'Out of Coverage')}`
138
154
  ) : (
@@ -205,20 +221,19 @@ const TopBar = (props:any) => {
205
221
  {props?.selectedOrderType === 3 && t('EAT_IN', 'Eat in')}
206
222
  </OText>
207
223
  </View>
208
-
209
- <TouchableOpacity
210
- onPress={props?.handleClearProducts}
211
- >
212
- <View>
213
- <OText
214
- size={20}
215
- weight="500"
216
- color={theme.colors.primary}
217
- >
218
- {t('CANCEL_ORDER', 'Cancel order')}
219
- </OText>
220
- </View>
221
- </TouchableOpacity>
224
+ <OIconButton
225
+ bgColor="transparent"
226
+ borderColor="transparent"
227
+ RenderIcon={() =>
228
+ <EvilIcons
229
+ name={'close'}
230
+ size={40}
231
+ color={theme.colors.primary}
232
+ />
233
+ }
234
+ style={{ flex:1, justifyContent: 'flex-end', left: 30 }}
235
+ onClick={props.hideCartBottomSheet}
236
+ />
222
237
  </StyledTopBar>
223
238
  );
224
239
  }
@@ -10,7 +10,8 @@ import {
10
10
  ProductSubOption,
11
11
  ProductComment
12
12
  } from './styles';
13
- import { OButton, OImage, OText } from '../shared';
13
+ import { OButton, OImage, OText, OIconButton } from '../shared';
14
+ import EvilIcons from 'react-native-vector-icons/EvilIcons';
14
15
  import { Product } from '../../types';
15
16
  import QuantityControl from '../QuantityControl';
16
17
  import { LANDSCAPE, useDeviceOrientation } from '../../../../../src/hooks/DeviceOrientation';
@@ -52,7 +53,7 @@ const CartItem = (props: CartItemProps) => {
52
53
  }
53
54
  return product
54
55
  }
55
-
56
+ const isProductIngredients = productInfo()?.ingredients.length > 0 || productInfo()?.options.length > 0 || product?.comment
56
57
  const getFormattedSubOptionName = ({ quantity, name, position, price }: { quantity: number, name: string, position: string, price: number }) => {
57
58
  const pos = position ? `(${position})` : ''
58
59
  return `${quantity} x ${name} ${pos} +${price}`
@@ -64,7 +65,7 @@ const CartItem = (props: CartItemProps) => {
64
65
  onPress={() => (!product?.valid_menu && isCartProduct)
65
66
  ? {}
66
67
  : setActiveState(!isActive)}
67
- activeOpacity={1}
68
+ activeOpacity={0.5}
68
69
  >
69
70
  <StyledCartItem>
70
71
  <View style={{ flexDirection: 'row' }}>
@@ -105,6 +106,21 @@ const CartItem = (props: CartItemProps) => {
105
106
  }}
106
107
  onClick={() => { onEditProduct ? onEditProduct(product) : null }}
107
108
  />
109
+ <OIconButton
110
+ bgColor="transparent"
111
+ borderColor="transparent"
112
+ RenderIcon={isProductIngredients && (() =>
113
+ <EvilIcons
114
+ name={isActive ? 'chevron-up': 'chevron-down'}
115
+ size={40}
116
+ color={theme.colors.primary}
117
+ />
118
+ )}
119
+ style={{ justifyContent: 'flex-start', right: 40 }}
120
+ onClick={() => (!product?.valid_menu && isCartProduct)
121
+ ? {}
122
+ : setActiveState(!isActive)}
123
+ />
108
124
  </View>
109
125
  </View>
110
126
  </View>
@@ -90,7 +90,7 @@ const CategoriesMenu = (props: any): React.ReactElement => {
90
90
  <Container nopadding nestedScrollEnabled>
91
91
  <View style={{ paddingTop: 20 }}>
92
92
  <NavBar
93
- title={t('CATEGORY_X_ID', 'Category')}
93
+ title={categories[curIndexCateg].name}
94
94
  onActionLeft={goToBack}
95
95
  rightComponent={cart && (
96
96
  <TouchableOpacity
@@ -128,7 +128,7 @@ const CategoriesMenu = (props: any): React.ReactElement => {
128
128
  image={{ uri: product?.images }}
129
129
  style={{
130
130
  width: orientationState?.orientation === LANDSCAPE
131
- ? orientationState?.dimensions?.width * 0.16
131
+ ? bottomSheetVisibility ? orientationState?.dimensions?.width * 0.15 :orientationState?.dimensions?.width * 0.16
132
132
  : orientationState?.dimensions?.width * 0.21
133
133
  }}
134
134
  titleStyle={{marginTop: Platform.OS === 'ios' ? 10 : 0}}
@@ -34,7 +34,7 @@ const CustomerName = (props: Props): React.ReactElement => {
34
34
  marginBottom: 20,
35
35
  borderWidth: 1,
36
36
  borderColor: theme.colors.disabled,
37
- height: 44
37
+ height: 50
38
38
  },
39
39
  });
40
40
 
@@ -67,72 +67,99 @@ const CustomerName = (props: Props): React.ReactElement => {
67
67
  }}
68
68
  />);
69
69
 
70
+ const skipButton = (
71
+ <View style={{flex:1, left: orientationState?.dimensions.width * 0.2,}}>
72
+ <OButton
73
+ text={t('SKIP', 'Skip')}
74
+ onClick={onProceedToPay}
75
+ textStyle={{color: theme.colors.primaryContrast, fontSize: 20}}
76
+ parentStyle={{
77
+ height: orientationState?.orientation === PORTRAIT
78
+ ? 50 : 100
79
+ }}
80
+ style={{
81
+ width: orientationState?.orientation === PORTRAIT
82
+ ? orientationState?.dimensions.width - 40
83
+ : orientationState?.dimensions.width * 0.1,
84
+ }}
85
+ />
86
+ </View>
87
+ );
88
+
70
89
  return (
71
90
  <>
72
- <Container>
73
- <NavBar
74
- title={t('YOUR_NAME', 'Your name')}
75
- onActionLeft={goToBack}
76
- btnStyle={{paddingLeft: 0}}
77
- />
78
-
79
- <View style={{ marginVertical: orientationState?.dimensions?.height * 0.03 }}>
80
- <OText
81
- size={orientationState?.dimensions?.width * 0.05}
82
- >
83
- {t('WHOM_MIGHT_THIS', 'Whom might this')} {'\n'}
84
- <OText
85
- size={orientationState?.dimensions?.width * 0.05}
86
- weight={'700'}
87
- >
88
- {`${t('ORDER_BE_FOR', 'order be for?')}`}
89
- </OText>
90
- </OText>
91
- </View>
92
-
93
- <Controller
94
- control={control}
95
- render={({ onChange, value }: any) => (
96
- <OInput
97
- placeholder={t('WRITE_YOUR_NAME', 'Write your name')}
98
- style={{
99
- ...styles.inputStyle,
100
- width: orientationState?.orientation === PORTRAIT
101
- ? orientationState?.dimensions.width - 40
102
- : orientationState?.dimensions.width * 0.5,
103
- }}
104
- value={value}
105
- autoCapitalize="words"
106
- autoCorrect={false}
107
- onChange={(val: any) => onChange(val)}
108
- />
109
- )}
110
- name="name"
111
- rules={{
112
- required: t(
113
- 'VALIDATION_ERROR_REQUIRED',
114
- 'The field Customer Name is required',
115
- ).replace('_attribute_', t('REQUEST_COLLECTION_CUSTOMER_NAME', 'Customer Name')),
116
- pattern: {
117
- value: /^[a-zA-Z áéíóúüñçÁÉÍÓÚÜÑÇ]+$/i,
118
- message: t(
119
- 'INVALID_ERROR',
120
- 'Invalid name',
121
- ).replace('_attribute_', t('NAME', 'Name')),
122
- }
123
- }}
124
- defaultValue=""
125
- />
126
-
127
- {orientationState?.orientation === LANDSCAPE && submitButton}
128
- </Container>
91
+ <Container>
92
+ <NavBar
93
+ title={t('YOUR_NAME', 'Your name')}
94
+ onActionLeft={goToBack}
95
+ btnStyle={{paddingLeft: 0}}
96
+ />
97
+ <View style={{
98
+ marginVertical: orientationState?.dimensions?.height * 0.08,
99
+ paddingLeft: orientationState?.dimensions?.width * 0.25
100
+ }}>
101
+ <OText
102
+ size={orientationState?.dimensions?.width * 0.05}
103
+ style={{bottom: 20}}
104
+ >
105
+ {t('WHATS_YOUR_NAME', "What's your name?")}
106
+ {/* <OText
107
+ size={orientationState?.dimensions?.width * 0.05}
108
+ weight={'700'}
109
+ >
110
+ {`${t('ORDER_BE_FOR', 'order be for?')}`}
111
+ </OText> */}
112
+ </OText>
113
+ <Controller
114
+ control={control}
115
+ render={({ onChange, value }: any) => (
116
+ <OInput
117
+ placeholder={t('WRITE_YOUR_NAME', 'Write your name')}
118
+ style={{
119
+ ...styles.inputStyle,
120
+ width: orientationState?.orientation === PORTRAIT
121
+ ? orientationState?.dimensions.width - 40
122
+ : orientationState?.dimensions.width * 0.5,
123
+ }}
124
+ value={value}
125
+ autoCapitalize="words"
126
+ autoCorrect={false}
127
+ onChange={(val: any) => onChange(val)}
128
+ onSubmitEditing={handleSubmit(onSubmit)}
129
+ />
130
+ )}
131
+ name="name"
132
+ rules={{
133
+ required: t(
134
+ 'VALIDATION_ERROR_REQUIRED',
135
+ 'The field Customer Name is required',
136
+ ).replace('_attribute_', t('REQUEST_COLLECTION_CUSTOMER_NAME', 'Customer Name')),
137
+ pattern: {
138
+ value: /^[a-zA-Z áéíóúüñçÁÉÍÓÚÜÑÇ]+$/i,
139
+ message: t(
140
+ 'INVALID_ERROR',
141
+ 'Invalid name',
142
+ ).replace('_attribute_', t('NAME', 'Name')),
143
+ }
144
+ }}
145
+ defaultValue=""
146
+ />
129
147
 
130
- {(orientationState?.orientation === PORTRAIT) && (
131
- <OSActions>
132
- {submitButton}
133
- </OSActions>
134
- )}
135
- </>
148
+ {orientationState?.orientation === LANDSCAPE && submitButton}
149
+ {orientationState?.orientation === LANDSCAPE && skipButton}
150
+ {(orientationState?.orientation === PORTRAIT) && (
151
+ <OSActions>
152
+ {submitButton}
153
+ </OSActions>
154
+ )}
155
+ {(orientationState?.orientation === PORTRAIT) && (
156
+ <OSActions>
157
+ {skipButton}
158
+ </OSActions>
159
+ )}
160
+ </View>
161
+ </Container>
162
+ </>
136
163
  );
137
164
  };
138
165
 
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react'
2
2
  import styled from 'styled-components/native'
3
3
  import { OIcon, OButton, OText } from '../shared'
4
- import { TextStyle, View } from 'react-native'
4
+ import { ImageStyle, TextStyle, View } from 'react-native'
5
5
  import { OrderTypeSelector } from '../OrderTypeSelector'
6
6
  import { useConfig } from 'ordering-components/native'
7
7
  import { useTheme } from 'styled-components/native'
@@ -53,6 +53,7 @@ interface Props {
53
53
  style?: TextStyle,
54
54
  paddingTop?: number,
55
55
  includeOrderTypeSelector?: boolean,
56
+ imgLeftStyle?: ImageStyle
56
57
  }
57
58
 
58
59
  const NavBar = (props: Props) => {
@@ -68,6 +69,7 @@ const NavBar = (props: Props) => {
68
69
  imgRightSrc={null}
69
70
  style={{ ...btnBackArrow, ...props.btnStyle }}
70
71
  onClick={props.onActionLeft}
72
+ imgLeftStyle= {props.imgLeftStyle}
71
73
  />)
72
74
  }
73
75
  <TitleTopWrapper>
@@ -27,7 +27,7 @@ import {
27
27
  import { OrderDetailsParams, Product } from '../../types'
28
28
  import { Container } from '../../layouts/Container';
29
29
  import NavBar from '../../components/NavBar';
30
- import { OButton, OImage, OInput, OText } from '../../components/shared';
30
+ import { OButton, OIconButton, OImage, OInput, OText } from '../../components/shared';
31
31
  import GridContainer from '../../layouts/GridContainer';
32
32
  import OptionSwitch, { Opt } from '../../components/shared/OOptionToggle';
33
33
  import { verifyDecimals } from '../../../../../src/utils'
@@ -35,6 +35,7 @@ import { LANDSCAPE, PORTRAIT, useDeviceOrientation } from '../../../../../src/ho
35
35
  import { useTheme } from 'styled-components/native'
36
36
  import { _retrieveStoreData } from '../../../../../src/providers/StoreUtil';
37
37
  import MaterialIcon from 'react-native-vector-icons/MaterialCommunityIcons'
38
+ import EvilIcons from 'react-native-vector-icons/EvilIcons'
38
39
  const _EMAIL = 'email';
39
40
  const _SMS = 'sms';
40
41
 
@@ -210,6 +211,14 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
210
211
  setCustomerName(name)
211
212
  }
212
213
  getCustomerName()
214
+ const redirectHome = setTimeout(() =>{
215
+ navigation.reset({
216
+ routes: [{ name: 'Intro' }],
217
+ });
218
+ }, 60000);
219
+ return () => {
220
+ clearTimeout(redirectHome);
221
+ }
213
222
  }, [])
214
223
 
215
224
  useEffect(() => {
@@ -327,7 +336,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
327
336
  </OSInputWrapper>
328
337
 
329
338
  <OButton
330
- text={`${t('YOU_ARE_DONE', 'You are done')}!`}
339
+ text={`${t('YOU_ARE_DONE', 'You are done! Click to close')}!`}
331
340
  onClick={() => {
332
341
  navigation.reset({
333
342
  routes: [{ name: 'Intro' }],
@@ -485,18 +494,46 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
485
494
  <>
486
495
  <Container>
487
496
  <NavBar
488
- title={t('TAKE_YOUR_RECEIPT', 'Take your receipt')}
497
+ title={t('BACK_BUTTON_CONFIRMATION', 'Confirmation')}
489
498
  style={{ right: 10 }}
499
+ rightComponent={
500
+ <OIconButton
501
+ bgColor="transparent"
502
+ borderColor="transparent"
503
+ RenderIcon={() =>
504
+ <EvilIcons
505
+ name={'close'}
506
+ size={40}
507
+ color={theme.colors.primary}
508
+ />
509
+ }
510
+ style={{ flex:1, justifyContent: 'flex-end', left: 30 }}
511
+ onClick={() => {
512
+ navigation.reset({
513
+ routes: [{ name: 'Intro' }],
514
+ });
515
+ }}
516
+ />
517
+ }
490
518
  />
491
519
 
492
520
  <View style={{
493
521
  marginVertical: orientationState?.dimensions?.height * 0.03,
494
522
  flexDirection: orientationState?.orientation === PORTRAIT ? 'column' : 'row',
495
523
  }}>
524
+ <View
525
+ style={{
526
+ flex: 1,
527
+ marginVertical: orientationState?.orientation === PORTRAIT ? 40 : 0,
528
+ }}
529
+ >
530
+ {orderDetailsContent}
531
+ </View>
496
532
  <View style={{
497
- flex: 1,
533
+ flex: 1.1,
498
534
  marginRight: orientationState?.orientation === PORTRAIT ? 0 : 20,
499
- justifyContent: 'space-between'
535
+ justifyContent: 'space-between',
536
+ marginLeft: 20
500
537
  }}>
501
538
  <View>
502
539
  <OText
@@ -515,22 +552,13 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
515
552
  <OText
516
553
  size={orientationState?.dimensions?.width * (orientationState?.orientation === PORTRAIT ? 0.04 : 0.025)}
517
554
  >
518
- {t('TO_FINISH_TAKE_YOUR_RECEIPT_AND_GO_TO_THE_FRONT_COUNTER', 'To finish take your receipt and go to the front counter.')}
555
+ {t('TO_FINISH_TAKE_YOUR_RECEIPT_AND_GO_TO_THE_FRONT_COUNTER', "We`ve received your order and we will call you by your name or your order number.")}
519
556
  </OText>
520
557
 
521
558
  </View>
522
559
 
523
560
  {orientationState?.orientation === LANDSCAPE && actionsContent}
524
561
  </View>
525
-
526
- <View
527
- style={{
528
- flex: 1.4,
529
- marginVertical: orientationState?.orientation === PORTRAIT ? 40 : 0,
530
- }}
531
- >
532
- {orderDetailsContent}
533
- </View>
534
562
  </View>
535
563
  </Container>
536
564
 
@@ -135,14 +135,14 @@ const PaymentOptionsUI = (props: any) => {
135
135
  cashIndex !== -1
136
136
  ? {
137
137
  style: cardStyle,
138
- title: t('CASH', supportedMethods[cashIndex]?.name),
138
+ title: t('CASH', 'Cash'),
139
139
  description: t(
140
140
  'GO_FOR_YOR_RECEIPT_AND_GO_TO_THE_FRONT_COUNTER',
141
- 'Go for yor receipt and go to the front counter',
141
+ 'Pay with cash in the front counter',
142
142
  ),
143
143
  bgImage: theme.images.general.cash,
144
144
  icon: theme.images.general.shoppingCart,
145
- callToActionText: t('TAKE_MY_RECEIPT', 'Take my receipt'),
145
+ callToActionText: t('LETS_GO', 'LETS_GO'),
146
146
  onClick: () =>
147
147
  onSelectPaymethod(supportedMethods[cashIndex], false),
148
148
  ...supportedMethods[cashIndex],
@@ -137,8 +137,6 @@ export const ProductOptionsUI = (props: any) => {
137
137
  const navBarProps = {
138
138
  style: { backgroundColor: 'transparent', width: orientationState?.dimensions?.width, borderBottomWidth: 0 },
139
139
  paddingTop: 20,
140
- title: t('YOUR_DISH', 'Your dish'),
141
- btnStyle: { backgroundColor: 'transparent' },
142
140
  onActionLeft: onClose ? onClose : navigation ? goToBack : undefined,
143
141
  };
144
142
 
@@ -238,12 +236,29 @@ export const ProductOptionsUI = (props: any) => {
238
236
  {...navBarProps}
239
237
  titleColor={theme.colors.white}
240
238
  {...((navigation || onClose) && { leftImg: theme.images.general.arrow_left_white })}
239
+ btnStyle={{
240
+ width: 55,
241
+ height: 55,
242
+ backgroundColor: 'black',
243
+ borderRadius: 100,
244
+ opacity: 0.8,
245
+ left: 20,
246
+ }}
247
+ imgLeftStyle={{ width: 27, height: 27 }}
241
248
  />
242
249
  </Animated.View>
243
250
  <Animated.View style={{ opacity: navBar2ContainerOpacity, position: 'absolute' }}>
244
251
  <NavBar
245
252
  {...navBarProps}
246
253
  {...((navigation || onClose) && { leftImg: theme.images.general.arrow_left })}
254
+ btnStyle={{
255
+ width: 55,
256
+ height: 55,
257
+ backgroundColor: 'transparent',
258
+ borderRadius: 100,
259
+ left: 20,
260
+ }}
261
+ imgLeftStyle={{ width: 27, height: 27 }}
247
262
  />
248
263
  </Animated.View>
249
264
 
@@ -178,30 +178,6 @@ const UpsellingProductsUI = (props: UpsellingProductsParams) => {
178
178
  alignItems: 'center'
179
179
  }}
180
180
  >
181
-
182
- <View style={{ height: '100%', width: '35%' }}>
183
- <OText
184
- size={orientationState?.dimensions?.width * 0.048}
185
- >
186
- {t('DO_YOU_WANT', 'Do you want')} {'\n'}
187
- <OText
188
- size={orientationState?.dimensions?.width * 0.048}
189
- weight={'700'}
190
- >
191
- {t('SOMETHING_ELSE', 'something else')} {'?'}
192
- </OText>
193
- </OText>
194
-
195
- <CloseUpsellingLand>
196
- <OButton
197
- imgRightSrc=''
198
- text={t('I_AM_FINE_THANK_YOU', 'I’m fine, thank you')}
199
- style={styles.closeUpsellingButton}
200
- onClick={() => handleUpsellingPage()}
201
- />
202
- </CloseUpsellingLand>
203
- </View>
204
-
205
181
  <View style={{ width: '65%', marginBottom: 30 }}>
206
182
  <GridContainer>
207
183
  {
@@ -258,7 +234,27 @@ const UpsellingProductsUI = (props: UpsellingProductsParams) => {
258
234
  }
259
235
  </GridContainer>
260
236
  </View>
261
-
237
+ <View style={{ height: '100%', width: '35%' }}>
238
+ <OText
239
+ size={orientationState?.dimensions?.width * 0.040}
240
+ >
241
+ {t('DO_YOU_WANT', 'Do you want')} {'\n'}
242
+ <OText
243
+ size={orientationState?.dimensions?.width * 0.040}
244
+ weight={'700'}
245
+ >
246
+ {t('SOMETHING_ELSE', 'something else')} {'?'}
247
+ </OText>
248
+ </OText>
249
+ <CloseUpsellingLand>
250
+ <OButton
251
+ imgRightSrc=''
252
+ text={t('I_AM_FINE_THANK_YOU', 'I’m fine, thank you')}
253
+ style={styles.closeUpsellingButton}
254
+ onClick={() => handleUpsellingPage()}
255
+ />
256
+ </CloseUpsellingLand>
257
+ </View>
262
258
  </View>
263
259
  </>
264
260
  )
@@ -48,9 +48,10 @@ interface Props {
48
48
  iconCover?: boolean,
49
49
  urlIcon?: any,
50
50
  cover?: any,
51
+ RenderIcon?: React.FunctionComponent
51
52
  }
52
-
53
53
  const OIconButton = (props: Props) => {
54
+ const { RenderIcon } = props
54
55
  const theme = useTheme()
55
56
 
56
57
  return (
@@ -66,7 +67,7 @@ const OIconButton = (props: Props) => {
66
67
  ...props.style
67
68
  }}
68
69
  >
69
- {props.icon ? (
70
+ {props.icon && typeof props.icon !== 'object' ? (
70
71
  <Icon
71
72
  source={props.icon}
72
73
  style={{
@@ -75,6 +76,9 @@ const OIconButton = (props: Props) => {
75
76
  }}
76
77
  />
77
78
  ) : null}
79
+ {RenderIcon ? (
80
+ <RenderIcon />
81
+ ) : null}
78
82
  {props.title ? (
79
83
  <Title style={{
80
84
  color: props.textColor || props.color,
@@ -97,7 +101,7 @@ const OIconButton = (props: Props) => {
97
101
  >
98
102
  {props.icon ? (
99
103
  <Icon
100
- source={props.urlIcon ? {uri: props.icon} : props.icon}
104
+ source={props.urlIcon ? { uri: props.icon } : props.icon}
101
105
  resizeMode={props.cover ? 'cover' : 'contain'}
102
106
  style={{
103
107
  tintColor: props.iconColor,
@@ -105,6 +109,9 @@ const OIconButton = (props: Props) => {
105
109
  }}
106
110
  />
107
111
  ) : null}
112
+ {RenderIcon ? (
113
+ <RenderIcon />
114
+ ) : null}
108
115
  {props.title ? (
109
116
  <Title style={{
110
117
  color: props.textColor || props.color,
@@ -1,31 +1,76 @@
1
- import { AddressForm } from './src/components/AddressForm';
2
- import { AddressDetails } from './src/components/AddressDetails';
3
- import { Home } from './src/components/Home';
4
- import { LoginForm } from './src/components/LoginForm';
5
- import { SignupForm } from './src/components/SignupForm';
6
1
  import { ActiveOrders } from './src/components/ActiveOrders';
2
+ import { AddressDetails } from './src/components/AddressDetails';
3
+ import { AddressForm } from './src/components/AddressForm';
7
4
  import { AddressList } from './src/components/AddressList';
8
5
  import { AppleLogin } from './src/components/AppleLogin';
6
+ import BottomWrapper from './src/components/BottomWrapper';
7
+ import { BusinessBasicInformation } from './src/components/BusinessBasicInformation';
8
+ import { BusinessController } from './src/components/BusinessController';
9
9
  import { BusinessesListing } from './src/components/BusinessesListing';
10
+ import { BusinessFeaturedController } from './src/components/BusinessFeaturedController';
11
+ import { BusinessInformation } from './src/components/BusinessInformation';
12
+ import { BusinessItemAccordion } from './src/components/BusinessItemAccordion';
13
+ import { BusinessProductsCategories } from './src/components/BusinessProductsCategories';
14
+ import { BusinessProductsList } from './src/components/BusinessProductsList';
10
15
  import { BusinessProductsListing } from './src/components/BusinessProductsListing';
16
+ import { BusinessReviews } from './src/components/BusinessReviews';
17
+ import { BusinessTypeFilter } from './src/components/BusinessTypeFilter';
18
+ import { Cart } from './src/components/Cart';
11
19
  import { CartContent } from './src/components/CartContent';
12
20
  import { Checkout } from './src/components/Checkout';
21
+ import { CouponControl } from './src/components/CouponControl';
22
+ import { DriverTips } from './src/components/DriverTips';
23
+ import { FacebookLogin } from './src/components/FacebookLogin';
24
+ import { FloatingButton } from './src/components/FloatingButton';
13
25
  import { ForgotPasswordForm } from './src/components/ForgotPasswordForm';
26
+ import { GoogleLogin } from './src/components/GoogleLogin';
27
+ import { GoogleMap } from './src/components/GoogleMap';
28
+ import { GPSButton } from './src/components/GPSButton';
29
+ import { Help } from './src/components/Help';
30
+ import { HelpAccountAndPayment } from './src/components/HelpAccountAndPayment';
31
+ import { HelpGuide } from './src/components/HelpGuide';
32
+ import { HelpOrder } from './src/components/HelpOrder';
33
+ import { Home } from './src/components/Home';
34
+ import { LanguageSelector } from './src/components/LanguageSelector';
35
+ import { LastOrder } from './src/components/LastOrder';
36
+ import { LastOrders } from './src/components/LastOrders';
37
+ import { LoginForm } from './src/components/LoginForm';
38
+ import { LogoutButton } from './src/components/LogoutButton';
39
+ import { Messages } from './src/components/Messages';
14
40
  import { MomentOption } from './src/components/MomentOption';
15
- import { OrdersOption } from './src/components/OrdersOption';
41
+ import NavBar from './src/components/NavBar';
42
+ import { NotFoundSource } from './src/components/NotFoundSource';
43
+ import Notifications from './src/components/Notifications';
16
44
  import { OrderDetails } from './src/components/OrderDetails';
17
- import { UserProfileForm } from './src/components/UserProfileForm';
45
+ import { OrdersOption } from './src/components/OrdersOption';
46
+ import { OrderSummary } from './src/components/OrderSummary';
47
+ import { OrderTypeSelector } from './src/components/OrderTypeSelector';
48
+ import { PaymentOptionCash } from './src/components/PaymentOptionCash';
49
+ import { PaymentOptions } from './src/components/PaymentOptions';
50
+ import { PaymentOptionStripe } from './src/components/PaymentOptionStripe';
51
+ import { PhoneInputNumber } from './src/components/PhoneInputNumber';
52
+ import { PreviousOrders } from './src/components/PreviousOrders';
53
+ import { ProductForm } from './src/components/ProductForm';
54
+ import { ProductIngredient } from './src/components/ProductIngredient';
55
+ import { ProductItemAccordion } from './src/components/ProductItemAccordion';
56
+ import { ProductOption } from './src/components/ProductOption';
57
+ import { ProductOptionSubOption } from './src/components/ProductOptionSubOption';
18
58
  import { ReviewOrder } from './src/components/ReviewOrder';
59
+ import { SearchBar } from './src/components/SearchBar';
60
+ import { SignupForm } from './src/components/SignupForm';
61
+ import { SingleProductCard } from './src/components/SingleProductCard';
62
+ import { StripeCardForm } from './src/components/StripeCardForm';
63
+ import { StripeCardsList } from './src/components/StripeCardsList';
64
+ import { StripeElementsForm } from './src/components/StripeElementsForm';
65
+ import { StripeRedirectForm } from './src/components/StripeRedirectForm';
66
+ import TagSelector from './src/components/TagSelector';
67
+ import { UpsellingProducts } from './src/components/UpsellingProducts';
68
+ import { UserDetails } from './src/components/UserDetails';
69
+ import { UserFormDetailsUI } from './src/components/UserFormDetails';
19
70
  import { UserProfile } from './src/components/UserProfile';
20
- import { NotFoundSource } from './src/components/NotFoundSource';
21
- import { Help } from './src/components/Help';
22
- import { HelpOrder } from './src/components/HelpOrder';
23
- import { HelpGuide } from './src/components/HelpGuide';
24
- import { HelpAccountAndPayment } from './src/components/HelpAccountAndPayment';
25
- import { OrderTypeSelector } from './src/components/OrderTypeSelector';
26
- import Notifications from './src/components/Notifications';
71
+ import { UserProfileForm } from './src/components/UserProfileForm';
72
+ import { VerifyPhone } from './src/components/VerifyPhone';
27
73
 
28
- import { Toast } from './src/components/shared/OToast';
29
74
  import {
30
75
  OText,
31
76
  OButton,
@@ -40,6 +85,7 @@ import {
40
85
  OAlert,
41
86
  OModal,
42
87
  OBottomPopup,
88
+ Toast
43
89
  } from './src/components/shared';
44
90
 
45
91
  import { Container } from './src/layouts/Container';
@@ -78,6 +124,52 @@ export {
78
124
  HelpAccountAndPayment,
79
125
  OrderTypeSelector,
80
126
  Notifications,
127
+ BottomWrapper,
128
+ BusinessBasicInformation,
129
+ BusinessController,
130
+ BusinessFeaturedController,
131
+ BusinessInformation,
132
+ BusinessItemAccordion,
133
+ BusinessProductsCategories,
134
+ BusinessProductsList,
135
+ BusinessReviews,
136
+ BusinessTypeFilter,
137
+ Cart,
138
+ CouponControl,
139
+ DriverTips,
140
+ FacebookLogin,
141
+ FloatingButton,
142
+ GoogleLogin,
143
+ GoogleMap,
144
+ GPSButton,
145
+ LanguageSelector,
146
+ LastOrder,
147
+ LastOrders,
148
+ LogoutButton,
149
+ Messages,
150
+ NavBar,
151
+ OrderSummary,
152
+ PaymentOptionCash,
153
+ PaymentOptions,
154
+ PaymentOptionStripe,
155
+ PhoneInputNumber,
156
+ PreviousOrders,
157
+ ProductForm,
158
+ ProductIngredient,
159
+ ProductItemAccordion,
160
+ ProductOption,
161
+ ProductOptionSubOption,
162
+ SearchBar,
163
+ SingleProductCard,
164
+ StripeCardForm,
165
+ StripeCardsList,
166
+ StripeElementsForm,
167
+ StripeRedirectForm,
168
+ TagSelector,
169
+ UpsellingProducts,
170
+ UserDetails,
171
+ UserFormDetailsUI,
172
+ VerifyPhone,
81
173
 
82
174
  // OComponents
83
175
  Toast,
@@ -104,4 +196,4 @@ export {
104
196
  _setStoreData,
105
197
  _removeStoreData,
106
198
  _clearStoreData
107
- }
199
+ }
@@ -1,16 +1,17 @@
1
- import OText from './OText'
1
+ import OAlert from './OAlert'
2
+ import OBottomPopup from './OBottomPopup'
2
3
  import OButton from './OButton'
3
- import OInput from './OInput'
4
4
  import ODropDown from './ODropDown'
5
5
  import OIcon from './OIcon'
6
- import OIconText from './OIconText'
7
6
  import OIconButton from './OIconButton'
8
- import OTextarea from './OTextarea'
9
- import OToggle from './OToggle'
7
+ import OIconText from './OIconText'
8
+ import OInput from './OInput'
10
9
  import OKeyButton from './OKeyButton'
11
10
  import OModal from './OModal'
12
- import OAlert from './OAlert'
13
- import OBottomPopup from './OBottomPopup'
11
+ import OText from './OText'
12
+ import OTextarea from './OTextarea'
13
+ import { Toast } from './OToast'
14
+ import OToggle from './OToggle'
14
15
 
15
16
  export {
16
17
  OText,
@@ -24,6 +25,7 @@ export {
24
25
  OToggle,
25
26
  OKeyButton,
26
27
  OAlert,
27
- OModal,
28
+ OModal,
28
29
  OBottomPopup,
30
+ Toast
29
31
  }