ordering-ui-react-native 0.15.52 → 0.15.55

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.15.52",
3
+ "version": "0.15.55",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -1,18 +1,66 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, useEffect } from 'react';
2
2
  import { StyleSheet, View, Dimensions, Platform } from 'react-native';
3
- import { useLanguage } from 'ordering-components/native';
3
+ import { useForm, Controller } from 'react-hook-form';
4
+ import { useLanguage, useApi } from 'ordering-components/native';
4
5
  import { useTheme } from 'styled-components/native';
5
- import { LogoWrapper, Container, BackgroundImage } from './styles';
6
- import { OButton, OIcon, OText } from '../shared';
6
+ import { LogoWrapper, Container, BackgroundImage, FormInput } from './styles';
7
+ import { OButton, OIcon, OText, OInput } from '../shared';
7
8
  import { _setStoreData } from '../../providers/StoreUtil';
8
9
 
9
10
  export const Home = (props: any) => {
10
- const { onNavigationRedirect } = props;
11
+ const { onNavigationRedirect, useRootPoint } = props;
11
12
  const safeHeight = Platform.OS === 'ios' ? 80 : 40;
12
13
 
13
14
  const theme = useTheme();
15
+ const [ordering, { setOrdering }] = useApi();
14
16
  const [, t] = useLanguage();
17
+ const { control, handleSubmit, errors } = useForm();
15
18
 
19
+
20
+ const styles = StyleSheet.create({
21
+ logo: {
22
+ height: 65,
23
+ width: 300,
24
+ },
25
+ wrapperContent: {
26
+ width: '100%',
27
+ },
28
+ wrapperText: {
29
+ marginBottom: 20,
30
+ },
31
+ textTitle: {
32
+ fontWeight: '600',
33
+ fontStyle: 'normal',
34
+ fontSize: 50,
35
+ },
36
+ textSubtitle: {
37
+ fontWeight: 'normal',
38
+ fontStyle: 'normal',
39
+ fontSize: 14,
40
+ },
41
+ wrapperBtn: {
42
+ marginBottom: 20
43
+ },
44
+ btn: {
45
+ borderRadius: 7.6,
46
+ marginTop: 20,
47
+ },
48
+ btnText: {
49
+ fontFamily: 'Poppins',
50
+ fontStyle: 'normal',
51
+ fontWeight: 'normal',
52
+ fontSize: 18,
53
+ },
54
+ input: {
55
+ borderWidth: 1,
56
+ borderRadius: 7.6,
57
+ borderColor: Object.keys(errors).length > 0 ? theme.colors.error : theme.colors.inputSignup,
58
+ backgroundColor: theme.colors.transparent,
59
+ },
60
+ });
61
+
62
+ const [projectName, setProjectName] = useState<any>(null)
63
+ const [isLoadingProject, setLoadingProject] = useState(false)
16
64
  const [orientation, setOrientation] = useState(
17
65
  Dimensions.get('window').width < Dimensions.get('window').height
18
66
  ? 'Portrait'
@@ -34,6 +82,27 @@ export const Home = (props: any) => {
34
82
  }
35
83
  });
36
84
 
