From 29da04bf067756e3c82490e89c6325dddb72682c Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Wed, 30 Oct 2024 12:57:49 +0530 Subject: [PATCH 01/21] erp modifications in registration form --- .../UI/Form/PhoneInput/PhoneInput.tsx | 6 +- .../Steps/Address/Address.module.css | 45 ++++++++++ .../Onboarding/Steps/Address/Address.tsx | 86 +++++++++++++++++++ .../Onboarding/Steps/OrgDetails.tsx | 63 ++++++++++---- .../Onboarding/Steps/PaymentDetails.tsx | 39 +++++++-- .../Onboarding/Steps/PlatformDetails.tsx | 9 +- .../Onboarding/Steps/SigningAuthority.tsx | 71 +++++++++++---- src/i18n/en/en.json | 4 +- 8 files changed, 278 insertions(+), 45 deletions(-) create mode 100644 src/containers/Organization/Onboarding/Steps/Address/Address.module.css create mode 100644 src/containers/Organization/Onboarding/Steps/Address/Address.tsx diff --git a/src/components/UI/Form/PhoneInput/PhoneInput.tsx b/src/components/UI/Form/PhoneInput/PhoneInput.tsx index 816a262b1..42c53a913 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?: any; } 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/Steps/Address/Address.module.css b/src/containers/Organization/Onboarding/Steps/Address/Address.module.css new file mode 100644 index 000000000..29f777b82 --- /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: 0px; + 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 000000000..48777e28d --- /dev/null +++ b/src/containers/Organization/Onboarding/Steps/Address/Address.tsx @@ -0,0 +1,86 @@ +import { OutlinedInput, Typography } from '@mui/material'; +import styles from './Address.module.css'; +import { ChangeEvent, useState } from 'react'; + +interface RegisteredAddressProps { + inputLabel: string; + inputLabelSubtext: any; + address: any; + disabled: boolean; + setAddress: any; + form: { touched: any; errors: any; setFieldValue: any }; + field: { name: string; value: any }; +} + +function x(str: string) { + return str + .replace(/_/g, ' ') // Replace underscores with spaces + .replace(/([a-z])([0-9])/gi, '$1 $2') // Insert space before digits + .replace(/\b\w/g, (char) => char.toUpperCase()); // Capitalize each word +} + +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]; + console.log(disabled); + + return ( +
+ + {inputLabel} + {inputLabelSubtext} + + +
+ {Object.keys(address) + .slice(0, 2) + .map((key) => ( +
+

{x(key)}

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

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

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

{x(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 674473ce0..039caf7f4 100644 --- a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx @@ -8,16 +8,35 @@ 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) => { + return 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); @@ -27,12 +46,22 @@ export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { 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,8 +143,9 @@ 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); } }; diff --git a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx index 7c01dc37f..1fd7201e7 100644 --- a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx @@ -15,16 +15,21 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => const { t } = useTranslation(); const [billing_frequency, setPaymentType] = useState('yearly'); - const [name, setName] = useState(''); + const [first_name, setFirstName] = useState(''); + const [last_name, setLastName] = useState(''); const [designation, setDesignation] = useState(''); const [phone, setPhone] = useState(''); + const [formattedPhone, setFormattedPhone] = useState(''); const [email, setEmail] = useState(''); const [loading, setLoading] = useState(false); const FormSchema = Yup.object().shape({ - name: Yup.string() - .required(t('Name is required.')) + first_name: Yup.string() + .required(t('First name is required.')) + .max(25, t('Please enter not more than 25 characters')), + last_name: 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.')) @@ -35,13 +40,19 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => email: Yup.string().required(t('Email is required.')).email(t('Enter a valid email.')), }); const initialFormValues: any = { - name, + first_name, + last_name, 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 +69,15 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => children: [ { component: Input, - name: 'name', + name: 'first_name', + type: 'text', + inputLabel: 'First Name', + }, + { + component: Input, + name: 'last_name', type: 'text', - inputLabel: 'Name', + inputLabel: 'Last Name', }, { component: Input, @@ -73,6 +90,7 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => name: 'phone', type: 'phone', inputLabel: 'Phone Number', + changeHandler: handlePhoneNumberChange, }, { component: Input, @@ -95,6 +113,7 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => const updatedPayload = { finance_poc: { ...payload, + phone: formattedPhone, }, registration_id: registrationData.registration_details.registration_id, org_id: registrationData.registration_details.org_id, @@ -107,10 +126,14 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => }; const setStates = (states: any) => { - const { name, designation, phone, email, billing_frequency } = states.finance_poc; - setName(name); + const { first_name, last_name, designation, phone, email, billing_frequency } = + states.finance_poc; + + setFirstName(first_name); + setLastName(last_name); setDesignation(designation); setPhone(phone); + setFormattedPhone(phone); setEmail(email); setPaymentType(billing_frequency); }; diff --git a/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx b/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx index c9ebc1e61..9c3fecb0e 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 [formattedPhone, setFormattedPhone] = useState(''); const [isDisabled, setIsDisabled] = useState(false); const [loading, setLoading] = useState(false); @@ -39,6 +40,11 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = .min(7, t('Enter a valid phone number.')), }); + const handlePhoneNumberChange = (_: any, data: any, formFieldItems: any) => { + const formattedValue = formFieldItems.split(data.dialCode).join(data.dialCode + '-'); + setFormattedPhone(formattedValue); + }; + const initialFormValues: any = { name, app_name, api_key, shortcode, phone }; const createTooltip = (title: any) => ( @@ -84,6 +90,7 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = inputLabel: 'Chatbot Number', helperText: 'WhatsApp number that will be used for chatbot', disabled: isDisabled, + changeHandler: handlePhoneNumberChange, }, { component: Input, @@ -137,7 +144,7 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = return { api_key, app_name, - phone, + phone: formattedPhone, shortcode, name, token, diff --git a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index 1e5fde60a..960637627 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -20,9 +20,12 @@ export const SigningAuthority = ({ 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(''); @@ -34,14 +37,20 @@ 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.'), + 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.'), signingAuthorityEmail: Yup.string() .required(t('Email is required.')) @@ -57,9 +66,12 @@ export const SigningAuthority = ({ }); const initialFormValues: any = { - submitterName, + submitterFirstName, + submitterLastName, submitterEmail, - signingAuthorityName, + submitterDesignation, + signingAuthorityFirstName, + signingAuthorityLastName, signingAuthorityDesignation, signingAuthorityEmail, permissions, @@ -71,9 +83,21 @@ export const SigningAuthority = ({ children: [ { component: Input, - name: 'submitterName', + name: 'submitterFirstName', + type: 'text', + inputLabel: 'First Name', + }, + { + component: Input, + name: 'submitterLastName', + type: 'text', + inputLabel: 'Last Name', + }, + { + component: Input, + name: 'submitterDesignation', type: 'text', - inputLabel: 'Name', + inputLabel: 'Designation', }, { component: Input, @@ -88,9 +112,15 @@ export const SigningAuthority = ({ children: [ { component: Input, - name: 'signingAuthorityName', + name: 'signingAuthorityFirstName', + type: 'text', + inputLabel: 'First Name', + }, + { + component: Input, + name: 'signingAuthorityLastName', type: 'text', - inputLabel: 'Name', + inputLabel: 'Last Name', }, { component: Input, @@ -121,11 +151,14 @@ 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, + first_name: payload.signingAuthorityFirstName, + last_name: payload.signingAuthorityLastName, designation: payload.signingAuthorityDesignation, email: payload.signingAuthorityEmail, }, @@ -136,6 +169,7 @@ export const SigningAuthority = ({ has_submitted: true, }; + console.log(updatedPayload); return updatedPayload; } @@ -144,9 +178,12 @@ export const SigningAuthority = ({ const setStates = (states: any) => { const { signing_authority, submitter } = states; - setSubmitterName(submitter?.name); + setSubmitterFirstName(submitter?.first_name); + setSubmitterLastName(submitter?.last_name); setSubmitterEmail(submitter?.email); - setSigningAuthorityName(signing_authority?.name); + setSubmitterDesignation(submitter?.designation); + setSigningAuthorityFirstName(signing_authority?.first_name); + setSigningAuthorityLastName(signing_authority?.last_name); setSigningAuthorityDesignation(signing_authority?.designation); setSigningAuthorityEmail(signing_authority?.email); setPermissions({ support_staff_account: false, terms_agreed: false }); diff --git a/src/i18n/en/en.json b/src/i18n/en/en.json index 09ea81d46..ff93654ae 100644 --- a/src/i18n/en/en.json +++ b/src/i18n/en/en.json @@ -512,5 +512,7 @@ "Template Flows": "Template Flows", "Template Flow": "Template Flow", "Template flow copy": "Template flow copy", - "Flow created successfully from template!": "Flow created successfully from template!" + "Flow created successfully from template!": "Flow created successfully from template!", + "First name is required.": "First Nname is required.", + "Last name is required.": "Last name is required." } From 42eeb7bb6d58dd53e98f7c11a1029df3a706fdbe Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Mon, 4 Nov 2024 13:22:29 +0530 Subject: [PATCH 02/21] removed first name from finance and signing authority --- .../Onboarding/Steps/PaymentDetails.tsx | 28 +++++-------------- .../Onboarding/Steps/SigningAuthority.tsx | 25 ++++------------- 2 files changed, 13 insertions(+), 40 deletions(-) diff --git a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx index 1fd7201e7..3f3dbe740 100644 --- a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx @@ -14,9 +14,7 @@ import { FormStepProps } from './OrgDetails'; export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => { const { t } = useTranslation(); const [billing_frequency, setPaymentType] = useState('yearly'); - - const [first_name, setFirstName] = useState(''); - const [last_name, setLastName] = useState(''); + const [name, setName] = useState(''); const [designation, setDesignation] = useState(''); const [phone, setPhone] = useState(''); const [formattedPhone, setFormattedPhone] = useState(''); @@ -25,11 +23,8 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => const [loading, setLoading] = useState(false); const FormSchema = Yup.object().shape({ - first_name: Yup.string() - .required(t('First name is required.')) - .max(25, t('Please enter not more than 25 characters')), - last_name: Yup.string() - .required(t('Last name is required.')) + name: Yup.string() + .required(t('Name is required.')) .max(25, t('Please enter not more than 25 characters')), designation: Yup.string() .required(t('Designation is required.')) @@ -40,8 +35,7 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => email: Yup.string().required(t('Email is required.')).email(t('Enter a valid email.')), }); const initialFormValues: any = { - first_name, - last_name, + name, designation, phone, email, @@ -69,16 +63,10 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => children: [ { component: Input, - name: 'first_name', + name: 'name', type: 'text', inputLabel: 'First Name', }, - { - component: Input, - name: 'last_name', - type: 'text', - inputLabel: 'Last Name', - }, { component: Input, name: 'designation', @@ -126,11 +114,9 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => }; const setStates = (states: any) => { - const { first_name, last_name, designation, phone, email, billing_frequency } = - states.finance_poc; + const { name, designation, phone, email, billing_frequency } = states.finance_poc; - setFirstName(first_name); - setLastName(last_name); + setName(name); setDesignation(designation); setPhone(phone); setFormattedPhone(phone); diff --git a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index 960637627..85e0083dc 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -24,8 +24,7 @@ export const SigningAuthority = ({ const [submitterLastName, setSubmitterLastName] = useState(''); const [submitterEmail, setSubmitterEmail] = useState(''); const [submitterDesignation, setSubmitterDesignation] = useState(''); - const [signingAuthorityFirstName, setSigningAuthorityFirstName] = useState(''); - const [signingAuthorityLastName, setSigningAuthorityLastName] = useState(''); + const [signingAuthorityName, setSigningAuthorityName] = useState(''); const [signingAuthorityDesignation, setSigningAuthorityDesignation] = useState(''); const [signingAuthorityEmail, setSigningAuthorityEmail] = useState(''); @@ -45,11 +44,8 @@ export const SigningAuthority = ({ .max(25, t('Please enter not more than 25 characters')), submitterEmail: Yup.string().required(t('Email is required.')).email(t('Enter a valid email.')), submitterDesignation: Yup.string().required('Designation is required.'), - 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.')) + signingAuthorityName: Yup.string() + .required(t('Name is required.')) .max(25, t('Please enter not more than 25 characters')), signingAuthorityDesignation: Yup.string().required('Designation is required.'), signingAuthorityEmail: Yup.string() @@ -70,8 +66,7 @@ export const SigningAuthority = ({ submitterLastName, submitterEmail, submitterDesignation, - signingAuthorityFirstName, - signingAuthorityLastName, + signingAuthorityName, signingAuthorityDesignation, signingAuthorityEmail, permissions, @@ -116,12 +111,6 @@ export const SigningAuthority = ({ type: 'text', inputLabel: 'First Name', }, - { - component: Input, - name: 'signingAuthorityLastName', - type: 'text', - inputLabel: 'Last Name', - }, { component: Input, name: 'signingAuthorityDesignation', @@ -157,8 +146,7 @@ export const SigningAuthority = ({ email: payload.submitterEmail, }, signing_authority: { - first_name: payload.signingAuthorityFirstName, - last_name: payload.signingAuthorityLastName, + name: payload.signingAuthorityName, designation: payload.signingAuthorityDesignation, email: payload.signingAuthorityEmail, }, @@ -182,8 +170,7 @@ export const SigningAuthority = ({ setSubmitterLastName(submitter?.last_name); setSubmitterEmail(submitter?.email); setSubmitterDesignation(submitter?.designation); - setSigningAuthorityFirstName(signing_authority?.first_name); - setSigningAuthorityLastName(signing_authority?.last_name); + setSigningAuthorityName(signing_authority?.name); setSigningAuthorityDesignation(signing_authority?.designation); setSigningAuthorityEmail(signing_authority?.email); setPermissions({ support_staff_account: false, terms_agreed: false }); From 258dd022e38670c0d5eea607a3568bd470a646a5 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Tue, 5 Nov 2024 09:56:19 +0530 Subject: [PATCH 03/21] minor refactoring --- .../Onboarding/Steps/Address/Address.tsx | 1 - .../Onboarding/Steps/PaymentDetails.tsx | 32 ++++++++++++------- .../Onboarding/Steps/PlatformDetails.tsx | 9 +----- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/containers/Organization/Onboarding/Steps/Address/Address.tsx b/src/containers/Organization/Onboarding/Steps/Address/Address.tsx index 48777e28d..90c9c44c2 100644 --- a/src/containers/Organization/Onboarding/Steps/Address/Address.tsx +++ b/src/containers/Organization/Onboarding/Steps/Address/Address.tsx @@ -1,6 +1,5 @@ import { OutlinedInput, Typography } from '@mui/material'; import styles from './Address.module.css'; -import { ChangeEvent, useState } from 'react'; interface RegisteredAddressProps { inputLabel: string; diff --git a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx index 3f3dbe740..ab456387c 100644 --- a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx @@ -10,6 +10,7 @@ import { PhoneInput } from 'components/UI/Form/PhoneInput/PhoneInput'; import { FormLayout } from '../FormLayout/FormLayout'; import { PaymentOptions } from '../PaymentType/PaymentOptions'; import { FormStepProps } from './OrgDetails'; +import { setNotification } from 'common/notification'; export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => { const { t } = useTranslation(); @@ -127,19 +128,26 @@ 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((errors) => { + setLoading(false); + setNotification('Something went wrong', 'error'); + }); }; return ( diff --git a/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx b/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx index 9c3fecb0e..c9ebc1e61 100644 --- a/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx @@ -20,7 +20,6 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = const [shortcode, setShortcode] = useState(''); const [phone, setPhone] = useState(''); const [code, setCode] = useState('[shortcode]'); - const [formattedPhone, setFormattedPhone] = useState(''); const [isDisabled, setIsDisabled] = useState(false); const [loading, setLoading] = useState(false); @@ -40,11 +39,6 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = .min(7, t('Enter a valid phone number.')), }); - const handlePhoneNumberChange = (_: any, data: any, formFieldItems: any) => { - const formattedValue = formFieldItems.split(data.dialCode).join(data.dialCode + '-'); - setFormattedPhone(formattedValue); - }; - const initialFormValues: any = { name, app_name, api_key, shortcode, phone }; const createTooltip = (title: any) => ( @@ -90,7 +84,6 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = inputLabel: 'Chatbot Number', helperText: 'WhatsApp number that will be used for chatbot', disabled: isDisabled, - changeHandler: handlePhoneNumberChange, }, { component: Input, @@ -144,7 +137,7 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = return { api_key, app_name, - phone: formattedPhone, + phone, shortcode, name, token, From 707b933da88499a90a0332f2ee5a0aabd6b8fbaf Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Tue, 5 Nov 2024 12:47:09 +0530 Subject: [PATCH 04/21] changed payment methods --- .../Onboarding/PaymentType/PaymentOptions.tsx | 20 +++++++++---------- .../Onboarding/Steps/SigningAuthority.tsx | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/containers/Organization/Onboarding/PaymentType/PaymentOptions.tsx b/src/containers/Organization/Onboarding/PaymentType/PaymentOptions.tsx index 897b93719..91f72a8ef 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/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index 85e0083dc..cd84a543a 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -107,9 +107,9 @@ export const SigningAuthority = ({ children: [ { component: Input, - name: 'signingAuthorityFirstName', + name: 'signingAuthorityName', type: 'text', - inputLabel: 'First Name', + inputLabel: 'Name', }, { component: Input, From 60e5fbbd18c6b20f2320a0163fd204cfc187d812 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Tue, 5 Nov 2024 15:58:23 +0530 Subject: [PATCH 05/21] added validations + error message --- .../Onboarding/FormLayout/FormLayout.tsx | 24 ++++++++- .../Onboarding/Steps/OrgDetails.tsx | 54 ++++++++++++++++--- .../Onboarding/Steps/PlatformDetails.tsx | 6 +++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/containers/Organization/Onboarding/FormLayout/FormLayout.tsx b/src/containers/Organization/Onboarding/FormLayout/FormLayout.tsx index c510b131f..58042ddf4 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 = ( ); + 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/Steps/OrgDetails.tsx b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx index 039caf7f4..203f9fb3e 100644 --- a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx @@ -44,22 +44,64 @@ export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { const { t } = useTranslation(); + const firstLetterCapitalized = (value: string) => { + if (!value) return true; // Allow empty values to be handled by other validations + return /^[A-Z]/.test(value); + }; + const FormSchema = Yup.object().shape({ gstin: Yup.string().length(15, t('Invalid gst number')), 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'), + city: Yup.string() + .required('City is required') + .test( + 'first-letter-capitalized', + 'First letter must be capitalized', + firstLetterCapitalized + ), + state: Yup.string() + .required('State is required') + .test( + 'first-letter-capitalized', + 'First letter must be capitalized', + firstLetterCapitalized + ), + country: Yup.string() + .required('Country is required') + .test( + 'first-letter-capitalized', + 'First letter must be capitalized', + firstLetterCapitalized + ), 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'), + city: Yup.string() + .required('City is required') + .test( + 'first-letter-capitalized', + 'First letter must be capitalized', + firstLetterCapitalized + ), + + state: Yup.string() + .required('State is required') + .test( + 'first-letter-capitalized', + 'First letter must be capitalized', + firstLetterCapitalized + ), + country: Yup.string() + .required('Country is required') + .test( + 'first-letter-capitalized', + 'First letter must be capitalized', + firstLetterCapitalized + ), pincode: Yup.string().matches(/^\d+$/, 'Invalid Pincode').required('Pincode is required'), }), }); diff --git a/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx b/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx index c9ebc1e61..07a271cfc 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); @@ -163,6 +164,9 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = return true; } else { + if (data.messages.global) { + setCustomError(data.messages.global); + } setErrors(data.messages); saveData(data.messages, 'errors'); return false; @@ -234,6 +238,8 @@ export const PlatformDetails = ({ handleStepChange, saveData }: FormStepProps) = showModal={true} isDisabled={isDisabled} handleEffect={generateShortcode} + customError={customError} + setCustomError={setCustomError} /> ); }; From b9ded55c6bfce8c607ed81e54f5f997c4d361d4e Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Tue, 5 Nov 2024 16:19:03 +0530 Subject: [PATCH 06/21] added test cases --- .../Organization/Onboarding/Form.test.tsx | 27 ++++++++++++++----- .../Onboarding/Steps/Address/Address.tsx | 1 - .../Onboarding/Steps/OrgDetails.tsx | 6 +++++ .../Onboarding/Steps/PaymentDetails.tsx | 8 +++++- .../Onboarding/Steps/SigningAuthority.tsx | 1 - 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/containers/Organization/Onboarding/Form.test.tsx b/src/containers/Organization/Onboarding/Form.test.tsx index 7d72f0c78..de86881a2 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' } }); @@ -189,14 +195,18 @@ test('it should submit the form', async () => { const inputFieldssigningdetails = getAllByRole('textbox'); const [ - submitterName, + submitterFirstName, + submitterLastName, + submitterDesignation, submitterEmail, signingAuthorityName, 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' } }); @@ -253,9 +263,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' } }); diff --git a/src/containers/Organization/Onboarding/Steps/Address/Address.tsx b/src/containers/Organization/Onboarding/Steps/Address/Address.tsx index 90c9c44c2..96e9929f3 100644 --- a/src/containers/Organization/Onboarding/Steps/Address/Address.tsx +++ b/src/containers/Organization/Onboarding/Steps/Address/Address.tsx @@ -35,7 +35,6 @@ export const RegisteredAddress = ({ const errors = form.errors[field.name]; const touched = form.touched[field.name]; - console.log(disabled); return (
diff --git a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx index 203f9fb3e..fbdfc21f9 100644 --- a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx @@ -41,6 +41,7 @@ export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { const [disable, setDisable] = useState(false); const [loading, setLoading] = useState(false); + const [customError, setCustomError] = useState(null); const { t } = useTranslation(); @@ -198,6 +199,9 @@ export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { if (data.is_valid) { handleStepChange(); } else { + if (data.messages.global) { + setCustomError(data.messages.global); + } setErrors(data.messages); } }); @@ -228,6 +232,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 ab456387c..3ca2a0625 100644 --- a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx @@ -14,12 +14,13 @@ import { setNotification } from 'common/notification'; export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => { const { t } = useTranslation(); - const [billing_frequency, setPaymentType] = useState('yearly'); + const [billing_frequency, setPaymentType] = useState('Annually'); const [name, setName] = 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); @@ -135,6 +136,9 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => if (data.is_valid) { handleStepChange(); } else { + if (data.messages.global) { + setCustomError(data.messages.global); + } const errors = Object.keys(data.messages).reduce((acc, key) => { const newKey = key.replace('finance_poc_', ''); return { ...acc, [newKey]: data.messages[key] }; @@ -165,6 +169,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/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index cd84a543a..75871121c 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -157,7 +157,6 @@ export const SigningAuthority = ({ has_submitted: true, }; - console.log(updatedPayload); return updatedPayload; } From 0752f0acfb94a930600dedb0ee077b202d7ab305 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Wed, 6 Nov 2024 12:59:51 +0530 Subject: [PATCH 07/21] code cleanup --- src/common/utils.ts | 6 +++ .../UI/Form/PhoneInput/PhoneInput.tsx | 2 +- .../Onboarding/FormLayout/FormLayout.tsx | 10 ++-- .../Steps/Address/Address.module.css | 2 +- .../Onboarding/Steps/Address/Address.tsx | 13 ++--- .../Onboarding/Steps/OrgDetails.tsx | 30 ++++++----- .../Onboarding/Steps/PaymentDetails.tsx | 6 +-- .../Onboarding/Steps/PlatformDetails.tsx | 51 ++++++++++--------- .../Onboarding/Steps/SigningAuthority.tsx | 29 +++++++---- 9 files changed, 83 insertions(+), 66 deletions(-) diff --git a/src/common/utils.ts b/src/common/utils.ts index b3331c807..fa8d349a9 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 42c53a913..6ce4eef0e 100644 --- a/src/components/UI/Form/PhoneInput/PhoneInput.tsx +++ b/src/components/UI/Form/PhoneInput/PhoneInput.tsx @@ -18,7 +18,7 @@ export interface InputProps { form: { touched: any; errors: any; setFieldValue: any }; inputLabel?: string | null; disabled?: boolean; - changeHandler?: any; + changeHandler?: (event: string, data: {}, formFieldItems: string) => void; } export const PhoneInput = ({ diff --git a/src/containers/Organization/Onboarding/FormLayout/FormLayout.tsx b/src/containers/Organization/Onboarding/FormLayout/FormLayout.tsx index 58042ddf4..f3dca372b 100644 --- a/src/containers/Organization/Onboarding/FormLayout/FormLayout.tsx +++ b/src/containers/Organization/Onboarding/FormLayout/FormLayout.tsx @@ -229,8 +229,8 @@ export const FormLayout = ({ handleOk={() => { saveHandler(formik.values, formik.setErrors); }} - title={'Confirmation'} - buttonOk={'Confirm'} + title="Confirmation" + buttonOk="Confirm" buttonCancel="Cancel" buttonOkLoading={loading} > @@ -248,10 +248,10 @@ export const FormLayout = ({ setCustomError(null)} handleCancel={() => setCustomError(null)} - title={'Something went wrong!'} - buttonOk={'Ok'} + title="Something went wrong!" + buttonOk="Ok" skipCancel - colorOk={'warning'} + colorOk="warning" >

{customError}

diff --git a/src/containers/Organization/Onboarding/Steps/Address/Address.module.css b/src/containers/Organization/Onboarding/Steps/Address/Address.module.css index 29f777b82..2887bfdc3 100644 --- a/src/containers/Organization/Onboarding/Steps/Address/Address.module.css +++ b/src/containers/Organization/Onboarding/Steps/Address/Address.module.css @@ -37,7 +37,7 @@ .Errors { font-size: 12px; - margin: 0px; + margin: 0; margin-left: 14px; line-height: 18px; font-weight: 400; diff --git a/src/containers/Organization/Onboarding/Steps/Address/Address.tsx b/src/containers/Organization/Onboarding/Steps/Address/Address.tsx index 96e9929f3..60d994631 100644 --- a/src/containers/Organization/Onboarding/Steps/Address/Address.tsx +++ b/src/containers/Organization/Onboarding/Steps/Address/Address.tsx @@ -1,4 +1,5 @@ import { OutlinedInput, Typography } from '@mui/material'; +import { formatString } from 'common/utils'; import styles from './Address.module.css'; interface RegisteredAddressProps { @@ -6,18 +7,10 @@ interface RegisteredAddressProps { inputLabelSubtext: any; address: any; disabled: boolean; - setAddress: any; form: { touched: any; errors: any; setFieldValue: any }; field: { name: string; value: any }; } -function x(str: string) { - return str - .replace(/_/g, ' ') // Replace underscores with spaces - .replace(/([a-z])([0-9])/gi, '$1 $2') // Insert space before digits - .replace(/\b\w/g, (char) => char.toUpperCase()); // Capitalize each word -} - export const RegisteredAddress = ({ inputLabel, address, @@ -48,7 +41,7 @@ export const RegisteredAddress = ({ .slice(0, 2) .map((key) => (
-

{x(key)}

+

{formatString(key)}

(
-

{x(key)}

+

{formatString(key)}

{ - return Object.keys(address1).every((key) => address1[key] === address2[key]); -}; +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(''); @@ -194,17 +193,22 @@ export const OrgDetails = ({ 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 { - if (data.messages.global) { - setCustomError(data.messages.global); + await axios + .post(ONBOARD_URL_UPDATE, payload) + .then(({ data }) => { + setLoading(false); + if (data.is_valid) { + handleStepChange(); + } else { + if (data.messages.global) { + setCustomError(data.messages.global); + } + setErrors(data.messages); } - setErrors(data.messages); - } - }); + }) + .catch(() => { + setLoading(false); + }); }; const handleAutoUpdateAddress = (identifier: string, formik: any) => { diff --git a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx index 3ca2a0625..02a1feb42 100644 --- a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx @@ -10,7 +10,6 @@ import { PhoneInput } from 'components/UI/Form/PhoneInput/PhoneInput'; import { FormLayout } from '../FormLayout/FormLayout'; import { PaymentOptions } from '../PaymentType/PaymentOptions'; import { FormStepProps } from './OrgDetails'; -import { setNotification } from 'common/notification'; export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => { const { t } = useTranslation(); @@ -45,7 +44,7 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => }; const handlePhoneNumberChange = (_: any, data: any, formFieldItems: any) => { - const formattedValue = formFieldItems.split(data.dialCode).join(data.dialCode + '-'); + const formattedValue = formFieldItems.split(data.dialCode).join(`${data.dialCode}-`); setFormattedPhone(formattedValue); }; @@ -148,9 +147,8 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => setLoading(false); } }) - .catch((errors) => { + .catch(() => { setLoading(false); - setNotification('Something went wrong', 'error'); }); }; diff --git a/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx b/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx index 07a271cfc..a7d4e7186 100644 --- a/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx @@ -148,30 +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 { - if (data.messages.global) { - setCustomError(data.messages.global); + 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; } - setErrors(data.messages); - saveData(data.messages, 'errors'); - return false; - } - }); + }) + .catch((errors) => { + setLoading(false); + }); }; const setStates = (states: any) => { diff --git a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index 75871121c..40eb1ab5a 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -27,6 +27,7 @@ export const SigningAuthority = ({ const [signingAuthorityName, setSigningAuthorityName] = useState(''); const [signingAuthorityDesignation, setSigningAuthorityDesignation] = useState(''); const [signingAuthorityEmail, setSigningAuthorityEmail] = useState(''); + const [customError, setCustomError] = useState(null); const [permissions, setPermissions] = useState({ terms_agreed: false, @@ -178,15 +179,23 @@ 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 { + if (data.messages.global) { + setCustomError(data.messages.global); + } + setErrors(data.messages); + } + }) + .catch(() => { + setLoading(false); + }); }; return ( @@ -205,6 +214,8 @@ export const SigningAuthority = ({ loading={loading} submitData={handleSubmit} buttonState={{ text: 'Submit' }} + setCustomError={setCustomError} + customError={customError} /> ); }; From 772422ca83784d1af200e4a179e64f4d16a4a4df Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Wed, 6 Nov 2024 16:42:55 +0530 Subject: [PATCH 08/21] updated regex for shortcode --- .../Organization/Onboarding/Steps/PlatformDetails.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx b/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx index a7d4e7186..d940fad61 100644 --- a/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PlatformDetails.tsx @@ -34,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.')), From 4f10b165af9e95486ac229d5ae3fc54f03ed5e47 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Wed, 6 Nov 2024 16:57:16 +0530 Subject: [PATCH 09/21] handling errors --- .../Organization/Onboarding/Steps/OrgDetails.tsx | 8 ++++---- .../Organization/Onboarding/Steps/PaymentDetails.tsx | 8 ++++---- .../Organization/Onboarding/Steps/SigningAuthority.tsx | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx index f2a89d4a9..358f2e8f8 100644 --- a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx @@ -200,13 +200,13 @@ export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { if (data.is_valid) { handleStepChange(); } else { - if (data.messages.global) { - setCustomError(data.messages.global); - } setErrors(data.messages); } }) - .catch(() => { + .catch((data) => { + if (data.response.data.error.message) { + setCustomError(data.messages.global); + } setLoading(false); }); }; diff --git a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx index 02a1feb42..a00a53fbc 100644 --- a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx @@ -135,9 +135,6 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => if (data.is_valid) { handleStepChange(); } else { - if (data.messages.global) { - setCustomError(data.messages.global); - } const errors = Object.keys(data.messages).reduce((acc, key) => { const newKey = key.replace('finance_poc_', ''); return { ...acc, [newKey]: data.messages[key] }; @@ -147,7 +144,10 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => setLoading(false); } }) - .catch(() => { + .catch((data) => { + if (data.response.data.error.message) { + setCustomError(data.messages.global); + } setLoading(false); }); }; diff --git a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index 40eb1ab5a..90698deb4 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -187,13 +187,13 @@ export const SigningAuthority = ({ handleStepChange(); localStorage.removeItem('registrationData'); } else { - if (data.messages.global) { - setCustomError(data.messages.global); - } setErrors(data.messages); } }) - .catch(() => { + .catch((data) => { + if (data.response.data.error.message) { + setCustomError(data.messages.global); + } setLoading(false); }); }; From 7b22061420118c9ee1c5c69e35a75fe88f17ec7d Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Thu, 7 Nov 2024 21:21:36 +0530 Subject: [PATCH 10/21] fixed typo --- src/i18n/en/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/en/en.json b/src/i18n/en/en.json index ff93654ae..e668552cb 100644 --- a/src/i18n/en/en.json +++ b/src/i18n/en/en.json @@ -513,6 +513,6 @@ "Template Flow": "Template Flow", "Template flow copy": "Template flow copy", "Flow created successfully from template!": "Flow created successfully from template!", - "First name is required.": "First Nname is required.", + "First name is required.": "First Name is required.", "Last name is required.": "Last name is required." } From ed12b4799925ca0e9ce9aa855d027814d08574c0 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Fri, 8 Nov 2024 20:45:02 +0530 Subject: [PATCH 11/21] added validations --- src/App.tsx | 5 +++++ .../Organization/Onboarding/Steps/SigningAuthority.tsx | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index be6b5c2b9..dacefc44e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,6 +13,7 @@ import { UnauthenticatedRoute } from 'routes/UnauthenticatedRoute/Unauthenticate import { AuthenticatedRoute } from 'routes/AuthenticatedRoute/AuthenticatedRoute'; import { Logout } from 'containers/Auth/Logout/Logout'; import { checkSessionValidity } from 'common/utils'; +import axios from 'axios'; const App = () => { const navigate = useNavigate(); @@ -21,6 +22,10 @@ const App = () => { const [authenticated, setAuthenticated] = useState(); const [drawerOpen, setDrawerOpen] = useState(true); + axios + .get('http://localhost:4000/flow-editor/interactive-templates/') + .then((data) => console.log(data)); + useEffect(() => { const checkAuth = async () => { const isAccessTokenPresent = getAuthSession('accessToken') !== null; diff --git a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index 90698deb4..5519d513d 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -44,11 +44,15 @@ export const SigningAuthority = ({ .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.')), - submitterDesignation: Yup.string().required('Designation is required.'), + submitterDesignation: Yup.string() + .required('Designation is required.') + .max(25, t('Please enter not more than 25 characters')), signingAuthorityName: Yup.string() .required(t('Name is required.')) .max(25, t('Please enter not more than 25 characters')), - signingAuthorityDesignation: Yup.string().required('Designation is required.'), + 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.'), From 0d9016dfeb8282e506b58310780fd049f5d54869 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Wed, 13 Nov 2024 10:14:22 +0530 Subject: [PATCH 12/21] removed unnecessary code --- src/App.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index dacefc44e..be6b5c2b9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,7 +13,6 @@ import { UnauthenticatedRoute } from 'routes/UnauthenticatedRoute/Unauthenticate import { AuthenticatedRoute } from 'routes/AuthenticatedRoute/AuthenticatedRoute'; import { Logout } from 'containers/Auth/Logout/Logout'; import { checkSessionValidity } from 'common/utils'; -import axios from 'axios'; const App = () => { const navigate = useNavigate(); @@ -22,10 +21,6 @@ const App = () => { const [authenticated, setAuthenticated] = useState(); const [drawerOpen, setDrawerOpen] = useState(true); - axios - .get('http://localhost:4000/flow-editor/interactive-templates/') - .then((data) => console.log(data)); - useEffect(() => { const checkAuth = async () => { const isAccessTokenPresent = getAuthSession('accessToken') !== null; From 259fd285c60454bd3591e486044a52010b009e57 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Wed, 13 Nov 2024 10:48:47 +0530 Subject: [PATCH 13/21] fixed temperature slider --- src/components/UI/Heading/Heading.tsx | 17 ++--- .../AssistantOptions.module.css | 24 +++++-- .../AssistantOptions/AssistantOptions.tsx | 68 +++++++++++-------- .../CreateAssistant/CreateAssistant.tsx | 40 +++-------- src/i18n/en/en.json | 2 +- 5 files changed, 76 insertions(+), 75 deletions(-) diff --git a/src/components/UI/Heading/Heading.tsx b/src/components/UI/Heading/Heading.tsx index 631402922..296fabc5e 100644 --- a/src/components/UI/Heading/Heading.tsx +++ b/src/components/UI/Heading/Heading.tsx @@ -20,14 +20,7 @@ export interface HeadingProps { }; } -export const Heading = ({ - formTitle, - helpData, - showHeaderHelp = true, - backLink, - headerHelp, - button, -}: HeadingProps) => { +export const Heading = ({ formTitle, helpData, showHeaderHelp = true, backLink, headerHelp, button }: HeadingProps) => { const navigate = useNavigate(); const addIcon = ; @@ -39,12 +32,12 @@ export const Heading = ({
-
{formTitle}
+
+ {formTitle} +
{helpData ? : ''}
-
- {showHeaderHelp ? headerHelp || `Please enter below details.` : ''} -
+
{showHeaderHelp ? headerHelp || `Please enter below details.` : ''}
{button && button.show && ( diff --git a/src/containers/Assistants/AssistantOptions/AssistantOptions.module.css b/src/containers/Assistants/AssistantOptions/AssistantOptions.module.css index ca21b53f2..f26b427f2 100644 --- a/src/containers/Assistants/AssistantOptions/AssistantOptions.module.css +++ b/src/containers/Assistants/AssistantOptions/AssistantOptions.module.css @@ -21,15 +21,21 @@ .Temperature { display: flex; column-gap: 1rem; - align-items: center; + align-items: start; padding: 1rem 0; } +.SliderContainer { + width: 100%; + display: flex; + flex-direction: column; +} + .Slider { - width: 80%; display: flex; align-items: center; column-gap: 1rem; + justify-content: space-between; } .SliderDisplay { @@ -37,10 +43,21 @@ padding: 4px 12px; border: 0.5px solid #a4a4a4; border-radius: 4px; - width: 15%; text-align: center; } +.Error { + border-color: #fb5c5c; +} + +.ErrorText { + width: 100%; + color: #fb5c5c; + font-size: 0.8rem; + margin-top: 0.5rem; + text-align: right; +} + .SliderDisplay:focus { outline: none; } @@ -147,7 +164,6 @@ .VectorStore { display: flex; width: 100%; - padding: 1rem 2rem; background-color: #ebf8ee; font-size: 0.8rem; padding: 0.5rem 1rem; diff --git a/src/containers/Assistants/AssistantOptions/AssistantOptions.tsx b/src/containers/Assistants/AssistantOptions/AssistantOptions.tsx index 642a4aea1..4383c40ab 100644 --- a/src/containers/Assistants/AssistantOptions/AssistantOptions.tsx +++ b/src/containers/Assistants/AssistantOptions/AssistantOptions.tsx @@ -34,6 +34,7 @@ const temperatureInfo = export const AssistantOptions = ({ currentId, options, setOptions }: AssistantOptionsProps) => { const [showUploadDialog, setShowUploadDialog] = useState(false); const [files, setFiles] = useState([]); + const [error, setError] = useState(false); const { t } = useTranslation(); const [uploadFile, { loading: uploadingFile }] = useMutation(UPLOAD_FILE_TO_OPENAI); @@ -201,34 +202,45 @@ export const AssistantOptions = ({ currentId, options, setOptions }: AssistantOp }} /> - -
- { - setOptions({ - ...options, - temperature: value, - }); - }} - value={options.temperature} - step={0.01} - max={2} - /> - { - setOptions({ - ...options, - temperature: event.target.value, - }); - }} - className={styles.SliderDisplay} - /> +
+
+ { + setOptions({ + ...options, + temperature: value, + }); + }} + value={options.temperature} + step={0.01} + max={2} + min={0} + /> + { + const value = parseFloat(event.target.value); + if (value < 0 || value > 2) { + setError(true); + return; + } + setError(false); + setOptions({ + ...options, + temperature: value, + }); + }} + className={`${styles.SliderDisplay} ${error ? styles.Error : ''}`} + /> +
+ {error &&

Temperature value should be between 0-1

}
diff --git a/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx b/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx index 063f93e1f..456011f66 100644 --- a/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx +++ b/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx @@ -31,12 +31,7 @@ interface CreateAssistantProps { setUpdateList: any; } -export const CreateAssistant = ({ - currentId, - setUpdateList, - setCurrentId, - updateList, -}: CreateAssistantProps) => { +export const CreateAssistant = ({ currentId, setUpdateList, setCurrentId, updateList }: CreateAssistantProps) => { const [assistantId, setAssistantId] = useState(''); const [name, setName] = useState(''); const [model, setModel] = useState(null); @@ -75,9 +70,7 @@ export const CreateAssistant = ({ onCompleted: ({ assistant }) => { setAssistantId(assistant?.assistant?.assistantId); setName(assistant?.assistant?.name); - let modelValue = modelOptions?.find( - (item: any) => item.label === assistant?.assistant?.model - ); + let modelValue = modelOptions?.find((item: any) => item.label === assistant?.assistant?.model); setModel(modelValue); setInstructions(assistant?.assistant?.instructions || ''); setOptions({ @@ -90,12 +83,7 @@ export const CreateAssistant = ({ }, [currentId, modelsList]); const handleCreate = () => { - const { - instructions: instructionsValue, - model: modelValue, - name: nameValue, - options: optionsValue, - } = states; + const { instructions: instructionsValue, model: modelValue, name: nameValue, options: optionsValue } = states; const payload = { instructions: instructionsValue, @@ -138,9 +126,7 @@ export const CreateAssistant = ({ onChange: (value: any) => setName(value), helperText: (
- - {t('Give a recognizable name for your assistant')} - + {t('Give a recognizable name for your assistant')}
copyToClipboard(assistantId)}> {assistantId} @@ -191,10 +177,7 @@ export const CreateAssistant = ({ }, onCompleted: ({ deleteAssistant }) => { setShowConfirmation(false); - setNotification( - `Assistant ${deleteAssistant.assistant.name} deleted successfully`, - 'success' - ); + setNotification(`Assistant ${deleteAssistant.assistant.name} deleted successfully`, 'success'); setCurrentId(null); setUpdateList(!updateList); }, @@ -205,7 +188,7 @@ export const CreateAssistant = ({ if (showConfirmation) { dialog = ( -
{t("You won't be able to use this assistant.")}
+
+ {t('Please confirm that this assistant is not being used in any of the active flows.')} +
); } @@ -240,12 +225,7 @@ export const CreateAssistant = ({ ))}
-
- {error &&

Temperature value should be between 0-1

} + {error &&

Temperature value should be between 0-2

}
diff --git a/src/containers/Assistants/Assistants.test.tsx b/src/containers/Assistants/Assistants.test.tsx index b5f6b8ba0..f50d0ccbb 100644 --- a/src/containers/Assistants/Assistants.test.tsx +++ b/src/containers/Assistants/Assistants.test.tsx @@ -216,3 +216,28 @@ test('it deletes the assistant', async () => { expect(notificationSpy).toHaveBeenCalled(); }); }); + +test('it should show errors for invalid value in temperature', async () => { + render(assistantsComponent()); + + await waitFor(() => { + expect(screen.getByText('Assistants')).toBeInTheDocument(); + expect(screen.getByText('Assistant-1')).toBeInTheDocument(); + }); + + await waitFor(() => { + expect(screen.getByText('Instructions')).toBeInTheDocument(); + }); + + fireEvent.change(screen.getByRole('sliderDisplay'), { target: { value: 2.5 } }); + + await waitFor(() => { + expect(screen.getByText('Temperature value should be between 0-2')).toBeInTheDocument(); + }); + + fireEvent.change(screen.getByRole('sliderDisplay'), { target: { value: -2.5 } }); + + await waitFor(() => { + expect(screen.getByText('Temperature value should be between 0-2')).toBeInTheDocument(); + }); +}); diff --git a/src/mocks/Assistants.ts b/src/mocks/Assistants.ts index c0ebc59a8..da83ddb2c 100644 --- a/src/mocks/Assistants.ts +++ b/src/mocks/Assistants.ts @@ -266,6 +266,7 @@ export const MOCKS = [ listOpenaiModels, getAssistant('1'), getAssistant('1'), + getAssistant('1'), getAssistant('2'), getAssistant('2'), getAssistant('2'), From 1a2921a7f0d4e5bad07b1da7cb109906012fc8fc Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Fri, 15 Nov 2024 11:50:31 +0530 Subject: [PATCH 16/21] fixed codacy issues --- .../Assistants/CreateAssistant/CreateAssistant.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx b/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx index 456011f66..0de0cd907 100644 --- a/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx +++ b/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx @@ -70,7 +70,10 @@ export const CreateAssistant = ({ currentId, setUpdateList, setCurrentId, update onCompleted: ({ assistant }) => { setAssistantId(assistant?.assistant?.assistantId); setName(assistant?.assistant?.name); - let modelValue = modelOptions?.find((item: any) => item.label === assistant?.assistant?.model); + console.log(modelOptions); + const modelValue = modelOptions?.find( + (item: { label: string }) => item.label === assistant?.assistant?.model + ); setModel(modelValue); setInstructions(assistant?.assistant?.instructions || ''); setOptions({ @@ -188,7 +191,7 @@ export const CreateAssistant = ({ currentId, setUpdateList, setCurrentId, update if (showConfirmation) { dialog = ( Date: Fri, 15 Nov 2024 11:53:58 +0530 Subject: [PATCH 17/21] removed unnecessary code --- src/containers/Assistants/CreateAssistant/CreateAssistant.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx b/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx index 0de0cd907..b2a2bd56f 100644 --- a/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx +++ b/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx @@ -70,7 +70,6 @@ export const CreateAssistant = ({ currentId, setUpdateList, setCurrentId, update onCompleted: ({ assistant }) => { setAssistantId(assistant?.assistant?.assistantId); setName(assistant?.assistant?.name); - console.log(modelOptions); const modelValue = modelOptions?.find( (item: { label: string }) => item.label === assistant?.assistant?.model ); From 4fd2eae19731b2e3b8ab4321fc0a2bf3cb452ff6 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Mon, 18 Nov 2024 21:55:21 +0530 Subject: [PATCH 18/21] made form consistent --- .../Onboarding/Steps/OrgDetails.tsx | 54 +++---------------- .../Onboarding/Steps/PaymentDetails.tsx | 34 +++++++----- .../Onboarding/Steps/SigningAuthority.tsx | 42 +++++++++------ 3 files changed, 53 insertions(+), 77 deletions(-) diff --git a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx index 358f2e8f8..c7731eef3 100644 --- a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx @@ -44,64 +44,22 @@ export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { const { t } = useTranslation(); - const firstLetterCapitalized = (value: string) => { - if (!value) return true; // Allow empty values to be handled by other validations - return /^[A-Z]/.test(value); - }; - const FormSchema = Yup.object().shape({ gstin: Yup.string().length(15, t('Invalid gst number')), 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') - .test( - 'first-letter-capitalized', - 'First letter must be capitalized', - firstLetterCapitalized - ), - state: Yup.string() - .required('State is required') - .test( - 'first-letter-capitalized', - 'First letter must be capitalized', - firstLetterCapitalized - ), - country: Yup.string() - .required('Country is required') - .test( - 'first-letter-capitalized', - 'First letter must be capitalized', - firstLetterCapitalized - ), + 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') - .test( - 'first-letter-capitalized', - 'First letter must be capitalized', - firstLetterCapitalized - ), - - state: Yup.string() - .required('State is required') - .test( - 'first-letter-capitalized', - 'First letter must be capitalized', - firstLetterCapitalized - ), - country: Yup.string() - .required('Country is required') - .test( - 'first-letter-capitalized', - 'First letter must be capitalized', - firstLetterCapitalized - ), + 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'), }), }); diff --git a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx index a00a53fbc..62d74b35a 100644 --- a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx @@ -14,7 +14,8 @@ import { FormStepProps } from './OrgDetails'; export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => { const { t } = useTranslation(); const [billing_frequency, setPaymentType] = useState('Annually'); - const [name, setName] = useState(''); + const [firstName, setFirstName] = useState(''); + const [lastName, setLastName] = useState(''); const [designation, setDesignation] = useState(''); const [phone, setPhone] = useState(''); const [formattedPhone, setFormattedPhone] = useState(''); @@ -24,19 +25,19 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => 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, @@ -64,10 +65,16 @@ 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: 'Last Name', + }, { component: Input, name: 'designation', @@ -86,9 +93,7 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => name: 'email', type: 'text', inputLabel: 'Email Address', - helperText: ( - Invoice will be sent to this email - ), + helperText: Invoice will be sent to this email, }, ], }, @@ -96,6 +101,7 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => const setPayload = (payload: any) => { const data = localStorage.getItem('registrationData'); + const { firstName, lastName } = payload; if (data) { let registrationData = JSON.parse(data); @@ -103,6 +109,7 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => finance_poc: { ...payload, phone: formattedPhone, + name: firstName + ' ' + lastName, }, registration_id: registrationData.registration_details.registration_id, org_id: registrationData.registration_details.org_id, @@ -115,9 +122,10 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => }; const setStates = (states: any) => { - const { name, designation, phone, email, billing_frequency } = states.finance_poc; + const { firstName, lastName, designation, phone, email, billing_frequency } = states.finance_poc; - setName(name); + setFirstName(firstName); + setLastName(lastName); setDesignation(designation); setPhone(phone); setFormattedPhone(phone); diff --git a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index 5519d513d..39c188962 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -14,17 +14,14 @@ interface SigningAuthorityProps extends FormStepProps { openReachOutToUs?: Function; } -export const SigningAuthority = ({ - handleStepChange, - openReachOutToUs, - saveData, -}: SigningAuthorityProps) => { +export const SigningAuthority = ({ handleStepChange, openReachOutToUs, saveData }: SigningAuthorityProps) => { const { t } = useTranslation(); const [submitterFirstName, setSubmitterFirstName] = useState(''); const [submitterLastName, setSubmitterLastName] = useState(''); const [submitterEmail, setSubmitterEmail] = useState(''); const [submitterDesignation, setSubmitterDesignation] = useState(''); - const [signingAuthorityName, setSigningAuthorityName] = useState(''); + const [signingAuthorityFirstName, setSigningAuthorityFirstName] = useState(''); + const [signingAuthorityLastName, setSigningAuthorityLastName] = useState(''); const [signingAuthorityDesignation, setSigningAuthorityDesignation] = useState(''); const [signingAuthorityEmail, setSigningAuthorityEmail] = useState(''); const [customError, setCustomError] = useState(null); @@ -47,15 +44,16 @@ export const SigningAuthority = ({ submitterDesignation: Yup.string() .required('Designation is required.') .max(25, t('Please enter not more than 25 characters')), - signingAuthorityName: Yup.string() - .required(t('Name is required.')) + 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.'), + 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.') @@ -71,7 +69,8 @@ export const SigningAuthority = ({ submitterLastName, submitterEmail, submitterDesignation, - signingAuthorityName, + signingAuthorityFirstName, + signingAuthorityLastName, signingAuthorityDesignation, signingAuthorityEmail, permissions, @@ -112,9 +111,15 @@ export const SigningAuthority = ({ children: [ { component: Input, - name: 'signingAuthorityName', + name: 'signingAuthorityFirstName', + type: 'text', + inputLabel: 'First Name', + }, + { + component: Input, + name: 'signingAuthorityLastName', type: 'text', - inputLabel: 'Name', + inputLabel: 'Last Name', }, { component: Input, @@ -151,7 +156,7 @@ export const SigningAuthority = ({ email: payload.submitterEmail, }, signing_authority: { - name: payload.signingAuthorityName, + name: payload.signingAuthorityFirstName + ' ' + payload.signingAuthorityLastName, designation: payload.signingAuthorityDesignation, email: payload.signingAuthorityEmail, }, @@ -169,12 +174,17 @@ export const SigningAuthority = ({ const setStates = (states: any) => { const { signing_authority, submitter } = states; + let name; + if (signing_authority.name) { + name = signing_authority.name.split(' '); + } setSubmitterFirstName(submitter?.first_name); setSubmitterLastName(submitter?.last_name); setSubmitterEmail(submitter?.email); setSubmitterDesignation(submitter?.designation); - setSigningAuthorityName(signing_authority?.name); + setSigningAuthorityFirstName(name[0]); + setSigningAuthorityLastName(name[1]); setSigningAuthorityDesignation(signing_authority?.designation); setSigningAuthorityEmail(signing_authority?.email); setPermissions({ support_staff_account: false, terms_agreed: false }); From 6f24ddf201225eac3141afe104302df87249f5a4 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Wed, 20 Nov 2024 14:11:45 +0530 Subject: [PATCH 19/21] updated deletion message --- src/containers/Assistants/CreateAssistant/CreateAssistant.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx b/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx index b2a2bd56f..c8488e8a1 100644 --- a/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx +++ b/src/containers/Assistants/CreateAssistant/CreateAssistant.tsx @@ -190,7 +190,7 @@ export const CreateAssistant = ({ currentId, setUpdateList, setCurrentId, update if (showConfirmation) { dialog = ( Date: Wed, 20 Nov 2024 14:51:12 +0530 Subject: [PATCH 20/21] fixed test case --- .../Organization/Onboarding/Form.test.tsx | 16 ++++++++----- .../Onboarding/Steps/OrgDetails.tsx | 4 ++-- .../Onboarding/Steps/PaymentDetails.tsx | 9 ++++---- .../Onboarding/Steps/SigningAuthority.tsx | 23 +++++++++++-------- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/containers/Organization/Onboarding/Form.test.tsx b/src/containers/Organization/Onboarding/Form.test.tsx index de86881a2..a331fb93a 100644 --- a/src/containers/Organization/Onboarding/Form.test.tsx +++ b/src/containers/Organization/Onboarding/Form.test.tsx @@ -170,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' } }); @@ -199,7 +200,8 @@ test('it should submit the form', async () => { submitterLastName, submitterDesignation, submitterEmail, - signingAuthorityName, + signingAuthorityFirstName, + signingAuthorityLastName, signingAuthorityDesignation, signingAuthorityEmail, ] = inputFieldssigningdetails; @@ -209,7 +211,8 @@ test('it should submit the form', async () => { 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' } }); @@ -281,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/Steps/OrgDetails.tsx b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx index c7731eef3..a761cb8fb 100644 --- a/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/OrgDetails.tsx @@ -162,8 +162,8 @@ export const OrgDetails = ({ handleStepChange, saveData }: FormStepProps) => { } }) .catch((data) => { - if (data.response.data.error.message) { - setCustomError(data.messages.global); + if (data?.response?.data?.error?.message) { + setCustomError(data?.response?.data?.error?.message); } setLoading(false); }); diff --git a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx index 62d74b35a..80512c1ef 100644 --- a/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx +++ b/src/containers/Organization/Onboarding/Steps/PaymentDetails.tsx @@ -102,10 +102,11 @@ 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, @@ -114,7 +115,7 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => 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; @@ -153,8 +154,8 @@ export const PaymentDetails = ({ handleStepChange, saveData }: FormStepProps) => } }) .catch((data) => { - if (data.response.data.error.message) { - setCustomError(data.messages.global); + if (data?.response?.data?.error?.message) { + setCustomError(data?.response?.data?.error?.message); } setLoading(false); }); diff --git a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index 39c188962..24c1422e1 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -24,7 +24,7 @@ export const SigningAuthority = ({ handleStepChange, openReachOutToUs, saveData const [signingAuthorityLastName, setSigningAuthorityLastName] = useState(''); const [signingAuthorityDesignation, setSigningAuthorityDesignation] = useState(''); const [signingAuthorityEmail, setSigningAuthorityEmail] = useState(''); - const [customError, setCustomError] = useState(null); + const [customError, setCustomError] = useState(null); const [permissions, setPermissions] = useState({ terms_agreed: false, @@ -175,16 +175,16 @@ export const SigningAuthority = ({ handleStepChange, openReachOutToUs, saveData const setStates = (states: any) => { const { signing_authority, submitter } = states; let name; - if (signing_authority.name) { - name = signing_authority.name.split(' '); + if (signing_authority?.name) { + name = signing_authority?.name.split(' '); } setSubmitterFirstName(submitter?.first_name); setSubmitterLastName(submitter?.last_name); setSubmitterEmail(submitter?.email); setSubmitterDesignation(submitter?.designation); - setSigningAuthorityFirstName(name[0]); - setSigningAuthorityLastName(name[1]); + setSigningAuthorityFirstName(name[0] || ''); + setSigningAuthorityLastName(name[1] || ''); setSigningAuthorityDesignation(signing_authority?.designation); setSigningAuthorityEmail(signing_authority?.email); setPermissions({ support_staff_account: false, terms_agreed: false }); @@ -204,11 +204,16 @@ export const SigningAuthority = ({ handleStepChange, openReachOutToUs, saveData setErrors(data.messages); } }) - .catch((data) => { - if (data.response.data.error.message) { - setCustomError(data.messages.global); - } + .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); + } }); }; From 91b9ad2bef49b8dfc23053da74f8d3c8ab6eeb27 Mon Sep 17 00:00:00 2001 From: Akansha Sakhre Date: Wed, 20 Nov 2024 14:57:25 +0530 Subject: [PATCH 21/21] fixed deepscan issues --- .../Organization/Onboarding/Steps/SigningAuthority.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx index 24c1422e1..6d6c60d61 100644 --- a/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx +++ b/src/containers/Organization/Onboarding/Steps/SigningAuthority.tsx @@ -174,17 +174,19 @@ export const SigningAuthority = ({ handleStepChange, openReachOutToUs, saveData const setStates = (states: any) => { const { signing_authority, submitter } = states; - let name; + let firstName; + let lastName; if (signing_authority?.name) { - name = signing_authority?.name.split(' '); + firstName = signing_authority?.name?.split(' ')[0]; + lastName = signing_authority?.name?.split(' ')[1]; } setSubmitterFirstName(submitter?.first_name); setSubmitterLastName(submitter?.last_name); setSubmitterEmail(submitter?.email); setSubmitterDesignation(submitter?.designation); - setSigningAuthorityFirstName(name[0] || ''); - setSigningAuthorityLastName(name[1] || ''); + setSigningAuthorityFirstName(firstName || ''); + setSigningAuthorityLastName(lastName || ''); setSigningAuthorityDesignation(signing_authority?.designation); setSigningAuthorityEmail(signing_authority?.email); setPermissions({ support_staff_account: false, terms_agreed: false });