Vaibhav_Task-#89 #29

Merged
vikas.nale merged 3 commits from Vaibhav_Task-#89 into Feature_Task_Management 2025-04-19 04:52:06 +00:00
6 changed files with 123 additions and 56 deletions

View File

@ -30,6 +30,8 @@ const ManageEmployee = () => {
const [isloading, setLoading] = useState(false); const [isloading, setLoading] = useState(false);
const navigation = useNavigate(); const navigation = useNavigate();
const [currentEmployee, setCurrentEmployee] = useState(); const [currentEmployee, setCurrentEmployee] = useState();
const [currentAddressLength, setCurrentAddressLength] = useState(0);
const [permanentAddressLength, setPermanentAddressLength] = useState(0);
const userSchema = z.object({ const userSchema = z.object({
...(employeeId ? { Id: z.number().optional() } : {}), ...(employeeId ? { Id: z.number().optional() } : {}),
@ -217,6 +219,8 @@ const ManageEmployee = () => {
} }
: {} // Empty object resets the form : {} // Empty object resets the form
); );
setCurrentAddressLength(currentEmployee?.currentAddress?.length || 0);
setPermanentAddressLength(currentEmployee?.permanentAddress?.length || 0);
}, [currentEmployee, reset]); }, [currentEmployee, reset]);
return ( return (
@ -430,12 +434,17 @@ const ManageEmployee = () => {
aria-label="Current Address" aria-label="Current Address"
aria-describedby="basic-icon-default-message2" aria-describedby="basic-icon-default-message2"
{...register("CurrentAddress")} {...register("CurrentAddress")}
onChange={(e) => {
setCurrentAddressLength(e.target.value.length);
// let react-hook-form still handle it
register("CurrentAddress").onChange(e);
}}
></textarea> ></textarea>
<div className="text-end small">
{500 - currentAddressLength} characters left
</div>
{errors.CurrentAddress && ( {errors.CurrentAddress && (
<div <div className="danger-text text-start" style={{ fontSize: "12px" }}>
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.CurrentAddress.message} {errors.CurrentAddress.message}
</div> </div>
)} )}
@ -452,12 +461,16 @@ const ManageEmployee = () => {
aria-label="Permanent Address" aria-label="Permanent Address"
aria-describedby="basic-icon-default-message2" aria-describedby="basic-icon-default-message2"
{...register("PermanentAddress")} {...register("PermanentAddress")}
onChange={(e) => {
setPermanentAddressLength(e.target.value.length);
register("PermanentAddress").onChange(e);
}}
></textarea> ></textarea>
<div className="text-end small">
{500 - permanentAddressLength} characters left
</div>
{errors.PermanentAddress && ( {errors.PermanentAddress && (
<div <div className="danger-text text-start" style={{ fontSize: "12px" }}>
className="danger-text text-start"
style={{ fontSize: "12px" }}
>
{errors.PermanentAddress.message} {errors.PermanentAddress.message}
</div> </div>
)} )}

View File

@ -21,7 +21,8 @@ const ManageProjectInfo = ( {project,handleSubmitForm, onClose} ) =>
const [CurrentProject,setCurrentProject] = useState() const [CurrentProject,setCurrentProject] = useState()
const [ isloading, setLoading ] = useState( false ) const [ isloading, setLoading ] = useState( false )
const [addressLength, setAddressLength] = useState(0);
const maxAddressLength = 500;
const projectSchema = z.object( { const projectSchema = z.object( {
...(project?.id ? { id: z.number().optional() } : {}), ...(project?.id ? { id: z.number().optional() } : {}),
@ -79,7 +80,9 @@ const ManageProjectInfo = ( {project,handleSubmitForm, onClose} ) =>
projectStatusId: String(project.projectStatusId) || "0" , projectStatusId: String(project.projectStatusId) || "0" ,
} :{} } :{}
) )
setAddressLength(project?.projectAddress?.length || 0);
},[project,reset,]) },[project,reset,])
@ -205,16 +208,20 @@ const ManageProjectInfo = ( {project,handleSubmitForm, onClose} ) =>
</label> </label>
<div className="input-group"> <div className="input-group">
<textarea <textarea
type="text"
id="projectAddress" id="projectAddress"
name="projectAddress" name="projectAddress"
className="form-control" className="form-control"
maxLength={maxAddressLength}
{...register("projectAddress")} {...register("projectAddress")}
onChange={(e) => {
setAddressLength(e.target.value.length);
}}
/> />
</div> </div>
<div className="text-end" style={{ fontSize: "12px" }}>
{maxAddressLength - addressLength} characters left
</div>
{errors.projectAddress && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.projectAddress.message}</div>} {errors.projectAddress && <div className="danger-text text-start" style={{fontSize:"12px"}}>{errors.projectAddress.message}</div>}
</div> </div>
<div className="col-12 text-center"> <div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3" > <button type="submit" className="btn btn-sm btn-primary me-3" >