85
+ const onSubmit = (values: any) => {
86
+ setLoadingProject(true)
87
+ setProjectName(values)
88
+ setOrdering({ ...ordering, project: values?.project_name })
89
+ _setStoreData('project_name', values?.project_name)
90
+ };
91
+
92
+ useEffect(() => {
93
+ if (Object.keys(errors).length > 0) {
94
+ setProjectName(null)
95
+ setLoadingProject(false)
96
+ }
97
+ }, [errors])
98
+
99
+ useEffect(() => {
100
+ if (ordering?.project === projectName?.project_name) {
101
+ setLoadingProject(false)
102
+ onNavigationRedirect('Login')
103
+ }
104
+ }, [ordering])
105
+
37
106
  return (
38
107
  <Container height={windowHeight - safeHeight} orientation={orientation}>
39
108
  <BackgroundImage
@@ -54,58 +123,62 @@ export const Home = (props: any) => {
54
123
  </OText>
55
124
  </View>
56
125
 
57
- <View style={styles.wrapperBtn}>
58
- <OButton
59
- text={t('LOGIN', 'Login')}
60
- textStyle={{
61
- ...styles.btnText,
62
- color: theme.colors.inputTextColor,
63
- }}
64
- bgColor={theme.colors.primary}
65
- borderColor={theme.colors.primary}
66
- style={styles.btn}
67
- imgRightSrc={false}
68
- onClick={() => onNavigationRedirect('Login')}
69
- />
70
- </View>
126
+ <>
127
+ {useRootPoint && (
128
+ <FormInput>
129
+ <Controller
130
+ control={control}
131
+ name='project_name'
132
+ rules={{ required: t(`VALIDATION_ERROR_PROJECT_NAME_REQUIRED`, 'The field project name is required') }}
133
+ defaultValue=""
134
+ render={({ onChange, value }: any) => (
135
+ <OInput
136
+ name='project_name'
137
+ placeholderTextColor={theme.colors.arrowColor}
138
+ placeholder={t('PROJECT_NAME', 'Project Name')}
139
+ icon={theme.images.general.project}
140
+ iconColor={theme.colors.arrowColor}
141
+ onChange={(e: any) => onChange(e?.target?.value)}
142
+ selectionColor={theme.colors.primary}
143
+ color={theme.colors.white}
144
+ value={value}
145
+ style={styles.input}
146
+ returnKeyType='done'
147
+ autoCorrect={false}
148
+ autoCapitalize='none'
149
+ blurOnSubmit={false}
150
+ onSubmitEditing={() => handleSubmit(onSubmit)()}
151
+ />
152
+ )}
153
+ />
154
+ </FormInput>
155
+ )}
156
+ {Object.keys(errors).length > 0 && (
157
+ <OText
158
+ color={theme.colors.white}
159
+ style={{ alignSelf: 'center', marginTop: 5 }}
160
+ >
161
+ {errors['project_name'].message}
162
+ </OText>
163
+ )}
164
+ <View style={styles.wrapperBtn}>
165
+ <OButton
166
+ text={useRootPoint ? t('SET_PROJECT', 'Set project') : t('LOGIN', 'Login')}
167
+ textStyle={{
168
+ ...styles.btnText,
169
+ color: theme.colors.inputTextColor,
170
+ }}
171
+ bgColor={theme.colors.primary}
172
+ borderColor={theme.colors.primary}
173
+ isLoading={isLoadingProject}
174
+ style={styles.btn}
175
+ imgRightSrc={false}
176
+ onClick={() => useRootPoint ? handleSubmit(onSubmit)() : onNavigationRedirect('Login')}
177
+ />
178
+ </View>
179
+ </>
71
180
  </View>
72
181
  </BackgroundImage>
73
182
  </Container>
74
183
  );
75
184
  };
76
-
77
- const styles = StyleSheet.create({
78
- logo: {
79
- height: 65,
80
- width: 300,
81
- },
82
- wrapperContent: {
83
- width: '100%',
84
- },
85
- wrapperText: {
86
- marginBottom: 20,
87
- },
88
- textTitle: {
89
- fontWeight: '600',
90
- fontStyle: 'normal',
91
- fontSize: 50,
92
- },
93
- textSubtitle: {
94
- fontWeight: 'normal',
95
- fontStyle: 'normal',
96
- fontSize: 14,
97
- },
98
- wrapperBtn: {
99
- marginBottom: 20,
100
- },
101
- btn: {
102
- borderRadius: 7.6,
103
- marginTop: 20,
104
- },
105
- btnText: {
106
- fontFamily: 'Poppins',
107
- fontStyle: 'normal',
108
- fontWeight: 'normal',
109
- fontSize: 18,
110
- },
111
- });
@@ -1,4 +1,4 @@
1
- import styled from 'styled-components/native';
1
+ import styled, { css } from 'styled-components/native';
2
2
 
