diff --git a/src/common/utils.ts b/src/common/utils.ts index b3331c807d..fa8d349a9a 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -300,3 +300,9 @@ export const updateContactCache = (client: any, id: any) => { return null; }; + +export const formatString = (str: string) => + str + .replace(/_/g, ' ') + .replace(/([a-z])([0-9])/gi, '$1 $2') + .replace(/\b\w/g, (char) => char.toUpperCase()); diff --git a/src/components/UI/Form/PhoneInput/PhoneInput.tsx b/src/components/UI/Form/PhoneInput/PhoneInput.tsx index 816a262b12..6ce4eef0e9 100644 --- a/src/components/UI/Form/PhoneInput/PhoneInput.tsx +++ b/src/components/UI/Form/PhoneInput/PhoneInput.tsx @@ -18,6 +18,7 @@ export interface InputProps { form: { touched: any; errors: any; setFieldValue: any }; inputLabel?: string | null; disabled?: boolean; + changeHandler?: (event: string, data: {}, formFieldItems: string) => void; } export const PhoneInput = ({ @@ -33,6 +34,7 @@ export const PhoneInput = ({ inputLabel = null, disabled = false, helperText, + changeHandler, }: InputProps) => { const errorText = getIn(errors, field.name); const touchedVal = getIn(touched, field.name); @@ -58,7 +60,9 @@ export const PhoneInput = ({ inputProps={inputProps} {...field} value={field.value} - onChange={(event) => { + onChange={(event, data, _, formFieldItems) => { + if (changeHandler) changeHandler(event, data, formFieldItems); + setFieldValue(field.name, event); }} /> diff --git a/src/containers/Organization/Onboarding/Form.test.tsx b/src/containers/Organization/Onboarding/Form.test.tsx index 7d72f0c78c..a331fb93ad 100644 --- a/src/containers/Organization/Onboarding/Form.test.tsx +++ b/src/containers/Organization/Onboarding/Form.test.tsx @@ -144,9 +144,15 @@ test('it should submit the form', async () => { const inputFieldsOrgdetails = getAllByRole('textbox'); - const [registeredAddress, gstin] = inputFieldsOrgdetails; + const [line1, line2, city, state, country, pincode, gstin] = inputFieldsOrgdetails; + + fireEvent.change(line1, { target: { value: 'line1' } }); + fireEvent.change(line2, { target: { value: 'line2' } }); + fireEvent.change(city, { target: { value: 'City' } }); + fireEvent.change(state, { target: { value: 'State' } }); + fireEvent.change(country, { target: { value: 'Country' } }); + fireEvent.change(pincode, { target: { value: '123456' } }); - fireEvent.change(registeredAddress, { target: { value: 'address' } }); fireEvent.click(screen.getByRole('checkbox')); fireEvent.change(gstin, { target: { value: '123456789012345' } }); @@ -164,12 +170,13 @@ test('it should submit the form', async () => { }); const inputFieldsPaymentdetails = getAllByRole('textbox'); - const [name, designation, phone, email] = inputFieldsPaymentdetails; + const [firstName, lastName, designation, phone, email] = inputFieldsPaymentdetails; const radioButtons = getAllByTestId('radio-btn'); fireEvent.click(radioButtons[1]); - fireEvent.change(name, { target: { value: 'Default finance poc name' } }); + fireEvent.change(firstName, { target: { value: 'finance poc firstName' } }); + fireEvent.change(lastName, { target: { value: 'finance poc lastName' } }); fireEvent.change(designation, { target: { value: 'finance' } }); fireEvent.change(phone, { target: { value: '09421050449' } }); fireEvent.change(email, { target: { value: 'finance@email.com' } }); @@ -189,17 +196,23 @@ test('it should submit the form', async () => { const inputFieldssigningdetails = getAllByRole('textbox'); const [ - submitterName, + submitterFirstName, + submitterLastName, + submitterDesignation, submitterEmail, - signingAuthorityName, + signingAuthorityFirstName, + signingAuthorityLastName, signingAuthorityDesignation, signingAuthorityEmail, ] = inputFieldssigningdetails; - fireEvent.change(submitterName, { target: { value: 'Default submitter' } }); + fireEvent.change(submitterFirstName, { target: { value: 'first name' } }); + fireEvent.change(submitterLastName, { target: { value: 'last name' } }); + fireEvent.change(submitterDesignation, { target: { value: 'submitter' } }); fireEvent.change(submitterEmail, { target: { value: 'submitter@email.com' } }); - fireEvent.change(signingAuthorityName, { target: { value: 'Default signing' } }); + fireEvent.change(signingAuthorityFirstName, { target: { value: 'Default signing firstName' } }); + fireEvent.change(signingAuthorityLastName, { target: { value: 'Default signing lastName' } }); fireEvent.change(signingAuthorityDesignation, { target: { value: 'signing authority' } }); fireEvent.change(signingAuthorityEmail, { target: { value: 'signing@email.com' } }); @@ -253,9 +266,14 @@ test('it should disgree and send an email', async () => { const inputFieldsOrgdetails = getAllByRole('textbox'); - const [registeredAddress, gstin] = inputFieldsOrgdetails; + const [line1, line2, city, state, country, pincode, gstin] = inputFieldsOrgdetails; - fireEvent.change(registeredAddress, { target: { value: 'address' } }); + fireEvent.change(line1, { target: { value: 'line1' } }); + fireEvent.change(line2, { target: { value: 'line2' } }); + fireEvent.change(city, { target: { value: 'City' } }); + fireEvent.change(state, { target: { value: 'State' } }); + fireEvent.change(country, { target: { value: 'Country' } }); + fireEvent.change(pincode, { target: { value: '123456' } }); fireEvent.click(screen.getByRole('checkbox')); fireEvent.change(gstin, { target: { value: '123456789012345' } }); @@ -266,12 +284,13 @@ test('it should disgree and send an email', async () => { }); const inputFieldsPaymentdetails = getAllByRole('textbox'); - const [name, designation, phone, email] = inputFieldsPaymentdetails; + const [firstName, lastName, designation, phone, email] = inputFieldsPaymentdetails; const radioButtons = getAllByTestId('radio-btn'); fireEvent.click(radioButtons[1]); - fireEvent.change(name, { target: { value: 'Default finance poc name' } }); + fireEvent.change(firstName, { target: { value: 'finance poc firstName' } }); + fireEvent.change(lastName, { target: { value: 'finance poc lastName' } }); fireEvent.change(designation, { target: { value: 'finance' } }); fireEvent.change(phone, { target: { value: '09421050449' } }); fireEvent.change(email, { target: { value: 'finance@email.com' } }); diff --git a/src/containers/Organization/Onboarding/FormLayout/FormLayout.tsx b/src/containers/Organization/Onboarding/FormLayout/FormLayout.tsx index c510b131f6..f3dca372b7 100644 --- a/src/containers/Organization/Onboarding/FormLayout/FormLayout.tsx +++ b/src/containers/Organization/Onboarding/FormLayout/FormLayout.tsx @@ -30,6 +30,8 @@ interface FormLayoutProps { showModal?: boolean; isDisabled?: boolean; handleEffect?: Function; + customError?: null | string; + setCustomError?: Function; } export const FormLayout = ({ @@ -52,6 +54,8 @@ export const FormLayout = ({ showModal, isDisabled, handleEffect, + customError, + setCustomError, }: FormLayoutProps) => { const [isModalOpen, setIsModalOpen] = useState(false); @@ -217,7 +221,7 @@ export const FormLayout = ({ ); let modal; - + let errorModal; if (showModal) modal = ( { saveHandler(formik.values, formik.setErrors); }} - title={'Confirmation'} - buttonOk={'Confirm'} + title="Confirmation" + buttonOk="Confirm" buttonCancel="Cancel" buttonOkLoading={loading} > @@ -239,6 +243,23 @@ export const FormLayout = ({ ); + if (customError && setCustomError) { + errorModal = ( + setCustomError(null)} + handleCancel={() => setCustomError(null)} + title="Something went wrong!" + buttonOk="Ok" + skipCancel + colorOk="warning" + > +
+

{customError}

+

Please contact the Glific team for support.

+
+
+ ); + } return (
@@ -246,6 +267,7 @@ export const FormLayout = ({ {form}
{isModalOpen && modal} + {errorModal}
); }; diff --git a/src/containers/Organization/Onboarding/PaymentType/PaymentOptions.tsx b/src/containers/Organization/Onboarding/PaymentType/PaymentOptions.tsx index 897b937195..91f72a8eff 100644 --- a/src/containers/Organization/Onboarding/PaymentType/PaymentOptions.tsx +++ b/src/containers/Organization/Onboarding/PaymentType/PaymentOptions.tsx @@ -25,32 +25,32 @@ export const PaymentOptions = ({ form: { setFieldValue, values } }: PaymentOptio
} - label={'Yearly'} - className={isChecked('yearly') ? styles.Selectedlabel : styles.Label} + label={'Annually'} + className={isChecked('Annually') ? styles.Selectedlabel : styles.Label} />
One month fee waived off!
} label={'Quarterly'} - className={isChecked('quarterly') ? styles.Selectedlabel : styles.Label} + className={isChecked('Quarterly') ? styles.Selectedlabel : styles.Label} />
} label={'Monthly'} - className={isChecked('monthly') ? styles.Selectedlabel : styles.Label} + className={isChecked('Monthly') ? styles.Selectedlabel : styles.Label} />
diff --git a/src/containers/Organization/Onboarding/Steps/Address/Address.module.css b/src/containers/Organization/Onboarding/Steps/Address/Address.module.css new file mode 100644 index 0000000000..2887bfdc3d --- /dev/null +++ b/src/containers/Organization/Onboarding/Steps/Address/Address.module.css @@ -0,0 +1,45 @@ +.Label { + font-size: 14px; + font-weight: 500; + color: #111; + line-height: 22px; + margin: 6px 0; + display: flex; + column-gap: 4px; +} + +.Heading { + composes: Label; + font-size: 1rem; +} + +.InputBox { + width: 100%; +} + +.OutlinedInput { + padding: 12.5px 14px; +} + + +.AddressField { + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: repeat(3, 1fr); + grid-gap: 0.5rem; + +} + +.FullRow { + grid-column-start: 1; + grid-column-end: 3; +} + +.Errors { + font-size: 12px; + margin: 0; + margin-left: 14px; + line-height: 18px; + font-weight: 400; + color: #fb5c5c; +} \ No newline at end of file diff --git a/src/containers/Organization/Onboarding/Steps/Address/Address.tsx b/src/containers/Organization/Onboarding/Steps/Address/Address.tsx new file mode 100644 index 0000000000..60d994631d --- /dev/null +++ b/src/containers/Organization/Onboarding/Steps/Address/Address.tsx @@ -0,0 +1,77 @@ +import { OutlinedInput, Typography } from '@mui/material'; +import { formatString } from 'common/utils'; +import styles from './Address.module.css'; + +interface RegisteredAddressProps { + inputLabel: string; + inputLabelSubtext: any; + address: any; + disabled: boolean; + form: { touched: any; errors: any; setFieldValue: any }; + field: { name: string; value: any }; +} + +export const RegisteredAddress = ({ + inputLabel, + address, + disabled, + inputLabelSubtext, + form, + field, +}: RegisteredAddressProps) => { + const handleChange = (e: any, value: any) => { + form.setFieldValue(field.name, { + ...field.value, + [value]: e.target.value, + }); + }; + + const errors = form.errors[field.name]; + const touched = form.touched[field.name]; + + return ( +
+ + {inputLabel} + {inputLabelSubtext} + + +
+ {Object.keys(address) + .slice(0, 2) + .map((key) => ( +
+

{formatString(key)}

+ handleChange(e, key)} + value={field.value[key]} + /> +

+ {touched && errors && touched[key] && errors[key] ? errors[key] : ''} +

+
+ ))} + {Object.keys(address) + .slice(2) + .map((key) => ( +
+

{formatString(key)}

+ handleChange(e, key)} + value={field.value[key]} + /> +

+ {touched && errors && touched[key] && errors[key] ? errors[key] : ''} +

+
+ ))} +
+
+ ); +}; diff --git a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx index 674473ce07..a761cb8fb4 100644 --- a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx @@ -8,31 +8,60 @@ import styles from '../FormLayout/FormLayout.module.css'; import { Input } from 'components/UI/Form/Input/Input'; import { FormLayout } from '../FormLayout/FormLayout'; import { useTranslation } from 'react-i18next'; +import { RegisteredAddress } from './Address/Address'; export interface FormStepProps { handleStepChange: Function; saveData: Function; } +const isSameAddress = (address1: any, address2: any) => + Object.keys(address1).every((key) => address1[key] === address2[key]); + export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { const [gstin, setGstNumber] = useState(''); - const [registered_address, setRegisteredAddress] = useState(''); - const [current_address, setCurrentAddress] = useState(''); + const [registered_address, setRegisteredAddress] = useState({ + address_line1: '', + address_line2: '', + city: '', + state: '', + country: '', + pincode: '', + }); + const [current_address, setCurrentAddress] = useState({ + address_line1: '', + address_line2: '', + city: '', + state: '', + country: '', + pincode: '', + }); const [same_address, setSameAddress] = useState(false); const [disable, setDisable] = useState(false); const [loading, setLoading] = useState(false); + const [customError, setCustomError] = useState(null); const { t } = useTranslation(); const FormSchema = Yup.object().shape({ gstin: Yup.string().length(15, t('Invalid gst number')), - registered_address: Yup.string() - .required(t('Registered address is required.')) - .max(300, t('Address should not exceed 300 characters')), - current_address: Yup.string() - .required(t('Current address is required.')) - .max(300, t('Address should not exceed 300 characters')), + registered_address: Yup.object().shape({ + address_line1: Yup.string().required('Address Line 1 is required'), + address_line2: Yup.string(), + city: Yup.string().required('City is required'), + state: Yup.string().required('State is required'), + country: Yup.string().required('Country is required'), + pincode: Yup.string().matches(/^\d+$/, 'Invalid Pincode').required('Pincode is required'), + }), + current_address: Yup.object().shape({ + address_line1: Yup.string().required('Address Line 1 is required'), + address_line2: Yup.string(), + city: Yup.string().required('City is required'), + state: Yup.string().required('State is required'), + country: Yup.string().required('Country is required'), + pincode: Yup.string().matches(/^\d+$/, 'Invalid Pincode').required('Pincode is required'), + }), }); const initialFormValues: any = { @@ -61,23 +90,22 @@ export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { const formFields = [ { - component: Input, + component: RegisteredAddress, name: 'registered_address', - type: 'text', - inputLabel: 'Registered Address', - textArea: true, inputLabelSubtext: (As per your documentation), - additionalStyles: styles.MessageField, + inputLabel: 'Registered Address', + address: registered_address, + setAddress: setRegisteredAddress, }, { - component: Input, + component: RegisteredAddress, name: 'current_address', - type: 'text', inputLabel: 'Current Address', - textArea: true, additionalStyles: styles.MessageField, fieldEndAdornment: { show: true, component: inputendAdornment }, disabled: disable, + address: current_address, + setAddress: setCurrentAddress, }, { component: Input, @@ -115,21 +143,30 @@ export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { setGstNumber(gstin); setRegisteredAddress(registered_address); setCurrentAddress(current_address); - if (current_address === registered_address) { + if (isSameAddress(registered_address, current_address)) { setSameAddress(true); + setDisable(true); } }; const handleSubmit = async (payload: any, setErrors: any) => { setLoading(true); - await axios.post(ONBOARD_URL_UPDATE, payload).then(({ data }) => { - setLoading(false); - if (data.is_valid) { - handleStepChange(); - } else { - setErrors(data.messages); - } - }); + await axios + .post(ONBOARD_URL_UPDATE, payload) + .then(({ data }) => { + setLoading(false); + if (data.is_valid) { + handleStepChange(); + } else { + setErrors(data.messages); + } + }) + .catch((data) => { + if (data?.response?.data?.error?.message) { + setCustomError(data?.response?.data?.error?.message); + } + setLoading(false); + }); }; const handleAutoUpdateAddress = (identifier: string, formik: any) => { @@ -157,6 +194,8 @@ export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { submitData={handleSubmit} loading={loading} handleEffect={handleAutoUpdateAddress} + setCustomError={setCustomError} + customError={customError} /> ); }; diff --git a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx index 7c01dc37f2..80512c1ef2 100644 --- a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx @@ -13,35 +13,42 @@ import { FormStepProps } from './OrgDetails'; export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => { const { t } = useTranslation(); - const [billing_frequency, setPaymentType] = useState('yearly'); - - const [name, setName] = useState(''); + const [billing_frequency, setPaymentType] = useState('Annually'); + const [firstName, setFirstName] = useState(''); + const [lastName, setLastName] = useState(''); const [designation, setDesignation] = useState(''); const [phone, setPhone] = useState(''); + const [formattedPhone, setFormattedPhone] = useState(''); const [email, setEmail] = useState(''); + const [customError, setCustomError] = useState(null); const [loading, setLoading] = useState(false); const FormSchema = Yup.object().shape({ - name: Yup.string() - .required(t('Name is required.')) + firstName: Yup.string() + .required(t('First name is required.')) .max(25, t('Please enter not more than 25 characters')), + lastName: Yup.string().required(t('Last name is required.')).max(25, t('Please enter not more than 25 characters')), designation: Yup.string() .required(t('Designation is required.')) .max(25, t('Please enter not more than 25 characters')), - phone: Yup.string() - .required(t('Phone number is required.')) - .min(7, t('Enter a valid phone number.')), + phone: Yup.string().required(t('Phone number is required.')).min(7, t('Enter a valid phone number.')), email: Yup.string().required(t('Email is required.')).email(t('Enter a valid email.')), }); const initialFormValues: any = { - name, + firstName, + lastName, designation, phone, email, billing_frequency, }; + const handlePhoneNumberChange = (_: any, data: any, formFieldItems: any) => { + const formattedValue = formFieldItems.split(data.dialCode).join(`${data.dialCode}-`); + setFormattedPhone(formattedValue); + }; + const formFields = [ { label: 'Preferred Billing Frequency', @@ -58,9 +65,15 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => children: [ { component: Input, - name: 'name', + name: 'firstName', + type: 'text', + inputLabel: 'First Name', + }, + { + component: Input, + name: 'lastName', type: 'text', - inputLabel: 'Name', + inputLabel: 'Last Name', }, { component: Input, @@ -73,15 +86,14 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => name: 'phone', type: 'phone', inputLabel: 'Phone Number', + changeHandler: handlePhoneNumberChange, }, { component: Input, name: 'email', type: 'text', inputLabel: 'Email Address', - helperText: ( - Invoice will be sent to this email - ), + helperText: Invoice will be sent to this email, }, ], }, @@ -89,17 +101,21 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => const setPayload = (payload: any) => { const data = localStorage.getItem('registrationData'); + const { firstName, lastName } = payload; + const billing_frequency = payload.billing_frequency; if (data) { let registrationData = JSON.parse(data); - const updatedPayload = { + const updatedPayload: any = { finance_poc: { ...payload, + phone: formattedPhone, + name: firstName + ' ' + lastName, }, registration_id: registrationData.registration_details.registration_id, org_id: registrationData.registration_details.org_id, has_submitted: false, - billing_frequency: payload.billing_frequency, + billing_frequency, }; return updatedPayload; @@ -107,10 +123,13 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => }; const setStates = (states: any) => { - const { name, designation, phone, email, billing_frequency } = states.finance_poc; - setName(name); + const { firstName, lastName, designation, phone, email, billing_frequency } = states.finance_poc; + + setFirstName(firstName); + setLastName(lastName); setDesignation(designation); setPhone(phone); + setFormattedPhone(phone); setEmail(email); setPaymentType(billing_frequency); }; @@ -118,19 +137,28 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => const handleSubmit = async (payload: any, setErrors: any) => { setLoading(true); - await axios.post(ONBOARD_URL_UPDATE, payload).then(({ data }) => { - setLoading(false); - if (data.is_valid) { - handleStepChange(); - } else { - const errors = Object.keys(data.messages).reduce((acc, key) => { - const newKey = key.replace('finance_poc_', ''); - return { ...acc, [newKey]: data.messages[key] }; - }, {}); + await axios + .post(ONBOARD_URL_UPDATE, payload) + .then(({ data }) => { + setLoading(false); + if (data.is_valid) { + handleStepChange(); + } else { + const errors = Object.keys(data.messages).reduce((acc, key) => { + const newKey = key.replace('finance_poc_', ''); + return { ...acc, [newKey]: data.messages[key] }; + }, {}); - setErrors(errors); - } - }); + setErrors(errors); + setLoading(false); + } + }) + .catch((data) => { + if (data?.response?.data?.error?.message) { + setCustomError(data?.response?.data?.error?.message); + } + setLoading(false); + }); }; return ( @@ -148,6 +176,8 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => saveData={saveData} submitData={handleSubmit} loading={loading} + setCustomError={setCustomError} + customError={customError} /> ); }; diff --git a/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx b/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx index c9ebc1e612..d940fad618 100644 --- a/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx @@ -20,6 +20,7 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = const [shortcode, setShortcode] = useState(''); const [phone, setPhone] = useState(''); const [code, setCode] = useState('[shortcode]'); + const [customError, setCustomError] = useState(null); const [isDisabled, setIsDisabled] = useState(false); const [loading, setLoading] = useState(false); @@ -33,7 +34,7 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = shortcode: Yup.string() .required(t('Shortcode is required.')) .max(8, 'Shortcode cannot be more than 8 characters.') - .matches(/^\S*$/, 'Shortcode cannot contain spaces.'), + .matches(/^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/, 'Invalid shortcode.'), phone: Yup.string() .required(t('Phone number is required.')) .min(7, t('Enter a valid phone number.')), @@ -147,27 +148,35 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = const handleSubmit = async (payload: any, setErrors: Function) => { if (isDisabled) handleStepChange(); setLoading(true); - await axios.post(ONBOARD_URL_SETUP, payload).then(({ data }) => { - setLoading(false); - if (data.is_valid) { - saveData( - { - registration_id: data.registration_id, - org_id: data.organization?.id, - submitted: true, - }, - 'registration_details' - ); - - handleStepChange(); - - return true; - } else { - setErrors(data.messages); - saveData(data.messages, 'errors'); - return false; - } - }); + await axios + .post(ONBOARD_URL_SETUP, payload) + .then(({ data }) => { + setLoading(false); + if (data.is_valid) { + saveData( + { + registration_id: data.registration_id, + org_id: data.organization?.id, + submitted: true, + }, + 'registration_details' + ); + + handleStepChange(); + + return true; + } else { + if (data.messages.global) { + setCustomError(data.messages.global); + } + setErrors(data.messages); + saveData(data.messages, 'errors'); + return false; + } + }) + .catch((errors) => { + setLoading(false); + }); }; const setStates = (states: any) => { @@ -234,6 +243,8 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = showModal={true} isDisabled={isDisabled} handleEffect={generateShortcode} + customError={customError} + setCustomError={setCustomError} /> ); }; diff --git a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index 1e5fde60a5..6d6c60d61b 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -14,17 +14,17 @@ interface SigningAuthorityProps extends FormStepProps { openReachOutToUs?: Function; } -export const SigningAuthority = ({ - handleStepChange, - openReachOutToUs, - saveData, -}: SigningAuthorityProps) => { +export const SigningAuthority = ({ handleStepChange, openReachOutToUs, saveData }: SigningAuthorityProps) => { const { t } = useTranslation(); - const [submitterName, setSubmitterName] = useState(''); + const [submitterFirstName, setSubmitterFirstName] = useState(''); + const [submitterLastName, setSubmitterLastName] = useState(''); const [submitterEmail, setSubmitterEmail] = useState(''); - const [signingAuthorityName, setSigningAuthorityName] = useState(''); + const [submitterDesignation, setSubmitterDesignation] = useState(''); + const [signingAuthorityFirstName, setSigningAuthorityFirstName] = useState(''); + const [signingAuthorityLastName, setSigningAuthorityLastName] = useState(''); const [signingAuthorityDesignation, setSigningAuthorityDesignation] = useState(''); const [signingAuthorityEmail, setSigningAuthorityEmail] = useState(''); + const [customError, setCustomError] = useState(null); const [permissions, setPermissions] = useState({ terms_agreed: false, @@ -34,18 +34,26 @@ export const SigningAuthority = ({ const [loading, setLoading] = useState(false); const FormSchema = Yup.object().shape({ - submitterName: Yup.string() - .required(t('Name is required.')) + submitterFirstName: Yup.string() + .required(t('First name is required.')) + .max(25, t('Please enter not more than 25 characters')), + submitterLastName: Yup.string() + .required(t('Last name is required.')) .max(25, t('Please enter not more than 25 characters')), submitterEmail: Yup.string().required(t('Email is required.')).email(t('Enter a valid email.')), - signingAuthorityName: Yup.string() - .required(t('Name is required.')) + submitterDesignation: Yup.string() + .required('Designation is required.') .max(25, t('Please enter not more than 25 characters')), - - signingAuthorityDesignation: Yup.string().required('Designation is required.'), - signingAuthorityEmail: Yup.string() - .required(t('Email is required.')) - .email('Enter a valid email.'), + signingAuthorityFirstName: Yup.string() + .required(t('First name is required.')) + .max(25, t('Please enter not more than 25 characters')), + signingAuthorityLastName: Yup.string() + .required(t('Last name is required.')) + .max(25, t('Please enter not more than 25 characters')), + signingAuthorityDesignation: Yup.string() + .required('Designation is required.') + .max(25, t('Please enter not more than 25 characters')), + signingAuthorityEmail: Yup.string().required(t('Email is required.')).email('Enter a valid email.'), permissions: Yup.object({ terms_agreed: Yup.boolean() .oneOf([true], 'Please agree to the terms and conditions.') @@ -57,9 +65,12 @@ export const SigningAuthority = ({ }); const initialFormValues: any = { - submitterName, + submitterFirstName, + submitterLastName, submitterEmail, - signingAuthorityName, + submitterDesignation, + signingAuthorityFirstName, + signingAuthorityLastName, signingAuthorityDesignation, signingAuthorityEmail, permissions, @@ -71,9 +82,21 @@ export const SigningAuthority = ({ children: [ { component: Input, - name: 'submitterName', + name: 'submitterFirstName', type: 'text', - inputLabel: 'Name', + inputLabel: 'First Name', + }, + { + component: Input, + name: 'submitterLastName', + type: 'text', + inputLabel: 'Last Name', + }, + { + component: Input, + name: 'submitterDesignation', + type: 'text', + inputLabel: 'Designation', }, { component: Input, @@ -88,9 +111,15 @@ export const SigningAuthority = ({ children: [ { component: Input, - name: 'signingAuthorityName', + name: 'signingAuthorityFirstName', type: 'text', - inputLabel: 'Name', + inputLabel: 'First Name', + }, + { + component: Input, + name: 'signingAuthorityLastName', + type: 'text', + inputLabel: 'Last Name', }, { component: Input, @@ -121,11 +150,13 @@ export const SigningAuthority = ({ const updatedPayload = { submitter: { - name: payload.submitterName, + first_name: payload.submitterFirstName, + last_name: payload.submitterLastName, + designation: payload.submitterDesignation, email: payload.submitterEmail, }, signing_authority: { - name: payload.signingAuthorityName, + name: payload.signingAuthorityFirstName + ' ' + payload.signingAuthorityLastName, designation: payload.signingAuthorityDesignation, email: payload.signingAuthorityEmail, }, @@ -143,10 +174,19 @@ export const SigningAuthority = ({ const setStates = (states: any) => { const { signing_authority, submitter } = states; + let firstName; + let lastName; + if (signing_authority?.name) { + firstName = signing_authority?.name?.split(' ')[0]; + lastName = signing_authority?.name?.split(' ')[1]; + } - setSubmitterName(submitter?.name); + setSubmitterFirstName(submitter?.first_name); + setSubmitterLastName(submitter?.last_name); setSubmitterEmail(submitter?.email); - setSigningAuthorityName(signing_authority?.name); + setSubmitterDesignation(submitter?.designation); + setSigningAuthorityFirstName(firstName || ''); + setSigningAuthorityLastName(lastName || ''); setSigningAuthorityDesignation(signing_authority?.designation); setSigningAuthorityEmail(signing_authority?.email); setPermissions({ support_staff_account: false, terms_agreed: false }); @@ -155,15 +195,28 @@ export const SigningAuthority = ({ const handleSubmit = async (payload: any, setErrors: any) => { setLoading(true); - await axios.post(ONBOARD_URL_UPDATE, payload).then(({ data }) => { - setLoading(false); - if (data.is_valid) { - handleStepChange(); - localStorage.removeItem('registrationData'); - } else { - setErrors(data.messages); - } - }); + await axios + .post(ONBOARD_URL_UPDATE, payload) + .then(({ data }) => { + setLoading(false); + if (data.is_valid) { + handleStepChange(); + localStorage.removeItem('registrationData'); + } else { + setErrors(data.messages); + } + }) + .catch((data: any) => { + setLoading(false); + + if (data?.response?.data?.error?.message) { + if (data?.response?.data?.error?.message?.includes('Failed to update address')) { + setCustomError('Please check the entered address and try again!'); + return; + } + setCustomError(data?.response?.data?.error?.message); + } + }); }; return ( @@ -182,6 +235,8 @@ export const SigningAuthority = ({ loading={loading} submitData={handleSubmit} buttonState={{ text: 'Submit' }} + setCustomError={setCustomError} + customError={customError} /> ); }; diff --git a/src/i18n/en/en.json b/src/i18n/en/en.json index fe56b8a3ad..40f922e9df 100644 --- a/src/i18n/en/en.json +++ b/src/i18n/en/en.json @@ -528,5 +528,7 @@ "Temperature": "Temperature", "Upload File": "Upload File", "Add Files": "Add Files", - "Add files to file search": "Add files to file search" + "Add files to file search": "Add files to file search", + "First name is required.": "First Name is required.", + "Last name is required.": "Last name is required." }