From bb6c48300cd5dea83b0d4621687cb49d83217dc4 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Mon, 21 Apr 2025 17:35:42 +0530 Subject: [PATCH 1/9] Fixes error where it was showing multiple error in login and forget page --- .../authentication/ForgotPasswordPage.jsx | 8 ++++-- src/pages/authentication/LoginPage.jsx | 1 + src/utils/axiosClient.jsx | 26 +++++++++++-------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/pages/authentication/ForgotPasswordPage.jsx b/src/pages/authentication/ForgotPasswordPage.jsx index 2a3ab64c..6dc9219c 100644 --- a/src/pages/authentication/ForgotPasswordPage.jsx +++ b/src/pages/authentication/ForgotPasswordPage.jsx @@ -35,13 +35,17 @@ const ForgotPasswordPage = () => { setLoading(true) const response = await AuthRepository.forgotPassword(data) if ( response.data && response.success ) - showToast( response.message, "success" ) + showToast( "verification email has been sent to your registered email address", "success" ) reset() setLoading( false ) } catch ( err ) { + if(err.response.status === 404){ + showToast( "verification email has been sent to your registered email address", "success" ) + }else{ + showToast("Something wrong","error") + } - showToast( err.message, "error" ) setLoading(false) } } diff --git a/src/pages/authentication/LoginPage.jsx b/src/pages/authentication/LoginPage.jsx index 84b46aeb..92d03ba6 100644 --- a/src/pages/authentication/LoginPage.jsx +++ b/src/pages/authentication/LoginPage.jsx @@ -44,6 +44,7 @@ const LoginPage = () => { setLoading(false); navigate("/dashboard"); } catch (err) { + showToast("Invalid username or password.","error") console.log("Unable to proceed. Please try again."); setLoading(false); } diff --git a/src/utils/axiosClient.jsx b/src/utils/axiosClient.jsx index 527ec140..80d2d34e 100644 --- a/src/utils/axiosClient.jsx +++ b/src/utils/axiosClient.jsx @@ -11,7 +11,6 @@ export const axiosClient = axios.create({ "Content-Type": "application/json", // Specify the content type }, }); - axiosRetry(axiosClient, { retries: 3 }); // Request interceptor to add Bearer token @@ -21,6 +20,10 @@ axiosClient.interceptors.request.use( const token = localStorage.getItem("jwtToken"); if (token) { config.headers["Authorization"] = `Bearer ${token}`; + config._retry = true; + } + else{ + config._retry = false; } } return config; @@ -32,7 +35,9 @@ axiosClient.interceptors.request.use( // Add an interceptor to handle expired tokens axiosClient.interceptors.response.use( (response) => response, + async (error) => { + const originalRequest = error.config; if (!originalRequest) { @@ -80,13 +85,12 @@ axiosClient.interceptors.response.use( 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 { - showToast(error.response.data.message, "error"); - } - + } + // else { + // // showToast(error.response.data.message, "error"); // repeted toast + // } if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; - try { // Get the refresh token from secure storage const refreshToken = localStorage.getItem("refreshToken"); @@ -129,11 +133,11 @@ axiosClient.interceptors.response.use( //showToast("Server is unreachable. Try again later!", "error"); console.log("6 - error fetching refresh token :", error); } - showToast( - error.response.data?.message || - "An error occurred. Please try again.", - "error" - ); + // showToast( + // error.response.data?.message || + // "An error occurred. Please try again.", + // "error" + // ); } } else { console.error("An unknown error occurred:", error.message); From a096f3d743ed21b55e0f237ad3961f4aee801682 Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Tue, 22 Apr 2025 13:00:32 +0530 Subject: [PATCH 2/9] Set default project to the first one associated with the logged-in user. --- src/hooks/useProjects.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/hooks/useProjects.js b/src/hooks/useProjects.js index fd7320ae..aa5fa3f6 100644 --- a/src/hooks/useProjects.js +++ b/src/hooks/useProjects.js @@ -7,6 +7,7 @@ import { setProjectId } from "../slices/localVariablesSlice"; export const useProjects = () => { + const {profile} = useProfile() const dispatch = useDispatch(); const [projects, setProjects] = useState([]); const [loading, setLoading] = useState(false); @@ -48,9 +49,19 @@ export const useProjects = () => fetchData(); }, []); - useEffect(() => { - dispatch(setProjectId(projects[0]?.id)); - }, [projects]); + useEffect( () => + { + if (projects ) + { + if ( profile?.projects && profile?.projects?.length > 0 ) + { + dispatch(setProjectId(profile?.projects[0])) + } else + { + dispatch(setProjectId(1)) + } + } + }, [profile]); return { projects, loading, error, refetch: fetchData }; }; From 1caeeb890d2f566ee809fac48be7ece68552810b Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Tue, 22 Apr 2025 13:01:31 +0530 Subject: [PATCH 3/9] added filter, only display logged user associated projects --- src/pages/employee/EmployeeList.jsx | 50 +++++++++++++++-------------- src/pages/project/ProjectList.jsx | 11 ++++--- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/pages/employee/EmployeeList.jsx b/src/pages/employee/EmployeeList.jsx index 13207bb4..2e0f3bb2 100644 --- a/src/pages/employee/EmployeeList.jsx +++ b/src/pages/employee/EmployeeList.jsx @@ -163,30 +163,32 @@ const EmployeeList = () => { className="dataTables_length text-start" id="DataTables_Table_0_length" > - + diff --git a/src/pages/project/ProjectList.jsx b/src/pages/project/ProjectList.jsx index a0e9ea3e..1f5fd1e5 100644 --- a/src/pages/project/ProjectList.jsx +++ b/src/pages/project/ProjectList.jsx @@ -176,10 +176,13 @@ const ProjectList = () => {loading &&

Loading...

} - {currentItems && - currentItems.map((item) => ( - - ))} + {Array.isArray(currentItems) && loginUser?.projects && ( + currentItems + .filter((item) => loginUser.projects.includes(String(item.id))) + .map((item) => ( + + )) +)} {/* Pagination */} {!loading && ( From 461ffeb83dfc146dd9944c4fcead800cfa5a2872 Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Mon, 21 Apr 2025 22:32:42 +0530 Subject: [PATCH 4/9] fixed correct projectId is used when navigating to DailyTask --- src/pages/Activities/DailyTask.jsx | 38 ++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/pages/Activities/DailyTask.jsx b/src/pages/Activities/DailyTask.jsx index 44ed2480..f4146ac6 100644 --- a/src/pages/Activities/DailyTask.jsx +++ b/src/pages/Activities/DailyTask.jsx @@ -19,15 +19,37 @@ const DailyTask = () => { const { profile: LoggedUser } = useProfile(); const [searchParams] = useSearchParams(); const projectId = searchParams.get("project"); - + const selectedProject = useSelector( + (store) => store.localVariables.projectId + ); const { projects, loading: project_lodaing, error: projects_Error, } = useProjects(); - const selectedProject = useSelector( - (store) => store.localVariables.projectId - ); + + + + const [initialized, setInitialized] = useState(false); + + // Sync projectId (either from URL or pick first accessible one) + useEffect(() => { + if (!project_lodaing && projects.length > 0) { + const userProjects = projects.filter((p) => + LoggedUser?.projects?.map(Number).includes(p.id) + ); + + if (projectId) { + dispatch(setProjectId(projectId)); + } else if (!selectedProject && userProjects.length > 0) { + dispatch(setProjectId(userProjects[0].id)); + } + + setInitialized(true); + } + }, [project_lodaing, projects, projectId, selectedProject]); + + const dispatch = useDispatch(selectedProject); const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" }); @@ -60,9 +82,6 @@ const DailyTask = () => { openModal(); }; - useEffect(() => { - if (projectId) dispatch(setProjectId(projectId)); - }, [projectId]); return ( <>
{ )} + {(!initialized || !selectedProject) && ( + +

Loading..

+ + )} {TaskLists.map((task, index) => { const accordionId = `accordion-${index}`; From 450c8143ffc9cb7f41375d6d979834e25e75e2bf Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Tue, 22 Apr 2025 09:53:04 +0530 Subject: [PATCH 5/9] removed extra padding. --- src/components/common/GlobalModel.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/common/GlobalModel.jsx b/src/components/common/GlobalModel.jsx index d12aeb34..04d24d5a 100644 --- a/src/components/common/GlobalModel.jsx +++ b/src/components/common/GlobalModel.jsx @@ -45,7 +45,7 @@ const GlobalModel = ({ return (
-
+
-
+
{/* Close button inside the modal header */}
-
+
{children} {/* Render children here, which can be the ReportTask component */}
From a5d74a0b349969dc747623cde1111ec96275f68f Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Tue, 22 Apr 2025 09:54:27 +0530 Subject: [PATCH 6/9] updated a employee list and selected employe list --- src/components/Project/AssignRole.jsx | 141 ++++++++++++++------------ 1 file changed, 76 insertions(+), 65 deletions(-) diff --git a/src/components/Project/AssignRole.jsx b/src/components/Project/AssignRole.jsx index 1b7bfcb0..8e898bde 100644 --- a/src/components/Project/AssignRole.jsx +++ b/src/components/Project/AssignRole.jsx @@ -34,18 +34,24 @@ const AssignRoleModel = ({ assignData, onClose }) => { const [selectedRole, setSelectedRole] = useState("all"); const [selectedEmployees, setSelectedEmployees] = useState([]); - -const { handleSubmit, control, setValue, watch, formState: { errors },reset } = useForm({ - defaultValues: { - selectedEmployees: [], - description:"" - }, - resolver: (data) => { - const validation = schema.safeParse(data); - if (validation.success) return { values: data, errors: {} }; - return { values: {}, errors: validation.error.formErrors.fieldErrors }; - }, -}); + const { + handleSubmit, + control, + setValue, + watch, + formState: { errors }, + reset, + } = useForm({ + defaultValues: { + selectedEmployees: [], + description: "", + }, + resolver: (data) => { + const validation = schema.safeParse(data); + if (validation.success) return { values: data, errors: {} }; + return { values: {}, errors: validation.error.formErrors.fieldErrors }; + }, + }); const handleRoleChange = (event) => { setSelectedRole(event.plannedTask.value); @@ -78,62 +84,49 @@ const { handleSubmit, control, setValue, watch, formState: { errors },reset } = }); }; - -const onSubmit = async(data) => { - const formattedData = { - taskTeam: data.selectedEmployees, - plannedTask: parseInt( plannedTask, 10 ), - description: data.description, - assignmentDate: new Date().toISOString(), - workItemId:assignData?.workItem?.workItem.id + const onSubmit = async (data) => { + const formattedData = { + taskTeam: data.selectedEmployees, + plannedTask: parseInt(plannedTask, 10), + description: data.description, + assignmentDate: new Date().toISOString(), + workItemId: assignData?.workItem?.workItem.id, + }; + try { + let response = await TasksRepository.assignTask(formattedData); + showToast("Task Successfully Assigend", "success"); + reset(); + onClose(); + } catch (error) { + showToast("something wrong", "error"); + } }; - try - { - let response = await TasksRepository.assignTask( formattedData ); - showToast( "Task Successfully Assigend", "success" ) - reset() - onClose() - } catch ( error ) - { - showToast("something wrong","error") - - } - -}; -useEffect(()=>{ - dispatch(changeMaster("Job Role")) - return ()=> setSelectedRole("all") -},[dispatch]) - + useEffect(() => { + dispatch(changeMaster("Job Role")); + return () => setSelectedRole("all"); + }, [dispatch]); return ( <>
-
-
+
+

{[ assignData?.building?.name, assignData?.floor?.floorName, assignData?.workArea?.areaName, assignData?.workItem?.workItem?.activityMaster?.activityName, - ].map((item, index, array) => ( -

-
- {item} - - {/* Arrow between items */} + ] + .filter(Boolean) + .map((item, index, array) => ( + + {item} {index < array.length - 1 && ( -
- -
+ )} -
-
- ))} -
+ + ))} +

@@ -166,7 +159,10 @@ useEffect(()=>{
Employee
- {selectedRole !== "" && ( + +
+
+ {selectedRole !== "" && (
@@ -178,7 +174,7 @@ useEffect(()=>{ return (
@@ -200,10 +196,19 @@ useEffect(()=>{ )} />
-
+

{emp.firstName} {emp.lastName} -

- +

+ {loading && (

{

)} - +
+
+ {selectedEmployees.length > 0 && (
@@ -233,7 +240,7 @@ useEffect(()=>{ return ( {emp.firstName} {emp.lastName}

{

)} +
+
+ +
@@ -273,7 +284,7 @@ useEffect(()=>{ setPlannedTask(e.target.value)} id="defaultFormControlInput" @@ -298,7 +309,7 @@ useEffect(()=>{ {...field} className="form-control" id="exampleFormControlTextarea1" - rows="3" + rows="2" /> )} /> From b15f5df8e759330f0518d8c6a27a091a93a927b1 Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Tue, 22 Apr 2025 10:00:49 +0530 Subject: [PATCH 7/9] added assign task button for mobile view --- src/components/Project/Infrastructure/WorkItem.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/Project/Infrastructure/WorkItem.jsx b/src/components/Project/Infrastructure/WorkItem.jsx index 956991da..ae279024 100644 --- a/src/components/Project/Infrastructure/WorkItem.jsx +++ b/src/components/Project/Infrastructure/WorkItem.jsx @@ -159,8 +159,14 @@ const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => { {" "} - Delete + Delete + {!projectId && ( + {" "} + Assign + )}
From fc2f69f4291c685440941593e0e44bec5f9dc6d3 Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Tue, 22 Apr 2025 10:15:41 +0530 Subject: [PATCH 8/9] selected employee list will empty after submission and close model perfectly --- src/components/Project/AssignRole.jsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Project/AssignRole.jsx b/src/components/Project/AssignRole.jsx index 8e898bde..be557dd4 100644 --- a/src/components/Project/AssignRole.jsx +++ b/src/components/Project/AssignRole.jsx @@ -94,9 +94,11 @@ const AssignRoleModel = ({ assignData, onClose }) => { }; try { let response = await TasksRepository.assignTask(formattedData); - showToast("Task Successfully Assigend", "success"); + showToast( "Task Successfully Assigend", "success" ); + setSelectedEmployees([]) reset(); - onClose(); + closeModal() + } catch (error) { showToast("something wrong", "error"); } From 7f7f05277a541e08970d1011a06326b137221657 Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Tue, 22 Apr 2025 11:03:23 +0530 Subject: [PATCH 9/9] modified projectBanner padding and fontsize. --- src/components/Project/ProjectBanner.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Project/ProjectBanner.jsx b/src/components/Project/ProjectBanner.jsx index 466c5854..0b485a88 100644 --- a/src/components/Project/ProjectBanner.jsx +++ b/src/components/Project/ProjectBanner.jsx @@ -79,18 +79,18 @@ const ProjectBanner = ( {project_data} ) => {/* Project Banner */}
-
+
{/* Left: Icon + Name */}
user image -

+

{CurrentProject.name ? CurrentProject.name : "N/A"} -
+
{manageProject && (