3
3
  export const Container = styled.View`
4
4
  width: 100%;
@@ -25,3 +25,10 @@ export const BackgroundImage = styled.ImageBackground`
25
25
  align-items: center;
26
26
  padding: 20px 40px;
27
27
  `;
28
+
29
+ export const FormInput = styled.View`
30
+ display: flex;
31
+ flex-direction: column;
32
+ width: 100%;
33
+ min-height: 50px;
34
+ `;
@@ -101,9 +101,9 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
101
101
  };
102
102
 
103
103
  const handleOpenMapView = async () => {
104
- if (permissions.locationStatus === 'granted') {
104
+ if (permissions?.locationStatus === 'granted') {
105
105
  setOpenModalForMapView(!openModalForMapView);
106
- } else if (permissions.locationStatus === 'blocked') {
106
+ } else if (permissions?.locationStatus === 'blocked') {
107
107
  // redirectToSettings();
108
108
  showToast(
109
109
  ToastType.Error,
@@ -141,9 +141,9 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
141
141
  handleArrowBack()
142
142
  }
143
143
 
144
- const handleAcceptLogisticOrder = (order : any) => {
144
+ const handleAcceptLogisticOrder = (order: any) => {
145
145
  handleClickLogisticOrder?.(1, order?.logistic_order_id)
146
- if(order?.order_group){
146
+ if (order?.order_group) {
147
147
  handleArrowBack()
148
148
  }
149
149
  }
@@ -166,10 +166,10 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
166
166
  ];
167
167
 
168
168
  useEffect(() => {
169
- if (permissions.locationStatus !== 'granted' && openModalForMapView) {
169
+ if (permissions?.locationStatus !== 'granted' && openModalForMapView) {
170
170
  setOpenModalForMapView(false);
171
171
  }
172
- }, [permissions.locationStatus]);
172
+ }, [permissions?.locationStatus]);
173
173
 
174
174
  useEffect(() => {
175
175
  if (openModalForAccept) {
@@ -215,8 +215,8 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
215
215
  }, [messagesReadList]);
216
216
 
217
217
  useEffect(() => {
218
- forceUpdate && handleViewActionOrder && handleViewActionOrder(forceUpdate === 9 ? 'forcePickUp': 'forceDelivery')
219
- },[forceUpdate])
218
+ forceUpdate && handleViewActionOrder && handleViewActionOrder(forceUpdate === 9 ? 'forcePickUp' : 'forceDelivery')
219
+ }, [forceUpdate])
220
220
 
221
221
  const styles = StyleSheet.create({
222
222
  btnPickUp: {
@@ -254,7 +254,7 @@ export const OrderDetailsUI = (props: OrderDetailsParams) => {
254
254
  );
255
255
  }
256
256
 
257
- const OrderDetailsInformation = (props : {order: any, isOrderGroup?: boolean, lastOrder?: boolean}) => {
257
+ const OrderDetailsInformation = (props: { order: any, isOrderGroup?: boolean, lastOrder?: boolean }) => {
258
258
  const {
259
259
  order,
260
260
  isOrderGroup,
@@ -248,7 +248,7 @@ const BusinessProductsListUI = (props: BusinessProductsListParams) => {
248
248
  style={{ borderRadius: 7.6 }}
249
249
  />
250
250
  )}
251
- <OText>{openDescription?.description}</OText>
251
+ <OText mBottom={40}>{openDescription?.description}</OText>
252
252
  </ScrollView>
253
253
  </OModal>
254
254
  </ProductsContainer>
@@ -90,33 +90,12 @@ const BusinessReviewsUI = (props: BusinessReviewsParams) => {
90
90
  </View>
91
91
  );
92
92
 
93
- const ReviewItem = ({ comment, created_at, total, customer }: any) => (
93
+ const ReviewItem = ({ comment, created_at, total }: any) => (
94
94
  <View style={{ marginBottom: 30 }}>
95
- <View
96
- style={{ flexDirection: 'row', marginBottom: 19, alignItems: 'center' }}>
97
- <OIcon
98
- url={theme.images.dummies.customerPhoto}
99
- width={38}
100
- height={38}
101
- style={{
102
- borderRadius: 7.6,
103
- borderWidth: 1,
104
- borderColor: theme.colors.border,
105
- marginEnd: 9,
106
- }}
107
- />
108
- <View>
109
- <OText size={12} color={theme.colors.textNormal} weight={'500'}>
110
- {customer?.name || 'Jane Cooper'}
111
- </OText>
112
- <OText size={10} color={theme.colors.textSecondary}>
113
- {moment(created_at).format('MMMM d, yyyy • hh:mm')}
114
- </OText>
115
- </View>
116
- </View>
117
- <OText size={10} color={theme.colors.textNormal}>
118
- {comment}
95
+ <OText size={12} color={theme.colors.textSecondary}>
96
+ {moment(created_at).format('MMMM d, yyyy hh:mm')}
119
97
  </OText>
98
+ <OText size={12} color={theme.colors.textNormal}>{comment}</OText>
120
99
  </View>
121
100
  );
122
101
 
@@ -112,7 +112,7 @@ const OrderSummaryUI = (props: any) => {
112
112
  {cart?.products?.length > 0 && (
113
113
  <>
114
114
  <OSProductList>
115
- {cart?.products.map((product: any) => (
115
+ {cart?.products?.map((product: any) => (
116
116
  <ProductItemAccordion
117
117
  key={product.code}
118
118
  product={product}
@@ -1,11 +1,12 @@
1
1
  import React, { useEffect, useRef, useState } from 'react';
2
- import { View, Pressable, StyleSheet, Linking, Platform } from 'react-native';
2
+ import { View, Pressable, StyleSheet, Linking, Platform, TouchableOpacity } from 'react-native';
3
3
  import { useForm, Controller } from 'react-hook-form';
4
4
  import Spinner from 'react-native-loading-spinner-overlay';
5
5
  import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
6
6
  import CheckBox from '@react-native-community/checkbox';
7
7
  import { PhoneInputNumber } from '../PhoneInputNumber';
8
8
  import { FacebookLogin } from '../FacebookLogin';
9
+ import Recaptcha from 'react-native-recaptcha-that-works'
9
10
 
10
11
  import {
11
12
  SignupForm as SignUpController,
@@ -23,6 +24,7 @@ import {
23
24
  LoginWith as SignupWith,
24
25
  OTab,
25
26
  OTabs,
27
+ RecaptchaButton
26
28
  } from '../LoginForm/styles';
27
29
 
28
30
  import NavBar from '../NavBar';
@@ -63,7 +65,9 @@ const SignupFormUI = (props: SignupParams) => {
63
65
  handleSendVerifyCode,
64
66
  handleCheckPhoneCode,
65
67
  notificationState,
66
- handleChangePromotions
68
+ handleChangePromotions,
69
+ enableReCaptcha,
70
+ handleReCaptcha
67
71
  } = props;
68
72
 
69
73
  const theme = useTheme();
@@ -117,6 +121,8 @@ const SignupFormUI = (props: SignupParams) => {
117
121
  cellphone: null,
118
122
  },
119
123
  });
124
+ const [recaptchaConfig, setRecaptchaConfig] = useState<any>({})
125
+ const [recaptchaVerified, setRecaptchaVerified] = useState(false)
120
126
 
121
127
  const nameRef = useRef<any>(null);
122
128
  const lastnameRef = useRef<any>(null);
@@ -125,6 +131,7 @@ const SignupFormUI = (props: SignupParams) => {
125
131
  const emailRef = useRef<any>(null);
126
132
  const phoneRef = useRef<any>(null);
127
133
  const passwordRef = useRef<any>(null);
134
+ const recaptchaRef = useRef<any>({});
128
135
 
129
136
  const showInputPhoneNumber = (validationFields?.fields?.checkout?.cellphone?.enabled ?? false) || configs?.verification_phone_required?.value === '1'
130
137
 
@@ -286,6 +293,33 @@ const SignupFormUI = (props: SignupParams) => {
286
293
  }
287
294
  }
288
295
 
296
+ const handleOpenRecaptcha = () => {
297
+ setRecaptchaVerified(false)
298
+ if (!recaptchaConfig?.siteKey) {
299
+ showToast(ToastType.Error, t('NO_RECAPTCHA_SITE_KEY', 'The config doesn\'t have recaptcha site key'));
300
+ return
301
+ }
302
+ if (!recaptchaConfig?.baseUrl) {
303
+ showToast(ToastType.Error, t('NO_RECAPTCHA_BASE_URL', 'The config doesn\'t have recaptcha base url'));
304
+ return
305
+ }
306
+ recaptchaRef.current.open()
307
+ }
308
+
309
+ const onRecaptchaVerify = (token: any) => {
310
+ setRecaptchaVerified(true)
311
+ handleReCaptcha(token)
312
+ }
313
+
314
+ useEffect(() => {
315
+ if (configs && Object.keys(configs).length > 0 && enableReCaptcha) {
316
+ setRecaptchaConfig({
317
+ siteKey: configs?.security_recaptcha_site_key?.value || null,
318
+ baseUrl: configs?.security_recaptcha_base_url?.value || null
319
+ })
320
+ }
321
+ }, [configs, enableReCaptcha])
322
+
289
323
  useEffect(() => {
290
324
  if (!formState.loading && formState.result?.error) {
291
325
  formState.result?.result &&
@@ -467,6 +501,39 @@ const SignupFormUI = (props: SignupParams) => {
467
501
  </View>
468
502
  )}
469
503
 
504
+ {enableReCaptcha && (
505
+ <>
506
+ <TouchableOpacity
507
+ onPress={handleOpenRecaptcha}
508
+ style={{ marginHorizontal: 4, marginBottom: 10 }}
509
+ >
510
+ <RecaptchaButton>
511
+ {recaptchaVerified ? (
512
+ <MaterialCommunityIcons
513
+ name="checkbox-marked"
514
+ size={23}
515
+ color={theme.colors.primary}
516
+ />
517
+ ) : (
518
+ <MaterialCommunityIcons
519
+ name="checkbox-blank-outline"
520
+ size={23}
521
+ color={theme.colors.disabled}
522
+ />
523
+ )}
524
+ <OText size={14} mLeft={8}>{t('VERIFY_ReCAPTCHA', 'Verify reCAPTCHA')}</OText>
525
+ </RecaptchaButton>
526
+ </TouchableOpacity>
527
+ <Recaptcha
528
+ ref={recaptchaRef}
529
+ siteKey={recaptchaConfig?.siteKey}
530
+ baseUrl={recaptchaConfig?.baseUrl}
531
+ onVerify={onRecaptchaVerify}
532
+ onExpire={() => setRecaptchaVerified(false)}
533
+ />
534
+ </>
535
+ )}
536
+
470
537
  <View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 20 }}>
471
538
  <Controller
472
539
  control={control}
@@ -736,6 +803,7 @@ const SignupFormUI = (props: SignupParams) => {
736
803
  export const SignupForm = (props: any) => {
737
804
  const signupProps = {
738
805
  ...props,
806
+ isRecaptchaEnable: true,
739
807
  UIComponent: SignupFormUI,
740
808
  };
741
809
  return <SignUpController {...signupProps} />;
@@ -102,6 +102,8 @@ export interface SignupParams {
102
102
  handleCheckPhoneCode?: any;
103
103
  notificationState?: any;
104
104
  handleChangePromotions: () => void;
105
+ enableReCaptcha?: boolean;
106
+ handleReCaptcha?: () => void;
105
107
  }
106
108
 
107
109
  export interface PhoneInputParams {