View File

@ -58,14 +58,16 @@ const CreateJobRole = ({onClose}) => {
reset({ reset({
role: "", role: "",
description: "" description: ""
}) });
setDescriptionLength(0);
} }
useEffect(()=>{ useEffect(()=>{
return ()=>resetForm() return ()=>resetForm()
},[]) },[])
const [descriptionLength, setDescriptionLength] = useState(0);
const maxDescriptionLength = 255;
return (<> return (<>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}> <form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
@ -83,7 +85,14 @@ const CreateJobRole = ({onClose}) => {
rows="3" rows="3"
{...register("description")} {...register("description")}
className={`form-control ${errors.description ? 'is-invalids' : ''}`} className={`form-control ${errors.description ? 'is-invalids' : ''}`}
onChange={(e) => {
setDescriptionLength(e.target.value.length);
register("description").onChange(e);
}}
></textarea> ></textarea>
<div className="text-end small text-muted">
{maxDescriptionLength - descriptionLength} characters left
</div>
{errors.description && ( {errors.description && (
<p className="text-danger">{errors.description.message}</p> <p className="text-danger">{errors.description.message}</p>
)} )}

View File

@ -73,6 +73,11 @@ const onSubmit = (values) => {
}; };
const [descriptionLength, setDescriptionLength] = useState(0);
const maxDescriptionLength = 255;
useEffect(() => {
setDescriptionLength(0);
}, []);
return ( return (
@ -95,7 +100,16 @@ const onSubmit = (values) => {
rows="3" rows="3"
{...register("description")} {...register("description")}
className={`form-control ${errors.description ? 'is-invalids' : ''}`} className={`form-control ${errors.description ? 'is-invalids' : ''}`}
onChange={(e) => {
setDescriptionLength(e.target.value.length);
// Also update react-hook-form's value
register("description").onChange(e);
}}
></textarea> ></textarea>
<div className="text-end small text-muted">
{maxDescriptionLength - descriptionLength} characters left
</div>
{errors.description && ( {errors.description && (
<p className="text-danger">{errors.description.message}</p> <p className="text-danger">{errors.description.message}</p>
)} )}

View File

@ -68,9 +68,13 @@ const EditJobRole = ({data,onClose}) => {
reset({ reset({
role: data?.name, role: data?.name,
description: data?.description description: data?.description
}) });
setDescriptionLength(data?.description?.length || 0);
}, [data, reset]);
const [descriptionLength, setDescriptionLength] = useState(data?.description?.length || 0);
const maxDescriptionLength = 255;
},[data,reset])
return (<> return (<>
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}> <form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
@ -88,10 +92,18 @@ const EditJobRole = ({data,onClose}) => {
rows="3" rows="3"
{...register("description")} {...register("description")}
className={`form-control ${errors.description ? 'is-invalids' : ''}`} className={`form-control ${errors.description ? 'is-invalids' : ''}`}
onChange={(e) => {
setDescriptionLength(e.target.value.length);
register("description").onChange(e);
}}
></textarea> ></textarea>
<div className="text-end small text-muted">
{maxDescriptionLength - descriptionLength} characters left
</div>
{errors.description && ( {errors.description && (
<p className="text-danger">{errors.description.message}</p> <p className="text-danger">{errors.description.message}</p>
)} )}
</div> </div>
<div className="col-12 text-center"> <div className="col-12 text-center">

View File

@ -126,8 +126,13 @@ const EditMaster=({master,onClose})=> {
role: master?.item?.role, role: master?.item?.role,
description: master?.item?.description, description: master?.item?.description,
permissions: initialPermissions, permissions: initialPermissions,
}) });
},[master,reset]) setDescriptionLength(master?.item?.description?.length || 0);
}, [master, reset]);
const [descriptionLength, setDescriptionLength] = useState(master?.item?.description?.length || 0);
const maxDescriptionLength = 255;
return ( return (
@ -148,7 +153,14 @@ const EditMaster=({master,onClose})=> {
rows="3" rows="3"
{...register("description")} {...register("description")}
className={`form-control ${errors.description ? 'is-invalids' : ''}`} className={`form-control ${errors.description ? 'is-invalids' : ''}`}
onChange={(e) => {
setDescriptionLength(e.target.value.length);
register("description").onChange(e);
}}
></textarea> ></textarea>
<div className="text-end small text-muted">
{maxDescriptionLength - descriptionLength} characters left
</div>
{errors.description && ( {errors.description && (
<p className="text-danger">{errors.description.message}</p> <p className="text-danger">{errors.description.message}</p>
)} )}