Created
June 25, 2025 13:25
-
-
Save hakimnuwair/d85b0d572eafd40f180880c932eb1cd4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div className="add-modal-overlay"> | |
<Formik | |
initialValues={formValues} | |
enableReinitialize | |
validateOnChange={true} | |
validationSchema={getValidationSchema(detailsStep)} | |
onSubmit={(values, actions) => handleNextStep(values, actions)} | |
> | |
{({ | |
values, | |
errors, | |
touched, | |
handleChange, | |
handleBlur, | |
setFieldValue, | |
setFieldTouched, | |
}) => ( | |
<Form | |
onClick={(e) => e.stopPropagation()} | |
className="add-modal-content" | |
style={ | |
detailsStep === 4 && values?.isDependents == "true" | |
? { maxWidth: "1370px" } | |
: undefined | |
} | |
> | |
<div className="add-modal-header"> | |
<span className="add-modal-title"> | |
{empPublicId ? t("Edit Employee") : t("Add New Employee")} | |
</span> | |
<div | |
className="add-modal-icon-container" | |
onClick={onCloseWarning} | |
> | |
<img src={cancelIcon} alt="cancel icon" /> | |
</div> | |
</div> | |
<div className="add-subheader"> | |
<div className="add-steps-container"> | |
<div | |
className={`add-step-content ${ | |
detailsStep === 1 ? "active" : "" | |
}`} | |
> | |
<div className={`add-step-no`}>1</div> | |
<span className="add-step-heading">{t("Personal Info")}</span> | |
</div> | |
<div | |
className={`add-step-content ${ | |
detailsStep === 2 ? "active" : "" | |
}`} | |
> | |
<div className="add-step-no">2</div> | |
<span className="add-step-heading"> | |
{t("Employment Info")} | |
</span> | |
</div> | |
<div | |
className={`add-step-content ${ | |
detailsStep === 3 ? "active" : "" | |
}`} | |
> | |
<div className="add-step-no">3</div> | |
<span className="add-step-heading">{t("Documents")}</span> | |
{console.log( | |
"dobhijri, dobGregorian, value:", | |
values.dobHijri, | |
values?.dobGregorian | |
)} | |
</div> | |
<div | |
className={`add-step-content ${ | |
detailsStep === 4 ? "active" : "" | |
}`} | |
> | |
<div className="add-step-no">4</div> | |
<span className="add-step-heading"> | |
{t("Dependents Info")} | |
</span> | |
</div> | |
</div> | |
{detailsStep !== 3 && !empPublicId && ( | |
<p | |
style={detailsStep === 4 ? { maxWidth: "752px" } : undefined} | |
className="add-desc" | |
> | |
{t( | |
"Fill in the details below to add a new employee to your team. Once added, you can manage their profile, roles, and permissions seamlessly." | |
)} | |
</p> | |
)} | |
</div> | |
{dataLoading ? ( | |
<div className=""> | |
<PageLoader /> | |
</div> | |
) : ( | |
<> | |
<div className="add-body"> | |
{detailsStep === 1 ? ( | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Personal Info")} | |
</h3> | |
{/* <div className="relative"> | |
<select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> | |
<span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> | |
</div> */} | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="firstName"> | |
{t("Employee First Name (EN)")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<input | |
id="firstName" | |
name="firstName" | |
className="add-input" | |
placeholder={t("First Name (EN)")} | |
value={values?.firstName} | |
onChange={(e) => { | |
setFieldValue("firstName", e.target.value); | |
// setFieldTouched("firstName", true); | |
}} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="firstName" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="firstNameArb" | |
> | |
{t("Employee First Name (AR)")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<input | |
id="firstNameArb" | |
name="firstNameArb" | |
className="add-input" | |
placeholder={t("First Name (AR)")} | |
value={values?.firstNameArb} | |
onChange={(e) => { | |
setFieldValue("firstNameArb", e.target.value); | |
// setFieldTouched("firstNameArb", true); | |
}} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="firstNameArb" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="secondName"> | |
{t("Employee Second Name (EN)")} | |
</label> | |
</div> | |
<input | |
id="secondName" | |
name="secondName" | |
className="add-input" | |
placeholder={t("Second Name (EN)")} | |
value={values?.secondName} | |
onChange={(e) => | |
setFieldValue("secondName", e.target.value) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="secondName" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="secondName"> | |
{t("Employee Second Name (AR)")} | |
</label> | |
</div> | |
<input | |
id="secondNameArb" | |
name="secondNameArb" | |
className="add-input" | |
placeholder={t("Second Name (AR)")} | |
value={values?.secondNameArb} | |
onChange={(e) => | |
setFieldValue("secondNameArb", e.target.value) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="secondNameArb" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="thirdName"> | |
{t("Employee Third Name (EN)")} | |
</label> | |
</div> | |
<input | |
id="thirdName" | |
name="thirdName" | |
className="add-input" | |
placeholder={t("Third Name (EN)")} | |
value={values?.thirdName} | |
onChange={(e) => | |
setFieldValue("thirdName", e.target.value) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="thirdName" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="thirdNameArb" | |
> | |
{t("Employee Third Name (AR)")} | |
</label> | |
</div> | |
<input | |
id="thirdNameArb" | |
name="thirdNameArb" | |
className="add-input" | |
placeholder={t("Third Name (AR)")} | |
value={values?.thirdNameArb} | |
onChange={(e) => | |
setFieldValue("thirdNameArb", e.target.value) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="thirdNameArb" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="lastName"> | |
{t("Employee Last Name (EN)")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<input | |
id="lastName" | |
name="lastName" | |
className="add-input" | |
placeholder={t("Last Name (EN)")} | |
value={values?.lastName} | |
onChange={(e) => | |
setFieldValue("lastName", e.target.value) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="lastName" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="lastNameArb" | |
> | |
{t("Employee Last Name (AR)")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<input | |
id="lastNameArb" | |
name="lastNameArb" | |
className="add-input" | |
placeholder={t("Last Name (EN)")} | |
value={values?.lastNameArb} | |
onChange={(e) => | |
setFieldValue("lastNameArb", e.target.value) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="lastNameArb" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="phone"> | |
{t("Contact Number")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div>{" "} | |
<div | |
className="phone-input-container" | |
style={{ display: "flex" }} | |
> | |
<input | |
id="phone" | |
name="phone" | |
className="add-input" | |
placeholder={t("Enter Saudi Mobile Number")} | |
value={values?.phone} | |
onChange={(e) => | |
handlePhoneChange(e, setFieldValue) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
</div> | |
<ValidateIndicators | |
isSearching={phoneSearch.isSearching} | |
validationResult={phoneSearch.validationResult} | |
error={phoneSearch.error} | |
/> | |
<CustomErrorMessage | |
name="phone" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="email"> | |
{t("Email")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.email || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<input | |
id="email" | |
name="email" | |
className="add-input" | |
placeholder={t("Enter Email")} | |
value={values?.email} | |
onChange={(e) => | |
handleEmailChange(e, setFieldValue) | |
} | |
onBlur={handleBlur} | |
/> | |
)} | |
</div> | |
<ValidateIndicators | |
isSearching={emailSearch.isSearching} | |
validationResult={emailSearch.validationResult} | |
error={emailSearch.error} | |
/> | |
<CustomErrorMessage | |
name="email" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="dobGregorian" | |
> | |
{t("Date Of Birth (Gregorian)")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="dobGregorian" | |
name="dobGregorian" | |
className={`add-wrap-input ${ | |
!values?.dobGregorian || | |
values.dobGregorian === "DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values?.dobGregorian | |
? formatDateToYYYYMMDD(values.dobGregorian) | |
: "" | |
} | |
onChange={(e) => { | |
convertGregorianToHijri( | |
e.target.value, | |
setFieldValue, | |
setDobGregorianError | |
); | |
setFieldValue("dobGregorian", e.target.value); | |
}} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="dobGregorian" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="dobHijri"> | |
{t("Date Of Birth (Hijri)")} | |
</label> | |
</div> | |
<div className="add-input-wrapper"> | |
<HijriDatePicker | |
value={ | |
values.dobHijri | |
? convertAndFormatHijriDate(values.dobHijri) | |
: "" | |
} // Pass the Formik value | |
onChange={(date) => { | |
convertHijriToGregorian( | |
date, | |
setFieldValue, | |
setDobHijriError | |
); | |
setFieldValue("dobHijri", date); // Update Formik value | |
}} | |
onBlur={handleBlur} | |
/> | |
{/* <img | |
src={dateIcon} | |
alt="date icon" | |
className="add-input-in" | |
/> */} | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="dobHijri" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="religion"> | |
{t("Religion")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<AsyncSelect | |
id="religion" | |
name="religion" | |
value={values.religion} | |
onChange={(selectedOption) => | |
setFieldValue("religion", selectedOption) | |
} | |
loadOptions={onSearchReligionDebounce} | |
defaultOptions={religionOptions} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select religion")} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="religion" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label"> | |
{t("Marital Status")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-radio-input-container"> | |
<div className="add-radio-container"> | |
<input | |
id="married" | |
type="radio" | |
name="maritalStatus" | |
className="add-radio-input" | |
value="Married" // Set the value directly | |
onChange={(e) => | |
setFieldValue( | |
"maritalStatus", | |
e.target.value | |
) | |
} | |
checked={values?.maritalStatus === "Married"} // Bind checked state | |
/> | |
<label htmlFor="married" className="add-label"> | |
{t("Married")} | |
</label> | |
</div> | |
<div className="add-radio-container"> | |
<input | |
id="single" | |
type="radio" | |
name="maritalStatus" | |
className="add-radio-input" | |
value="Single" | |
onChange={(e) => | |
setFieldValue( | |
"maritalStatus", | |
e.target.value | |
) | |
} | |
checked={values?.maritalStatus === "Single"} // Bind checked state | |
/> | |
<label htmlFor="single" className="add-label"> | |
{t("Single")} | |
</label> | |
</div> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="maritalStatus" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label">{t("Gender")}</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-radio-input-container"> | |
<div className="add-radio-container"> | |
<input | |
id="Male" | |
type="radio" | |
name="gender" | |
className="add-radio-input" | |
value="Male" | |
onChange={(e) => | |
setFieldValue("gender", e.target.value) | |
} | |
checked={values?.gender === "Male"} | |
/> | |
<label htmlFor="Male" className="add-label"> | |
{t("Male")} | |
</label> | |
</div> | |
<div className="add-radio-container"> | |
<input | |
id="Female" | |
type="radio" | |
name="gender" | |
className="add-radio-input" | |
value="Female" | |
onChange={(e) => | |
setFieldValue("gender", e.target.value) | |
} | |
checked={values?.gender === "Female"} | |
/> | |
<label htmlFor="Female" className="add-label"> | |
{t("Female")} | |
</label> | |
</div> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="gender" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label"> | |
{t("Citizen")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-radio-input-container"> | |
<div className="add-radio-container"> | |
<input | |
id="yes" | |
type="radio" | |
name="citizen" | |
className="add-radio-input" | |
value="true" | |
onChange={(e) => | |
setFieldValue("citizen", e.target.value) | |
} | |
checked={values?.citizen === "true"} | |
/> | |
<label htmlFor="yes" className="add-label"> | |
{t("Yes")} | |
</label> | |
</div> | |
<div className="add-radio-container"> | |
<input | |
id="no" | |
type="radio" | |
name="citizen" | |
className="add-radio-input" | |
value="false" | |
onChange={(e) => | |
setFieldValue("citizen", e.target.value) | |
} | |
checked={values?.citizen === "false"} | |
/> | |
<label htmlFor="false" className="add-label"> | |
{t("No")} | |
</label> | |
</div> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="citizen" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
{values?.citizen === "true" ? ( | |
<> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="nationalId" | |
> | |
{t("National ID")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<input | |
id="nationalId" | |
name="nationalId" | |
className="add-input" | |
placeholder={t("Enter National ID")} | |
value={values?.nationalId} | |
onChange={(e) => | |
handleNationalIdChange(e, setFieldValue) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<ValidateIndicators | |
isSearching={nationalIdSearch.isSearching} | |
validationResult={ | |
nationalIdSearch.validationResult | |
} | |
error={nationalIdSearch.error} | |
/> | |
<CustomErrorMessage | |
name="nationalId" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</> | |
) : ( | |
<> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="nationality" | |
> | |
{t("Nationality")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<AsyncSelect | |
id="nationality" | |
name="nationality" | |
value={values.nationality} | |
onChange={(selectedOption) => | |
setFieldValue("nationality", selectedOption) | |
} | |
loadOptions={loadOptions} | |
defaultOptions={countryOptions} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select nationality")} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="nationality" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</> | |
)} | |
</div> | |
</div> | |
) : detailsStep === 2 ? ( | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Employment Information")} | |
</h3> | |
<div className="relative"> | |
{/* <select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> */} | |
{/* <span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> */} | |
</div> | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="branch"> | |
{t("Branch / Location")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.branch?.label || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<AsyncSelect | |
id="branch" | |
name="branch" | |
value={values.branch} | |
onChange={(selectedOption) => | |
setFieldValue("branch", selectedOption) | |
} | |
loadOptions={onSearchBranchDebounce} | |
defaultOptions={branchOptions} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select Branch")} | |
/> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="branch" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="role"> | |
{t("Role")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.role?.label || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<AsyncSelect | |
id="role" | |
name="role" | |
value={values.role} | |
onChange={(selectedOption) => | |
setFieldValue("role", selectedOption) | |
} | |
loadOptions={onSearchRoleDebounce} | |
defaultOptions={roleOptions} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select Role")} | |
/> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="role" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="jobTitle"> | |
{t("Job Title")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.jobTitle?.label || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<AsyncSelect | |
id="jobTitle" | |
name="jobTitle" | |
value={values.jobTitle} | |
onChange={(selectedOption) => | |
setFieldValue("jobTitle", selectedOption) | |
} | |
loadOptions={onSearchJobTitleDebounce} | |
defaultOptions={jobTitleOptions} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select Job Title")} | |
/> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="jobTitle" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="designation" | |
> | |
{t("Designation")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.designation?.label || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<AsyncSelect | |
id="designation" | |
name="designation" | |
value={values.designation} | |
onChange={(selectedOption) => | |
setFieldValue("designation", selectedOption) | |
} | |
loadOptions={onSearchDesignationDebounce} | |
defaultOptions={designationOptions} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select Designation")} | |
/> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="designation" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="department"> | |
{t("Department")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.department?.label || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<AsyncSelect | |
id="department" | |
name="department" | |
value={values.department} | |
onChange={(selectedOption) => | |
setFieldValue("department", selectedOption) | |
} | |
loadOptions={onSearchDepartmentDebounce} | |
defaultOptions={departmentOptions} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select Department")} | |
/> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="department" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="reportingTo" | |
> | |
{t("Reporting To")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.reportingTo?.label || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<AsyncSelect | |
id="reportingTo" | |
name="reportingTo" | |
value={values.reportingTo} | |
onChange={(selectedOption) => | |
setFieldValue("reportingTo", selectedOption) | |
} | |
loadOptions={onSearchReportingToDebounce} | |
defaultOptions={reportingTo} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select Manager")} | |
/> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="reportingTo" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="joiningDate" | |
> | |
{t("Joining Date")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.joiningDate || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="joiningDate" | |
name="joiningDate" | |
className={`add-wrap-input ${ | |
!values?.joiningDate || | |
values.joiningDate === "DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values?.joiningDate | |
? formatDateToYYYYMMDD(values.joiningDate) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue("joiningDate", e.target.value) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="joiningDate" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="jobGrade"> | |
{t("Job Grade")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.jobGrade || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<input | |
id="jobGrade" | |
name="jobGrade" | |
className="add-input" | |
placeholder={t("Enter Job Grade")} | |
value={values?.jobGrade} | |
onChange={(e) => | |
setFieldValue("jobGrade", e.target.value) | |
} | |
onBlur={handleBlur} | |
/> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="jobGrade" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="contractType" | |
> | |
{t("Contract Type")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.contractType?.label || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<AsyncSelect | |
id="contractType" | |
name="contractType" | |
value={values.contractType} | |
onChange={(selectedOption) => | |
setFieldValue("contractType", selectedOption) | |
} | |
loadOptions={loadContractTypeOptions} | |
defaultOptions={contractType} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select Contract Type")} | |
/> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="contractType" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="probationPeriod" | |
> | |
{t("Probation Period")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.probationPeriod | |
? `${values.probationPeriod} days` | |
: "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<input | |
id="probationPeriod" | |
name="probationPeriod" | |
className="add-input" | |
placeholder={t( | |
"Enter Probation Period in Days" | |
)} | |
type="number" | |
min="1" | |
max="180" | |
value={values?.probationPeriod} | |
onChange={(e) => { | |
const value = e.target.value; | |
if ( | |
/^\d*$/.test(value) && | |
Number(value) <= 180 | |
) { | |
setFieldValue("probationPeriod", value); | |
} | |
}} | |
onBlur={handleBlur} | |
/> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="probationPeriod" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="employementType" | |
> | |
{t("Employment Type")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.employmentType?.label || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<AsyncSelect | |
id="employmentType" | |
name="employmentType" | |
value={values.employmentType} | |
onChange={(selectedOption) => | |
setFieldValue( | |
"employmentType", | |
selectedOption | |
) | |
} | |
loadOptions={loadEmploymentTypeOptions} | |
defaultOptions={employmentType} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select Employment Type")} | |
/> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="employmentType" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
</div> | |
) : detailsStep === 3 ? ( | |
<> | |
<div className="add-tabs-container"> | |
{docsTabs | |
?.filter((tab) => { | |
if (values?.citizen === "true") { | |
return tab !== "Iqama" && tab !== "Visa"; // Hide 'iqama' and 'visa' if citizen is true | |
} else { | |
return tab !== "National ID"; // hide national id for non-citizen | |
} | |
}) | |
.map((tab, index) => ( | |
<div | |
key={tab} | |
className={`add-tab ${ | |
documentTab === tab ? "active" : "" | |
}`} | |
// onClick={() => setDocumnetTab(tab)} | |
> | |
{t(tab)} | |
</div> | |
))} | |
</div> | |
{documentTab === "Salary Details" ? ( | |
<> | |
<div className="add-details-type-container"></div> | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Salary Details")} | |
</h3> | |
<div className="relative"> | |
{/* <select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> */} | |
{/* <span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> */} | |
</div> | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="basicPay" | |
> | |
{t("Basic Pay")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.basicPay | |
? `${values.basicPay} SAR` | |
: "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="basicPay" | |
name="basicPay" | |
className="add-wrap-input" | |
placeholder="0" | |
maxLength={10} | |
value={values?.basicPay} | |
onChange={(e) => | |
setFieldValue( | |
"basicPay", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<span className="add-input-in"> | |
{t("SAR")} | |
</span> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="basicPay" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="housingAllows" | |
> | |
{t("Housing Allows")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.housingAllows | |
? `${values.housingAllows} SAR` | |
: "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="housingAllows" | |
name="housingAllows" | |
className="add-wrap-input" | |
placeholder="0" | |
maxLength={10} | |
value={values?.housingAllows} | |
onChange={(e) => | |
setFieldValue( | |
"housingAllows", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<span className="add-input-in"> | |
{t("SAR")} | |
</span> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="housingAllows" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="transportAllows" | |
> | |
{t("Transport Allows")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.transportAllows | |
? `${values.transportAllows} SAR` | |
: "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="transportAllows" | |
name="transportAllows" | |
className="add-wrap-input" | |
placeholder="0" | |
maxLength={10} | |
value={values?.transportAllows} | |
onChange={(e) => | |
setFieldValue( | |
"transportAllows", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<span className="add-input-in"> | |
{t("SAR")} | |
</span> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="transportAllows" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="foodAllows" | |
> | |
{t("Food Allows")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.foodAllows | |
? `${values.foodAllows} SAR` | |
: "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="foodAllows" | |
name="foodAllows" | |
className="add-wrap-input" | |
placeholder="0" | |
maxLength={10} | |
value={values?.foodAllows} | |
onChange={(e) => | |
setFieldValue( | |
"foodAllows", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<span className="add-input-in"> | |
{t("SAR")} | |
</span> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="foodAllows" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="otherAllows" | |
> | |
{t("Other Allows")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.otherAllows | |
? `${values.otherAllows} SAR` | |
: "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="otherAllows" | |
name="otherAllows" | |
className="add-wrap-input" | |
placeholder="0" | |
maxLength={10} | |
value={values?.otherAllows} | |
onChange={(e) => | |
setFieldValue( | |
"otherAllows", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<span className="add-input-in"> | |
{t("SAR")} | |
</span> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="otherAllows" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
</div> | |
{values.citizen === "true" && ( | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Gosi Deduction")} | |
</h3> | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="basicPay" | |
> | |
{t("Basic Pay")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.basicPay | |
? `${values.basicPay} SAR` | |
: "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="basicPay" | |
name="basicPay" | |
className="add-wrap-input" | |
placeholder="0" | |
maxLength={10} | |
value={values?.basicPay} | |
onChange={(e) => | |
setFieldValue( | |
"basicPay", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<span className="add-input-in"> | |
{t("SAR")} | |
</span> | |
</div> | |
)} | |
</div> | |
{values.citizen === "true" && | |
!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="basicPay" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="housingAllows" | |
> | |
{t("Housing Allows")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.housingAllows | |
? `${values.housingAllows} SAR` | |
: "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="housingAllows" | |
name="housingAllows" | |
className="add-wrap-input" | |
placeholder="0" | |
maxLength={10} | |
value={values?.housingAllows} | |
onChange={(e) => | |
setFieldValue( | |
"housingAllows", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<span className="add-input-in"> | |
{t("SAR")} | |
</span> | |
</div> | |
)} | |
</div> | |
{values.citizen === "true" && | |
!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="housingAllows" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="gosiDeduction" | |
> | |
{t("Gosi Deduction")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.gosiDeduction | |
? `${values.gosiDeduction}%` | |
: "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="gosiDeduction" | |
name="gosiDeduction" | |
className="add-wrap-input" | |
placeholder="0" | |
maxLength={10} | |
value={values?.gosiDeduction} | |
onChange={(e) => | |
setFieldValue( | |
"gosiDeduction", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<span className="add-input-in">%</span> | |
</div> | |
)} | |
</div> | |
{values.citizen === "true" && | |
!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="gosiDeduction" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="deductionAmount" | |
> | |
{t("Deduction Amount")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.deductionAmount | |
? `${values.deductionAmount} SAR` | |
: "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
disabled={true} | |
id="deductionAmount" | |
name="deductionAmount" | |
className="add-wrap-input" | |
placeholder="0" | |
maxLength={10} | |
value={values?.deductionAmount} | |
onChange={(e) => | |
setFieldValue( | |
"deductionAmount", | |
e.target.value | |
) | |
} | |
/> | |
<span className="add-input-in"> | |
{t("SAR")} | |
</span> | |
</div> | |
)} | |
</div> | |
{values.citizen === "true" && | |
!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="deductionAmount" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
</div> | |
)} | |
<SalaryComponent | |
totalSalary={totalSalary} | |
handleSetTotalSalary={handleSetTotalSalary} | |
values={values} | |
setFieldValue={setFieldValue} | |
/> | |
</> | |
) : ( | |
<> | |
{documentTab === "Iqama" ? ( | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Iqama")} | |
</h3> | |
<div className="relative"> | |
{/* <select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> */} | |
{/* <span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> */} | |
</div> | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="iqamaProfession" | |
> | |
{t("Iqama Profession")} | |
</label> | |
{values.citizen === "false" && ( | |
<span className="add-req-mark">*</span> | |
)} | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.iqamaProfession || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="iqamaProfession" | |
name="iqamaProfession" | |
className="add-input" | |
placeholder={t( | |
"Enter Iqama Profession" | |
)} | |
value={values?.iqamaProfession} | |
onChange={(e) => | |
setFieldValue( | |
"iqamaProfession", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{values.citizen === "false" && | |
!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="iqamaProfession" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="iqamaId" | |
> | |
{t("Iqama ID")} | |
</label> | |
{values.citizen === "false" && ( | |
<span className="add-req-mark">*</span> | |
)} | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.iqamaId || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="iqamaId" | |
name="iqamaId" | |
className="add-wrap-input" | |
placeholder={t("Enter Iqama ID")} | |
value={values?.iqamaId} | |
onChange={(e) => | |
handleIqamaIdChange( | |
e, | |
setFieldValue | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{values.citizen === "false" && | |
!currentEmployeeEditing && ( | |
<> | |
<ValidateIndicators | |
isSearching={ | |
iqamaIdSearch.isSearching | |
} | |
validationResult={ | |
iqamaIdSearch.validationResult | |
} | |
error={iqamaIdSearch.error} | |
/> | |
<CustomErrorMessage | |
name="iqamaId" | |
errors={errors} | |
touched={touched} | |
/> | |
</> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="iqamaIdExpiry" | |
> | |
{t("Iqama ID Expiry")} | |
</label> | |
{values.citizen === "false" && ( | |
<span className="add-req-mark">*</span> | |
)} | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.iqamaIdExpiry || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="iqamaIdExpiry" | |
name="iqamaIdExpiry" | |
className={`add-wrap-input ${ | |
!values?.iqamaIdExpiry || | |
values.iqamaIdExpiry === | |
"DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values?.iqamaIdExpiry | |
? formatDateToYYYYMMDD( | |
values.iqamaIdExpiry | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"iqamaIdExpiry", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
)} | |
</div> | |
{values.citizen === "false" && | |
!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="iqamaIdExpiry" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="workPermitNo" | |
> | |
{t("Work Permit No")} | |
</label> | |
{values.citizen === "false" && ( | |
<span className="add-req-mark">*</span> | |
)} | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.workPermitNo || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="workPermitNo" | |
name="workPermitNo" | |
className="add-wrap-input" | |
placeholder={t( | |
"Enter Work Permit No" | |
)} | |
value={values?.workPermitNo} | |
onChange={(e) => | |
setFieldValue( | |
"workPermitNo", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="workPermitNo" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
{/* Work Permit Expiry */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="workPermitExpiry" | |
> | |
{t("Work Permit Expiry")} | |
</label> | |
{values.citizen === "false" && ( | |
<span className="add-req-mark">*</span> | |
)} | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.workPermitExpiry || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="workPermitExpiry" | |
name="workPermitExpiry" | |
className={`add-wrap-input ${ | |
!values?.workPermitExpiry || | |
values.workPermitExpiry === | |
"DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values?.workPermitExpiry | |
? formatDateToYYYYMMDD( | |
values.workPermitExpiry | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"workPermitExpiry", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="workPermitExpiry" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
{values.citizen === "true" && ( | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Nationality")} | |
</h3> | |
</div> | |
<div className="add-body-content-grid"></div> | |
</div> | |
)} | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="iqamaDocFront" | |
backDocKey="iqamaDocBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
currentEmployeeEditing={currentEmployeeEditing} | |
onDocModal={onDocModal} | |
errors={errors} | |
touched={touched} | |
/> | |
{docModal && ( | |
<> | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div | |
className="upload-modal-icon-container" | |
onClick={() => | |
closeDocModal(setFieldValue) | |
} | |
> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="iqamaDocFront" | |
className="upload-label" | |
> | |
{t("Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.iqamaDocFront | |
? values?.iqamaDocFront?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="iqamaDocFront" | |
// value={values.iqamaDocFront} | |
ref={fileInputRef1} | |
id="iqamaDocFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => { | |
setFieldValue( | |
"iqamaDocFront", | |
e.target.files[0] | |
); | |
}} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="iqamaDocFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="iqamaDocBack" | |
className="upload-label" | |
> | |
{t("Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.iqamaDocBack | |
? values?.iqamaDocBack?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="iqamaDocBack" | |
// value={values.iqamaDocBack} | |
ref={fileInputRef2} | |
id="iqamaDocBack" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => { | |
setFieldValue( | |
"iqamaDocBack", | |
e.target.files[0] | |
); | |
}} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="iqamaDocBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
className="upload-footer-btn" | |
disabled={docUploadLoading} | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"iqamaDoc" | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
</> | |
)} | |
</div> | |
) : documentTab === "National ID" ? ( | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("National ID")} | |
</h3> | |
<div className="relative"> | |
{/* <select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> */} | |
{/* <span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> */} | |
</div> | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="nationalId" | |
> | |
{t("National ID")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<input | |
disabled | |
id="nationalId" | |
name="nationalId" | |
className="add-input bg-gray-100 border border-gray-300 cursor-not-allowed" | |
placeholder={t("Enter National ID")} | |
value={values?.nationalId} | |
onChange={(e) => | |
handleNationalIdChange(e, setFieldValue) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<ValidateIndicators | |
isSearching={nationalIdSearch.isSearching} | |
validationResult={ | |
nationalIdSearch.validationResult | |
} | |
error={nationalIdSearch.error} | |
/> | |
<CustomErrorMessage | |
name="nationalId" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="nationalIdExpiry" | |
> | |
{t("National ID Expiry")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="nationalIdExpiry" | |
name="nationalIdExpiry" | |
className={`add-wrap-input ${ | |
!values?.nationalIdExpiry || | |
values.nationalIdExpiry === | |
"DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
min={ | |
new Date().toISOString().split("T")[0] | |
} // Restricts past dates | |
value={ | |
values?.nationalIdExpiry | |
? formatDateToYYYYMMDD( | |
values.nationalIdExpiry | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"nationalIdExpiry", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="nationalIdExpiry" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="dobGregorian" | |
> | |
{t("Date Of Birth")} | |
</label> | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
disabled | |
type="date" | |
id="dobGregorian" | |
name="dobGregorian" | |
className={`add-wrap-input ${ | |
!values?.dobGregorian || | |
values.dobGregorian === "DD-MM-YYYY" | |
? "empty" | |
: "" | |
} bg-gray-100 text-gray-400 border border-gray-300 cursor-not-allowed`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values?.dobGregorian | |
? formatDateToYYYYMMDD( | |
values.dobGregorian | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"dobGregorian", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="dobGregorian" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="placeOfBirth" | |
> | |
{t("Place of Birth")} | |
</label> | |
</div> | |
<input | |
id="placeOfBirth" | |
name="placeOfBirth" | |
className="add-input" | |
placeholder={t("Enter Place of Birth")} | |
value={values?.placeOfBirth} | |
onChange={(e) => | |
setFieldValue( | |
"placeOfBirth", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMessage | |
name="placeOfBirth" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="nationalDocFront" | |
backDocKey="nationalDocBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
onDocModal={onDocModal} | |
errors={errors} | |
touched={touched} | |
/> | |
{docModal && ( | |
<> | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div | |
className="upload-modal-icon-container" | |
onClick={() => | |
closeDocModal(setFieldValue) | |
} | |
> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="nationalDocFront" | |
className="upload-label" | |
> | |
{t("Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.nationalDocFront | |
? values?.nationalDocFront | |
?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="nationalDocFront" | |
// value={values.nationalDocFront} | |
ref={fileInputRef1} | |
id="nationalDocFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => { | |
setFieldValue( | |
"nationalDocFront", | |
e.target.files[0] | |
); | |
}} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="nationalDocFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="nationalDocBack" | |
className="upload-label" | |
> | |
{t("Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.nationalDocBack | |
? values?.nationalDocBack | |
?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="nationalDocBack" | |
// value={values.nationalDocBack} | |
ref={fileInputRef2} | |
id="nationalDocBack" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => { | |
setFieldValue( | |
"nationalDocBack", | |
e.target.files[0] | |
); | |
}} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="nationalDocBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
className="upload-footer-btn" | |
disabled={docUploadLoading} | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"nationalDoc" | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
</> | |
)} | |
</div> | |
) : documentTab === "Account" ? ( | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Bank Account")} | |
</h3> | |
{/* <div className="relative"> | |
<select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> | |
<span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> | |
</div> */} | |
</div> | |
<div className="add-body-content-flex"> | |
<div className="form-group"> | |
<div className="add-body-input-section-full"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="bank" | |
> | |
{t("Bank")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.bank?.label || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<AsyncSelect | |
id="bank" | |
name="bank" | |
value={values.bank} | |
onChange={(selectedOption) => | |
setFieldValue( | |
"bank", | |
selectedOption | |
) | |
} | |
loadOptions={onSearchBankDebounce} | |
defaultOptions={bank} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select Bank")} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="bank" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
{/* Account Holder Name */} | |
<div className="form-group"> | |
<div className="add-body-input-section-full"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="accountHolderName" | |
> | |
{t("Account Holder Name")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.accountHolderName || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="accountHolderName" | |
name="accountHolderName" | |
className="add-input-full" | |
placeholder={t("Enter Holder Name")} | |
value={values?.accountHolderName} | |
onChange={(e) => | |
setFieldValue( | |
"accountHolderName", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="accountHolderName" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="ibanNo" | |
> | |
{t("IBAN Number")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.ibanNo || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="ibanNo" | |
name="ibanNo" | |
className="add-wrap-input" | |
placeholder={t("Enter IBAN Number")} | |
value={values?.ibanNo} | |
onChange={(e) => | |
handleIbanNoChange( | |
e, | |
setFieldValue | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<> | |
<ValidateIndicators | |
isSearching={ibanNoSearch.isSearching} | |
validationResult={ | |
ibanNoSearch.validationResult | |
} | |
error={ibanNoSearch.error} | |
/> | |
<CustomErrorMessage | |
name="ibanNo" | |
errors={errors} | |
touched={touched} | |
/> | |
</> | |
)} | |
</div> | |
{/* Confirm IBAN Number */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="confirmIban" | |
> | |
{t("Confirm IBAN Number")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.confirmIban || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="confirmIban" | |
name="confirmIban" | |
className="add-wrap-input" | |
placeholder="0" | |
onPaste={(e) => e.preventDefault()} | |
value={values?.confirmIban} | |
onChange={(e) => | |
setFieldValue( | |
"confirmIban", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="confirmIban" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section-full"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="ifscCode" | |
> | |
{t("IFSC Code")}{" "} | |
<span | |
style={{ | |
color: "#6c757d", | |
fontSize: "12px", | |
}} | |
> | |
(e.g., HDFC0CAG001) | |
</span> | |
</label> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.ifscCode || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="ifscCode" | |
name="ifscCode" | |
className="add-input-full" | |
placeholder={t("Enter IFSC Code")} | |
value={values?.ifscCode} | |
onChange={(e) => | |
setFieldValue( | |
"ifscCode", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="ifscCode" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="accountFront" | |
backDocKey="accountBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
currentEmployeeEditing={currentEmployeeEditing} | |
onDocModal={onDocModal} | |
errors={errors} | |
touched={touched} | |
/> | |
{docModal && ( | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div className="upload-modal-icon-container"> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
onClick={() => | |
closeDocModalAccount(setFieldValue) | |
} | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="accountFront" | |
className="upload-label" | |
> | |
{t("Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.accountFront | |
? values?.accountFront?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="accountFront" | |
ref={fileInputRef1} | |
id="accountFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"accountFront", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="accountFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="accountDocBack" | |
className="upload-label" | |
> | |
{t("Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.accountBack | |
? values?.accountBack?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="accountBack" | |
// value={values.insuranceDocBack} | |
ref={fileInputRef2} | |
id="accountBack" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"accountBack", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="accountBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
disabled={docUploadLoading} | |
className="upload-footer-btn" | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"accountDoc" | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
)} | |
</div> | |
) : documentTab === "Health Insurance" ? ( | |
<> | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Health Insurance")} | |
</h3> | |
{/* <div className="relative"> | |
<select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> | |
<span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> | |
</div> */} | |
</div> | |
<div className="add-body-content-flex"> | |
<div className="form-group"> | |
<div className="add-body-input-section-full"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="insuranceClass" | |
> | |
{t("Health Insurance Class")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.insuranceClass || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="insuranceClass" | |
name="insuranceClass" | |
className="add-input" | |
placeholder={t( | |
"Enter Health Insurance" | |
)} | |
value={values?.insuranceClass} | |
onChange={(e) => | |
setFieldValue( | |
"insuranceClass", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="insuranceClass" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="insuranceNo" | |
> | |
{t("Health Insurance Number")} | |
</label> | |
<span className="add-req-mark"> | |
* | |
</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.insuranceNo || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="insuranceNo" | |
name="insuranceNo" | |
className="add-input" | |
placeholder={t( | |
"Enter Health Insurance Number" | |
)} | |
value={values?.insuranceNo} | |
onChange={(e) => | |
handleInsuranceNoChange( | |
e, | |
setFieldValue | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<> | |
<ValidateIndicators | |
isSearching={ | |
insuranceNoSearch.isSearching | |
} | |
validationResult={ | |
insuranceNoSearch.validationResult | |
} | |
error={insuranceNoSearch.error} | |
/> | |
<CustomErrorMessage | |
name="insuranceNo" | |
errors={errors} | |
touched={touched} | |
/> | |
</> | |
)} | |
</div> | |
{/* Insurance Expiry */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="insuranceExpiry" | |
> | |
{t("Insurance Expiry")} | |
</label> | |
<span className="add-req-mark"> | |
* | |
</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.insuranceExpiry || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="insuranceExpiry" | |
type="date" | |
name="insuranceExpiry" | |
className={`add-wrap-input ${ | |
!values?.insuranceExpiry || | |
values.insuranceExpiry === | |
"DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
min={ | |
new Date() | |
.toISOString() | |
.split("T")[0] | |
} | |
value={ | |
values?.insuranceExpiry | |
? formatDateToYYYYMMDD( | |
values.insuranceExpiry | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"insuranceExpiry", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="insuranceExpiry" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
{/* <div className="form-group"> | |
<div className="add-body-input-section-full"> | |
<div className="add-label-container"> | |
<label className="add-label" htmlFor="ifsc"> | |
IFSC Code | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
id="ifsc" | |
name="ifsc" | |
className="add-input-full" | |
placeholder="Enter IFSC Code" | |
value={values?.ifsc} | |
onChange={(e) => | |
setFieldValue("ifsc", e.target.value) | |
} | |
/> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="ifsc" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> */} | |
</div> | |
</div> | |
<div | |
className="add-body-content-container" | |
style={{ marginTop: "12px" }} | |
> | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="insuranceDocFront" | |
backDocKey="insuranceDocBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
currentEmployeeEditing={ | |
currentEmployeeEditing | |
} | |
onDocModal={onDocModal} | |
errors={errors} | |
touched={touched} | |
/> | |
{docModal && ( | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div className="upload-modal-icon-container"> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
onClick={() => | |
closeDocModalInsurance( | |
setFieldValue | |
) | |
} | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="insuranceDocFront" | |
className="upload-label" | |
> | |
{t("Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.insuranceDocFront?.name | |
? values?.insuranceDocFront | |
?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="insuranceDocFront" | |
ref={fileInputRef1} | |
id="insuranceDocFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"insuranceDocFront", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="insuranceDocFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="insuranceDocBack" | |
className="upload-label" | |
> | |
{t("Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.insuranceDocBack | |
? values?.insuranceDocBack | |
?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="insuranceDocBack" | |
// value={values.i} | |
ref={fileInputRef2} | |
id="i" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"insuranceDocBack", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="insuranceDocBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
className="upload-footer-btn" | |
disabled={docUploadLoading} | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"insuranceDoc" | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
)} | |
</div> | |
</> | |
) : documentTab === "Health Card" ? ( | |
<> | |
<div | |
className="add-body-content-container" | |
style={{ marginTop: "12px" }} | |
> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Health Card")} | |
</h3> | |
{/* <div className="relative"> | |
<select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> | |
<span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> | |
</div> */} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label"> | |
{t("Health Card")} | |
</label> | |
<span className="upload-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.healthCard === "true" | |
? t("Yes") | |
: t("No")} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-radio-input-container"> | |
<div className="add-radio-container"> | |
<input | |
id="yes" | |
type="radio" | |
name="healthCard" | |
className="add-radio-input" | |
value="true" | |
onChange={(e) => | |
setFieldValue( | |
"healthCard", | |
e.target.value | |
) | |
} | |
checked={ | |
values?.healthCard === "true" | |
} | |
/> | |
<label | |
htmlFor="yes" | |
className="add-label" | |
> | |
{t("Yes")} | |
</label> | |
</div> | |
<div className="add-radio-container"> | |
<input | |
id="no" | |
type="radio" | |
name="healthCard" | |
className="add-radio-input" | |
value="false" | |
onChange={(e) => | |
setFieldValue( | |
"healthCard", | |
e.target.value | |
) | |
} | |
checked={ | |
values?.healthCard === "false" | |
} | |
/> | |
<label | |
htmlFor="no" | |
className="add-label" | |
> | |
{t("No")} | |
</label> | |
</div> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="healthCard" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
<div className="add-body-content-flex"> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="healthCardNo" | |
> | |
{t("Health Card Number")} | |
</label> | |
<span className="add-req-mark"> | |
* | |
</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.healthCardNo || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="healthCardNo" | |
name="healthCardNo" | |
className="add-input" | |
placeholder={t( | |
"Enter Health Card Number" | |
)} | |
value={values?.healthCardNo} | |
onChange={(e) => | |
handleHealthCardNoChange( | |
e, | |
setFieldValue | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<> | |
<ValidateIndicators | |
isSearching={ | |
healthCardNoSearch.isSearching | |
} | |
validationResult={ | |
healthCardNoSearch.validationResult | |
} | |
error={healthCardNoSearch.error} | |
/> | |
<CustomErrorMessage | |
name="healthCardNo" | |
errors={errors} | |
touched={touched} | |
/> | |
</> | |
)} | |
</div> | |
{/* Health Card Expiry */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="healthCardExpiry" | |
> | |
{t("Health Card Expiry")} | |
</label> | |
<span className="add-req-mark"> | |
* | |
</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.healthCardExpiry || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="healthCardExpiry" | |
name="healthCardExpiry" | |
className={`add-wrap-input ${ | |
!values?.healthCardExpiry || | |
values.healthCardExpiry === | |
"DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values?.healthCardExpiry | |
? formatDateToYYYYMMDD( | |
values.healthCardExpiry | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"healthCardExpiry", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="healthCardExpiry" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
</div> | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="healthCardDocFront" | |
backDocKey="healthCardDocBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
currentEmployeeEditing={ | |
currentEmployeeEditing | |
} | |
onDocModal={onDocModal} | |
errors={errors} | |
touched={touched} | |
/> | |
{docModal && ( | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div className="upload-modal-icon-container"> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
onClick={() => | |
closeDocModalHealthCard( | |
setFieldValue | |
) | |
} | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="healthCardDocFront" | |
className="upload-label" | |
> | |
{t("Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.healthCardDocFront | |
?.name | |
? values?.healthCardDocFront | |
?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="healthCardDocFront" | |
ref={fileInputRef1} | |
id="healthCardDocFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"healthCardDocFront", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="healthCardDocFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="healthCardDocBack" | |
className="upload-label" | |
> | |
{t("Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.healthCardDocBack | |
? values?.healthCardDocBack | |
?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="healthCardDocBack" | |
// value={values.i} | |
ref={fileInputRef2} | |
id="i" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"healthCardDocBack", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="healthCardDocBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
className="upload-footer-btn" | |
disabled={docUploadLoading} | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"healthCardDoc" | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
)} | |
</div> | |
</> | |
) : documentTab === "Passport" ? ( | |
<> | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Passport")} | |
</h3> | |
{/* <div className="relative"> | |
<select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> | |
<span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> | |
</div> */} | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="passportNo" | |
> | |
{t("Passport Number")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
id="passportNo" | |
name="passportNo" | |
className="add-input" | |
placeholder={t( | |
"Enter Passport Number" | |
)} | |
value={values?.passportNo} | |
onChange={(e) => | |
handlePassportNoChange( | |
e, | |
setFieldValue | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
</div> | |
<ValidateIndicators | |
isSearching={passportNoSearch.isSearching} | |
validationResult={ | |
passportNoSearch.validationResult | |
} | |
error={passportNoSearch.error} | |
/> | |
<CustomErrorMessage | |
name="passportNo" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="passportExpiry" | |
> | |
{t("Passport Expiry")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="passportExpiry" | |
name="passportExpiry" | |
className={`add-wrap-input ${ | |
!values?.passportExpiry || | |
values.passportExpiry === | |
"DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
min={ | |
new Date() | |
.toISOString() | |
.split("T")[0] | |
} | |
value={ | |
values?.passportExpiry | |
? formatDateToYYYYMMDD( | |
values.passportExpiry | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"passportExpiry", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="passportExpiry" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="passportIssue" | |
> | |
{t("Passport Issue")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="passportIssue" | |
name="passportIssue" | |
max={ | |
new Date() | |
.toISOString() | |
.split("T")[0] | |
} | |
className={`add-wrap-input ${ | |
!values?.passportIssue || | |
values.passportIssue === | |
"DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values?.passportIssue | |
? formatDateToYYYYMMDD( | |
values.passportIssue | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"passportIssue", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="passportIssue" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="issuePlace" | |
> | |
{t("Place of Issue")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
id="issuePlace" | |
name="issuePlace" | |
className="add-input" | |
placeholder={t( | |
"Enter Place Of Issue" | |
)} | |
value={values?.issuePlace} | |
onChange={(e) => | |
setFieldValue( | |
"issuePlace", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="issuePlace" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="passportDocFront" | |
backDocKey="passportDocBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
onDocModal={onDocModal} | |
errors={errors} | |
touched={touched} | |
customStyle={{ marginTop: "12px" }} | |
/> | |
{docModal && ( | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div className="upload-modal-icon-container"> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
onClick={() => | |
closeDocModalPassport(setFieldValue) | |
} | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="passportDocFront" | |
className="upload-label" | |
> | |
{t("Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.passportDocFront | |
? values?.passportDocFront?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="passportDocFront" | |
ref={fileInputRef1} | |
id="passportDocFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"passportDocFront", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="passportDocFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="passportDocBack" | |
className="upload-label" | |
> | |
{t("Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.passportDocBack | |
? values?.passportDocBack?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="passportDocBack" | |
// value={values.i} | |
ref={fileInputRef2} | |
id="i" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"passportDocBack", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="passportDocBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
className="upload-footer-btn" | |
disabled={docUploadLoading} | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"passportDoc" | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
)} | |
</> | |
) : documentTab === "Visa" ? ( | |
<> | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Visa")} | |
</h3> | |
{/* <div className="relative"> | |
<select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> | |
<span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> | |
</div> */} | |
</div> | |
<div className="add-body-content-grid"> | |
{/* Visa Number */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="visaNo" | |
> | |
{t("Visa Number")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span>{values?.visaNo || "-"}</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="visaNo" | |
name="visaNo" | |
className="add-input" | |
placeholder={t("Enter Visa Number")} | |
value={values?.visaNo} | |
onChange={(e) => | |
handleVisaNoChange( | |
e, | |
setFieldValue | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<> | |
<ValidateIndicators | |
isSearching={visaNoSearch.isSearching} | |
validationResult={ | |
visaNoSearch.validationResult | |
} | |
error={visaNoSearch.error} | |
/> | |
<CustomErrorMessage | |
name="visaNo" | |
errors={errors} | |
touched={touched} | |
/> | |
</> | |
)} | |
</div> | |
{/* Visa Expiry */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="visaExpiry" | |
> | |
{t("Visa Expiry")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.visaExpiry || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="visaExpiry" | |
name="visaExpiry" | |
className={`add-wrap-input ${ | |
!values?.visaExpiry || | |
values.visaExpiry === "DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values?.visaExpiry | |
? formatDateToYYYYMMDD( | |
values.visaExpiry | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"visaExpiry", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="visaExpiry" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
{/* Visa Issue */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="visaIssue" | |
> | |
{t("Visa Issue")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.visaIssue || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="visaIssue" | |
name="visaIssue" | |
className={`add-wrap-input ${ | |
!values?.visaIssue || | |
values.visaIssue === "DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values?.visaIssue | |
? formatDateToYYYYMMDD( | |
values.visaIssue | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"visaIssue", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="visaIssue" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
{/* Place of Issue */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="visaIssuePlace" | |
> | |
{t("Place of Issue")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.visaIssuePlace || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="visaIssuePlace" | |
name="visaIssuePlace" | |
className="add-input" | |
placeholder={t( | |
"Enter Place Of Issue" | |
)} | |
value={values?.visaIssuePlace} | |
onChange={(e) => | |
setFieldValue( | |
"visaIssuePlace", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="visaIssuePlace" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
{/* Visa Type */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="visaType" | |
> | |
{t("Visa Type")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.visaType?.label || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<AsyncSelect | |
id="visaType" | |
name="visaType" | |
value={values.visaType} | |
onChange={(selectedOption) => | |
setFieldValue( | |
"visaType", | |
selectedOption | |
) | |
} | |
loadOptions={loadVisaTypeOptions} | |
defaultOptions={visaType} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t("Select Visa Type")} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="visaType" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
</div> | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="visaDocFront" | |
backDocKey="visaDocBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
t={t} | |
currentEmployeeEditing={currentEmployeeEditing} | |
onDocModal={onDocModal} | |
errors={errors} | |
touched={touched} | |
customStyle={{ marginTop: "12px" }} | |
/> | |
{docModal && ( | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div className="upload-modal-icon-container"> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
onClick={() => | |
closeDocModalVisa(setFieldValue) | |
} | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="visaDocFront" | |
className="upload-label" | |
> | |
{t("Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.visaDocFront | |
? values?.visaDocFront?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="visaDocFront" | |
ref={fileInputRef1} | |
id="visaDocFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"visaDocFront", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="visaDocFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="visaDocBack" | |
className="upload-label" | |
> | |
{t("Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.visaDocBack | |
? values?.visaDocBack?.name | |
: "Upload Document"} | |
</span> | |
<input | |
name="visaDocBack" | |
// value={values.i} | |
ref={fileInputRef2} | |
id="i" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"visaDocBack", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="visaDocBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
className="upload-footer-btn" | |
disabled={docUploadLoading} | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"visaDoc" | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
)} | |
</> | |
) : documentTab === "Contract" ? ( | |
<> | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Contract")} | |
</h3> | |
{/* <div className="relative"> | |
<select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> | |
<span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> | |
</div> */} | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="contractNo" | |
> | |
{t("Contract Number")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.contractNo || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="contractNo" | |
name="contractNo" | |
className="add-input" | |
placeholder={t( | |
"Enter QIWA Contract Number" | |
)} | |
value={values?.contractNo} | |
onChange={(e) => | |
handleContractNoChange( | |
e, | |
setFieldValue | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<> | |
<ValidateIndicators | |
isSearching={ | |
contractNoSearch.isSearching | |
} | |
validationResult={ | |
contractNoSearch.validationResult | |
} | |
error={contractNoSearch.error} | |
/> | |
<CustomErrorMessage | |
name="contractNo" | |
errors={errors} | |
touched={touched} | |
/> | |
</> | |
)} | |
</div> | |
{/* Contract End */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="contractEnd" | |
> | |
{t("Contract End")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.contractEnd || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="contractEnd" | |
name="contractEnd" | |
className={`add-wrap-input ${ | |
!values?.contractEnd || | |
values.contractEnd === | |
"DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values?.contractEnd | |
? formatDateToYYYYMMDD( | |
values.contractEnd | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"contractEnd", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="contractEnd" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
</div> | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="contractDocFront" | |
backDocKey="contractDocBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
currentEmployeeEditing={currentEmployeeEditing} | |
onDocModal={onDocModal} | |
errors={errors} | |
touched={touched} | |
customStyle={{ marginTop: "12px" }} | |
/> | |
{docModal && ( | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div className="upload-modal-icon-container"> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
onClick={() => | |
closeDocModalContract(setFieldValue) | |
} | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="contractDocFront" | |
className="upload-label" | |
> | |
{t("Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.contractDocFront | |
? values?.contractDocFront?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="contractDocFront" | |
ref={fileInputRef1} | |
id="contractDocFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"contractDocFront", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="contractDocFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="contractDocBack" | |
className="upload-label" | |
> | |
{t("Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.contractDocBack | |
? values?.contractDocBack?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="contractDocBack" | |
// value={values.i} | |
ref={fileInputRef2} | |
id="i" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"contractDocBack", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="contractDocBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
className="upload-footer-btn" | |
disabled={docUploadLoading} | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"contractDoc" | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
)} | |
</> | |
) : documentTab === "Driving License" ? ( | |
<> | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Driving License")} | |
</h3> | |
{/* <div className="relative"> | |
<select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> | |
<span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> | |
</div> */} | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="drivingLicenseNo" | |
> | |
{t("Driving License Number")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
id="drivingLicenseNo" | |
name="drivingLicenseNo" | |
className="add-input" | |
placeholder={t( | |
"Enter Driving License Number" | |
)} | |
value={values?.drivingLicenseNo} | |
onChange={(e) => | |
handleDrivingLicenseNoChange( | |
e, | |
setFieldValue | |
) | |
} | |
onBlur={handleBlur} | |
// onChange={(e) => { | |
// const value = e.target.value; | |
// // if (/^[0-9]*$/.test(value)) { | |
// // setFieldValue( | |
// // "drivingLicenseNo", | |
// // value | |
// // ); | |
// // } | |
// // For alphanumeric with specific format (e.g., ABC12345), use: | |
// if (/^[A-Za-z0-9]*$/.test(value)) { | |
// setFieldValue( | |
// "drivingLicenseNo", | |
// value | |
// ); | |
// } | |
// }} | |
/> | |
</div> | |
</div> | |
<ValidateIndicators | |
isSearching={ | |
drivingLicenseNoSearch.isSearching | |
} | |
validationResult={ | |
drivingLicenseNoSearch.validationResult | |
} | |
error={drivingLicenseNoSearch.error} | |
/> | |
<CustomErrorMessage | |
name="drivingLicenseNo" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="licenseValidity" | |
> | |
{t("Driving License Validity")} | |
</label> | |
<span className="add-req-mark">*</span> | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id="licenseValidity" | |
name="licenseValidity" | |
className={`add-wrap-input ${ | |
!values?.licenseValidity || | |
values.licenseValidity === | |
"DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
min={ | |
new Date() | |
.toISOString() | |
.split("T")[0] | |
} | |
value={ | |
values?.licenseValidity | |
? formatDateToYYYYMMDD( | |
values.licenseValidity | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
"licenseValidity", | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="licenseValidity" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="drivingLicenseDocFront" | |
backDocKey="drivingLicenseDocBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
onDocModal={onDocModal} | |
errors={errors} | |
touched={touched} | |
customStyle={{ marginTop: "12px" }} | |
/> | |
{docModal && ( | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div className="upload-modal-icon-container"> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
onClick={() => | |
closeDocModalLicense(setFieldValue) | |
} | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="drivingLicenseDocFront" | |
className="upload-label" | |
> | |
{t("Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.drivingLicenseDocFront | |
? values?.drivingLicenseDocFront | |
?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="drivingLicenseDocFront" | |
ref={fileInputRef1} | |
id="drivingLicenseDocFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"drivingLicenseDocFront", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="drivingLicenseDocFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="drivingLicenseDocBack" | |
className="upload-label" | |
> | |
{t("Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.drivingLicenseDocBack | |
? values?.drivingLicenseDocBack | |
?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="drivingLicenseDocBack" | |
// value={values.i} | |
ref={fileInputRef2} | |
id="i" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"drivingLicenseDocBack", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="drivingLicenseDocBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
className="upload-footer-btn" | |
disabled={docUploadLoading} | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"drivingLicenseDoc" | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
)} | |
</> | |
) : documentTab === "Subscription" ? ( | |
<> | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Registrations")} | |
</h3> | |
{/* <div className="relative"> | |
<select | |
value={values.lang} | |
onChange={(e) => | |
setFieldValue("lang", e.target.value) | |
} | |
className="appearance-none w-full bg-[#F9FAFB] text-[#04080B] border border-[#F2F4F7] rounded-lg py-2 pl-4 pr-10 focus:outline-none focus:ring-2 focus:ring-gray-300" | |
> | |
<option value="en">English</option> | |
<option value="ar">Arabic</option> | |
</select> | |
<span className="absolute right-3 top-1/2 -translate-y-1/2 text-[#F9FAFB] pointer-events-none"> | |
<DropDownIcon /> | |
</span> | |
</div> */} | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="gosiRegNo" | |
> | |
{t("GOSI Registration Number")} | |
</label> | |
<span className="upload-req-mark"> | |
* | |
</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.gosiRegNo || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="gosiRegNo" | |
name="gosiRegNo" | |
className="add-input" | |
placeholder={t( | |
"Enter Registration Number" | |
)} | |
value={values?.gosiRegNo} | |
onChange={(e) => | |
handleGosiRegNoChange( | |
e, | |
setFieldValue | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<> | |
<ValidateIndicators | |
isSearching={ | |
gosiRegNoSearch.isSearching | |
} | |
validationResult={ | |
gosiRegNoSearch.validationResult | |
} | |
error={gosiRegNoSearch.error} | |
/> | |
<CustomErrorMessage | |
name="gosiRegNo" | |
errors={errors} | |
touched={touched} | |
/> | |
</> | |
)} | |
</div> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label"> | |
{t("GOSI Registration")} | |
</label> | |
<span className="upload-req-mark"> | |
* | |
</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.gosiReg === "true" | |
? t("Yes") | |
: t("No")} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-radio-input-container"> | |
<div className="add-radio-container"> | |
<input | |
id="yes" | |
type="radio" | |
name="gosiReg" | |
className="add-radio-input" | |
value="true" | |
onChange={(e) => | |
setFieldValue( | |
"gosiReg", | |
e.target.value | |
) | |
} | |
checked={ | |
values?.gosiReg === "true" | |
} | |
/> | |
<label | |
htmlFor="yes" | |
className="add-label" | |
> | |
{t("Yes")} | |
</label> | |
</div> | |
<div className="add-radio-container"> | |
<input | |
id="no" | |
type="radio" | |
name="gosiReg" | |
className="add-radio-input" | |
value="false" | |
onChange={(e) => | |
setFieldValue( | |
"gosiReg", | |
e.target.value | |
) | |
} | |
checked={ | |
values?.gosiReg === "false" | |
} | |
/> | |
<label | |
htmlFor="no" | |
className="add-label" | |
> | |
{t("No")} | |
</label> | |
</div> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="gosiReg" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="gosiDocFront" | |
backDocKey="gosiDocBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
currentEmployeeEditing={ | |
currentEmployeeEditing | |
} | |
onDocModal={onDocModalGosi} | |
errors={errors} | |
touched={touched} | |
customStyle={{ marginTop: "12px" }} | |
headerText="Upload GOSI Documents" | |
/> | |
{/* Mudad Registration Number (conditional) */} | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor="mudadRegNo" | |
> | |
{t("Mudad Registration Number")} | |
</label> | |
<span className="upload-req-mark"> | |
* | |
</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.mudadRegNo || "-"} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-input-wrapper"> | |
<input | |
id="mudadRegNo" | |
name="mudadRegNo" | |
className="add-input" | |
placeholder={t( | |
"Enter Registration Number" | |
)} | |
value={values?.mudadRegNo} | |
onChange={(e) => | |
handleMudadRegNoChange( | |
e, | |
setFieldValue | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<> | |
<ValidateIndicators | |
isSearching={ | |
mudadRegNoSearch.isSearching | |
} | |
validationResult={ | |
mudadRegNoSearch.validationResult | |
} | |
error={mudadRegNoSearch.error} | |
/> | |
<CustomErrorMessage | |
name="mudadRegNo" | |
errors={errors} | |
touched={touched} | |
/> | |
</> | |
)} | |
</div> | |
{/* Mudad Registration Radio */} | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label"> | |
{t("Mudad Registration")} | |
</label> | |
<span className="upload-req-mark"> | |
* | |
</span> | |
</div> | |
{currentEmployeeEditing ? ( | |
<div className="add-input-value"> | |
<span> | |
{values?.mudadReg === "true" | |
? t("Yes") | |
: t("No")} | |
</span> | |
<span className="add-input-badge"> | |
{noEditingMsg} | |
</span> | |
</div> | |
) : ( | |
<div className="add-radio-input-container"> | |
<div className="add-radio-container"> | |
<input | |
id="yes" | |
type="radio" | |
name="mudadReg" | |
className="add-radio-input" | |
value="true" | |
onChange={(e) => | |
setFieldValue( | |
"mudadReg", | |
e.target.value | |
) | |
} | |
checked={ | |
values?.mudadReg === "true" | |
} | |
/> | |
<label | |
htmlFor="yes" | |
className="add-label" | |
> | |
{t("Yes")} | |
</label> | |
</div> | |
<div className="add-radio-container"> | |
<input | |
id="no" | |
type="radio" | |
name="mudadReg" | |
className="add-radio-input" | |
value="false" | |
onChange={(e) => | |
setFieldValue( | |
"mudadReg", | |
e.target.value | |
) | |
} | |
checked={ | |
values?.mudadReg === "false" | |
} | |
/> | |
<label | |
htmlFor="no" | |
className="add-label" | |
> | |
{t("No")} | |
</label> | |
</div> | |
</div> | |
)} | |
</div> | |
{!currentEmployeeEditing && ( | |
<CustomErrorMessage | |
name="mudadReg" | |
errors={errors} | |
touched={touched} | |
/> | |
)} | |
</div> | |
</div> | |
<DocumentUploadDisplay | |
values={values} | |
frontDocKey="subscriptionDocFront" | |
backDocKey="subscriptionDocBack" | |
handleRemoveDocument={handleRemoveDocument} | |
setFieldValue={setFieldValue} | |
currentEmployeeEditing={ | |
currentEmployeeEditing | |
} | |
onDocModal={onDocModal} | |
errors={errors} | |
touched={touched} | |
customStyle={{ marginTop: "12px" }} | |
headerText="Upload Mudad Documents" | |
/> | |
</div> | |
{docModalGosi && ( | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div className="upload-modal-icon-container"> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
onClick={() => | |
closeDocModalGosi(setFieldValue) | |
} | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="gosiDocFront" | |
className="upload-label" | |
> | |
{t("GOSI Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInputGosi} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.gosiDocFront | |
? values?.gosiDocFront?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="gosiDocFront" | |
ref={fileInputRef1Gosi} | |
id="gosiDocFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"gosiDocFront", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="gosiDocFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="gosiDocBack" | |
className="upload-label" | |
> | |
{t("GOSI Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2Gosi} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.gosiDocBack | |
? values?.gosiDocBack?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="gosiDocBack" | |
// value={values.i} | |
ref={fileInputRef2Gosi} | |
id="i" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"gosiDocBack", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="gosiDocBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
className="upload-footer-btn" | |
disabled={docUploadLoading} | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"gosiDoc", | |
true | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
)} | |
{docModal && ( | |
<div className="upload-modal-overlay"> | |
<div className="upload-modal-content"> | |
<div className="upload-modal-header"> | |
<span className="upload-modal-title"> | |
{t("Upload Documents")} | |
</span> | |
<div className="upload-modal-icon-container"> | |
<img | |
src={arrowIcon} | |
alt="arrow icon" | |
onClick={() => | |
closeDocModalSubscription( | |
setFieldValue | |
) | |
} | |
/> | |
</div> | |
</div> | |
<div className="upload-body"> | |
<p className="upload-desc"> | |
{t( | |
"Please select the import file from your device" | |
)} | |
</p> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="subscriptionDocFront" | |
className="upload-label" | |
> | |
{t("Mudad Front Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.subscriptionDocFront | |
? values?.subscriptionDocFront | |
?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="subscriptionDocFront" | |
ref={fileInputRef1} | |
id="subscriptionDocFront" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"subscriptionDocFront", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="subscriptionDocFront" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="upload-file-input-container"> | |
<div className="upload-file-input-container2"> | |
<div className="upload-label-container"> | |
<label | |
htmlFor="subscriptionDocBack" | |
className="upload-label" | |
> | |
{t("Mudad Back Document")} | |
</label> | |
{/* <span className="upload-req-mark"> | |
* | |
</span> */} | |
</div> | |
<div | |
className="upload-file-input-wrapper" | |
onClick={handleOpenFileInput2} | |
> | |
<span className="upload-file-input-replacer"> | |
{values?.subscriptionDocBack | |
? values?.subscriptionDocBack | |
?.name | |
: t("Upload Document")} | |
</span> | |
<input | |
name="subscriptionDocBack" | |
// value={values.i} | |
ref={fileInputRef2} | |
id="i" | |
type="file" | |
className="upload-file-hidden-input" | |
onChange={(e) => | |
setFieldValue( | |
"subscriptionDocBack", | |
e.target.files[0] | |
) | |
} | |
/> | |
<button | |
type="button" | |
className="upload-btn" | |
> | |
{t("Upload File")} | |
</button> | |
</div> | |
<CustomErrorMessage | |
name="subscriptionDocBack" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className="upload-footer"> | |
<button | |
type="button" | |
className="upload-footer-btn" | |
disabled={docUploadLoading} | |
onClick={() => | |
handleSubmitDocument( | |
values, | |
"subscriptionDoc" | |
) | |
} | |
> | |
{!docUploadLoading ? ( | |
t("Submit") | |
) : ( | |
<ButtonLoading /> | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
)} | |
</> | |
) : null} | |
</> | |
)} | |
</> | |
) : detailsStep === 4 ? ( | |
<> | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Dependents Info")} | |
</h3> | |
</div> | |
<div className="add-body-content-grid"> | |
<div className="form-group"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label"> | |
{t("Dependents")} | |
</label> | |
<span className="upload-req-mark">*</span> | |
</div> | |
<div className="add-radio-input-container"> | |
<div className="add-radio-container"> | |
<input | |
id="yes" | |
type="radio" | |
name="isDependents" | |
className="add-radio-input" | |
value="true" // Set the value directly | |
onChange={(e) => | |
setFieldValue( | |
"isDependents", | |
e.target.value | |
) | |
} | |
checked={values?.isDependents === "true"} // Bind checked state | |
/> | |
<label htmlFor="yes" className="add-label"> | |
{t("Yes")} | |
</label> | |
</div> | |
<div className="add-radio-container"> | |
<input | |
id="no" | |
type="radio" | |
name="isDependents" | |
className="add-radio-input" | |
value="false" | |
onChange={(e) => | |
setFieldValue( | |
"isDependents", | |
e.target.value | |
) | |
} | |
checked={values?.isDependents === "false"} // Bind checked state | |
/> | |
<label htmlFor="no" className="add-label"> | |
{t("No")} | |
</label> | |
</div> | |
</div> | |
</div> | |
<CustomErrorMessage | |
name="isDependents" | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</div> | |
{values?.isDependents == "true" && ( | |
<div className="add-body-content-container"> | |
<div className="add-body-content-header"> | |
<h3 className="add-body-content-heading"> | |
{t("Add Dependents Info")} | |
</h3> | |
<div | |
className="add-member-btn-container" | |
onClick={handleClickAddMember} | |
> | |
<img src={addIcon} alt="plus icon" /> | |
<span className="add-member-txt"> | |
{t("Add Member")} | |
</span> | |
</div> | |
</div> | |
{/* <FieldArray name="members"> | |
{({ push, remove }) => ( | |
<> | |
<div | |
ref={addMemberRef} | |
className="add-member-btn-container-hidden" | |
onClick={() => push({ name: "" })} // Add a new member with an empty name | |
> | |
<img src={addIcon} alt="plus icon" /> | |
<span className="add-member-txt">Add Member</span> | |
</div> | |
{values.members && values.members.length >= 0 && ( | |
<div className="members-container"> | |
{values.members.map((member, index) => ( | |
<div key={index} className="member-row"> | |
<div className="add-field-wrapper"> | |
<div className="add-member-input-wrap"> | |
<span className="member-no"> | |
{index + 1}.{" "} | |
</span> | |
<Field | |
name={`members[${index}].name`} | |
placeholder="Enter name" | |
className="member-input" | |
/> | |
<button | |
type="button" | |
className="remove-member-btn" | |
onClick={() => remove(index)} // Remove the member | |
> | |
Remove Member | |
</button> | |
</div> | |
<CustomErrorMessage | |
name={`members[${index}].name`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
))} | |
</div> | |
)} | |
</> | |
)} | |
</FieldArray> */} | |
<FieldArray name="members"> | |
{({ push, remove }) => ( | |
<> | |
{/* Members Summary Section */} | |
{values?.members?.length > 0 && ( | |
<div className="members-summary-container"> | |
{values.members && | |
values.members.map((member, index) => ( | |
<> | |
{!dependentEditing ? ( | |
<div | |
key={index} | |
className="member-summary-row" | |
> | |
<> | |
<span className="member-label">{`${t( | |
"Member" | |
)} ${index + 1}`}</span> | |
{activeMemberIndex > 0 && | |
index !== | |
values?.members?.length - | |
1 && ( | |
<button | |
type="button" | |
className="edit-member-btn" | |
onClick={() => { | |
setActiveMemberIndex( | |
index | |
); | |
setDependentEditing( | |
!dependentEditing | |
); | |
}} // Set the member to edit | |
> | |
{t("Edit")} | |
</button> | |
)} | |
<button | |
type="button" | |
className="member-summary-remove" | |
onClick={() => { | |
remove(index); | |
if ( | |
index === | |
activeMemberIndex | |
) { | |
// If the removed member was the active member | |
if ( | |
values.members.length > | |
1 | |
) { | |
// Set the active member to the previous member | |
setActiveMemberIndex( | |
index > 0 | |
? index - 1 | |
: 0 | |
); | |
} else { | |
// No members left, reset active member | |
setActiveMemberIndex( | |
null | |
); | |
} | |
} else if ( | |
index < activeMemberIndex | |
) { | |
// If the removed member was before the active member | |
setActiveMemberIndex( | |
activeMemberIndex - 1 | |
); | |
} | |
}} | |
> | |
{t("Remove")} | |
</button> | |
</> | |
</div> | |
) : ( | |
activeMemberIndex === index && ( | |
<> | |
<div className="save-summary-container"> | |
<span className="member-label">{`${t( | |
"Member" | |
)} ${index + 1}`}</span> | |
<div className="save-btn-container"> | |
<button | |
onClick={() => { | |
setDependentEditing( | |
!dependentEditing | |
); | |
setActiveMemberIndex( | |
values?.members | |
?.length - 1 | |
); | |
}} | |
className="dep-save-btn" | |
> | |
{t("Save")} | |
</button> | |
</div> | |
</div> | |
</> | |
) | |
)} | |
</> | |
))} | |
</div> | |
)} | |
{/* Input Section for Active Member */} | |
{values?.members?.length > 0 && ( | |
<div className="active-member-input-section"> | |
{activeMemberIndex !== null && ( | |
<> | |
<div className="row gx-4 gy-4"> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
htmlFor={`members[${activeMemberIndex}].depFirstName`} | |
> | |
{t("First Name")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<input | |
name={`members[${activeMemberIndex}].depFirstName`} | |
placeholder={t( | |
"Enter Dependent Name" | |
)} | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depFirstName | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depFirstName`, | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
className="member-input" | |
/> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depFirstName`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<label | |
htmlFor={`members[${activeMemberIndex}].depSecondName`} | |
> | |
{t("Second Name")} | |
</label> | |
<input | |
name={`members[${activeMemberIndex}].depSecondName`} | |
placeholder={t( | |
"Enter Dependent Second Name" | |
)} | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depSecondName | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depSecondName`, | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
className="member-input" | |
/> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depSecondName`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<label | |
htmlFor={`members[${activeMemberIndex}].depThirdName`} | |
> | |
{t("Third Name")} | |
</label> | |
<input | |
name={`members[${activeMemberIndex}].depThirdName`} | |
placeholder={t( | |
"Enter Dependent Third Name" | |
)} | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depThirdName | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depThirdName`, | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
className="member-input" | |
/> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depThirdName`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
htmlFor={`members[${activeMemberIndex}].depFourthName`} | |
> | |
{t("Last Name")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<input | |
name={`members[${activeMemberIndex}].depFourthName`} | |
placeholder="Enter Dependent Last Name" | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depFourthName | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depFourthName`, | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
className="member-input" | |
/> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depFourthName`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
{/* <div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<label | |
htmlFor={`members[${activeMemberIndex}].depIdNumber`} | |
> | |
IQAMA / ID Number | |
</label> | |
<input | |
name={`members[${activeMemberIndex}].depIdNumber`} | |
placeholder="Enter Dependent Name" | |
value={ | |
values.members[activeMemberIndex] | |
?.depIdNumber | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depIdNumber`, | |
e.target.value | |
) | |
} | |
className="member-input" | |
/> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depIdNumber`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> */} | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor={`members[${activeMemberIndex}].depPassportNo`} | |
> | |
{t("Passport Number")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<input | |
id={`members[${activeMemberIndex}].depPassportNo`} | |
name={`members[${activeMemberIndex}].depPassportNo`} | |
className="add-input" | |
placeholder={t( | |
"Enter Passport Number" | |
)} | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depPassportNo | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depPassportNo`, | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depPassportNo`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor={`members[${activeMemberIndex}].depPassportExpiry`} | |
> | |
{t("Passport Expiry")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id={`members[${activeMemberIndex}].depPassportExpiry`} | |
name={`members[${activeMemberIndex}].depPassportExpiry`} | |
className={`add-wrap-input ${ | |
!values?.members?.[ | |
activeMemberIndex | |
]?.depPassportExpiry || | |
values.members[ | |
activeMemberIndex | |
]?.depPassportExpiry === | |
"DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depPassportExpiry | |
? formatDateToYYYYMMDD( | |
values.members[ | |
activeMemberIndex | |
]?.depPassportExpiry | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depPassportExpiry`, | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depPassportExpiry`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor={`members[${activeMemberIndex}].depContactNo`} | |
> | |
{t("Contact Number")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<input | |
id={`members[${activeMemberIndex}].depContactNo`} | |
name={`members[${activeMemberIndex}].depContactNo`} | |
className="add-input" | |
placeholder={t( | |
"Enter Contact Number" | |
)} | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depContactNo | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depContactNo`, | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depContactNo`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor={`members[${activeMemberIndex}].depDob`} | |
> | |
{t("Date Of Birth")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<div className="add-input-wrapper"> | |
<input | |
type="date" | |
id={`members[${activeMemberIndex}].depDob`} | |
name={`members[${activeMemberIndex}].depDob`} | |
className={`add-wrap-input ${ | |
!values?.members?.[ | |
activeMemberIndex | |
]?.depDob || | |
values.members[ | |
activeMemberIndex | |
]?.depDob === "DD-MM-YYYY" | |
? "empty" | |
: "" | |
}`} | |
placeholder="DD/MM/YYYY" | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depDob | |
? formatDateToYYYYMMDD( | |
values.members[ | |
activeMemberIndex | |
]?.depDob | |
) | |
: "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depDob`, | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
<img | |
src={dateIcon} | |
alt="date icon" | |
className="add-date-input-in" | |
/> | |
</div> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depDob`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor={`members[${activeMemberIndex}].depRelation`} | |
> | |
{t("Relation")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<AsyncSelect | |
id={`members[${activeMemberIndex}].depRelation`} | |
name={`members[${activeMemberIndex}].depRelation`} | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depRelation || "" | |
} | |
onChange={(selectedOption) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depRelation`, | |
selectedOption | |
) | |
} | |
loadOptions={ | |
loadDepRelationOptions | |
} | |
defaultOptions={ | |
depRelationOptions | |
} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t( | |
"Select Relation" | |
)} | |
/> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depRelation`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor={`members[${activeMemberIndex}].depReligion`} | |
> | |
{t("Religion")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<AsyncSelect | |
id={`members[${activeMemberIndex}].depReligion`} | |
name={`members[${activeMemberIndex}].depReligion`} | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depReligion || "" | |
} | |
onChange={(selectedOption) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depReligion`, | |
selectedOption | |
) | |
} | |
loadOptions={ | |
onSearchReligionDebounce | |
} | |
defaultOptions={religionOptions} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t( | |
"Select Religion" | |
)} | |
/> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depReligion`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor={`members[${activeMemberIndex}].depNationality`} | |
> | |
{t("Nationality")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<AsyncSelect | |
id={`members[${activeMemberIndex}].depNationality`} | |
name={`members[${activeMemberIndex}].depNationality`} | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depNationality || "" | |
} | |
onChange={(selectedOption) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depNationality`, | |
selectedOption | |
) | |
} | |
loadOptions={loadOptions} | |
defaultOptions={countryOptions} | |
styles={asyncSelectStyles} | |
cacheOptions | |
placeholder={t( | |
"Select Nationality" | |
)} | |
/> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depNationality`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor={`members[${activeMemberIndex}].depSponsorName`} | |
> | |
{t("Sponsor Name")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<input | |
id={`members[${activeMemberIndex}].depSponsorName`} | |
name={`members[${activeMemberIndex}].depSponsorName`} | |
className="add-input" | |
placeholder={t( | |
"Enter Sponsor Name" | |
)} | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depSponsorName | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depSponsorName`, | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
/> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depSponsorName`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor={`members[${activeMemberIndex}].depSponsorId`} | |
> | |
{t("Sponsor ID")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<input | |
name={`members[${activeMemberIndex}].depSponsorId`} | |
value={ | |
values.members[ | |
activeMemberIndex | |
]?.depSponsorId || "" | |
} | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depSponsorId`, | |
e.target.value | |
) | |
} | |
onBlur={handleBlur} | |
placeholder={t( | |
"Enter Sponsor ID" | |
)} | |
className="add-input" | |
/> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depSponsorId`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label"> | |
{t("Citizen")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<div className="add-radio-input-container"> | |
<div className="add-radio-container"> | |
<input | |
id={`members[${activeMemberIndex}].yes`} | |
type="radio" | |
name={`members[${activeMemberIndex}].depCitizen`} | |
className="add-radio-input" | |
value="true" | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depCitizen`, | |
e.target.value | |
) | |
} | |
checked={ | |
values.members[ | |
activeMemberIndex | |
]?.depCitizen === "true" | |
} | |
/> | |
<label | |
htmlFor={`members[${activeMemberIndex}].yes`} | |
className="add-label" | |
> | |
{t("Yes")} | |
</label> | |
</div> | |
<div className="add-radio-container"> | |
<input | |
id={`members[${activeMemberIndex}].no`} | |
type="radio" | |
name={`members[${activeMemberIndex}].depCitizen`} | |
className="add-radio-input" | |
value="false" | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depCitizen`, | |
e.target.value | |
) | |
} | |
checked={ | |
values.members[ | |
activeMemberIndex | |
]?.depCitizen === "false" | |
} | |
/> | |
<label | |
htmlFor={`members[${activeMemberIndex}].no`} | |
className="add-label" | |
> | |
{t("No")} | |
</label> | |
</div> | |
</div> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depCitizen`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label | |
className="add-label" | |
htmlFor={`members[${activeMemberIndex}].depMaritalStatus`} | |
> | |
{t("Marital Status")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<div className="add-radio-input-container"> | |
<div className="add-radio-container"> | |
<input | |
id={`members[${activeMemberIndex}].married`} | |
type="radio" | |
name={`members[${activeMemberIndex}].depMaritalStatus`} | |
className="add-radio-input" | |
value="Married" | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depMaritalStatus`, | |
e.target.value | |
) | |
} | |
checked={ | |
values.members[ | |
activeMemberIndex | |
]?.depMaritalStatus === | |
"Married" | |
} | |
/> | |
<label | |
htmlFor={`members[${activeMemberIndex}].married`} | |
className="add-label" | |
> | |
{t("Married")} | |
</label> | |
</div> | |
<div className="add-radio-container"> | |
<input | |
id={`members[${activeMemberIndex}].single`} | |
type="radio" | |
name={`members[${activeMemberIndex}].depMaritalStatus`} | |
className="add-radio-input" | |
value="Single" | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depMaritalStatus`, | |
e.target.value | |
) | |
} | |
checked={ | |
values.members[ | |
activeMemberIndex | |
]?.depMaritalStatus === | |
"Single" | |
} | |
/> | |
<label | |
htmlFor={`members[${activeMemberIndex}].single`} | |
className="add-label" | |
> | |
{t("Single")} | |
</label> | |
</div> | |
</div> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depMaritalStatus`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
<div className="col-md-3"> | |
<div className="add-body-input-section"> | |
<div className="add-label-container"> | |
<label className="add-label"> | |
{t("Gender")} | |
</label> | |
{/* <span className="add-req-mark">*</span> */} | |
</div> | |
<div className="add-radio-input-container"> | |
<div className="add-radio-container"> | |
<input | |
id={`members[${activeMemberIndex}].male`} | |
type="radio" | |
name={`members[${activeMemberIndex}].depGender`} | |
className="add-radio-input" | |
value="Male" | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depGender`, | |
e.target.value | |
) | |
} | |
checked={ | |
values.members[ | |
activeMemberIndex | |
]?.depGender === "Male" | |
} | |
/> | |
<label | |
htmlFor={`members[${activeMemberIndex}].male`} | |
className="add-label" | |
> | |
{t("Male")} | |
</label> | |
</div> | |
<div className="add-radio-container"> | |
<input | |
id={`members[${activeMemberIndex}].female`} | |
type="radio" | |
name={`members[${activeMemberIndex}].depGender`} | |
className="add-radio-input" | |
value="Female" | |
onChange={(e) => | |
setFieldValue( | |
`members[${activeMemberIndex}].depGender`, | |
e.target.value | |
) | |
} | |
checked={ | |
values.members[ | |
activeMemberIndex | |
]?.depGender === "Female" | |
} | |
/> | |
<label | |
htmlFor={`members[${activeMemberIndex}].female`} | |
className="add-label" | |
> | |
{t("Female")} | |
</label> | |
</div> | |
</div> | |
</div> | |
<CustomErrorMsgArray | |
name={`members[${activeMemberIndex}].depGender`} | |
errors={errors} | |
touched={touched} | |
/> | |
</div> | |
</div> | |
</> | |
)} | |
</div> | |
)} | |
{/* Add Member Button */} | |
<div | |
className="add-member-btn-container" | |
style={{ display: "none" }} | |
ref={addMemberRef} | |
onClick={() => { | |
push({ | |
publicId: null, | |
depFirstName: "", | |
depSecondName: "", | |
depThirdName: "", | |
depFourthName: "", | |
depIdNumber: "", | |
idExpiry: null, | |
depPassportNo: "", | |
depPassportExpiry: null, | |
depContactNo: "", | |
depDob: null, | |
depGender: "", | |
depCitizen: "", | |
depNationality: null, | |
depSponsorName: "", | |
depSponsorId: "", | |
depReligion: null, | |
depMaritalStatus: "", | |
depRelation: null, | |
}); | |
setActiveMemberIndex(values.members.length); // Set the new member as active | |
}} | |
> | |
<img src={addIcon} alt="plus icon" /> | |
<span className="add-member-txt"> | |
{t("Add Member")} | |
</span> | |
</div> | |
</> | |
)} | |
</FieldArray> | |
</div> | |
)} | |
</> | |
) : null} | |
</div> | |
<div className="footer-wrapper"> | |
{!currentEmployeeEditing && | |
((!latestPublicId && detailsStep === 4) || | |
(personalInfo?.userInvitation !== "true" && | |
detailsStep === 4) ? ( | |
<div className="flex justify-end"> | |
<div className="flex items-center gap-2 px-3 pb-3"> | |
<label | |
htmlFor="userInvitation" | |
className="text-sm font-medium text-gray-700" | |
> | |
{t("Send Invitation")} | |
</label> | |
<CustomCheckbox | |
checked={values.userInvitation === "true"} | |
onChange={() => | |
setFieldValue( | |
"userInvitation", | |
values.userInvitation === "true" | |
? "false" | |
: "true" | |
) | |
} | |
/> | |
</div> | |
</div> | |
) : personalInfo?.userInvitation === "true" && | |
!invitePending ? ( | |
<div className="flex justify-end"> | |
<div className="flex items-center gap-2 px-3 pb-3"> | |
<span className="text-green-600 text-sm font-medium"> | |
{t("User already invited")} | |
</span> | |
<CustomCheckbox | |
checked={true} | |
onChange={() => {}} | |
className="opacity-50 cursor-not-allowed" | |
/> | |
</div> | |
</div> | |
) : null)} | |
<div | |
className="add-employee-footer" | |
style={detailsStep === 1 ? { justifyContent: "end" } : {}} | |
> | |
{detailsStep > 1 && detailsStep < 4 && ( | |
<div className="add-footer-left"> | |
<button | |
type="button" | |
className="add-footer-cancel-btn" | |
onClick={() => { | |
const filteredTabs = | |
values?.citizen === "true" | |
? docsTabs.filter( | |
(tab) => tab !== "Iqama" && tab !== "Visa" | |
) | |
: docsTabs.filter( | |
(tab) => tab !== "National ID" | |
); | |
const currentIndex = | |
filteredTabs.indexOf(documentTab); | |
if (detailsStep == 3) { | |
if (currentIndex == 0) { | |
setDetailsStep((prev) => prev - 1); | |
} else { | |
setDocumnetTab(filteredTabs[currentIndex - 1]); | |
} | |
} else if (detailsStep > 1) { | |
setDetailsStep((prev) => prev - 1); | |
} | |
}} | |
disabled={submitLoading || draftLoading} | |
> | |
{t("Back")} | |
</button> | |
{/* <button | |
type="button" | |
className="add-footer-cancel-btn" | |
onClick={() => setDetailsStep((prevState) => prevState + 1)} | |
> | |
Skip | |
</button> */} | |
</div> | |
)} | |
{detailsStep === 4 && ( | |
<div className="add-footer-left"> | |
<button | |
type="button" | |
className="add-footer-cancel-btn" | |
onClick={() => { | |
setDetailsStep((prevState) => prevState - 1); | |
setSkippedSections((prevSections) => | |
prevSections.filter( | |
(section) => section !== "Subscription" | |
) | |
); | |
}} | |
disabled={submitLoading || draftLoading} | |
> | |
{t("Back")} | |
</button> | |
</div> | |
)} | |
<div className="add-footer-right"> | |
{detailsStep < 4 && | |
detailsStep > 1 && | |
!shouldHideButtons && ( | |
<button | |
type="button" | |
className="add-footer-cancel-btn" | |
onClick={() => { | |
setIsDraft(false); | |
let currentSection; | |
if (detailsStep === 2) { | |
currentSection = "employmentInfo"; | |
} else if (detailsStep === 3) { | |
currentSection = documentTab; | |
} | |
// Add the current section to the skippedSections array | |
if (currentSection) { | |
setSkippedSections((prev) => | |
prev.includes(currentSection) | |
? prev | |
: [...prev, currentSection] | |
); | |
} | |
const filteredTabs = | |
values?.citizen === "true" | |
? docsTabs.filter( | |
(tab) => tab !== "Iqama" && tab !== "Visa" | |
) | |
: docsTabs.filter( | |
(tab) => tab !== "National ID" | |
); | |
const currentIndex = | |
filteredTabs.indexOf(documentTab); | |
const isLastTab = | |
currentIndex === filteredTabs.length - 1; | |
if (detailsStep == 3) { | |
if (isLastTab) { | |
setDetailsStep((prev) => prev + 1); | |
} else { | |
setDocumnetTab( | |
filteredTabs[currentIndex + 1] | |
); | |
} | |
} else if (detailsStep < 4) { | |
setDetailsStep((prev) => prev + 1); | |
} | |
}} | |
disabled={submitLoading || draftLoading} | |
> | |
{t("Skip")} | |
</button> | |
)} | |
{(personalInfo?.status !== "active" || | |
detailsStep !== 4) && | |
!shouldHideButtons && | |
((!personalInfo || personalInfo?.status === "draft") && | |
values.userInvitation === "true" && | |
detailsStep === 4 ? null : ( | |
<button | |
type="submit" | |
className="add-footer-cancel-btn" | |
onClick={() => { | |
setIsDraft(true); | |
if ( | |
!personalInfo || | |
personalInfo?.status === "draft" | |
) { | |
setDraftAndExit(true); | |
} else if (personalInfo?.status === "active") { | |
setSaveAndExit(true); | |
} | |
}} | |
disabled={ | |
submitLoading || | |
draftLoading || | |
hasValidationErrorInCurrentStep | |
} | |
> | |
{draftLoading ? ( | |
<ButtonLoading thisColor={"#475467"} /> | |
) : !personalInfo || | |
personalInfo?.status === "draft" ? ( | |
detailsStep === 4 ? ( | |
t("Save As Draft") | |
) : ( | |
t("Draft & Exit") | |
) | |
) : ( | |
personalInfo?.status === "active" && | |
t("Save & Exit") | |
)} | |
</button> | |
))} | |
<button | |
type={!shouldHideButtons ? "submit" : "button"} | |
className="add-footer-submit-btn" | |
disabled={ | |
submitLoading || | |
draftLoading || | |
hasValidationErrorInCurrentStep | |
} | |
onClick={(e) => { | |
setIsDraft(false); | |
if (shouldHideButtons) { | |
// CRITICAL: Prevent form submission | |
e.preventDefault(); | |
e.stopPropagation(); | |
let currentSection; | |
if (detailsStep === 2) { | |
currentSection = "employmentInfo"; | |
} else if (detailsStep === 3) { | |
currentSection = documentTab; | |
} | |
// Add the current section to the skippedSections array | |
if (currentSection) { | |
setSkippedSections((prev) => | |
prev.includes(currentSection) | |
? prev | |
: [...prev, currentSection] | |
); | |
} | |
const filteredTabs = | |
values?.citizen === "true" | |
? docsTabs.filter( | |
(tab) => tab !== "Iqama" && tab !== "Visa" | |
) | |
: docsTabs.filter( | |
(tab) => tab !== "National ID" | |
); | |
const currentIndex = | |
filteredTabs.indexOf(documentTab); | |
const isLastTab = | |
currentIndex === filteredTabs.length - 1; | |
if (detailsStep == 3) { | |
if (isLastTab) { | |
setDetailsStep((prev) => prev + 1); | |
} else { | |
const nextTab = filteredTabs[currentIndex + 1]; | |
setDocumnetTab(nextTab); | |
} | |
} else if (detailsStep < 4) { | |
setDetailsStep((prev) => prev + 1); | |
} | |
} | |
// If shouldHideButtons is false, let the form submission proceed normally | |
}} | |
> | |
{detailsStep === 4 ? ( | |
submitLoading ? ( | |
<ButtonLoading /> | |
) : ( | |
t("Submit") | |
) | |
) : ( | |
t("Next") | |
)} | |
</button> | |
</div> | |
</div> | |
</div> | |
</> | |
)} | |
</Form> | |
)} | |
</Formik> | |
</div> | |
css: | |
/* ImportEmployeeModal.css */ | |
.add-modal-overlay { | |
position: fixed; | |
inset-block-start: 0; | |
inset-inline-start: 0; | |
width: 100%; | |
height: 100%; | |
background: rgba(0, 0, 0, 0.5); | |
z-index: 1002; | |
overflow: auto; /* Enable scrolling if content overflows */ | |
display: flex; | |
justify-content: end; | |
align-items: center; | |
padding-block: 24px; | |
padding-inline: 0 24px; | |
} | |
/* | |
overflow: auto; | |
padding: 100px 0px; */ | |
.add-modal-content { | |
max-width: 800px; | |
width: 100%; | |
/* max-height: 1033px; | |
height: 100%; */ | |
min-height: 1033px; | |
height: auto; | |
/* height: 90vh; | |
overflow-y: auto; */ | |
border-radius: 12px; | |
border: 1px solid #f2f4f7; | |
box-shadow: 0px 24px 48px -12px #1018282e; | |
background-color: #fff; | |
display: flex; | |
flex-direction: column; | |
gap: 24px; | |
flex: 1; | |
margin-block: auto; | |
margin-inline: auto 0; | |
position: relative; | |
} | |
.add-modal-header { | |
width: 100%; | |
height: 72px; | |
padding-block: 16px; | |
padding-inline: 24px; | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
border-bottom: 1px solid #eaecf0; | |
background: #f4f4f4; | |
border-start-start-radius: 12px; | |
border-start-end-radius: 12px; | |
} | |
.add-modal-title { | |
font-size: 20px; | |
font-weight: 700; | |
line-height: 32px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
} | |
.add-modal-icon-container { | |
width: 40px; | |
height: 40px; | |
border-radius: 8px; | |
background: #ffffff; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
cursor: pointer; | |
} | |
.add-body { | |
padding: 24px; | |
flex: 1; | |
} | |
.add-subheader { | |
max-height: 117px; | |
width: 100%; | |
height: 100%; | |
display: flex; | |
flex-direction: column; | |
gap: 20px; | |
padding-block: 0; | |
padding-inline: 24px; | |
} | |
.add-steps-container { | |
width: 100%; | |
max-height: 53px; | |
height: 100%; | |
/* border: 1px solid #eaecf0; */ | |
display: flex; | |
justify-content: space-between; | |
position: relative; | |
} | |
.add-steps-container::before { | |
content: ""; | |
position: absolute; | |
inset-block-start: 20%; | |
inset-inline-start: 45px; | |
inset-inline-end: 45px; | |
height: 2px; | |
background-color: #eaecf0; | |
z-index: 0; | |
} | |
.add-step-content { | |
width: auto; | |
max-height: 52px; | |
height: 100%; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
gap: 4px; | |
z-index: 2; | |
} | |
.hide-modal { | |
display: none !important; | |
} | |
.add-step-content.active .add-step-no { | |
width: 27.19px; | |
height: 26px; | |
inset-inline-start: 28.17px; | |
border-radius: 8px; | |
background: #087a85; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
font-size: 14px; | |
font-weight: 700; | |
line-height: 16.8px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #ffffff; | |
z-index: 2; | |
} | |
.add-step-content.active .add-step-heading { | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 22.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #087a85; | |
width: max-content; | |
} | |
.add-step-no { | |
width: 27.19px; | |
height: 26px; | |
border-radius: 8px; | |
background: #f2f4f7; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
font-size: 14px; | |
font-weight: 700; | |
line-height: 16.8px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #087a85; | |
} | |
.add-step-heading { | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 22.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #ababab; | |
width: max-content; | |
} | |
.add-desc { | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 22.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #475467; | |
} | |
.add-body-content-container { | |
/* max-width: 752px; */ | |
/* min-height: 706px; */ | |
width: 100%; | |
height: auto; | |
display: flex; | |
flex-direction: column; | |
gap: 24px; | |
border-radius: 12px; | |
background: #ffffff; | |
border: 1px solid #f2f4f7; | |
padding: 16px; | |
margin-block-end: 12px; | |
margin-block-start: 16px; | |
position: unset; | |
} | |
.add-body-content-header { | |
display: flex; | |
justify-content: space-between; | |
} | |
.add-body-content-heading { | |
font-size: 18px; | |
font-weight: 700; | |
line-height: 21.6px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #04080b; | |
} | |
.add-dropdown-lang { | |
max-width: 108px; | |
width: 100%; | |
max-height: 36px; | |
height: 36px; | |
padding: 4px 8px; | |
gap: 8px; | |
border-radius: 8px; | |
border: 1px; | |
background: #f9fafb; | |
border: 1px solid #f2f4f7; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
} | |
.add-body-content-grid { | |
/* max-width: 720px; */ | |
width: 100%; | |
width: 100%; | |
height: auto; | |
display: grid; | |
grid-template-columns: 1fr 1fr; | |
align-items: start; | |
gap: 16px; | |
} | |
.add-body-content-flex { | |
/* max-width: 720px; */ | |
/* max-height: 623px; */ | |
width: 100%; | |
height: auto; | |
display: flex; | |
flex-direction: column; | |
gap: 16px; | |
flex: 1; | |
} | |
.add-body-content-flex-row { | |
/* max-width: 720px; */ | |
max-height: 623px; | |
width: 100%; | |
height: auto; | |
display: grid; | |
grid-template-columns: 1fr 1fr 1fr; | |
gap: 16px; | |
} | |
.add-body-content-grid3 { | |
/* max-width: 720px; */ | |
max-height: 623px; | |
width: 100%; | |
height: auto; | |
display: grid; | |
grid-template-columns: 1fr 1fr 1fr; | |
gap: 16px; | |
} | |
.add-body-input-section { | |
/* max-width: 352px; */ | |
width: 100%; | |
/* max-height: 81px; */ | |
/* height: 100%; */ | |
height: auto; | |
display: flex; | |
flex-direction: column; | |
gap: 4px; | |
} | |
.add-label-container { | |
width: auto; | |
height: auto; | |
display: flex; | |
align-items: center; | |
gap: 4px; | |
} | |
.add-label { | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 16.8px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #04080b; | |
} | |
.add-req-mark { | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 21px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #1a6d73; | |
} | |
.add-input { | |
/* max-width: 352px; */ | |
height: 56px; | |
width: 100%; | |
padding-block: 0px; | |
padding-inline: 16px; | |
border-radius: 12px; | |
background: #f9fafb; | |
border: 1px solid #f2f4f7; | |
font-size: 14px; | |
} | |
.add-input-value { | |
min-height: 56px; | |
width: 100%; | |
padding: 16px; | |
border-radius: 12px; | |
background: linear-gradient(to right, #fdfbfb, #ebedee); | |
border: none; | |
font-size: 14px; | |
color: #1e293b; | |
font-weight: 600; | |
display: flex; | |
align-items: center; | |
justify-content: space-between; | |
box-shadow: 0 0 0 1px #cbd5e1 inset, 0 1px 3px rgba(0, 0, 0, 0.06); | |
cursor: not-allowed; | |
} | |
.add-input-badge { | |
font-size: 12px; | |
background-color: #e2e8f0; | |
color: #475569; | |
padding: 2px 8px; | |
border-radius: 8px; | |
font-weight: 500; | |
white-space: nowrap; | |
} | |
.add-input-textarea { | |
/* max-width: 352px; */ | |
height: 120px; | |
width: 100%; | |
padding: 16px; | |
border-radius: 12px; | |
background: #f9fafb; | |
border: 1px solid #f2f4f7; | |
font-size: 14px; | |
} | |
.add-input-textarea::placeholder { | |
font-size: 12px; | |
font-weight: 400; | |
line-height: 14.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #a0a0a0; | |
} | |
.add-body-input-section-full { | |
width: 100%; | |
/* max-height: 81px; */ | |
/* height: 100%; */ | |
height: auto; | |
display: flex; | |
flex-direction: column; | |
gap: 4px; | |
margin-block-end: 10px; | |
} | |
.add-input-full { | |
height: 56px; | |
width: 100%; | |
padding-block: 0px; | |
padding-inline: 16px; | |
border-radius: 12px; | |
background: #f9fafb; | |
border: 1px solid #f2f4f7; | |
font-size: 14px; | |
} | |
.add-input-wrapper { | |
position: relative; | |
width: 100%; | |
} | |
.add-wrap-input { | |
height: 56px; | |
width: 100%; | |
padding-block: 0px !important; | |
padding-inline: 16px 45px !important; | |
border-radius: 12px; | |
background: #f9fafb !important; | |
border: 1px solid #f2f4f7; | |
color: #04080b; | |
font-size: 14px; | |
text-align: start; | |
} | |
.empty { | |
color: #a0a0a0; | |
} | |
/* Base styles for the date icon */ | |
.add-date-input-in { | |
z-index: 2; | |
position: absolute; | |
right: 16px; /* Default for LTR */ | |
top: 50%; | |
transform: translateY(-50%); | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 16.8px; | |
color: #04080b; | |
cursor: pointer; | |
pointer-events: none; | |
} | |
/* RTL-specific override for the date icon */ | |
[dir="rtl"] .add-date-input-in { | |
right: auto; /* Clear the right property */ | |
left: 16px; /* Place on the left side for RTL */ | |
} | |
/* RTL-specific padding adjustment for the input if needed */ | |
[dir="rtl"] .add-wrap-input { | |
padding-right: 16px !important; | |
padding-left: 45px !important; | |
} | |
input[type="date"]::-webkit-calendar-picker-indicator { | |
opacity: 0; | |
position: absolute; | |
inset-inline-start: 50%; /* Ensures the calendar still shows up */ | |
inset-inline-end: 0; | |
width: 100%; | |
height: 100%; | |
cursor: pointer; | |
} | |
input[type="date"] { | |
-moz-appearance: textfield; | |
position: relative; | |
z-index: 2; | |
background: transparent; | |
} | |
.add-wrap-input::placeholder { | |
font-size: 12px; | |
color: #a0a0a0; | |
} | |
.add-input-in { | |
position: absolute; | |
right: 16px; /* Default for LTR */ | |
top: 50%; | |
transform: translateY(-50%); | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 16.8px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #04080b; | |
cursor: pointer; | |
} | |
/* RTL-specific override for the input icon */ | |
[dir="rtl"] .add-input-in { | |
right: auto; /* Clear the right property */ | |
left: 16px; /* Place on the left side for RTL */ | |
} | |
.add-input-asyncselect { | |
height: 56px; | |
width: 100%; | |
padding-block: 0px; | |
padding-inline: 16px; | |
border-radius: 12px; | |
background: #f9fafb; | |
border: 1px solid #f2f4f7; | |
font-size: 14px; | |
display: flex; | |
align-items: center; | |
} | |
.add-input-asyncselect input { | |
height: 100%; | |
padding: 0; | |
border: none; | |
outline: none; | |
background: transparent; | |
font-size: 14px; | |
color: #04080b; | |
} | |
.add-input-asyncselect input::placeholder { | |
font-size: 12px; | |
font-weight: 400; | |
line-height: 14.4px; | |
text-align: start; | |
color: #a0a0a0; | |
} | |
.add-input-asyncselect input:focus { | |
border: 1px solid #b3b3b3; | |
outline: none; | |
} | |
.add-input::placeholder { | |
font-size: 12px; | |
font-weight: 400; | |
line-height: 14.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #a0a0a0; | |
} | |
.add-radio-input { | |
width: 20px; | |
height: 20px; | |
} | |
.add-radio-input-container { | |
max-width: 352px; | |
width: 100%; | |
height: 56px; | |
/* height: Fixed (56px)px; */ | |
display: flex; | |
align-items: center; | |
gap: 16px; | |
} | |
.add-radio-container { | |
display: flex; | |
align-items: center; | |
gap: 8px; | |
} | |
.add-tabs-container { | |
max-width: 756px; | |
width: 100%; | |
height: 40px; | |
border-bottom: 1px solid #f2f4f7; | |
display: flex; | |
align-items: center; | |
overflow-x: auto; | |
scrollbar-width: none; | |
} | |
.add-tab.active { | |
width: auto; | |
max-height: 40px; | |
height: 100%; | |
padding-block: 0px; | |
padding-inline: 16px; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 22.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: var(--Color, #475467); | |
background: #e8f0f1; | |
border-bottom: 2px solid #0c6e75; | |
} | |
.add-tab { | |
width: auto; | |
max-height: 40px; | |
height: 100%; | |
padding-block: 0px; | |
padding-inline: 16px; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
color: var(--Color, #475467); | |
font-size: 14px; | |
font-weight: 700; | |
line-height: 22.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
white-space: nowrap; | |
} | |
.text-danger-custom { | |
font-size: 14px; | |
margin-block-end: 3px; | |
white-space: normal; | |
word-wrap: break-word; | |
overflow-wrap: break-word; | |
display: block; | |
max-width: 100%; | |
color: #ff4d4f; | |
line-height: 1.5; | |
font-family: inherit; | |
} | |
.add-detail-type-container { | |
/* margin-top: 10px; */ | |
display: flex; | |
flex-direction: column; | |
} | |
.add-details-type-dropdown { | |
max-width: 108px; | |
width: 100%; | |
max-height: 36px; | |
height: 36px; | |
padding: 4px 8px; | |
gap: 8px; | |
border-radius: 8px; | |
border: 1px; | |
background: #f9fafb; | |
border: 1px solid #f2f4f7; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
justify-self: end; | |
align-self: flex-end; | |
} | |
.add-total-salary-container { | |
width: 100%; | |
height: 56px; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
padding-block: 0px; | |
padding-inline: 16px; | |
gap: 8px; | |
border-radius: 12px; | |
border: 1px solid #1a6d73; | |
align-self: flex-end; | |
} | |
.add-total-sal { | |
font-size: 14px; | |
font-weight: 700; | |
line-height: 16.8px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #04080b; | |
flex: 1; | |
} | |
.add-total-sal-amt { | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 16.8px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #04080b; | |
} | |
.add-upload-doc-container { | |
max-width: 752px; | |
height: auto; | |
/* height: Hug (219px)px; */ | |
padding-block: 20px; | |
padding-inline: 16px; | |
display: flex; | |
flex-direction: column; | |
gap: 24px; | |
border-radius: 12px; | |
background: #ffffff; | |
border: 1px solid #f2f4f7; | |
} | |
.add-upload-header { | |
max-width: 720px; | |
width: 100%; | |
height: 19px; | |
display: flex; | |
justify-content: space-between; | |
} | |
.add-upload-heading { | |
font-size: 16px; | |
font-weight: 700; | |
line-height: 19.2px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #04080b; | |
} | |
.add-upload-btn { | |
border: none; | |
font-size: 14px; | |
font-weight: 700; | |
line-height: 16.8px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #1a6d73; | |
background-color: #fff; | |
} | |
.status-input { | |
max-width: 752px; | |
width: 100%; | |
max-height: 537px; | |
height: 100%; | |
padding-block: 24px; | |
padding-inline: 16px; | |
border-radius: 12px; | |
background: #f9fafb; | |
border: 1px solid #f2f4f7; | |
flex: 1; | |
margin: 0 auto; | |
} | |
.status-btn { | |
all: unset; | |
font-size: 12px; | |
font-weight: 700; | |
line-height: 14.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #1a6d73; | |
} | |
.footer-wrapper { | |
width: 100%; | |
/* height: 88px; */ | |
padding-block: 16px; | |
padding-inline: 24px; | |
border-top: 1px solid #f2f4f7; | |
} | |
.input-hint { | |
font-size: 12px; | |
color: #777; | |
margin-block-start: 4px; | |
} | |
.add-employee-footer { | |
/* max-width: 800px; */ | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
} | |
.add-footer { | |
/* max-width: 800px; */ | |
width: 100%; | |
height: 88px; | |
padding-block: 16px; | |
padding-inline: 24px; | |
border-top: 1px solid #f2f4f7; | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
} | |
.add-footer-left { | |
display: flex; | |
align-items: center; | |
gap: 12px; | |
} | |
.add-footer-right { | |
display: flex; | |
align-items: center; | |
gap: 12px; | |
} | |
.padding-helper { | |
padding-inline: 24px; | |
} | |
.add-footer-cancel-btn { | |
max-width: fit-content; | |
width: 100%; | |
height: 56px; | |
padding-block: 8px; | |
padding-inline: 24px; | |
border-radius: 12px; | |
background: #f2f4f7; | |
border: 1px solid #eaecf0; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
font-size: 16px; | |
font-weight: 700; | |
line-height: 19.2px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #475467; | |
white-space: nowrap; | |
} | |
.add-footer-submit-btn { | |
border: none; | |
max-width: 157px; | |
width: 100%; | |
height: 56px; | |
padding-block: 8px; | |
padding-inline: 24px; | |
border-radius: 12px; | |
background: #b99a51; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
font-size: 16px; | |
font-weight: 700; | |
line-height: 19.2px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #ffffff; | |
} | |
.upload-modal-overlay { | |
position: absolute; | |
right: 103%; /* Default for LTR */ | |
max-width: 600px; | |
width: 100%; | |
max-height: 613px; | |
height: 100%; | |
top: 100%; | |
transform: translateY(-100%); | |
} | |
/* RTL support */ | |
[dir="rtl"] .upload-modal-overlay { | |
right: auto; | |
left: 103%; | |
} | |
.upload-modal-content { | |
max-width: 600px; | |
width: 100%; | |
max-height: 613px; | |
height: 100%; | |
border-radius: 12px; | |
border: 1px solid #f2f4f7; | |
box-shadow: 0px 24px 48px -12px #1018282e; | |
background-color: #fff; | |
display: flex; | |
flex-direction: column; | |
flex: 1; | |
z-index: 1004; | |
overflow-y: auto; | |
} | |
.upload-modal-header { | |
max-width: 600px; | |
width: 100%; | |
height: 72px; | |
padding-block: 16px; | |
padding-inline: 24px; | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
border-bottom: 1px solid #eaecf0; | |
background: #f4f4f4; | |
border-start-start-radius: 12px; | |
border-start-end-radius: 12px; | |
} | |
.upload-modal-title { | |
font-size: 20px; | |
font-weight: 700; | |
line-height: 32px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
} | |
.upload-modal-icon-container { | |
width: 40px; | |
height: 40px; | |
border-radius: 8px; | |
background: #ffffff; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
cursor: pointer; | |
} | |
.upload-body { | |
padding: 24px; | |
flex: 1; | |
} | |
.upload-desc { | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 22.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #475467; | |
} | |
.upload-file-input-container { | |
width: 100%; | |
height: fit-content; | |
margin-block-end: 24px; | |
} | |
.upload-file-input-container2 { | |
width: 100%; | |
height: fit-content; | |
display: flex; | |
flex-direction: column; | |
gap: 4px; | |
} | |
.upload-label-container { | |
width: max-content; | |
height: fit-content; | |
display: flex; | |
gap: 4px; | |
align-items: center; | |
} | |
.upload-label { | |
font-size: 14px; | |
font-weight: 700; | |
line-height: 16.8px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #04080b; | |
} | |
.upload-req-mark { | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 21px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #1a6d73; | |
} | |
.upload-file-input-wrapper { | |
width: 100%; | |
height: 56px; | |
padding-block: 0px; | |
padding-inline: 16px; | |
display: flex; | |
align-items: center; | |
gap: 8px; | |
border-radius: 12px; | |
border: 1px solid #f2f4f7; | |
background: #f9fafb; | |
cursor: pointer; | |
} | |
.upload-file-input-replacer { | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 16.8px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #a0a0a0; | |
flex: 1; | |
} | |
.upload-file-hidden-input { | |
display: none; | |
} | |
.upload-btn { | |
all: unset; | |
font-size: 12px; | |
font-weight: 700; | |
line-height: 14.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #1a6d73; | |
} | |
.upload-footer { | |
max-width: 600px; | |
width: 100%; | |
height: 88px; | |
padding-block: 16px; | |
padding-inline: 24px; | |
border-top: 1px solid #f2f4f7; | |
justify-self: end; | |
} | |
.upload-footer-btn { | |
border: none; | |
max-width: 552px; | |
width: 100%; | |
height: 56px; | |
padding-block: 8px; | |
padding-inline: 24px; | |
gap: 8px; | |
border-radius: 12px; | |
background: #b99a51; | |
font-size: 16px; | |
font-weight: 700; | |
line-height: 19.2px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #ffffff; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
} | |
.uploaded-file-details { | |
max-width: 720px; | |
max-height: 64px; | |
width: 100%; | |
height: 100%; | |
padding: 8px; | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
gap: 8px; | |
border-radius: 8px; | |
border: 1px; | |
background: #ffffff; | |
border: 1px solid #f2f4f7; | |
} | |
.file-info { | |
max-width: 586px; | |
max-height: 41px; | |
width: 100%; | |
height: 100%; | |
display: flex; | |
flex-direction: column; | |
} | |
.file-name { | |
font-size: 14px; | |
font-weight: 400; | |
line-height: 22.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #04080b; | |
} | |
.file-size { | |
font-size: 12px; | |
font-weight: 400; | |
line-height: 19.2px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #475467; | |
} | |
.remove-file-btn { | |
all: unset; | |
border: none; | |
background-color: white; | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 22.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #1a6d73; | |
cursor: pointer; | |
justify-self: end; | |
} | |
.add-member-btn-container { | |
max-width: 121px; | |
height: 24px; | |
display: flex; | |
align-items: center; | |
gap: 4px; | |
cursor: pointer; | |
} | |
.add-member-btn-container-hidden { | |
max-width: 121px; | |
height: 24px; | |
display: flex; | |
align-items: center; | |
gap: 4px; | |
display: none; | |
} | |
.add-member-txt { | |
font-size: 14px; | |
font-weight: 500; | |
line-height: 16.8px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #1a6d73; | |
} | |
.members-container { | |
width: 100%; | |
/* max-width: 1165px; */ | |
height: auto; | |
padding: 16px; | |
gap: 8px; | |
border-radius: 12px; | |
background: #f9fafb; | |
border: 1px solid #f2f4f7; | |
display: flex; | |
flex-direction: column; | |
} | |
.members-container > * { | |
border-bottom: 1px solid #f2f4f7; | |
} | |
.members-container > *:last-child { | |
border-bottom: none; | |
} | |
.member-row { | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
} | |
.add-field-wrapper { | |
display: flex; | |
flex-direction: column; | |
gap: 4px; | |
flex: 1; | |
} | |
.add-member-input-wrap { | |
position: relative; | |
} | |
.member-no { | |
position: absolute; | |
inset-block-start: 50%; | |
transform: translateY(-50%); | |
inset-inline-start: 0; | |
} | |
.remove-member-btn { | |
all: unset; | |
font-size: 12px; | |
font-weight: 500; | |
line-height: 14.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #b42318; | |
cursor: pointer; | |
position: absolute; | |
inset-block-start: 50%; | |
transform: translateY(-50%); | |
inset-inline-end: 16px; | |
} | |
.member-input { | |
height: 56px; | |
width: 100%; | |
padding-block: 0px; | |
padding-inline: 16px 10px; | |
border-radius: 12px; | |
background: #f9fafb; | |
border: none; | |
font-size: 14px; | |
} | |
.member-input::placeholder { | |
font-size: 12px; | |
color: #a0a0a0; | |
} | |
.members-summary-container { | |
width: 100%; | |
height: auto; | |
padding: 16px; | |
display: flex; | |
flex-direction: column; | |
gap: 8px; | |
border-radius: 12px; | |
background: #f9fafb; | |
border: 1px solid #f2f4f7; | |
} | |
.member-summary-row { | |
width: 100%; | |
height: auto; | |
padding: 1px 0px 1px 0px; | |
display: flex; | |
justify-content: space-between; | |
gap: 10px; | |
} | |
.member-summary-remove { | |
font-size: 12px; | |
font-weight: 500; | |
line-height: 14.4px; | |
text-align: start; | |
text-underline-position: from-font; | |
text-decoration-skip-ink: none; | |
color: #b42318; | |
} | |
.member-summary-row:not(:nth-last-child(2)):not(:last-child) { | |
border-bottom: 1px solid #eaecf0; | |
} | |
.save-summary-container { | |
display: flex; | |
align-items: center; | |
justify-content: space-between; | |
} | |
.save-btn-container { | |
display: flex; | |
justify-content: end; | |
} | |
.form-group { | |
width: 100%; | |
} | |
.file-preview { | |
display: flex; | |
align-items: center; | |
gap: 10px; | |
} | |
.file-preview-image { | |
width: 50px; | |
height: 50px; | |
object-fit: cover; | |
border: 1px solid #ccc; | |
border-radius: 4px; | |
} | |
.view-button { | |
background-color: #007bff; | |
color: white; | |
border: none; | |
padding: 5px 10px; | |
border-radius: 4px; | |
cursor: pointer; | |
} | |
.view-button:hover { | |
background-color: #0056b3; | |
} | |
.no-file { | |
color: #888; | |
font-style: italic; | |
} | |
.css-1xc3v61-indicatorContainer svg { | |
color: #04080b !important; | |
} | |
@media (max-width: 1465px) { | |
.upload-modal-overlay { | |
position: fixed; | |
top: 0; | |
left: 0; | |
right: 0; | |
width: 100%; | |
height: 100%; | |
background: rgba(0, 0, 0, 0.5); | |
z-index: 1003; | |
overflow: auto; /* Enable scrolling if content overflows */ | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
padding: 24px; | |
max-width: unset; | |
max-height: unset; | |
transform: none; | |
} | |
/* For RTL support in responsive mode */ | |
[dir="rtl"] .upload-modal-overlay { | |
left: 0; | |
right: 0; | |
} | |
} | |
@media (max-width: 768px) { | |
.add-modal-overlay { | |
padding-inline-start: 24px; | |
} | |
.add-body-content-grid { | |
display: flex; | |
flex-direction: column; | |
gap: 16px; | |
align-items: center; | |
} | |
.add-body { | |
padding: 12px; | |
} | |
.upload-modal-content { | |
max-height: unset; | |
height: auto; | |
} | |
} | |
@media (max-width: 500px) { | |
.add-steps-container { | |
width: 500px; | |
max-width: unset; | |
} | |
.add-subheader { | |
overflow-x: scroll; | |
scrollbar-width: thin; | |
} | |
.add-body-content-header { | |
display: flex; | |
flex-direction: column; | |
gap: 4px; | |
align-items: center; | |
} | |
.add-footer-cancel-btn { | |
padding-block: 4px; | |
padding-inline: 8px; | |
font-size: 12px; | |
} | |
.add-footer-submit-btn { | |
padding-block: 4px; | |
padding-inline: 8px; | |
font-size: 12px; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment