diff --git a/src/components/Activities/AttendcesLogs.jsx b/src/components/Activities/AttendcesLogs.jsx index 65a85be9..626c3c05 100644 --- a/src/components/Activities/AttendcesLogs.jsx +++ b/src/components/Activities/AttendcesLogs.jsx @@ -12,8 +12,9 @@ const AttendanceLog = ({ attendance, handleModalData, projectId }) => { const { data, loading, error } = useSelector((store) => store.attendanceLogs); // Set the default selected date to the current date - const currentDate = new Date().toISOString().split("T")[0]; // "YYYY-MM-DD" - + + // const currentDate = new Date().toISOString().split("T")[0]; // "YYYY-MM-DD" + const currentDate = new Date().toLocaleDateString('en-CA'); const handleDateChange = (e) => { const date = e.target.value; setSelectedDate(date); diff --git a/src/components/Activities/CheckCheckOutForm.jsx b/src/components/Activities/CheckCheckOutForm.jsx index 93b8069c..c4012e81 100644 --- a/src/components/Activities/CheckCheckOutForm.jsx +++ b/src/components/Activities/CheckCheckOutForm.jsx @@ -35,7 +35,6 @@ const CheckCheckOutmodel = ({modeldata,closeModal,handleSubmitForm,}) => { const onSubmit = ( data ) => { - console.log(data) let record = {...data, date: new Date().toLocaleDateString(),latitude:coords.latitude,longitude:coords.longitude,employeeId:modeldata.employeeId,action:modeldata.action,id:modeldata?.id || null} if(modeldata.forWhichTab === 1){ handleSubmitForm(record) @@ -134,7 +133,8 @@ export const Regularization = ({modeldata,closeModal,handleSubmitForm})=>{ const getCurrentDate = () => { const today = new Date(); - return today.toISOString().split("T")[0]; + // return today.toISOString().split("T")[0]; + return today.toLocaleDateString('en-CA'); }; @@ -143,7 +143,6 @@ export const Regularization = ({modeldata,closeModal,handleSubmitForm})=>{ let record = {...data, date: new Date().toLocaleDateString(),latitude:coords.latitude,longitude:coords.longitude, } - console.log(record) handleSubmitForm(record) closeModal() }; diff --git a/src/components/Dashboard/Dashboard.jsx b/src/components/Dashboard/Dashboard.jsx index fd970c1a..f4eb0ba3 100644 --- a/src/components/Dashboard/Dashboard.jsx +++ b/src/components/Dashboard/Dashboard.jsx @@ -37,7 +37,8 @@ const Dashboard = () => { const days = getDaysFromRange(range); const today = new Date(); - const FromDate = today.toISOString().split("T")[0]; // Always today + // const FromDate = today.toISOString().split("T")[0]; + const FromDate = today.toLocaleDateString('en-CA'); // Always today const { projectsCardData } = useDashboardProjectsCardData(); const { teamsCardData } = useDashboardTeamsCardData(); diff --git a/src/components/Employee/ManageEmployee.jsx b/src/components/Employee/ManageEmployee.jsx index 94d270f6..bb1f5ef4 100644 --- a/src/components/Employee/ManageEmployee.jsx +++ b/src/components/Employee/ManageEmployee.jsx @@ -23,8 +23,10 @@ const ManageEmployee = () => { employee, error, loading: empLoading, - } = useEmployeeProfile(employeeId); - dispatch(changeMaster("Job Role")); + } = useEmployeeProfile( employeeId ); + + dispatch( changeMaster( "Job Role" ) ); + const [disabledEmail, setDisabledEmail] = useState(false); const { data: job_role, loading } = useMaster(); const [isloading, setLoading] = useState(false); @@ -39,7 +41,7 @@ const ManageEmployee = () => { MiddleName: z.string().optional(), LastName: z.string().min(1, { message: "Last Name is required" }), Email: z - .string() + .string().max(80,"Email cannot exceed 80 characters") .optional() .refine((val) => !val || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val), { message: "Invalid email format", @@ -59,7 +61,7 @@ const ManageEmployee = () => { CurrentAddress: z .string() .min(1, { message: "Current Address is required" }) - .max(500, { message: "Address cannot exceed 250 characters" }), + .max(500, { message: "Address cannot exceed 500 characters" }), BirthDate: z .string() .min(1, { message: "Birth Date is required" }) @@ -111,7 +113,7 @@ const ManageEmployee = () => { PermanentAddress: z .string() .min(1, { message: "Permanent Address is required" }) - .max(500, { message: "Address cannot exceed 250 characters" }), + .max(500, { message: "Address cannot exceed 500 characters" }), PhoneNumber: z .string() .min(1, { message: "Phone Number is required" }) @@ -150,7 +152,8 @@ const ManageEmployee = () => { mode: "onChange", }); - const AadharNumberValue = watch("AadharNumber") || ""; + const AadharNumberValue = watch( "AadharNumber" ) || ""; + const onSubmit = (data) => { setLoading(true); @@ -181,8 +184,11 @@ const ManageEmployee = () => { .then((response) => { showToast("Employee details updated successfully.", "success"); clearCacheKey("employeeListByProject"); - clearCacheKey("allEmployeeList"); - setLoading(false); + clearCacheKey( "allEmployeeList" ); + clearCacheKey("employeeProfile") + + setLoading( false ); + reset() navigation("/employees"); }) .catch((error) => { @@ -251,7 +257,7 @@ const ManageEmployee = () => {
- {!currentEmployee && empLoading && ( + {(!currentEmployee && empLoading) && (

Loading Employee Data...

)} @@ -324,7 +330,7 @@ const ManageEmployee = () => { {...register("Email")} className="form-control form-control-sm" placeholder="example@domain.com" - aria-label="" + maxLength={80} aria-describedby="Email" disabled={!!currentEmployee?.email} /> @@ -347,6 +353,7 @@ const ManageEmployee = () => { className="form-control form-control-sm" placeholder="Phone Number" inputMode="numeric" + maxLength={10} /> {errors.PhoneNumber && (
{ placeholder="Current Address" aria-label="Current Address" aria-describedby="basic-icon-default-message2" - {...register("CurrentAddress")} + {...register( "CurrentAddress" )} + maxLength={500} onChange={(e) => { setCurrentAddressLength(e.target.value.length); // let react-hook-form still handle it register("CurrentAddress").onChange(e); }} > -
- {500 - currentAddressLength} characters left +
+ {500 - currentAddressLength} characters left
{errors.CurrentAddress && (
{ placeholder="Permanent Address" aria-label="Permanent Address" aria-describedby="basic-icon-default-message2" - {...register("PermanentAddress")} + {...register( "PermanentAddress" )} + maxLength={500} onChange={(e) => { setPermanentAddressLength(e.target.value.length); register("PermanentAddress").onChange(e); }} > -
- {500 - permanentAddressLength} characters left +
+ {500 - permanentAddressLength} characters left
{errors.PermanentAddress && (
{ id="EmergencyPhoneNumber" placeholder="Phone Number" inputMode="numeric" + maxLength={10} /> {errors.EmergencyPhoneNumber && (
{ const buildDefaultRoles = () => { const defaults = {}; data.forEach((role) => { - const isRoleEnabled = employeeRoles?.data?.some( + const isRoleEnabled = employeeRoles?.some( (empRole) => empRole.roleId === role.id ); defaults[role.id] = isRoleEnabled; diff --git a/src/components/Project/ManageProjectInfo.jsx b/src/components/Project/ManageProjectInfo.jsx index 5173e5aa..45f04b7c 100644 --- a/src/components/Project/ManageProjectInfo.jsx +++ b/src/components/Project/ManageProjectInfo.jsx @@ -3,7 +3,8 @@ import { useForm, Controller } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; -const currentDate = new Date().toISOString().split("T")[0]; +// const currentDate = new Date().toISOString().split("T")[0]; +const currentDate = new Date().toLocaleDateString('en-CA'); const formatDate = (date) => { if (!date) { return currentDate; @@ -12,7 +13,8 @@ const formatDate = (date) => { if (isNaN(d.getTime())) { return currentDate; } - return d.toISOString().split("T")[0]; + // return d.toISOString().split("T")[0]; + return d.toLocaleDateString('en-CA'); }; const ManageProjectInfo = ({ project, handleSubmitForm, onClose }) => { const [CurrentProject, setCurrentProject] = useState(); diff --git a/src/components/Project/ProjectOverview.jsx b/src/components/Project/ProjectOverview.jsx index 1aa1f300..a15a8ae5 100644 --- a/src/components/Project/ProjectOverview.jsx +++ b/src/components/Project/ProjectOverview.jsx @@ -4,7 +4,7 @@ import {useEmployeesByProjectAllocated, useProjects} from "../../hooks/useProjec const ProjectOverview = ({project}) => { const {projects} = useProjects() -const teamSize = projects.find((pro)=>pro.id == project) + const project_detail = projects.find( ( pro ) => pro.id == project ) return (
@@ -15,17 +15,18 @@ const teamSize = projects.find((pro)=>pro.id == project)
  • Task Planned:{" "} - 13.5k + {project_detail?.plannedWork + }
  • Task Completed:{" "} - 146 + {project_detail?.completedWork }
  • Current team Size:{" "} - {teamSize?.teamSize} + {project_detail?.teamSize}
  • diff --git a/src/components/common/DateRangePicker.jsx b/src/components/common/DateRangePicker.jsx index 9c5bc2a4..438069cc 100644 --- a/src/components/common/DateRangePicker.jsx +++ b/src/components/common/DateRangePicker.jsx @@ -20,10 +20,12 @@ const DateRangePicker = ({ onRangeChange }) => { onRangeChange?.({ startDate, endDate }); }, }); - + onRangeChange?.({ - startDate: fifteenDaysAgo.toISOString().split("T")[0], - endDate: today.toISOString().split("T")[0], + // startDate: fifteenDaysAgo.toISOString().split("T")[0], + // endDate: today.toISOString().split("T")[0], + startDate: fifteenDaysAgo.toLocaleDateString('en-CA'), + endDate: today.toLocaleDateString('en-CA'), }); return () => { diff --git a/src/components/master/CreateActivity.jsx b/src/components/master/CreateActivity.jsx index d26afd68..b7d2c862 100644 --- a/src/components/master/CreateActivity.jsx +++ b/src/components/master/CreateActivity.jsx @@ -14,7 +14,7 @@ const schema = z.object({ checkList: z .array( z.object({ - check: z.string().min(1, { message: "Checklist item cannot be empty" }), + description: z.string().min(1, { message: "descriptionlist item cannot be empty" }), isMandatory: z.boolean().default(false), id: z.any().default(0), }) @@ -82,18 +82,18 @@ const CreateActivity = ({ onClose }) => { const lastIndex = checkListItems.length - 1; if ( checkListItems.length > 0 && - (!values?.[lastIndex] || values[lastIndex].check.trim() === "") + (!values?.[lastIndex] || values[lastIndex].description.trim() === "") ) { - setError(`checkList.${lastIndex}.check`, { + setError(`checkList.${lastIndex}.description`, { type: "manual", message: "Please fill this checklist item before adding another.", }); return; } - clearErrors(`checkList.${lastIndex}.check`); + clearErrors(`checkList.${lastIndex}.description`); append({ id: 0, - check: "", + description: "", isMandatory: false, }); }; @@ -167,19 +167,19 @@ const CreateActivity = ({ onClose }) => { {...register(`checkList.${index}.id`)} > handleChecklistChange(index, e.target.value) } /> - {errors.checkList?.[index]?.check && ( + {errors.checkList?.[index]?.description && ( - {errors.checkList[index]?.check?.message} + {errors.checkList[index]?.description?.message} )} diff --git a/src/components/master/EditActivity.jsx b/src/components/master/EditActivity.jsx index 11d8c5f7..ea1cd364 100644 --- a/src/components/master/EditActivity.jsx +++ b/src/components/master/EditActivity.jsx @@ -14,7 +14,7 @@ const schema = z.object({ .array( z.object({ id: z.any().default(0), - check: z.string().min(1, { message: "Checklist item cannot be empty" }), + description: z.string().min(1, { message: "Checklist item cannot be empty" }), isMandatory: z.boolean().default(false), }) ) @@ -106,17 +106,17 @@ const UpdateActivity = ({ activityData, onClose }) => { if ( checkListItems.length > 0 && - (!values?.[lastIndex] || values[lastIndex].check.trim() === "") + (!values?.[lastIndex] || values[lastIndex].description.trim() === "") ) { - setError(`checkList.${lastIndex}.check`, { + setError(`checkList.${lastIndex}.description`, { type: "manual", message: "Please fill this checklist item before adding another.", }); return; } - clearErrors(`checkList.${lastIndex}.check`); - append({ id: 0, check: "", isMandatory: false }); + clearErrors(`checkList.${lastIndex}.description`); + append({ id: 0, description: "", isMandatory: false }); }; const removeChecklistItem = (index) => { @@ -178,19 +178,19 @@ const UpdateActivity = ({ activityData, onClose }) => { {...register(`checkList.${index}.id`)} > handleChecklistChange(index, e.target.value) } /> - {errors.checkList?.[index]?.check && ( + {errors.checkList?.[index]?.description && ( - {errors.checkList[index]?.check?.message} + {errors.checkList[index]?.description?.message} )} @@ -208,7 +208,7 @@ const UpdateActivity = ({ activityData, onClose }) => { onClick={() => removeChecklistItem(index)} className="btn btn-xs btn-icon btn-text-secondary" > - + @@ -223,7 +223,7 @@ const UpdateActivity = ({ activityData, onClose }) => { className="btn btn-xs btn-primary mt-2" onClick={addChecklistItem} > - +
    diff --git a/src/hooks/useEmployees.js b/src/hooks/useEmployees.js index 025e80bb..b48ac9bd 100644 --- a/src/hooks/useEmployees.js +++ b/src/hooks/useEmployees.js @@ -97,8 +97,8 @@ export const useEmployeeRoles = (employeeId)=>{ try { RolesRepository.getEmployeeRoles(employeeid) .then((response) => { - setEmployeeRoles(response); - cacheData("employeelist", response); + setEmployeeRoles(response.data); + cacheData("employeelist", response.data); }) .catch((error) => { setError("Failed to fetch data."); diff --git a/src/pages/employee/EmployeeList.jsx b/src/pages/employee/EmployeeList.jsx index f4559fde..13207bb4 100644 --- a/src/pages/employee/EmployeeList.jsx +++ b/src/pages/employee/EmployeeList.jsx @@ -458,30 +458,30 @@ const EmployeeList = () => { onClick={() => navigate(`/employee/${item.id}`) } - className="dropdown-item" + className="dropdown-item py-1" > - View + View - Edit + Edit
    diff --git a/src/router/ProtectedRoute.jsx b/src/router/ProtectedRoute.jsx index 23d23fec..a1879e85 100644 --- a/src/router/ProtectedRoute.jsx +++ b/src/router/ProtectedRoute.jsx @@ -41,31 +41,32 @@ const isTokenExpired = (token) => { // Function to validate and refresh the token if expired export const validateToken = async () => { const token = localStorage.getItem("jwtToken"); + const refreshTokenStored = localStorage.getItem("refreshToken"); + // If refresh token is absent, cannot proceed + if (!refreshTokenStored) { + console.warn("No refresh token available. Redirecting to login."); + return false; + } + // If access token expired, try to refresh if (isTokenExpired(token)) { - const refreshed = await refreshToken(); - return refreshed; + return await attemptTokenRefresh(refreshTokenStored); } return true; }; -// Function to refresh the access token -const refreshToken = async () => { +// Attempt to refresh the access token +const attemptTokenRefresh = async (storedRefreshToken) => { try { - AuthRepository.refreshToken({ + const response = await AuthRepository.refreshToken({ token: localStorage.getItem("jwtToken"), - refreshToken: refreshToken, - }) - .then((response) => { - localStorage.setItem("jwtToken", response.data.token); - localStorage.setItem("refreshToken", response.data.refreshToken); - return true; - }) - .catch((error) => { - console.error("Token refresh failed:", error); - }); + refreshToken: storedRefreshToken, + }); - // api + localStorage.setItem("jwtToken", response.data.token); + localStorage.setItem("refreshToken", response.data.refreshToken); + return true; + // api // .post("/api/auth/refresh-token", { // token: localStorage.getItem("jwtToken"), // refreshToken: refreshToken, @@ -92,8 +93,8 @@ const refreshToken = async () => { // } } catch (error) { console.error("Token refresh failed:", error); + return false; } - return false; }; export default ProtectedRoute; diff --git a/src/utils/axiosClient.jsx b/src/utils/axiosClient.jsx index 99eaee6f..527ec140 100644 --- a/src/utils/axiosClient.jsx +++ b/src/utils/axiosClient.jsx @@ -48,7 +48,7 @@ axiosClient.interceptors.response.use( "Connection refused. Please ensure the server is running." ); - if (error.config.url.indexOf("refresh-token") == -1) { + if (error.config.url.indexOf("refresh-token") != -1) { //showToast("Server is unreachable. Try again later!", "error"); console.log("1 - error fetching refresh token :", error); } else { @@ -59,7 +59,7 @@ axiosClient.interceptors.response.use( } } else if (error.code === "ERR_NETWORK") { console.error("Network error: Unable to reach the server."); - if (error.config.url.indexOf("refresh-token") == -1) { + if (error.config.url.indexOf("refresh-token") != -1) { //showToast("Server is unreachable. Try again later!", "error"); console.log("2 - error fetching refresh token :", error); } @@ -67,7 +67,7 @@ axiosClient.interceptors.response.use( } else if (error.code === "ECONNABORTED") { console.error("Request timed out."); - if (error.config.url.indexOf("refresh-token") == -1) { + if (error.config.url.indexOf("refresh-token") != -1) { //showToast("Server is unreachable. Try again later!", "error"); console.log("3 - error fetching refresh token :", error); } else { @@ -77,7 +77,7 @@ axiosClient.interceptors.response.use( ); } } else if (error.response) { - if (error.config.url.indexOf("refresh-token") == -1) { + if (error.config.url.indexOf("refresh-token") != -1) { //showToast("Server is unreachable. Try again later!", "error"); console.log("4 - error fetching refresh token :", error); } else { @@ -97,10 +97,14 @@ axiosClient.interceptors.response.use( return Promise.reject(error); } // Make a request to refresh the access token - const response = await axiosClient.post("/api/Auth/refresh-token", { - token: localStorage.getItem("jwtToken"), - refreshToken, - }); + const response = await axiosClient + .post("/api/Auth/refresh-token", { + token: localStorage.getItem("jwtToken"), + refreshToken, + }) + .catch((error) => { + console.log("7 - error fetching refresh token :", error); + }); const { token, refreshToken: newRefreshToken } = response.data.data; localStorage.setItem("jwtToken", token); @@ -121,7 +125,7 @@ axiosClient.interceptors.response.use( return Promise.reject(err); } } else { - if (error.config.url.indexOf("refresh-token") == -1) { + if (error.config.url.indexOf("refresh-token") != -1) { //showToast("Server is unreachable. Try again later!", "error"); console.log("6 - error fetching refresh token :", error); } diff --git a/src/utils/dateUtils.jsx b/src/utils/dateUtils.jsx index 7f4a222a..f18efd0f 100644 --- a/src/utils/dateUtils.jsx +++ b/src/utils/dateUtils.jsx @@ -23,7 +23,8 @@ export const getDateDifferenceInDays = (startDate, endDate) => { export const formatDate = (date) => { if (!date) return ""; // Return an empty string if no date const dateObj = new Date(date); - return dateObj.toISOString().split("T")[0]; // Get the date in YYYY-MM-DD format + // return dateObj.toISOString().split("T")[0]; + return dateObj.toLocaleDateString('en-CA'); // Get the date in YYYY-MM-DD format }; export const convertShortTime = (dateString) => {