ordering-ui-react-native 0.16.72-release → 0.16.73-release

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 (48) hide show
  1. package/package.json +1 -1
  2. package/src/components/OrderCreating/index.tsx +2 -2
  3. package/themes/business/src/components/AcceptOrRejectOrder/index.tsx +2 -2
  4. package/themes/business/src/components/LoginForm/Otp/index.tsx +120 -0
  5. package/themes/business/src/components/LoginForm/Otp/styles.tsx +7 -0
  6. package/themes/business/src/components/LoginForm/index.tsx +235 -80
  7. package/themes/business/src/components/LoginForm/styles.tsx +10 -0
  8. package/themes/business/src/components/ProductItemAccordion/index.tsx +21 -3
  9. package/themes/business/src/types/index.tsx +15 -0
  10. package/themes/business/src/utils/index.tsx +16 -0
  11. package/themes/kiosk/src/components/LoginForm/Otp/index.tsx +92 -0
  12. package/themes/kiosk/src/components/LoginForm/Otp/styles.tsx +7 -0
  13. package/themes/kiosk/src/components/LoginForm/index.tsx +473 -151
  14. package/themes/kiosk/src/components/LoginForm/styles.tsx +14 -1
  15. package/themes/kiosk/src/components/PhoneInputNumber/index.tsx +1 -0
  16. package/themes/kiosk/src/components/PhoneInputNumber/styles.tsx +1 -3
  17. package/themes/kiosk/src/components/shared/OModal.tsx +14 -11
  18. package/themes/kiosk/src/layouts/Container.tsx +7 -1
  19. package/themes/kiosk/src/types/index.d.ts +13 -0
  20. package/themes/kiosk/src/utils/index.tsx +15 -0
  21. package/themes/original/src/components/BusinessListingSearch/index.tsx +12 -7
  22. package/themes/original/src/components/BusinessProductsListing/index.tsx +1 -0
  23. package/themes/original/src/components/Cart/index.tsx +3 -2
  24. package/themes/original/src/components/Checkout/index.tsx +4 -3
  25. package/themes/original/src/components/Favorite/index.tsx +1 -1
  26. package/themes/original/src/components/Help/index.tsx +2 -2
  27. package/themes/original/src/components/HelpGuide/index.tsx +2 -2
  28. package/themes/original/src/components/HelpGuide/styles.tsx +1 -0
  29. package/themes/original/src/components/Messages/index.tsx +8 -7
  30. package/themes/original/src/components/OrderDetails/index.tsx +8 -3
  31. package/themes/original/src/components/OrderProgress/index.tsx +2 -5
  32. package/themes/original/src/components/OrdersOption/index.tsx +17 -29
  33. package/themes/original/src/components/ProductForm/index.tsx +29 -2
  34. package/themes/original/src/components/ProductOptionSubOption/index.tsx +1 -1
  35. package/themes/original/src/components/ProfessionalFilter/SingleProfessionalCard/index.tsx +108 -0
  36. package/themes/original/src/components/ProfessionalFilter/index.tsx +20 -50
  37. package/themes/original/src/components/ProfessionalProfile/index.tsx +1 -1
  38. package/themes/original/src/components/ServiceForm/index.tsx +11 -3
  39. package/themes/original/src/components/Sessions/index.tsx +11 -8
  40. package/themes/original/src/components/Sessions/styles.tsx +5 -0
  41. package/themes/original/src/components/SingleProductCard/index.tsx +62 -24
  42. package/themes/original/src/components/SingleProductCard/styles.tsx +12 -4
  43. package/themes/original/src/components/UpsellingProducts/index.tsx +3 -3
  44. package/themes/original/src/components/UserProfileForm/index.tsx +3 -1
  45. package/themes/original/src/components/UserProfileForm/styles.tsx +1 -1
  46. package/themes/original/src/components/Wallets/index.tsx +4 -3
  47. package/themes/original/src/types/index.tsx +2 -1
  48. package/themes/original/src/utils/index.tsx +12 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.16.72-release",
3
+ "version": "0.16.73-release",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -131,7 +131,7 @@ export const OrderCreating = (props: any) => {
131
131
  <OText size={14}>{address}</OText>
132
132
  </LocationWrapper>
133
133
  )}
134
- {cart && (
134
+ {cart && !orderState?.options?.moment && (
135
135
  <DeliveryWrapper>
136
136
  <DeliveryContentWrapper>
137
137
  <SimpleIcon
@@ -175,4 +175,4 @@ export const OrderCreating = (props: any) => {
175
175
  )}
176
176
  </OrderCreatingContainer>
177
177
  )
178
- }
178
+ }
@@ -95,7 +95,7 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
95
95
  upper: {
96
96
  flex: 1,
97
97
  zIndex: 1001,
98
- paddingTop: isPage ? 30 : 80,
98
+ paddingTop: isPage ? 30 : 50,
99
99
  marginBottom: 10,
100
100
  backgroundColor: theme.colors.backgroundPage
101
101
  },
@@ -418,7 +418,7 @@ export const AcceptOrRejectOrder = (props: AcceptOrRejectOrderParams) => {
418
418
  </Header>
419
419
 
420
420
  {action === 'accept' && (
421
- <View style={{ height: 400, justifyContent: 'center' }}>
421
+ <View style={{ height: 300, justifyContent: 'center' }}>
422
422
  <Timer onPress={() => openTimerIOnput()}>
423
423
  <OText weight="600" style={{ textAlign: 'center' }} size={55}>
424
424
  {hour}
@@ -0,0 +1,120 @@
1
+ import React, { useEffect, useState } from 'react'
2
+ import { formatSeconds } from '../../../utils'
3
+ import { StyleSheet, TouchableOpacity, Alert } from 'react-native';
4
+ import { useCountdownTimer } from '../../../../../../src/hooks/useCountdownTimer';
5
+ import { useLanguage } from 'ordering-components/native';
6
+ import { OTPContainer } from './styles';
7
+ import { OText, OButton } from '../../shared';
8
+ import OTPInputView from '@twotalltotems/react-native-otp-input'
9
+ import { useTheme } from 'styled-components/native';
10
+ import { otpParams } from '../../../types'
11
+
12
+ export const Otp = (props: otpParams) => {
13
+ const {
14
+ willVerifyOtpState,
15
+ setWillVerifyOtpState,
16
+ onSubmit,
17
+ handleLoginOtp,
18
+ setAlertState,
19
+ pinCount,
20
+ formState
21
+ } = props
22
+
23
+ const theme = useTheme();
24
+ const [, t] = useLanguage();
25
+ const [code, setCode] = useState('')
26
+ const [otpLeftTime, _, resetOtpLeftTime]: any = useCountdownTimer(
27
+ 600, willVerifyOtpState)
28
+
29
+
30
+ const handleOnSubmit = () => {
31
+ setAlertState({
32
+ open: true,
33
+ title: t('CODE_SENT', 'The code has been sent'),
34
+ })
35
+ resetOtpLeftTime()
36
+ onSubmit()
37
+ }
38
+
39
+ useEffect(() => {
40
+ if (otpLeftTime === 0) {
41
+ setAlertState({
42
+ open: true,
43
+ title: t('TIME_IS_UP', 'Time is up'),
44
+ content: t('PLEASE_RESEND_CODE', 'Please resend code again')
45
+ })
46
+ }
47
+ }, [otpLeftTime])
48
+
49
+ useEffect(() => {
50
+ if (!formState?.loading && formState?.result?.error) {
51
+ Alert.alert(
52
+ t('ERROR', 'Error'),
53
+ typeof formState.result?.result === 'string'
54
+ ? formState.result?.result
55
+ : formState.result?.result[0],
56
+ [
57
+ {
58
+ text: t('ACCEPT', 'Accept'),
59
+ onPress: () => {},
60
+ style: 'cancel'
61
+ },
62
+ ],
63
+ { cancelable: false }
64
+ )
65
+
66
+ if (code.length === (pinCount || 6)) {
67
+ setCode('')
68
+ }
69
+
70
+ }
71
+ }, [formState])
72
+
73
+ const loginStyle = StyleSheet.create({
74
+ underlineStyleBase: {
75
+ width: 45,
76
+ height: 60,
77
+ borderWidth: 1,
78
+ fontSize: 16
79
+ },
80
+ underlineStyleHighLighted: {
81
+ borderColor: theme.colors.primary,
82
+ color: theme.colors.primary,
83
+ fontSize: 16
84
+ },
85
+ });
86
+
87
+ return (
88
+ <>
89
+ <OTPContainer>
90
+ <OText size={24}>
91
+ {formatSeconds(otpLeftTime)}
92
+ </OText>
93
+ <OTPInputView
94
+ style={{ width: '100%', height: 150 }}
95
+ pinCount={pinCount || 6}
96
+ codeInputFieldStyle={loginStyle.underlineStyleBase}
97
+ codeInputHighlightStyle={loginStyle.underlineStyleHighLighted}
98
+ onCodeFilled={(code: string) => handleLoginOtp(code)}
99
+ selectionColor={theme.colors.primary}
100
+ editable
101
+ code={code}
102
+ onCodeChanged={(code: string) => setCode(code)}
103
+ />
104
+ <TouchableOpacity onPress={() => handleOnSubmit()} disabled={otpLeftTime > 520}>
105
+ <OText size={16} mBottom={30} color={otpLeftTime > 520 ? theme.colors.disabled : theme.colors.primary}>
106
+ {t('RESEND_CODE', 'Resend code')}
107
+ </OText>
108
+ </TouchableOpacity>
109
+ <OButton
110
+ onClick={() => setWillVerifyOtpState(false)}
111
+ bgColor={theme.colors.white}
112
+ borderColor={theme.colors.primary}
113
+ textStyle={{ color: theme.colors.primary }}
114
+ style={{ borderRadius: 8, width: '100%' }}
115
+ text={t('CANCEL', 'Cancel')}
116
+ />
117
+ </OTPContainer>
118
+ </>
119
+ )
120
+ }
@@ -0,0 +1,7 @@
1
+ import styled from 'styled-components/native';
2
+
3
+ export const OTPContainer = styled.View`
4
+ padding: 20px;
5
+ align-items: center;
6
+ flex: 1
7
+ `
@@ -28,7 +28,9 @@ import {
28
28
  TabsContainer,
29
29
  OrSeparator,
30
30
  LineSeparator,
31
- RecaptchaButton
31
+ RecaptchaButton,
32
+ TabBtn,
33
+ OTab
32
34
  } from './styles';
33
35
  import { _setStoreData } from '../../providers/StoreUtil'
34
36
  import { OText, OButton, OInput, OIconButton, OModal } from '../shared';
@@ -36,6 +38,9 @@ import { PhoneInputNumber } from '../PhoneInputNumber';
36
38
  import { VerifyPhone } from '../VerifyPhone';
37
39
  import { LoginParams } from '../../types';
38
40
 
41
+ import { Otp } from './Otp'
42
+ import Alert from '../../../../../src/providers/AlertProvider'
43
+
39
44
  const LoginFormUI = (props: LoginParams) => {
40
45
  const {
41
46
  navigation,
@@ -54,7 +59,14 @@ const LoginFormUI = (props: LoginParams) => {
54
59
  useRootPoint,
55
60
  notificationState,
56
61
  handleReCaptcha,
57
- enableReCaptcha
62
+ enableReCaptcha,
63
+
64
+ useLoginOtp,
65
+ otpType,
66
+ setOtpType,
67
+ generateOtpCode,
68
+ useLoginOtpEmail,
69
+ useLoginOtpCellphone,
58
70
  } = props;
59
71
 
60
72
  const [ordering, { setOrdering }] = useApi();
@@ -97,6 +109,12 @@ const LoginFormUI = (props: LoginParams) => {
97
109
 
98
110
  const recaptchaRef = useRef<any>({});
99
111
 
112
+ const [willVerifyOtpState, setWillVerifyOtpState] = useState(false)
113
+ const [alertState, setAlertState] = useState({ open: false, title: '', content: [] })
114
+ const isOtpEmail = loginTab === 'otp' && otpType === 'email'
115
+ const isOtpCellphone = loginTab === 'otp' && otpType === 'cellphone'
116
+
117
+
100
118
  const handleOpenRecaptcha = () => {
101
119
  setRecaptchaVerified(false)
102
120
  if (!recaptchaConfig?.siteKey) {
@@ -209,6 +227,31 @@ const LoginFormUI = (props: LoginParams) => {
209
227
  handleSubmit(onSubmit)();
210
228
  };
211
229
 
230
+ const mainLogin = (values) => {
231
+ if (loginTab === 'otp') {
232
+ if (phoneInputData.error && (loginTab !== 'otp' || (otpType === 'cellphone' && loginTab === 'otp'))) {
233
+ showToast(ToastType.Error, t('INVALID_PHONE_NUMBER', 'Invalid phone number'));
234
+ return
235
+ }
236
+ if (loginTab === 'otp') {
237
+ generateOtpCode({
238
+ ...values,
239
+ ...phoneInputData.phone
240
+ })
241
+ }
242
+ setWillVerifyOtpState(true)
243
+ } else {
244
+ if (phoneInputData.error) {
245
+ showToast(ToastType.Error, phoneInputData.error);
246
+ return;
247
+ }
248
+ handleButtonLoginClick({
249
+ ...values,
250
+ ...phoneInputData.phone,
251
+ });
252
+ }
253
+ }
254
+
212
255
  const onSubmit = (values: any) => {
213
256
  Keyboard.dismiss();
214
257
 
@@ -227,13 +270,26 @@ const LoginFormUI = (props: LoginParams) => {
227
270
  setSubmitted(true)
228
271
  return
229
272
  }
230
-
231
- handleButtonLoginClick({
232
- ...values,
233
- ...phoneInputData.phone
234
- });
273
+ mainLogin(values)
235
274
  };
236
275
 
276
+ const handleChangeOtpType = (type: string) => {
277
+ handleChangeTab('otp', type)
278
+ setOtpType(type)
279
+ }
280
+
281
+ const handleLoginOtp = (code: string) => {
282
+ handleButtonLoginClick({ code })
283
+ }
284
+
285
+ const closeAlert = () => {
286
+ setAlertState({
287
+ open: false,
288
+ title: '',
289
+ content: []
290
+ })
291
+ }
292
+
237
293
  const handleVerifyCodeClick = () => {
238
294
  if (phoneInputData.error) {
239
295
  showToast(ToastType.Error, phoneInputData.error);
@@ -272,27 +328,17 @@ const LoginFormUI = (props: LoginParams) => {
272
328
  showToast(ToastType.Info, t('TRY_AGAIN', 'Please try again'))
273
329
  return
274
330
  }
275
- formState?.result?.result &&
276
- showToast(
277
- ToastType.Error,
278
- loginTab === 'email' && typeof formState.result?.result === 'string'
279
- ? getTraduction(formState.result?.result)
280
- : loginTab === 'email' &&
281
- typeof formState.result?.result !== 'string'
282
- ? getTraduction(formState.result?.result[0])
283
- : loginTab === 'cellphone' &&
284
- typeof formState.result?.result === 'string'
285
- ? getTraduction(formState.result?.result).replace(
286
- t('USER', 'user').toLowerCase(),
287
- t('PHONE_NUMER', 'Phone number'),
288
- )
289
- : getTraduction(formState.result?.result[0]).replace(
290
- t('USER', 'user').toLowerCase(),
291
- t('PHONE_NUMER', 'Phone number'),
292
- ),
293
- );
331
+ formState.result?.result && showToast(
332
+ ToastType.Error,
333
+ typeof formState.result?.result === 'string'
334
+ ? formState.result?.result
335
+ : formState.result?.result[0]
336
+ )
294
337
  setSubmitted(false)
295
338
  }
339
+ if (!formState?.loading && !formState?.result?.error) {
340
+ setWillVerifyOtpState(false)
341
+ }
296
342
  }, [formState]);
297
343
 
298
344
  useEffect(() => {
@@ -360,9 +406,20 @@ const LoginFormUI = (props: LoginParams) => {
360
406
  if (values?.project_name) {
361
407
  delete values.project_name
362
408
  }
363
- handleButtonLoginClick({ ...values })
409
+ mainLogin(values)
410
+ setSubmitted(false)
364
411
  }, [ordering, submitted])
365
412
 
413
+ useEffect(() => {
414
+ if (checkPhoneCodeState?.result?.error) {
415
+ setAlertState({
416
+ open: true,
417
+ content: t(checkPhoneCodeState?.result?.error, checkPhoneCodeState?.result?.error),
418
+ title: ''
419
+ })
420
+ }
421
+ }, [checkPhoneCodeState])
422
+
366
423
  Dimensions.addEventListener('change', ({ window: { width, height } }) => {
367
424
  setWindowWidth(
368
425
  parseInt(parseFloat(String(Dimensions.get('window').width)).toFixed(0)),
@@ -445,6 +502,25 @@ const LoginFormUI = (props: LoginParams) => {
445
502
  fontWeight: 'normal',
446
503
  fontSize: 16,
447
504
  },
505
+
506
+ borderStyleBase: {
507
+ width: 30,
508
+ height: 45
509
+ },
510
+ borderStyleHighLighted: {
511
+ borderColor: "#03DAC6",
512
+ },
513
+ underlineStyleBase: {
514
+ width: 45,
515
+ height: 60,
516
+ borderWidth: 1,
517
+ fontSize: 16
518
+ },
519
+ underlineStyleHighLighted: {
520
+ borderColor: theme.colors.primary,
521
+ color: theme.colors.primary,
522
+ fontSize: 16
523
+ },
448
524
  });
449
525
 
450
526
  return (
@@ -461,7 +537,7 @@ const LoginFormUI = (props: LoginParams) => {
461
537
  <OText style={styles.title}>{t('LOGIN', 'Login')}</OText>
462
538
  </View>
463
539
 
464
- {(useLoginByEmail || useLoginByCellphone) && (
540
+ {(Number(useLoginByEmail) + Number(useLoginByCellphone) + Number(useLoginOtpEmail) + Number(useLoginOtpCellphone) > 1) && (
465
541
  <LoginWith>
466
542
  <ScrollView
467
543
  ref={scrollRefTab}
@@ -522,12 +598,63 @@ const LoginFormUI = (props: LoginParams) => {
522
598
  }}></View>
523
599
  </Pressable>
524
600
  )}
601
+
602
+ {useLoginOtpEmail && (
603
+ <Pressable
604
+ style={styles.btnTab}
605
+ onPress={() => handleChangeOtpType('email')}>
606
+ <OText
607
+ style={styles.btnTabText}
608
+ color={
609
+ isOtpEmail
610
+ ? theme.colors.textNormal
611
+ : theme.colors.disabled
612
+ }
613
+ weight={isOtpEmail ? 'bold' : 'normal'}>
614
+ {t('BY_OTP_EMAIL', 'By Otp Email')}
615
+ </OText>
616
+ <View
617
+ style={{
618
+ width: '100%',
619
+ borderBottomColor:
620
+ isOtpEmail
621
+ ? theme.colors.textGray
622
+ : theme.colors.tabBar,
623
+ borderBottomWidth: 2,
624
+ }} />
625
+ </Pressable>
626
+ )}
627
+ {useLoginOtpCellphone && (
628
+ <Pressable
629
+ style={styles.btnTab}
630
+ onPress={() => handleChangeOtpType('cellphone')}>
631
+ <OText
632
+ style={styles.btnTabText}
633
+ color={
634
+ isOtpCellphone
635
+ ? theme.colors.textNormal
636
+ : theme.colors.disabled
637
+ }
638
+ weight={isOtpCellphone ? 'bold' : 'normal'}>
639
+ {t('BY_OTP_PHONE', 'By Otp Phone')}
640
+ </OText>
641
+ <View
642
+ style={{
643
+ width: '100%',
644
+ borderBottomColor:
645
+ isOtpCellphone
646
+ ? theme.colors.textGray
647
+ : theme.colors.tabBar,
648
+ borderBottomWidth: 2,
649
+ }} />
650
+ </Pressable>
651
+ )}
525
652
  </TabsContainer>
526
653
  </ScrollView>
527
654
  </LoginWith>
528
655
  )}
529
656
 
530
- {(useLoginByCellphone || useLoginByEmail) && (
657
+ {(useLoginByCellphone || useLoginByEmail || useLoginOtp) && (
531
658
  <FormInput>
532
659
  {useRootPoint && (
533
660
  <Controller
@@ -561,7 +688,7 @@ const LoginFormUI = (props: LoginParams) => {
561
688
  />
562
689
  )}
563
690
 
564
- {useLoginByEmail && loginTab === 'email' && (
691
+ {((useLoginByEmail && loginTab === 'email') || (loginTab === 'otp' && otpType === 'email')) && (
565
692
  <Controller
566
693
  control={control}
567
694
  render={({ onChange, value }: any) => (
@@ -606,7 +733,7 @@ const LoginFormUI = (props: LoginParams) => {
606
733
  />
607
734
  )}
608
735
 
609
- {useLoginByCellphone && loginTab === 'cellphone' && (
736
+ {((useLoginByCellphone && loginTab === 'cellphone') || (loginTab === 'otp' && otpType === 'cellphone')) && (
610
737
  <View style={{ marginBottom: 20 }}>
611
738
  <PhoneInputNumber
612
739
  data={phoneInputData}
@@ -621,54 +748,56 @@ const LoginFormUI = (props: LoginParams) => {
621
748
  </View>
622
749
  )}
623
750
 
624
- <Controller
625
- control={control}
626
- render={({ onChange, value }: any) => (
627
- <OInput
628
- isSecured={!passwordSee ? true : false}
629
- placeholder={t('PASSWORD', 'Password')}
630
- placeholderTextColor={theme.colors.arrowColor}
631
- style={styles.input}
632
- icon={theme.images.logos.passwordInputIcon}
633
- iconColor={theme.colors.arrowColor}
634
- iconCustomRight={
635
- !passwordSee ? (
636
- <MaterialCommunityIcons
637
- name="eye-outline"
638
- size={24}
639
- color={theme.colors.arrowColor}
640
- onPress={() => setPasswordSee(!passwordSee)}
641
- />
642
- ) : (
643
- <MaterialCommunityIcons
644
- name="eye-off-outline"
645
- size={24}
646
- color={theme.colors.arrowColor}
647
- onPress={() => setPasswordSee(!passwordSee)}
648
- />
649
- )
650
- }
651
- selectionColor={theme.colors.primary}
652
- color={theme.colors.textGray}
653
- value={value}
654
- forwardRef={inputRef}
655
- onChange={(val: any) => onChange(val)}
656
- returnKeyType="done"
657
- onSubmitEditing={() => handleLogin()}
658
- blurOnSubmit
659
- />
660
- )}
661
- name="password"
662
- rules={{
663
- required: t(
664
- 'VALIDATION_ERROR_PASSWORD_REQUIRED',
665
- 'The field Password is required',
666
- ).replace('_attribute_', t('PASSWORD', 'Password')),
667
- }}
668
- defaultValue=""
669
- />
751
+ {loginTab !== 'otp' && (
752
+ <Controller
753
+ control={control}
754
+ render={({ onChange, value }: any) => (
755
+ <OInput
756
+ isSecured={!passwordSee ? true : false}
757
+ placeholder={t('PASSWORD', 'Password')}
758
+ placeholderTextColor={theme.colors.arrowColor}
759
+ style={styles.input}
760
+ icon={theme.images.logos.passwordInputIcon}
761
+ iconColor={theme.colors.arrowColor}
762
+ iconCustomRight={
763
+ !passwordSee ? (
764
+ <MaterialCommunityIcons
765
+ name="eye-outline"
766
+ size={24}
767
+ color={theme.colors.arrowColor}
768
+ onPress={() => setPasswordSee(!passwordSee)}
769
+ />
770
+ ) : (
771
+ <MaterialCommunityIcons
772
+ name="eye-off-outline"
773
+ size={24}
774
+ color={theme.colors.arrowColor}
775
+ onPress={() => setPasswordSee(!passwordSee)}
776
+ />
777
+ )
778
+ }
779
+ selectionColor={theme.colors.primary}
780
+ color={theme.colors.textGray}
781
+ value={value}
782
+ forwardRef={inputRef}
783
+ onChange={(val: any) => onChange(val)}
784
+ returnKeyType="done"
785
+ onSubmitEditing={() => handleLogin()}
786
+ blurOnSubmit
787
+ />
788
+ )}
789
+ name="password"
790
+ rules={{
791
+ required: t(
792
+ 'VALIDATION_ERROR_PASSWORD_REQUIRED',
793
+ 'The field Password is required',
794
+ ).replace('_attribute_', t('PASSWORD', 'Password')),
795
+ }}
796
+ defaultValue=""
797
+ />
798
+ )}
670
799
 
671
- {onNavigationRedirect && (
800
+ {onNavigationRedirect && loginTab !== 'otp' && (
672
801
  <Pressable
673
802
  style={{ marginRight: 'auto', marginBottom: 20 }}
674
803
  onPress={() => onNavigationRedirect('Forgot')}>
@@ -723,7 +852,7 @@ const LoginFormUI = (props: LoginParams) => {
723
852
  )}
724
853
  <OButton
725
854
  onClick={handleLogin}
726
- text={t('LOGIN', 'Login')}
855
+ text={loginTab !== 'otp' ? t('LOGIN', 'Login') : t('GET_VERIFY_CODE', 'Get verify code')}
727
856
  bgColor={theme.colors.primary}
728
857
  borderColor={theme.colors.primary}
729
858
  textStyle={styles.btnText}
@@ -763,7 +892,10 @@ const LoginFormUI = (props: LoginParams) => {
763
892
  </>
764
893
  )}
765
894
 
766
- <OModal open={isModalVisible} onClose={() => setIsModalVisible(false)}>
895
+ <OModal
896
+ open={isModalVisible}
897
+ onClose={() => setIsModalVisible(false)}
898
+ >
767
899
  <VerifyPhone
768
900
  phone={phoneInputData.phone}
769
901
  verifyPhoneState={verifyPhoneState}
@@ -773,6 +905,29 @@ const LoginFormUI = (props: LoginParams) => {
773
905
  handleVerifyCodeClick={handleVerifyCodeClick}
774
906
  />
775
907
  </OModal>
908
+ <OModal
909
+ open={willVerifyOtpState}
910
+ onClose={() => setWillVerifyOtpState(false)}
911
+ entireModal
912
+ hideIcons
913
+ title={t('ENTER_VERIFICATION_CODE', 'Enter verification code')}
914
+ >
915
+ <Otp
916
+ willVerifyOtpState={willVerifyOtpState}
917
+ setWillVerifyOtpState={setWillVerifyOtpState}
918
+ handleLoginOtp={handleLoginOtp}
919
+ onSubmit={handleLogin}
920
+ setAlertState={setAlertState}
921
+ formState={formState}
922
+ />
923
+ </OModal>
924
+ <Alert
925
+ open={alertState.open}
926
+ content={alertState.content}
927
+ title={alertState.title || ''}
928
+ onAccept={closeAlert}
929
+ onClose={closeAlert}
930
+ />
776
931
  </View>
777
932
  );
778
933
  };
@@ -52,3 +52,13 @@ export const RecaptchaButton = styled.View`
52
52
  align-items: center;
53
53
  margin-bottom: 10px;
54
54
  `
55
+ export const OTab = styled.View`
56
+ padding-bottom: 10px;
57
+ border-bottom-width: 1px;
58
+ margin-end: 14px;
59
+ `;
60
+
61
+ export const TabBtn = styled.TouchableOpacity`
62
+ min-height: 30px;
63
+ height: 30px;
64
+ `;
@@ -1,5 +1,5 @@
1
- import React, { useEffect, useState } from 'react';
2
- import { View, Animated } from 'react-native';
1
+ import React, { useEffect, useState, useCallback } from 'react';
2
+ import { View, Animated, TouchableOpacity } from 'react-native';
3
3
  import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons';
4
4
  import { useUtils, useLanguage } from 'ordering-components/native';
5
5
  import { useTheme } from 'styled-components/native';
@@ -36,6 +36,8 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
36
36
  const [{ parsePrice }] = useUtils();
37
37
 
38
38
  const [isActive, setActiveState] = useState(false);
39
+ const [isReadMore, setIsReadMore] = useState(false);
40
+ const [lengthMore, setLengthMore] = useState(false);
39
41
 
40
42
  const productInfo = () => {
41
43
  if (isCartProduct) {
@@ -108,6 +110,10 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
108
110
  }
109
111
  }, []);
110
112
 
113
+ const onTextLayout = useCallback((e: any) => {
114
+ setLengthMore(e.nativeEvent.lines.length >= 3); //to check the text is more than 2 lines or not
115
+ },[]);
116
+
111
117
  return (
112
118
  <AccordionSection>
113
119
  <Accordion
@@ -288,9 +294,21 @@ export const ProductItemAccordion = (props: ProductItemAccordionParams) => {
288
294
  color={theme.colors.unselectText}>
289
295
  {t('COMMENT', 'Comment')}
290
296
  </OText>
291
- <OText size={12} mLeft={10} color={theme.colors.unselectText}>
297
+ <OText
298
+ size={12}
299
+ style={{ width: '100%', paddingLeft: 10 }}
300
+ color={theme.colors.unselectText}
301
+ onTextLayout={onTextLayout}
302
+ numberOfLines={isReadMore ? 15 : 2}
303
+ ellipsizeMode="tail"
304
+ >
292
305
  {product.comment}
293
306
  </OText>
307
+ {lengthMore && (
308
+ <TouchableOpacity onPress={() => setIsReadMore(!isReadMore)} style={{ marginLeft: 10 }}>
309
+ <OText size={10} color={theme.colors.statusOrderBlue}>{isReadMore ? t('SHOW_LESS', 'Show less') : t('READ_MORE', 'Read more')}</OText>
310
+ </TouchableOpacity>
311
+ )}
294
312
  </ProductComment>
295
313
  )}
296
314
  </AccordionContent>