/* eslint-disable no-param-reassign */
/* eslint-disable no-underscore-dangle */
/* eslint-disable max-len */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable import/no-extraneous-dependencies */
import React, { FormEventHandler, useEffect, useState } from 'react';
import { useForm, Controller, SubmitHandler } from 'react-hook-form';
import { Autocomplete, Box, TextField } from '@mui/material';
import IconSave from '@assets/icon-save.svg';
import * as yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
import { Col, Row } from 'react-bootstrap';
import {
fetchLitigantApplicationDetails,
lawFirmRegistrationDetailSelector,
setisValidRegistrationForm,
submitLitigantApplicationDetails,
} from '@redux/slices/law-firm-registration';
import { useDispatch, useSelector } from 'react-redux';
import { trackPromise } from 'react-promise-tracker';
import api from '@api/index';
import {
resetErrorState,
setErrorInfo,
} from '@redux/slices/will-personal-information';
import { dropDownSelector, fetchCountryList } from '@redux/slices/dropDowns';
import './style.scss';
import useIsdCodesList from '@utils/hooks/useIsdCodesList';
interface LitigantProbonoApplicant {
litigantGuid: string;
applicantName: string;
applicantAddress: string;
applicantTelephone: string;
applicantFax: string;
applicantMobile: string;
applicantEmail: string;
isdCodeApplicantMobile: string;
}
interface Props {
completed: { [k: number]: boolean };
handleComplete: () => void;
completedSteps: () => number;
totalSteps: () => number;
activeStep: number;
handleBack: () => void;
isLastStep: () => boolean;
}
const commonSchema = yup.object().shape({
applicantName: yup.string().required('Applicant Name is required'),
applicantEmail: yup
.string()
.email('Invalid email')
.required('Applicant Email Address is required'),
applicantAddress: yup.string().required('Address is required'),
applicantTelephone: yup
.string()
.required('Telephone number is required')
.matches(/^[0-9]{6,14}$/, 'Invalid telephone number'),
applicantMobile: yup.string().required('Mobile number is required'),
applicantFax: yup.string().required('Fax number is required'),
isdCodeApplicantMobile: yup.string().required('Isd Code is required'),
});
const draftSchema = yup.object().shape({
applicantName: yup.string().required('Applicant Name is required'),
applicantEmail: yup
.string()
.email('Invalid email')
.required('Applicant Email Address is required'),
});
function index({
completed,
handleComplete,
completedSteps,
totalSteps,
activeStep,
handleBack,
isLastStep,
}: Props) {
const [applicantMobile, setApplicantMobile] = useState<string>('');
const [isdCodeLabel, setIsdCodeLabel] = useState<any>('');
const [isdCode1, setIsdCode1] = useState<string>('');
const [flagForLitigantApplicant, setFlagForLitigantApplicant] = useState<boolean>(false);
const [isSubmitted, setIsSubmitted] = useState<boolean>(false);
const [isDraft, setIsDraft] = useState<boolean>(false);
const [submitBtn, setSubmitBtn] = useState(false);
const [emailValidation, setEmailValidation] = useState(false);
const [isNext, setIsNext] = useState<boolean | null>(null);
const dispatch = useDispatch();
const schema = isNext ? commonSchema : draftSchema;
const {
control,
handleSubmit,
reset,
setValue,
register,
clearErrors,
setError,
trigger,
formState: { errors },
} = useForm<LitigantProbonoApplicant>({
resolver: yupResolver(schema as yup.AnyObjectSchema),
defaultValues: {
// cityID: null, countryID: null, homeJurisdiction: null, phoneNo: '',
},
});
console.log('litiganterrors', errors);
console.log('isDraft', isDraft);
const { litigantGuid, litigantDetails, isValidRegistrationForm } = useSelector(lawFirmRegistrationDetailSelector);
const checkLitigantEmail = async (email: string) => {
console.log('litigantGuid', litigantGuid);
await dispatch(resetErrorState());
try {
// Make the API call here (e.g., using fetch or Axios)
const response: any = await trackPromise(
api.checkIfLitigantEmailRegistered(email, litigantGuid),
);
if (response?.data?.applicantEmalExists) {
setFlagForLitigantApplicant(true);
dispatch(setErrorInfo('Litigant Email already exists!'));
dispatch<any>(setisValidRegistrationForm(false));
// If the firm name already exists, set the error message for the Firm Name field
setError('applicantEmail', {
type: 'manual',
message: 'Litigant Email already exists',
});
} else {
dispatch<any>(setisValidRegistrationForm(true));
setFlagForLitigantApplicant(false);
// If the firm name is unique, clear the error message for the Firm Name field
clearErrors('applicantEmail');
}
} catch (error) {
console.error('Error making API call:', error);
}
};
// Utility function to filter out all IDs from the list
const filterList = (list: any[], condition: (item: any) => boolean) => list.filter((item: any) => {
if (condition(item)) {
return item;
}
return '';
});
// Get all dropdown lists from redux
const { countryList } = useSelector(dropDownSelector);
// Custom hooks for getting various list information
const isdCodesList = useIsdCodesList(countryList);
const onSubmit: SubmitHandler<LitigantProbonoApplicant> = async (
data: LitigantProbonoApplicant,
) => {
// setSubmitBtn(true);
// await checkLitigantEmail(data.applicantEmail);
await trigger(['applicantEmail']);
if (Object.keys(errors).length === 0) {
const formData: LitigantProbonoApplicant = {
litigantGuid,
applicantName: data.applicantName,
applicantAddress: data.applicantAddress,
applicantTelephone: data.applicantTelephone,
applicantFax: data.applicantFax,
applicantEmail: data.applicantEmail,
applicantMobile,
isdCodeApplicantMobile: isdCode1,
};
if (isValidRegistrationForm) {
await dispatch<any>(
submitLitigantApplicationDetails(formData, isDraft),
);
if (!isDraft) handleComplete();
if (!isDraft) reset();
window.scrollTo(0, 0);
}
}
};
const submitFromSave = async (data: any) => {
console.log('Litigant Data', data);
const litigantDraft:LitigantProbonoApplicant = {
litigantGuid,
applicantName: data.applicantName,
applicantAddress: data.applicantAddress,
applicantTelephone: data.applicantTelephone,
applicantFax: data.applicantFax,
applicantEmail: data.applicantEmail,
applicantMobile,
isdCodeApplicantMobile: isdCode1,
};
await dispatch<any>(
submitLitigantApplicationDetails(litigantDraft, isDraft),
);
};
const emailValidationRegex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
React.useEffect(() => {
window.scrollTo(0, 0);
dispatch<any>(fetchCountryList());
}, []);
useEffect(() => {
if (litigantGuid !== '') {
dispatch<any>(fetchLitigantApplicationDetails(litigantGuid));
}
}, [litigantGuid]);
const handleIsdCode1Change = (e: any, val: any) => {
const isdCode1Value = val?.countryID;
const isdCode1Label = val?.label;
setIsdCode1(isdCode1Value);
setIsdCodeLabel(isdCode1Label);
};
useEffect(() => {
if (litigantDetails) {
const isCode = filterList(
isdCodesList,
(item: any) => item.countryID === litigantDetails?.isdCodeApplicantMobile,
);
console.log('isdCode', isCode);
setValue('applicantName', litigantDetails.applicantName);
setValue('applicantAddress', litigantDetails.applicantAddress);
setValue('applicantTelephone', litigantDetails.applicantTelephone);
// setValue('iSDCodeApplicantTelephone', litigantDetails.isdCodeApplicantMobile);
setValue('applicantFax', litigantDetails.applicantFax);
setValue('applicantMobile', litigantDetails.applicantMobile);
setValue('applicantEmail', litigantDetails.applicantEmail);
setValue(
'isdCodeApplicantMobile',
litigantDetails.isdCodeApplicantMobile,
);
setApplicantMobile(litigantDetails.applicantMobile);
setIsdCode1(isCode[0]?.countryID);
setIsdCodeLabel(isCode[0]?.label);
}
}, [litigantDetails]);
const handlePhoneNumber1Change = (e: any) => {
const { value } = e.target;
// eslint-disable-next-line no-param-reassign
e.target.value = value.replace(/[^0-9]/g, '');
setApplicantMobile(e.target.value);
};
const capitalizeWords = (text: string) => text
.split(' ')
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
.join(' ');
const handleTelephoneChange = (e: any) => {
const { value } = e.target;
// eslint-disable-next-line no-param-reassign
e.target.value = value.replace(/[^0-9]/g, '');
setValue('applicantTelephone', e.target.value);
};
const handleFaxChange = (e: any) => {
const { value } = e.target;
// eslint-disable-next-line no-param-reassign
e.target.value = value.replace(/[^0-9]/g, '');
setValue('applicantFax', e.target.value);
};
const handleCursor: FormEventHandler<HTMLInputElement> = (e: {
currentTarget: any;
}) => {
const input = e.currentTarget;
const cursorPosition = input.selectionStart || 0;
input.value = capitalizeWords(
input.value
.trimStart()
.replace(/\s+/g, ' ')
.replace(/[^a-zA-Z\W ]/g, ''),
);
input.setSelectionRange(cursorPosition, cursorPosition);
};
const handleInput: FormEventHandler<HTMLInputElement> = (e: {
currentTarget: any;
}) => {
setSubmitBtn(false);
if (emailValidationRegex.test(e.currentTarget.value)) {
setEmailValidation(false);
} else {
setEmailValidation(true);
}
const input = e.currentTarget;
const cursorPosition = input.selectionStart || 0;
input.value = input.value.trim();
input.setSelectionRange(cursorPosition, cursorPosition);
};
const handleInputForAddrress = (e: { currentTarget: any }) => {
const input = e.currentTarget;
const cursorPosition = input.selectionStart || 0;
input.value = capitalizeWords(input.value.trimStart());
input.setSelectionRange(cursorPosition, cursorPosition);
};
return (
<form
className="form"
onSubmit={handleSubmit(isNext ? onSubmit : submitFromSave)}
>
<h1>Application Details</h1>
<span className="mb-3">
Please indicate whether you will be the claimant or respondent
</span>
<div className="row" style={{ paddingTop: '40px' }}>
<div className="col-md-4">
<div className="mb-3">
<label htmlFor="name" className="form-label firmName-label w-100">
Name*
</label>
<input
type="text"
className={`${
errors?.applicantName
? 'validate-field'
: 'form-control'
} `}
onInput={handleCursor}
style={{ textTransform: 'capitalize' }}
id="applicantName"
placeholder="Enter Name"
// onChange={(e) => setState(e.target.value)}
{...register('applicantName', {
required: true,
})}
/>
</div>
</div>
<div className="col-md-4">
<div className="mb-3">
<label htmlFor="name" className="form-label firmName-label w-100">
Telephone*
</label>
<input
type="text"
max={15}
className={`${
errors?.applicantTelephone && isSubmitted
? 'validate-field'
: 'form-control'
} `}
id="applicantTelephone"
placeholder="Enter Telephone Number"
{...register('applicantTelephone', {
required: true,
})}
onChange={handleTelephoneChange}
/>
</div>
</div>
</div>
<div className="row">
<div className="col-md-4">
<div className="mb-3">
<label
htmlFor="applicantEmail"
className="form-label applicantEmail-label w-100"
>
Email*
</label>
<Controller
name="applicantEmail"
control={control}
render={({ field }) => (
<input
type="text"
className={`${
errors.applicantEmail
|| flagForLitigantApplicant
|| (emailValidation && submitBtn)
? 'validate-field'
: 'form-control'
}`}
{...field}
{...register('applicantEmail', {
required: true,
pattern: {
value: emailValidationRegex,
message: 'Please enter a valid email',
},
})}
id="applicantEmail"
aria-describedby="emailHelp"
placeholder="Enter Email Address"
onInput={handleInput}
onBlur={() => checkLitigantEmail(field.value)}
/>
)}
rules={{
required: 'Firm Email is required',
pattern: {
value: emailValidationRegex,
message: 'Please enter a valid email',
},
}}
/>
{/* {errors.firmEmail && (
<p className="error-message">{errors.firmEmail.message}</p>
)} */}
</div>
</div>
<div className="col-md-4">
<div className="mb-3">
<label htmlFor="phoneNumber" className="form-label w-100">
Mobile*
</label>
<div className="d-flex">
<Autocomplete
id="country-select-demo"
// sx={{ width: 1000 }}
options={isdCodesList}
autoHighlight
// value={isdCodeLabel}
value={
isdCodesList.find(
(option: any) => option.label === isdCodeLabel,
) || null
}
disableClearable
getOptionLabel={(option: any) => `${option.label} ${option.countryName}`}
// getOptionLabel={(option: any) => option?.countryName}
renderOption={(props, option) => (
<Box
component="li"
sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
{...props}
>
<img
loading="lazy"
width="20"
src={`https://flagcdn.com/w20/${option?.countryCode?.toLowerCase()}.png`}
srcSet={`https://flagcdn.com/w40/${option?.countryCode?.toLowerCase()}.png 2x`}
alt=""
/>
{option?.countryName}
{' '}
(
{option?.label}
)
</Box>
)}
renderInput={(params) => (
<TextField
{...params}
placeholder="+97"
// value={isdCodeLabel || ''}
inputProps={{
...params.inputProps,
autoComplete: 'new-password', // disable autocomplete and autofill
}}
{...register('isdCodeApplicantMobile', {
required: true,
})}
error={
errors?.isdCodeApplicantMobile
&& (isdCodeLabel === '' || isdCodeLabel === undefined)
}
className="isdcode-field"
/>
)}
className="isdcode-box"
onChange={(e, newVal: any) => handleIsdCode1Change(e, newVal)}
/>
<input
type="text"
placeholder="Enter Phone Number"
maxLength={15}
// className={`${
// isSubmitted
// && (applicantMobile === '' || applicantMobile === undefined)
// ? 'phonenumber-input-error'
// : 'form-control-phonenumber'
// } `}
className={`${
errors?.applicantMobile && isSubmitted && (applicantMobile === '' || applicantMobile === undefined)
? 'phonenumber-input-error'
: 'form-control-phonenumber'
} `}
id="applicantMobile"
aria-describedby="applicantMobileHelp"
{...register('applicantMobile', {
required: true,
})}
onChange={(e: any) => handlePhoneNumber1Change(e)}
/>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-md-4">
<div className="mb-3">
<label
htmlFor="applicantFax"
className="form-label applicantFax-label w-100"
>
Fax*
</label>
<input
type="text"
className={`${
errors?.applicantFax && isSubmitted
? 'validate-field'
: 'form-control'
} `}
id="applicantFax"
placeholder="Enter Fax Number"
{...register('applicantFax', {
required: true,
})}
onChange={handleFaxChange}
/>
</div>
</div>
</div>
<div className="row">
<div className="col-md-8">
<div className="mb-3">
<label
htmlFor="applicantAddress"
className="form-label firmName-label w-100"
>
Address*
</label>
<textarea
className={`${
errors?.applicantAddress
? 'validate-field'
: 'form-control'
} `}
id="applicantAddress"
placeholder="Enter Address*"
onInput={handleInputForAddrress}
{...register('applicantAddress', {
required: true,
})}
/>
</div>
</div>
</div>
<Row className="mb-3 pt-3">
<Col md={8}>
<button
type="submit"
className="next-button"
onClick={() => {
setIsSubmitted(true);
setIsDraft(false);
setSubmitBtn(true);
setIsNext(true);
}}
>
{isLastStep() ? 'Submit' : 'Next'}
</button>
<button
type="submit"
className="save-button"
onClick={() => {
setIsSubmitted(true);
setIsDraft(true);
setSubmitBtn(true);
setIsNext(false);
}}
>
<img src={IconSave} alt="" />
Save
</button>
</Col>
<Col className="mr-auto" md={4}>
{activeStep !== 0 && (
<button type="button" className="back-button" onClick={handleBack}>
Back
</button>
)}
</Col>
</Row>
</form>
);
}
export default index;
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter