import React, { useEffect, useRef, useState } from 'react'; import { View, StyleSheet, Keyboard } from 'react-native'; import { useForm, Controller } from 'react-hook-form'; import Spinner from 'react-native-loading-spinner-overlay'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import { SignupForm as SignUpController, useLanguage, ToastType, useToast, } from 'ordering-components/native'; import { useTheme } from 'styled-components/native'; import { FormInput } from './styles'; import { PhoneInputNumber } from '../PhoneInputNumber'; import { VerifyPhone } from '../VerifyPhone'; import { OButton, OInput, OModal, OIconButton, OText } from '../shared'; import { _removeStoreData } from '../../providers/StoreUtil'; import { SignupParams } from '../../types'; import { sortInputFields } from '../../utils'; const SignupFormUI = (props: SignupParams) => { const { navigation, formState, validationFields, showField, isRequiredField, useSignupByCellphone, handleSuccessSignup, handleButtonSignupClick, verifyPhoneState, checkPhoneCodeState, setCheckPhoneCodeState, handleSendVerifyCode, handleCheckPhoneCode, signupLevel, // notificationState, } = props; const notValidationFields = [ 'coupon', 'driver_tip', 'mobile_phone', 'address', 'address_notes', 'middle_name', 'lastname', 'second_lastname', ]; const showInputPhoneNumber = validationFields?.fields?.checkout?.cellphone?.enabled ?? false; const theme = useTheme(); const [, { showToast }] = useToast(); const [, t] = useLanguage(); const { control, handleSubmit, errors } = useForm(); const [passwordSee, setPasswordSee] = useState(false); const [formValues, setFormValues] = useState(null); const [isModalVisible, setIsModalVisible] = useState(false); const [isLoadingVerifyModal, setIsLoadingVerifyModal] = useState(false); const [phoneInputData, setPhoneInputData] = useState({ error: '', phone: { country_phone_code: null, cellphone: null, }, }); const nameRef = useRef(null); const lastnameRef = useRef(null); const middleNameRef = useRef(null); const secondLastnameRef = useRef(null); const emailRef = useRef(null); const phoneRef = useRef(null); const passwordRef = useRef(null); const handleRefs = (ref: any, code: string) => { switch (code) { case 'name': { nameRef.current = ref; break; } case 'middle_name': { middleNameRef.current = ref; } case 'lastname': { lastnameRef.current = ref; break; } case 'second_lastname': { secondLastnameRef.current = ref; break; } case 'email': { emailRef.current = ref; break; } } }; const handleFocusRef = (code: string) => { switch (code) { case 'name': { nameRef?.current?.focus(); break; } case 'middle_name': { middleNameRef?.current?.focus(); break; } case 'lastname': { lastnameRef?.current?.focus(); break; } case 'second_lastname': { secondLastnameRef?.current?.focus(); break; } case 'email': { emailRef?.current?.focus(); break; } } }; const getNextFieldCode = (index: number) => { const fields = sortInputFields({ values: validationFields?.fields?.checkout, })?.filter( (field: any) => !notValidationFields.includes(field.code) && showField(field.code), ); return fields[index + 1]?.code; }; const handleSignup = () => { handleSubmit(onSubmit)(); }; const onSubmit = (values: any) => { Keyboard.dismiss(); if (phoneInputData.error) { showToast(ToastType.Error, phoneInputData.error); return; } if ( !phoneInputData.phone.country_phone_code && !phoneInputData.phone.cellphone && validationFields?.fields?.checkout?.cellphone?.enabled && validationFields?.fields?.checkout?.cellphone?.required ) { showToast( ToastType.Error, t( 'VALIDATION_ERROR_MOBILE_PHONE_REQUIRED', 'The field Mobile phone is required.', ), ); return; } if (!useSignupByCellphone) { handleButtonSignupClick && handleButtonSignupClick({ ...values, ...phoneInputData.phone, level: signupLevel, }); if ( !formState.loading && formState.result.result && !formState.result.error ) { handleSuccessSignup && handleSuccessSignup(formState.result.result); } return; } setFormValues(values); handleVerifyCodeClick(values); }; const handleVerifyCodeClick = (values: any) => { const formData = values || formValues; handleSendVerifyCode && handleSendVerifyCode({ ...formData, ...phoneInputData.phone, }); setIsLoadingVerifyModal(true); }; // get object with rules for hook form inputs const getInputRules = (field: any) => { const rules: any = { required: isRequiredField(field.code) ? t( `VALIDATION_ERROR_${field.code.toUpperCase()}_REQUIRED`, `${field.name} is required`, ).replace('_attribute_', t(field.name, field.code)) : null, }; if (field.code && field.code === 'email') { rules.pattern = { value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i, message: t('INVALID_ERROR_EMAIL', 'Invalid email address').replace( '_attribute_', t('EMAIL', 'Email'), ), }; } return rules; }; const handleChangeInputEmail = (value: string, onChange: any) => { onChange(value.toLowerCase().replace(/[&,()%";:รง?<>{}\\[\]\s]/g, '')); }; useEffect(() => { if (!formState.loading && formState.result?.error) { formState.result?.result && showToast(ToastType.Error, formState.result?.result[0]); setIsLoadingVerifyModal(false); } }, [formState]); useEffect(() => { if (Object.keys(errors).length > 0) { // Convert all errors in one string to show in toast provider const list = Object.values(errors); if (phoneInputData.error) { list.push({ message: phoneInputData.error }); } if ( !phoneInputData.error && !phoneInputData.phone.country_phone_code && !phoneInputData.phone.cellphone && validationFields?.fields?.checkout?.cellphone?.enabled && validationFields?.fields?.checkout?.cellphone?.required ) { list.push({ message: t( 'VALIDATION_ERROR_MOBILE_PHONE_REQUIRED', 'The field Mobile phone is required.', ), }); } let stringError = ''; list.map((item: any, i: number) => { stringError += i + 1 === list.length ? `- ${item.message}` : `- ${item.message}\n`; }); showToast(ToastType.Error, stringError); setIsLoadingVerifyModal(false); } }, [errors]); useEffect(() => { if (verifyPhoneState && !verifyPhoneState?.loading) { if (verifyPhoneState.result?.error) { const message = typeof verifyPhoneState?.result?.result === 'string' ? verifyPhoneState?.result?.result : verifyPhoneState?.result?.result[0]; verifyPhoneState.result?.result && showToast(ToastType.Error, message); setIsLoadingVerifyModal(false); return; } const okResult = verifyPhoneState.result?.result === 'OK'; if (okResult) { !isModalVisible && setIsModalVisible(true); setIsLoadingVerifyModal(false); } } }, [verifyPhoneState]); const styles = StyleSheet.create({ header: { marginBottom: 30, justifyContent: 'space-between', }, arrowLeft: { maxWidth: 40, height: 25, justifyContent: 'flex-end', marginBottom: 25, }, title: { fontFamily: 'Poppins', fontStyle: 'normal', fontWeight: '600', fontSize: 26, color: theme.colors.textGray, }, btn: { borderRadius: 7.6, height: 44, }, btnText: { color: theme.colors.inputTextColor, fontFamily: 'Poppins', fontStyle: 'normal', fontWeight: 'normal', fontSize: 18, }, btnFlag: { borderWidth: 1, borderRadius: 7.6, marginRight: 9, borderColor: theme.colors.inputSignup, }, input: { color: theme.colors.inputTextColor, marginBottom: 20, borderWidth: 1, borderRadius: 7.6, borderColor: theme.colors.inputSignup, backgroundColor: theme.colors.transparent, }, }); return ( navigation?.canGoBack() && navigation.goBack()} /> {t('SIGNUP', 'Sign Up')} {!(validationFields?.loading && validationFields?.fields?.checkout) ? ( <> {sortInputFields({ values: validationFields?.fields?.checkout, }).map( (field: any, i: number) => !notValidationFields.includes(field.code) && showField && showField(field.code) && ( ( field.code !== 'email' ? onChange(val) : handleChangeInputEmail(val, onChange) } autoCapitalize={ field.code === 'email' ? 'none' : 'sentences' } autoCorrect={field.code === 'email' && false} type={ field.code === 'email' ? 'email-address' : 'default' } autoCompleteType={ field.code === 'email' ? 'email' : 'off' } selectionColor={theme.colors.primary} color={theme.colors.textGray} returnKeyType="next" blurOnSubmit={false} forwardRef={(ref: any) => handleRefs(ref, field.code)} onSubmitEditing={() => field.code === 'email' ? phoneRef?.current?.focus?.() : handleFocusRef(getNextFieldCode(i)) } /> )} name={field.code} rules={getInputRules(field)} defaultValue="" /> ), )} {!!showInputPhoneNumber && ( setPhoneInputData(val)} forwardRef={phoneRef} flagProps={styles.btnFlag} onSubmitEditing={() => null} textInputProps={{ returnKeyType: 'next', onSubmitEditing: () => passwordRef?.current?.focus?.(), }} /> )} ( setPasswordSee(!passwordSee)} /> ) : ( setPasswordSee(!passwordSee)} /> ) } selectionColor={theme.colors.primary} color={theme.colors.textGray} value={value} onChange={(val: any) => onChange(val)} returnKeyType="done" blurOnSubmit forwardRef={passwordRef} /> )} name="password" rules={{ required: isRequiredField('password') ? t( 'VALIDATION_ERROR_PASSWORD_REQUIRED', 'The field Password is required', ).replace('_attribute_', t('PASSWORD', 'password')) : null, minLength: { value: 8, message: t( 'VALIDATION_ERROR_PASSWORD_MIN_STRING', 'The Password must be at least 8 characters.', ) .replace('_attribute_', t('PASSWORD', 'Password')) .replace('_min_', 8), }, }} defaultValue="" /> ) : ( )} {useSignupByCellphone ? ( ) : ( )} setIsModalVisible(false)}> ); }; export const SignupForm = (props: any) => { const signupProps = { ...props, UIComponent: SignupFormUI, }; return ; };