added validation for aadhar, pan Number, email, phone number and address length.
This commit is contained in:
parent
21ca99455b
commit
e6a687c8e2
@ -13,7 +13,7 @@ import { useEmployeeProfile } from "../../hooks/useEmployees";
|
|||||||
import { clearCacheKey, getCachedData } from "../../slices/apiDataManager";
|
import { clearCacheKey, getCachedData } from "../../slices/apiDataManager";
|
||||||
import {clearApiCacheKey} from "../../slices/apiCacheSlice";
|
import {clearApiCacheKey} from "../../slices/apiCacheSlice";
|
||||||
|
|
||||||
const mobileNumberRegex = /^(?:\d{10}|\d{3}[-\s]?\d{3}[-\s]?\d{4})$/;
|
const mobileNumberRegex = /^[7-9]\d{9}$/;
|
||||||
|
|
||||||
const ManageEmployee = () => {
|
const ManageEmployee = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
@ -41,9 +41,17 @@ const ManageEmployee = () => {
|
|||||||
Email: z.string().optional(),
|
Email: z.string().optional(),
|
||||||
CurrentAddress: z
|
CurrentAddress: z
|
||||||
.string()
|
.string()
|
||||||
.min(1, { message: "Current Address is required" }),
|
.min(1, { message: "Current Address is required" }).max(150, { message: "Address cannot exceed 150 characters" }),
|
||||||
BirthDate: z.string().min(1, { message: "Birth Date is required" }),
|
BirthDate: z.string().min(1, { message: "Birth Date is required" }).refine((date, ctx) => {
|
||||||
JoiningDate: z.string().min(1, { message: "Joining Date is required" }),
|
return new Date(date) <= new Date();
|
||||||
|
}, {
|
||||||
|
message: "Birth date cannot be in the future",
|
||||||
|
}),
|
||||||
|
JoiningDate: z.string().min(1, { message: "Joining Date is required" }).refine((date, ctx) => {
|
||||||
|
return new Date(date) <= new Date();
|
||||||
|
}, {
|
||||||
|
message: "Joining date cannot be in the future",
|
||||||
|
}),
|
||||||
EmergencyPhoneNumber: z
|
EmergencyPhoneNumber: z
|
||||||
.string()
|
.string()
|
||||||
.min(1, { message: "Phone Number is required" })
|
.min(1, { message: "Phone Number is required" })
|
||||||
@ -52,7 +60,7 @@ const ManageEmployee = () => {
|
|||||||
.string()
|
.string()
|
||||||
.min(1, { message: "Emergency Contact Person is required" }),
|
.min(1, { message: "Emergency Contact Person is required" }),
|
||||||
AadharNumber: z.string()
|
AadharNumber: z.string()
|
||||||
.regex(/^\d{12}$/, "Aadhar card must be exactly 12 digits long") // Regex to ensure only 12 digits
|
.regex(/^\d{12}$/, "Aadhar card must be exactly 12 digits long")
|
||||||
.nonempty("Aadhar card is required"),
|
.nonempty("Aadhar card is required"),
|
||||||
Gender: z
|
Gender: z
|
||||||
.string()
|
.string()
|
||||||
@ -60,61 +68,22 @@ const ManageEmployee = () => {
|
|||||||
.refine((val) => val !== "Select Gender", {
|
.refine((val) => val !== "Select Gender", {
|
||||||
message: "Please select a gender",
|
message: "Please select a gender",
|
||||||
}),
|
}),
|
||||||
PanNumber: z.string().optional(),
|
PanNumber: z
|
||||||
|
.string()
|
||||||
|
.optional()
|
||||||
|
.refine((val) => !val || /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/.test(val), {
|
||||||
|
message: "Invalid PAN number",
|
||||||
|
}),
|
||||||
PeramnentAddress: z
|
PeramnentAddress: z
|
||||||
.string()
|
.string()
|
||||||
.min(1, { message: "Permanent Address is required" }),
|
.min(1, { message: "Permanent Address is required" }).max(150, { message: "Address cannot exceed 150 characters" }),
|
||||||
PhoneNumber: z
|
PhoneNumber: z
|
||||||
.string()
|
.string()
|
||||||
.min(1, { message: "Phone Number is required" })
|
.min(1, { message: "Phone Number is required" })
|
||||||
.regex(mobileNumberRegex, { message: "Invalid phone number " }),
|
.regex(mobileNumberRegex, { message: "Invalid phone number " }),
|
||||||
JobRoleId: z.string().min(1, { message: "Role is required" }),
|
JobRoleId: z.string().min(1, { message: "Role is required" }),
|
||||||
// Documents: z
|
|
||||||
// .array(z.unknown())
|
|
||||||
// // .optional()
|
|
||||||
// .default([])
|
|
||||||
// .refine((value) => value.length > 0, {
|
|
||||||
// message: "Documents is required",
|
|
||||||
// })
|
|
||||||
// .refine((value) => {
|
|
||||||
// return value.every((file) => file.size <= 5000000); //this required if want
|
|
||||||
// }, "Each file must be less than 5MB")
|
|
||||||
// .refine((value) => {
|
|
||||||
// if (!value || value.length === 0) return true;
|
|
||||||
// return value.every((file) =>
|
|
||||||
// ["application/pdf", "application/msword", "image/jpeg", "image/png"].includes(file.type)
|
|
||||||
// );
|
|
||||||
// }, "Only PDF, Word, and image files are allowed"),
|
|
||||||
// Photo: z
|
|
||||||
// .unknown()
|
|
||||||
// .default(null)
|
|
||||||
|
|
||||||
// .refine((value) => value !== undefined && value !== null, {
|
|
||||||
// message: "Photo is required",
|
|
||||||
// })
|
|
||||||
// .refine((value) => value?.size <= 5000000, { //this required if want
|
|
||||||
// message: "The file must be less than 5MB", //size
|
|
||||||
// })
|
|
||||||
// .refine((value) => {
|
|
||||||
// if (!value || value.length === 0) return true;
|
|
||||||
// return value && ["image/jpeg", "image/png", "image/jpg"].includes(value?.type);
|
|
||||||
// }, { message: "Only JPEG and PNG images are allowed" }),
|
|
||||||
})
|
})
|
||||||
.superRefine((data, ctx) => {
|
|
||||||
if (!data.AadharNumber && !data.PanNumber) {
|
|
||||||
ctx.addIssue({
|
|
||||||
code: z.ZodIssueCode.custom,
|
|
||||||
message: "Either Aadhar Number or Pan Number is required.",
|
|
||||||
path: ["AadharNumber"], // Add error to AadharNumber
|
|
||||||
});
|
|
||||||
|
|
||||||
ctx.addIssue({
|
|
||||||
code: z.ZodIssueCode.custom,
|
|
||||||
message: "Either Aadhar Number or Pan Number is required.",
|
|
||||||
path: ["PanNumber"], // Add error to PanNumber
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
@ -142,8 +111,6 @@ const ManageEmployee = () => {
|
|||||||
PeramnentAddress: currentEmployee?.peramnentAddress || "",
|
PeramnentAddress: currentEmployee?.peramnentAddress || "",
|
||||||
PhoneNumber: currentEmployee?.phoneNumber || "",
|
PhoneNumber: currentEmployee?.phoneNumber || "",
|
||||||
JobRoleId: currentEmployee?.jobRoleId || "",
|
JobRoleId: currentEmployee?.jobRoleId || "",
|
||||||
// Documents: currentEmployee?.documents || [],
|
|
||||||
// Photo: currentEmployee?.photo || null
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -175,13 +142,11 @@ const ManageEmployee = () => {
|
|||||||
EmployeeRepository.manageEmployee(formDataToSend)
|
EmployeeRepository.manageEmployee(formDataToSend)
|
||||||
.then( ( response ) =>
|
.then( ( response ) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
showToast("Employee details updated successfully.", "success" );
|
showToast("Employee details updated successfully.", "success" );
|
||||||
clearCacheKey("employeeListByProject")
|
clearCacheKey("employeeListByProject")
|
||||||
clearCacheKey("allEmployeeList")
|
clearCacheKey( "allEmployeeList" )
|
||||||
navigation("/employees");
|
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
navigation("/employees");
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
showToast(error.message, "error");
|
showToast(error.message, "error");
|
||||||
@ -218,12 +183,9 @@ const ManageEmployee = () => {
|
|||||||
PeramnentAddress: currentEmployee.peramnentAddress || "",
|
PeramnentAddress: currentEmployee.peramnentAddress || "",
|
||||||
PhoneNumber: currentEmployee.phoneNumber || "",
|
PhoneNumber: currentEmployee.phoneNumber || "",
|
||||||
JobRoleId: currentEmployee.jobRoleId?.toString() || "",
|
JobRoleId: currentEmployee.jobRoleId?.toString() || "",
|
||||||
// Documents: currentEmployee.documents || [],
|
|
||||||
// Photo: currentEmployee.photo || null,
|
|
||||||
}
|
}
|
||||||
: {} // Empty object resets the form
|
: {} // Empty object resets the form
|
||||||
);
|
);
|
||||||
// if(currentEmployee && currentEmployee.email) setDisabledEmail(true)
|
|
||||||
}, [currentEmployee, reset]);
|
}, [currentEmployee, reset]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -235,12 +197,11 @@ const ManageEmployee = () => {
|
|||||||
<h6 className="mb-0">
|
<h6 className="mb-0">
|
||||||
{employee ? "Update Employee" : "Create Employee"}
|
{employee ? "Update Employee" : "Create Employee"}
|
||||||
</h6>
|
</h6>
|
||||||
{/* <h6 className="cursor-pointer" onClick={() => navigation( "/employees" )}><i class='bx bx-arrow-back'></i>Back</h6> */}
|
|
||||||
|
|
||||||
<button className="btn btn-sm btn-secondary btn-prev" onClick={() => navigation( "/employees" )} >
|
<span className="cursor-pointer fs-6" data-htm="true" data-bs-toggle="tooltip"
|
||||||
<i className="icon-base bx bx-left-arrow-alt me-sm-2 me-0 scaleX-n1-rtl"></i>
|
data-bs-offset="0,6"
|
||||||
<span className="align-middle d-sm-inline-block d-none">Back</span>
|
data-bs-placement="top"
|
||||||
</button>
|
data-bs-html="true" title="Move Back" onClick={()=>navigation("/employees")}><i class='bx bxs-chevron-left'></i> Back</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
{!currentEmployee && empLoading && (
|
{!currentEmployee && empLoading && (
|
||||||
@ -310,8 +271,6 @@ const ManageEmployee = () => {
|
|||||||
<div className="row mb-3">
|
<div className="row mb-3">
|
||||||
<div className="col-sm-6">
|
<div className="col-sm-6">
|
||||||
<div className="form-text text-start">Email</div>
|
<div className="form-text text-start">Email</div>
|
||||||
|
|
||||||
{/* <div className="input-group input-group-merge"> */}
|
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
id="Email"
|
id="Email"
|
||||||
@ -550,9 +509,9 @@ const ManageEmployee = () => {
|
|||||||
id="AadharNumber"
|
id="AadharNumber"
|
||||||
placeholder="AADHAR Number"
|
placeholder="AADHAR Number"
|
||||||
/>
|
/>
|
||||||
{errors.root?.AadharNumber && (
|
{errors.AadharNumber && (
|
||||||
<div className="danger-text text-start">
|
<div className="danger-text text-start">
|
||||||
{errors.AadharNumber.root?.message}
|
{errors.AadharNumber.message}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -566,67 +525,9 @@ const ManageEmployee = () => {
|
|||||||
id="PanNumber"
|
id="PanNumber"
|
||||||
placeholder="PAN Number"
|
placeholder="PAN Number"
|
||||||
/>
|
/>
|
||||||
{/* {errors.PanNumber && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.PanNumber.message}</div>} */}
|
{errors.PanNumber && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.PanNumber.message}</div>}
|
||||||
</div>
|
</div>
|
||||||
{(errors.AadharNumber || errors.PanNumber ) && (
|
|
||||||
<div className="danger-text text-start">
|
|
||||||
{errors.AadharNumber?.message ||errors.PanNumber?.message
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="row mb-3">
|
|
||||||
<div className="col-sm-12">
|
|
||||||
<div className="form-text text-start">Upload Photo</div>
|
|
||||||
<Controller
|
|
||||||
name="Photo"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
accept="image/*"
|
|
||||||
className="form-control form-control-sm"
|
|
||||||
onChange={(e) => {
|
|
||||||
field.onChange(e.target.files[0]);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{errors.Photo && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.Photo.message}</div>}
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
{/* <div className="row mb-3">
|
|
||||||
<div className="col-sm-12">
|
|
||||||
<div className="form-text text-start">Upload Documents</div>
|
|
||||||
|
|
||||||
<Controller
|
|
||||||
name="Documents"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
accept=".doc,.docx,.pdf,image/*"
|
|
||||||
multiple
|
|
||||||
className="form-control form-control-sm"
|
|
||||||
onChange={(e) => {
|
|
||||||
|
|
||||||
field.onChange(Array.from(e.target.files));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="form-text text-start mt-1">
|
|
||||||
{getValues("Documents") && Array.from(getValues("Documents")).map((item, index) => (
|
|
||||||
<span key={index} className="ms-1 mt-1 badge rounded-pill bg-secondary">
|
|
||||||
{item.name}
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
{errors.Documents && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.Documents.message}</div>}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
|
|
||||||
{employeeId && (
|
{employeeId && (
|
||||||
<div className="row mb-3 d-none">
|
<div className="row mb-3 d-none">
|
||||||
|
@ -60,13 +60,11 @@ const AttendancePage = () =>
|
|||||||
modalElement.style.display = 'none';
|
modalElement.style.display = 'none';
|
||||||
document.body.classList.remove('modal-open');
|
document.body.classList.remove('modal-open');
|
||||||
document.querySelector('.modal-backdrop').remove();
|
document.querySelector('.modal-backdrop').remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const handleSubmit = ( formData ) =>{
|
const handleSubmit = ( formData ) =>{
|
||||||
|
|
||||||
dispatch( markCurrentAttendance( formData ) ).then( ( action ) =>
|
dispatch( markCurrentAttendance( formData ) ).then( ( action ) =>
|
||||||
{
|
{
|
||||||
const updatedAttendance = attendances.map(item =>
|
const updatedAttendance = attendances.map(item =>
|
||||||
|
@ -17,7 +17,6 @@ const MasterPage = () => {
|
|||||||
const [searchTerm, setSearchTerm] = useState('');
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
const [ filteredResults, setFilteredResults ] = useState( [] );
|
const [ filteredResults, setFilteredResults ] = useState( [] );
|
||||||
const hasMasterPermission = useHasUserPermission( MANAGE_MASTER )
|
const hasMasterPermission = useHasUserPermission( MANAGE_MASTER )
|
||||||
console.log(hasMasterPermission)
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const selectedMaster = useSelector((store)=>store.localVariables.selectedMaster)
|
const selectedMaster = useSelector((store)=>store.localVariables.selectedMaster)
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ const MasterTable = ( {data, columns, loading, handleModalData} ) =>
|
|||||||
>
|
>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
||||||
<th></th>
|
<th></th>
|
||||||
<th>{ selectedMaster} Name</th>
|
<th>{ selectedMaster} Name</th>
|
||||||
<th>{selectedMaster } Description</th>
|
<th>{selectedMaster } Description</th>
|
||||||
@ -73,12 +72,9 @@ const MasterTable = ( {data, columns, loading, handleModalData} ) =>
|
|||||||
) : (
|
) : (
|
||||||
item[col.key] !== undefined && item[col.key] !== null ? item[col.key] : " --- "
|
item[col.key] !== undefined && item[col.key] !== null ? item[col.key] : " --- "
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|
||||||
))}
|
))}
|
||||||
<td className={`${!hasMasterPermission && 'd-none'}`} >
|
<td className={`${!hasMasterPermission && 'd-none'}`} >
|
||||||
{/* className={` ${hasUserPermission('660131a4-788c-4739-a082-cbbf7879cbf2') ? "":"d-none"}`}> */}
|
|
||||||
<button
|
<button
|
||||||
aria-label="Modify"
|
aria-label="Modify"
|
||||||
type="button"
|
type="button"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user