Remove warnings
This commit is contained in:
parent
83b6c2a307
commit
1418f84976
@ -1,4 +1,10 @@
|
|||||||
import React, { createContext, useContext, useState, useEffect, useRef } from "react";
|
import React, {
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
} from "react";
|
||||||
|
|
||||||
const ModalContext = createContext();
|
const ModalContext = createContext();
|
||||||
|
|
||||||
@ -9,12 +15,12 @@ export const ModalProvider = ({ children }) => {
|
|||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [modalContent, setModalContent] = useState(null);
|
const [modalContent, setModalContent] = useState(null);
|
||||||
const [onSubmit, setOnSubmit] = useState(null);
|
const [onSubmit, setOnSubmit] = useState(null);
|
||||||
const [modalSize, setModalSize] = useState('lg');
|
const [modalSize, setModalSize] = useState("lg");
|
||||||
|
|
||||||
// Ref to track the modal content element
|
// Ref to track the modal content element
|
||||||
const modalRef = useRef(null);
|
const modalRef = useRef(null);
|
||||||
|
|
||||||
const openModal = (content, onSubmitCallback, size = 'lg') => {
|
const openModal = (content, onSubmitCallback, size = "lg") => {
|
||||||
setModalContent(content); // Set modal content dynamically
|
setModalContent(content); // Set modal content dynamically
|
||||||
setOnSubmit(() => onSubmitCallback); // Set the submit handler dynamically
|
setOnSubmit(() => onSubmitCallback); // Set the submit handler dynamically
|
||||||
setIsOpen(true); // Open the modal
|
setIsOpen(true); // Open the modal
|
||||||
@ -26,9 +32,20 @@ export const ModalProvider = ({ children }) => {
|
|||||||
setIsOpen(false); // Close the modal
|
setIsOpen(false); // Close the modal
|
||||||
setModalContent(null); // Clear modal content
|
setModalContent(null); // Clear modal content
|
||||||
setOnSubmit(null); // Clear the submit callback
|
setOnSubmit(null); // Clear the submit callback
|
||||||
setModalSize('lg'); // Reset modal size
|
setModalSize("lg"); // Reset modal size
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleEscape = (event) => {
|
||||||
|
if (event.key === "Escape") {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.addEventListener("keydown", handleEscape);
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener("keydown", handleEscape);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleClickOutside = (event) => {
|
const handleClickOutside = (event) => {
|
||||||
@ -43,14 +60,28 @@ export const ModalProvider = ({ children }) => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalContext.Provider value={{ isOpen, openModal, closeModal, modalContent, modalSize, onSubmit }}>
|
<ModalContext.Provider
|
||||||
|
value={{
|
||||||
|
isOpen,
|
||||||
|
openModal,
|
||||||
|
closeModal,
|
||||||
|
modalContent,
|
||||||
|
modalSize,
|
||||||
|
onSubmit,
|
||||||
|
}}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
{isOpen && (
|
{isOpen && (
|
||||||
<div style={overlayStyles}>
|
<div style={overlayStyles}>
|
||||||
<div ref={modalRef} style={{ ...modalStyles, maxWidth: modalSize === 'sm' ? '400px' : '800px' }}>
|
<div
|
||||||
|
ref={modalRef}
|
||||||
|
style={{
|
||||||
|
...modalStyles,
|
||||||
|
maxWidth: modalSize === "sm" ? "400px" : "800px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<div>{modalContent}</div>
|
<div>{modalContent}</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
import Avatar from '../common/Avatar';
|
import Avatar from "../common/Avatar";
|
||||||
import { convertShortTime } from '../../utils/dateUtils';
|
import { convertShortTime } from "../../utils/dateUtils";
|
||||||
import RenderAttendanceStatus from './RenderAttendanceStatus';
|
import RenderAttendanceStatus from "./RenderAttendanceStatus";
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from "react-redux";
|
||||||
import { fetchAttendanceData } from '../../slices/apiSlice/attedanceLogsSlice';
|
import { fetchAttendanceData } from "../../slices/apiSlice/attedanceLogsSlice";
|
||||||
|
|
||||||
const AttendanceLog = ({ attendance, handleModalData, projectId }) => {
|
const AttendanceLog = ({ attendance, handleModalData, projectId }) => {
|
||||||
const [attendances, setAttendnaces] = useState([]);
|
const [attendances, setAttendnaces] = useState([]);
|
||||||
const [selectedDate, setSelectedDate] = useState('');
|
const [selectedDate, setSelectedDate] = useState("");
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { data, loading, error } = useSelector((store) => store.attendanceLogs);
|
const { data, loading, error } = useSelector((store) => store.attendanceLogs);
|
||||||
|
|
||||||
// Set the default selected date to the current date
|
// 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 handleDateChange = (e) => {
|
const handleDateChange = (e) => {
|
||||||
const date = e.target.value;
|
const date = e.target.value;
|
||||||
@ -28,11 +28,15 @@ const AttendanceLog = ({ attendance, handleModalData, projectId }) => {
|
|||||||
setSelectedDate(currentDate); // Set default selected date to today
|
setSelectedDate(currentDate); // Set default selected date to today
|
||||||
}, [attendance]);
|
}, [attendance]);
|
||||||
|
|
||||||
const renderAttendanceData = selectedDate === currentDate ? attendances : data;
|
const renderAttendanceData =
|
||||||
|
selectedDate === currentDate ? attendances : data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="dataTables_length text-start py-2" id="DataTables_Table_0_length">
|
<div
|
||||||
|
className="dataTables_length text-start py-2"
|
||||||
|
id="DataTables_Table_0_length"
|
||||||
|
>
|
||||||
<div className="col-md-3">
|
<div className="col-md-3">
|
||||||
<input
|
<input
|
||||||
className="form-control form-control-sm"
|
className="form-control form-control-sm"
|
||||||
@ -50,10 +54,13 @@ const AttendanceLog = ({ attendance, handleModalData, projectId }) => {
|
|||||||
<table className="table mb-0">
|
<table className="table mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th className="border-top-1" colSpan={2}>Name</th>
|
<th className="border-top-1" colSpan={2}>
|
||||||
<th className="border-top-1" >Role</th>
|
Name
|
||||||
|
</th>
|
||||||
|
<th className="border-top-1">Role</th>
|
||||||
<th>
|
<th>
|
||||||
<i className="bx bxs-down-arrow-alt text-success"></i> Check-In
|
<i className="bx bxs-down-arrow-alt text-success"></i>{" "}
|
||||||
|
Check-In
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<i className="bx bxs-up-arrow-alt text-danger"></i> Check-Out
|
<i className="bx bxs-up-arrow-alt text-danger"></i> Check-Out
|
||||||
@ -65,14 +72,19 @@ const AttendanceLog = ({ attendance, handleModalData, projectId }) => {
|
|||||||
{loading && <td colSpan={5}>Loading...</td>}
|
{loading && <td colSpan={5}>Loading...</td>}
|
||||||
{error && <td colSpan={5}>{error}</td>}
|
{error && <td colSpan={5}>{error}</td>}
|
||||||
{selectedDate && renderAttendanceData.length === 0 && (
|
{selectedDate && renderAttendanceData.length === 0 && (
|
||||||
<td colSpan={5}>No Data Found</td>
|
<tr>
|
||||||
|
<td colSpan={5}>No Data Found</td>
|
||||||
|
</tr>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{renderAttendanceData?.map((attendance, index) => (
|
{renderAttendanceData?.map((attendance, index) => (
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td colSpan={2}>
|
<td colSpan={2}>
|
||||||
<div className="d-flex justify-content-start align-items-center">
|
<div className="d-flex justify-content-start align-items-center">
|
||||||
<Avatar firstName={attendance.firstName} lastName={attendance.lastName} />
|
<Avatar
|
||||||
|
firstName={attendance.firstName}
|
||||||
|
lastName={attendance.lastName}
|
||||||
|
/>
|
||||||
<div className="d-flex flex-column">
|
<div className="d-flex flex-column">
|
||||||
<a href="#" className="text-heading text-truncate">
|
<a href="#" className="text-heading text-truncate">
|
||||||
<span className="fw-medium">
|
<span className="fw-medium">
|
||||||
@ -82,9 +94,13 @@ const AttendanceLog = ({ attendance, handleModalData, projectId }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{ attendance.jobRoleName}</td>
|
<td>{attendance.jobRoleName}</td>
|
||||||
<td>{convertShortTime(attendance.checkInTime)}</td>
|
<td>{convertShortTime(attendance.checkInTime)}</td>
|
||||||
<td>{attendance.checkOutTime ? convertShortTime(attendance.checkOutTime) : '--'}</td>
|
<td>
|
||||||
|
{attendance.checkOutTime
|
||||||
|
? convertShortTime(attendance.checkOutTime)
|
||||||
|
: "--"}
|
||||||
|
</td>
|
||||||
<td className="text-center">
|
<td className="text-center">
|
||||||
<RenderAttendanceStatus
|
<RenderAttendanceStatus
|
||||||
attendanceData={attendance}
|
attendanceData={attendance}
|
||||||
|
@ -1,79 +1,82 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from "react";
|
||||||
import Avatar from '../common/Avatar';
|
import Avatar from "../common/Avatar";
|
||||||
import { convertShortTime } from '../../utils/dateUtils';
|
import { convertShortTime } from "../../utils/dateUtils";
|
||||||
import RegularizationActions from './RegularizationActions';
|
import RegularizationActions from "./RegularizationActions";
|
||||||
import {useSelector} from 'react-redux';
|
import { useSelector } from "react-redux";
|
||||||
import {useRegularizationRequests} from '../../hooks/useAttendance';
|
import { useRegularizationRequests } from "../../hooks/useAttendance";
|
||||||
import moment from 'moment';
|
import moment from "moment";
|
||||||
|
|
||||||
|
const Regularization = ({ handleRequest }) => {
|
||||||
const Regularization = ( { handleRequest} ) =>
|
|
||||||
{
|
|
||||||
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||||
const [ regularizesList, setregularizedList ] = useState( [] )
|
const [regularizesList, setregularizedList] = useState([]);
|
||||||
const { regularizes, loading,error,refetch} = useRegularizationRequests(selectedProject)
|
const { regularizes, loading, error, refetch } =
|
||||||
|
useRegularizationRequests(selectedProject);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setregularizedList(regularizes);
|
||||||
useEffect(()=>{
|
}, [regularizes]);
|
||||||
setregularizedList(regularizes)
|
|
||||||
},[regularizes])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="table-responsive text-nowrap">
|
<div className="table-responsive text-nowrap">
|
||||||
<table className="table mb-0">
|
<table className="table mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th colSpan={2}>Name</th>
|
<th colSpan={2}>Name</th>
|
||||||
<th>Date</th>
|
<th>Date</th>
|
||||||
<th><i className='bx bxs-down-arrow-alt text-success' ></i>Check-In</th>
|
<th>
|
||||||
<th><i className='bx bxs-up-arrow-alt text-danger' ></i>Check-Out</th>
|
<i className="bx bxs-down-arrow-alt text-success"></i>Check-In
|
||||||
<th>Action</th>
|
</th>
|
||||||
</tr>
|
<th>
|
||||||
</thead>
|
<i className="bx bxs-up-arrow-alt text-danger"></i>Check-Out
|
||||||
|
</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{loading && <td colSpan={5}>Loading...</td>}
|
||||||
{loading &&<td colSpan={5}>Loading...</td>}
|
{regularizes?.length > 0 ? (
|
||||||
{
|
regularizes?.map((att, index) => (
|
||||||
regularizes?.length > 0 ? (
|
<tr key={index}>
|
||||||
regularizes?.map((att, index) => (
|
<td colSpan={2}>
|
||||||
<tr key={index}>
|
<div className="d-flex justify-content-start align-items-center">
|
||||||
<td colSpan={2}>
|
<Avatar
|
||||||
<div className="d-flex justify-content-start align-items-center">
|
firstName={att.firstName}
|
||||||
<Avatar
|
lastName={att.lastName}
|
||||||
firstName={att.firstName}
|
></Avatar>
|
||||||
lastName={att.lastName}
|
<div className="d-flex flex-column">
|
||||||
></Avatar>
|
<a href="#" className="text-heading text-truncate">
|
||||||
<div className="d-flex flex-column">
|
<span className="fw-medium">
|
||||||
<a
|
{att.firstName} {att.lastName}
|
||||||
href="#"
|
</span>
|
||||||
className="text-heading text-truncate"
|
</a>
|
||||||
>
|
</div>
|
||||||
<span className="fw-medium">
|
</div>
|
||||||
{att.firstName} {att.lastName}
|
</td>
|
||||||
</span>
|
<td>{moment(att.checkOutTime).format("DD-MMM-YYYY")}</td>
|
||||||
</a>
|
<td>{convertShortTime(att.checkInTime)}</td>
|
||||||
</div>
|
<td>
|
||||||
</div>
|
{att.checkOutTime ? convertShortTime(att.checkOutTime) : "--"}
|
||||||
</td>
|
</td>
|
||||||
<td>{moment(att.checkOutTime).format("DD-MMM-YYYY")}</td>
|
<td className="text-center ">
|
||||||
<td>{convertShortTime(att.checkInTime)}</td>
|
{/* <div className='d-flex justify-content-center align-items-center gap-3'> */}
|
||||||
<td>{att.checkOutTime ? convertShortTime(att.checkOutTime):"--"}</td>
|
<RegularizationActions
|
||||||
<td className='text-center ' >
|
attendanceData={att}
|
||||||
{/* <div className='d-flex justify-content-center align-items-center gap-3'> */}
|
handleRequest={handleRequest}
|
||||||
<RegularizationActions attendanceData={att} handleRequest={handleRequest} refresh={refetch } />
|
refresh={refetch}
|
||||||
{/* </div> */}
|
/>
|
||||||
</td>
|
{/* </div> */}
|
||||||
</tr>
|
</td>
|
||||||
))
|
</tr>
|
||||||
):(
|
))
|
||||||
<td colSpan={5}>No Record Found</td>
|
) : (
|
||||||
)
|
<tr>
|
||||||
}
|
<td colSpan={5}>No Record Found</td>
|
||||||
</tbody>
|
</tr>
|
||||||
</table>
|
)}
|
||||||
</div>
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Regularization
|
export default Regularization;
|
||||||
|
@ -1,23 +1,29 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import {useNavigate} from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
const Breadcrumb = ({ data }) => {
|
const Breadcrumb = ({ data }) => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate();
|
||||||
return (
|
return (
|
||||||
<nav aria-label="breadcrumb">
|
<nav aria-label="breadcrumb">
|
||||||
<ol className="breadcrumb breadcrumb-style1">
|
<ol className="breadcrumb breadcrumb-style1">
|
||||||
{data.map((item,index) =>
|
{data.map((item, index) =>
|
||||||
item.link ? (
|
item.link ? (
|
||||||
<li className="breadcrumb-item cursor-pointer" key={index}>
|
<li className="breadcrumb-item cursor-pointer" key={index}>
|
||||||
<a
|
<a
|
||||||
aria-label="pagination link link-underline-primary "
|
aria-label="pagination link link-underline-primary "
|
||||||
onClick={()=>navigate(item.link)}
|
onClick={() => navigate(item.link)}
|
||||||
>
|
>
|
||||||
{item.label}
|
{item.label}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
) : (
|
) : (
|
||||||
<li className="breadcrumb-item active "> {item.label}</li>
|
<li
|
||||||
|
className="breadcrumb-item active "
|
||||||
|
key={new Date().getMilliseconds()}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
{item.label}
|
||||||
|
</li>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</ol>
|
</ol>
|
||||||
|
@ -23,8 +23,8 @@ const AttendancePage = () => {
|
|||||||
const loginUser = getCachedProfileData();
|
const loginUser = getCachedProfileData();
|
||||||
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
var selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||||
const { projects, loading: projectLoading } = useProjects();
|
const { projects, loading: projectLoading } = useProjects();
|
||||||
const {attendance, loading: attLoading} = useAttendace( selectedProject );
|
const { attendance, loading: attLoading } = useAttendace(selectedProject);
|
||||||
const [ attendances, setAttendances ] = useState();
|
const [attendances, setAttendances] = useState();
|
||||||
const [empRoles, setEmpRoles] = useState(null);
|
const [empRoles, setEmpRoles] = useState(null);
|
||||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||||
const [modelConfig, setModelConfig] = useState();
|
const [modelConfig, setModelConfig] = useState();
|
||||||
@ -32,11 +32,10 @@ const AttendancePage = () => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
markTime: "",
|
markTime: "",
|
||||||
description: "",
|
description: "",
|
||||||
date: new Date().toLocaleDateString(),
|
date: new Date().toLocaleDateString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const getRole = (roleId) => {
|
const getRole = (roleId) => {
|
||||||
if (!empRoles) return "Unassigned";
|
if (!empRoles) return "Unassigned";
|
||||||
@ -49,9 +48,7 @@ const AttendancePage = () => {
|
|||||||
setIsCreateModalOpen(true);
|
setIsCreateModalOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleModalData = ( employee ) =>
|
const handleModalData = (employee) => {
|
||||||
{
|
|
||||||
|
|
||||||
setModelConfig(employee);
|
setModelConfig(employee);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,25 +64,24 @@ const AttendancePage = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (formData) => {
|
||||||
const handleSubmit = ( formData ) =>
|
dispatch(markCurrentAttendance(formData))
|
||||||
{
|
.then((action) => {
|
||||||
|
const updatedAttendance = attendances.map((item) =>
|
||||||
dispatch( markCurrentAttendance( formData ) ).then( ( action ) =>
|
item.employeeId === action.payload.employeeId
|
||||||
{
|
? { ...item, ...action.payload }
|
||||||
const updatedAttendance = attendances.map(item =>
|
: item
|
||||||
item.employeeId === action.payload.employeeId
|
);
|
||||||
? { ...item, ...action.payload }
|
cacheData("Attendance", {
|
||||||
: item
|
data: updatedAttendance,
|
||||||
);
|
projectId: selectedProject,
|
||||||
cacheData("Attendance", { data: updatedAttendance, projectId: selectedProject })
|
});
|
||||||
setAttendances(updatedAttendance)
|
setAttendances(updatedAttendance);
|
||||||
showToast("Attedance Marked Successfully","success")
|
showToast("Attedance Marked Successfully", "success");
|
||||||
})
|
})
|
||||||
.catch( ( error ) =>
|
.catch((error) => {
|
||||||
{
|
showToast(error.message, "error");
|
||||||
showToast(error.message,"error")
|
});
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -94,14 +90,12 @@ const AttendancePage = () => {
|
|||||||
}
|
}
|
||||||
}, [modelConfig, isCreateModalOpen]);
|
}, [modelConfig, isCreateModalOpen]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setAttendances( attendance );
|
setAttendances(attendance);
|
||||||
}, [attendance]);
|
}, [attendance]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(setProjectId(projects[0]?.id));
|
dispatch(setProjectId(projects[0]?.id));
|
||||||
}, [projects]);
|
}, [projects]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isCreateModalOpen && modelConfig && (
|
{isCreateModalOpen && modelConfig && (
|
||||||
@ -126,59 +120,71 @@ const AttendancePage = () => {
|
|||||||
{ label: "Home", link: "/dashboard" },
|
{ label: "Home", link: "/dashboard" },
|
||||||
{ label: "Attendance", link: null },
|
{ label: "Attendance", link: null },
|
||||||
]}
|
]}
|
||||||
></Breadcrumb>
|
></Breadcrumb>
|
||||||
<div class="nav-align-top nav-tabs-shadow">
|
<div className="nav-align-top nav-tabs-shadow">
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
<ul className="nav nav-tabs" role="tablist">
|
||||||
<div
|
<div
|
||||||
className="dataTables_length text-start py-2 px-2"
|
className="dataTables_length text-start py-2 px-2"
|
||||||
id="DataTables_Table_0_length"
|
id="DataTables_Table_0_length"
|
||||||
>
|
>
|
||||||
{
|
{loginUser && loginUser?.projects?.length > 1 && (
|
||||||
((loginUser && loginUser?.projects?.length > 1) ) && (<label>
|
<label>
|
||||||
<select
|
<select
|
||||||
name="DataTables_Table_0_length"
|
name="DataTables_Table_0_length"
|
||||||
aria-controls="DataTables_Table_0"
|
aria-controls="DataTables_Table_0"
|
||||||
className="form-select form-select-sm"
|
className="form-select form-select-sm"
|
||||||
value={selectedProject}
|
value={selectedProject}
|
||||||
onChange={(e)=>dispatch(setProjectId(e.target.value))}
|
onChange={(e) => dispatch(setProjectId(e.target.value))}
|
||||||
aria-label=""
|
aria-label=""
|
||||||
|
>
|
||||||
|
{!projectLoading &&
|
||||||
|
projects
|
||||||
|
?.filter((project) =>
|
||||||
|
loginUser?.projects?.map(Number).includes(project.id)
|
||||||
|
)
|
||||||
|
.map((project) => (
|
||||||
|
<option value={project.id} key={project.id}>
|
||||||
|
{project.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
{projectLoading && (
|
||||||
|
<option value="Loading..." disabled>
|
||||||
|
Loading...
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
<ul className="nav nav-tabs" role="tablist">
|
||||||
|
<li className="nav-item">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="nav-link active"
|
||||||
|
role="tab"
|
||||||
|
data-bs-toggle="tab"
|
||||||
|
data-bs-target="#navs-top-home"
|
||||||
|
aria-controls="navs-top-home"
|
||||||
|
aria-selected="true"
|
||||||
>
|
>
|
||||||
{!projectLoading && projects?.filter(project =>
|
All
|
||||||
loginUser?.projects?.map(Number).includes(project.id)).map((project)=>(
|
</button>
|
||||||
<option value={project.id} key={project.id}>{project.name}</option>
|
</li>
|
||||||
))}
|
<li className="nav-item">
|
||||||
{projectLoading && <option value="Loading..." disabled>Loading...</option> }
|
<button
|
||||||
</select>
|
type="button"
|
||||||
</label>)
|
className="nav-link"
|
||||||
}
|
role="tab"
|
||||||
</div>
|
data-bs-toggle="tab"
|
||||||
</ul>
|
data-bs-target="#navs-top-profile"
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
aria-controls="navs-top-profile"
|
||||||
<li class="nav-item">
|
aria-selected="false"
|
||||||
<button
|
>
|
||||||
type="button"
|
Logs
|
||||||
class="nav-link active"
|
</button>
|
||||||
role="tab"
|
</li>
|
||||||
data-bs-toggle="tab"
|
<li className={`nav-item ${!DoRegularized && "d-none"}`}>
|
||||||
data-bs-target="#navs-top-home"
|
|
||||||
aria-controls="navs-top-home"
|
|
||||||
aria-selected="true">
|
|
||||||
All
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="nav-link"
|
|
||||||
role="tab"
|
|
||||||
data-bs-toggle="tab"
|
|
||||||
data-bs-target="#navs-top-profile"
|
|
||||||
aria-controls="navs-top-profile"
|
|
||||||
aria-selected="false">
|
|
||||||
Logs
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li className={`nav-item ${!DoRegularized && 'd-none'}`}>
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="nav-link "
|
className="nav-link "
|
||||||
@ -225,10 +231,7 @@ const AttendancePage = () => {
|
|||||||
id="navs-top-messages"
|
id="navs-top-messages"
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
>
|
>
|
||||||
<Regularization
|
<Regularization handleRequest={handleSubmit} />
|
||||||
|
|
||||||
handleRequest={handleSubmit}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -12,9 +12,7 @@ import { MANAGE_EMPLOYEES } from "../../utils/constants";
|
|||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import SuspendEmp from "../../components/Employee/SuspendEmp";
|
import SuspendEmp from "../../components/Employee/SuspendEmp";
|
||||||
|
|
||||||
const EmployeeList = () =>
|
const EmployeeList = () => {
|
||||||
{
|
|
||||||
|
|
||||||
const { profile: loginUser } = useProfile();
|
const { profile: loginUser } = useProfile();
|
||||||
const [selectedProject, setSelectedProject] = useState("");
|
const [selectedProject, setSelectedProject] = useState("");
|
||||||
const { projects, loading: projectLoading } = useProjects();
|
const { projects, loading: projectLoading } = useProjects();
|
||||||
@ -30,7 +28,7 @@ const EmployeeList = () =>
|
|||||||
const [itemsPerPage] = useState(10);
|
const [itemsPerPage] = useState(10);
|
||||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||||
const [searchText, setSearchText] = useState("");
|
const [searchText, setSearchText] = useState("");
|
||||||
const [ filteredData, setFilteredData ] = useState( [] );
|
const [filteredData, setFilteredData] = useState([]);
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@ -92,7 +90,7 @@ const EmployeeList = () =>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleShow = () => setShowModal(true);
|
const handleShow = () => setShowModal(true);
|
||||||
const handleClose = () => setShowModal( false );
|
const handleClose = () => setShowModal(false);
|
||||||
|
|
||||||
const handleConfigData = (config) => {
|
const handleConfigData = (config) => {
|
||||||
setModelConfig(config);
|
setModelConfig(config);
|
||||||
@ -110,14 +108,14 @@ const EmployeeList = () =>
|
|||||||
<ManageEmp employeeId={modelConfig} onClosed={closeModal} />
|
<ManageEmp employeeId={modelConfig} onClosed={closeModal} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={`modal fade ${showModal ? 'show' : ''}`}
|
className={`modal fade ${showModal ? "show" : ""}`}
|
||||||
tabIndex="-1"
|
tabIndex="-1"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
style={{ display: showModal ? 'block' : 'none' }}
|
style={{ display: showModal ? "block" : "none" }}
|
||||||
aria-hidden={!showModal}
|
aria-hidden={!showModal}
|
||||||
>
|
>
|
||||||
<SuspendEmp onClose={handleClose}/>
|
<SuspendEmp onClose={handleClose} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="container-xxl flex-grow-1 container-p-y">
|
<div className="container-xxl flex-grow-1 container-p-y">
|
||||||
@ -329,130 +327,134 @@ const EmployeeList = () =>
|
|||||||
</tr>
|
</tr>
|
||||||
)}
|
)}
|
||||||
{!loading && employeeList?.length === 0 && (
|
{!loading && employeeList?.length === 0 && (
|
||||||
<td
|
<tr>
|
||||||
colSpan={8}
|
<td
|
||||||
style={{ paddingTop: "20px", textAlign: "center" }}
|
colSpan={8}
|
||||||
>
|
style={{ paddingTop: "20px", textAlign: "center" }}
|
||||||
No Data Found
|
>
|
||||||
</td>
|
No Data Found
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
)}
|
)}
|
||||||
{!loading &&
|
{!loading &&
|
||||||
employeeList &&
|
employeeList &&
|
||||||
currentItems.length === 0 &&
|
currentItems.length === 0 &&
|
||||||
employeeList.length !== 0 && (
|
employeeList.length !== 0 && (
|
||||||
<td colSpan={8}>
|
<tr>
|
||||||
<small className="muted">
|
<td colSpan={8}>
|
||||||
'{searchText}' employee not found
|
<small className="muted">
|
||||||
</small>{" "}
|
'{searchText}' employee not found
|
||||||
</td>
|
</small>{" "}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{currentItems &&
|
{currentItems &&
|
||||||
!loading &&
|
!loading &&
|
||||||
currentItems
|
currentItems.map((item) => (
|
||||||
.map((item) => (
|
<tr className="odd" key={item.id}>
|
||||||
<tr className="odd" key={item.id}>
|
<td className="sorting_1" colSpan={2}>
|
||||||
<td className="sorting_1" colSpan={2}>
|
<div className="d-flex justify-content-start align-items-center user-name">
|
||||||
<div className="d-flex justify-content-start align-items-center user-name">
|
<Avatar
|
||||||
<Avatar
|
firstName={item.firstName}
|
||||||
firstName={item.firstName}
|
lastName={item.lastName}
|
||||||
lastName={item.lastName}
|
></Avatar>
|
||||||
></Avatar>
|
<div className="d-flex flex-column">
|
||||||
<div className="d-flex flex-column">
|
<a
|
||||||
<a
|
onClick={() =>
|
||||||
|
navigate(`/employee/${item.id}?for=account`)
|
||||||
|
}
|
||||||
|
className="text-heading text-truncate cursor-pointer"
|
||||||
|
>
|
||||||
|
<span className="fw-medium">
|
||||||
|
{item.firstName} {item.lastName}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="text-start d-none d-sm-table-cell">
|
||||||
|
{item.email ? (
|
||||||
|
<span className="text-truncate">
|
||||||
|
<i className="bx bxs-envelope text-primary me-2"></i>
|
||||||
|
|
||||||
|
{item.email}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-truncate text-italic">
|
||||||
|
NA
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td className="text-start d-none d-sm-table-cell">
|
||||||
|
<span className="text-truncate">
|
||||||
|
<i className="bx bxs-phone-call text-primary me-2"></i>
|
||||||
|
{item.phoneNumber}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className=" d-none d-sm-table-cell text-start">
|
||||||
|
<span className="text-truncate">
|
||||||
|
<i className="bx bxs-wrench text-success me-2"></i>
|
||||||
|
{item.jobRole || "Not Assign Yet"}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td className=" d-none d-md-table-cell">
|
||||||
|
{moment(item.joiningDate).format("DD-MMM-YYYY")}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span
|
||||||
|
className="badge bg-label-success"
|
||||||
|
text-capitalized=""
|
||||||
|
>
|
||||||
|
Active
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
{ManageEmployee && (
|
||||||
|
<td className="text-end">
|
||||||
|
<div className="dropdown">
|
||||||
|
<button
|
||||||
|
className="btn btn-icon dropdown-toggle hide-arrow"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
>
|
||||||
|
<i className="bx bx-dots-vertical-rounded bx-md"></i>
|
||||||
|
</button>
|
||||||
|
<div className="dropdown-menu dropdown-menu-end">
|
||||||
|
<button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
navigate(
|
navigate(`/employee/${item.id}`)
|
||||||
`/employee/${item.id}?for=account`
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
className="text-heading text-truncate cursor-pointer"
|
className="dropdown-item"
|
||||||
>
|
>
|
||||||
<span className="fw-medium">
|
View
|
||||||
{item.firstName} {item.lastName}
|
</button>
|
||||||
</span>
|
<Link
|
||||||
</a>
|
to={`/employee/manage/${item.id}`}
|
||||||
|
className="dropdown-item"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</Link>
|
||||||
|
<button
|
||||||
|
className="dropdown-item"
|
||||||
|
onClick={handleShow}
|
||||||
|
>
|
||||||
|
Suspend
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="dropdown-item"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#managerole-modal"
|
||||||
|
onClick={() => handleConfigData(item.id)}
|
||||||
|
>
|
||||||
|
Manage Role
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="text-start d-none d-sm-table-cell">
|
)}
|
||||||
{item.email ? (
|
</tr>
|
||||||
<span className="text-truncate">
|
))}
|
||||||
<i className="bx bxs-envelope text-primary me-2"></i>
|
|
||||||
|
|
||||||
{item.email}
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<span className="text-truncate text-italic">
|
|
||||||
NA
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
<td className="text-start d-none d-sm-table-cell">
|
|
||||||
<span className="text-truncate">
|
|
||||||
<i className="bx bxs-phone-call text-primary me-2"></i>
|
|
||||||
{item.phoneNumber}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td className=" d-none d-sm-table-cell text-start">
|
|
||||||
<span className="text-truncate">
|
|
||||||
<i className="bx bxs-wrench text-success me-2"></i>
|
|
||||||
{item.jobRole || "Not Assign Yet"}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td className=" d-none d-md-table-cell">
|
|
||||||
{moment(item.joiningDate).format("DD-MMM-YYYY")}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span
|
|
||||||
className="badge bg-label-success"
|
|
||||||
text-capitalized=""
|
|
||||||
>
|
|
||||||
Active
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
{ManageEmployee && (
|
|
||||||
<td className="text-end">
|
|
||||||
<div className="dropdown">
|
|
||||||
<button
|
|
||||||
className="btn btn-icon dropdown-toggle hide-arrow"
|
|
||||||
data-bs-toggle="dropdown"
|
|
||||||
>
|
|
||||||
<i className="bx bx-dots-vertical-rounded bx-md"></i>
|
|
||||||
</button>
|
|
||||||
<div className="dropdown-menu dropdown-menu-end">
|
|
||||||
<button
|
|
||||||
onClick={() =>
|
|
||||||
navigate(`/employee/${item.id}`)
|
|
||||||
}
|
|
||||||
className="dropdown-item"
|
|
||||||
>
|
|
||||||
View
|
|
||||||
</button>
|
|
||||||
<Link
|
|
||||||
to={`/employee/manage/${item.id}`}
|
|
||||||
className="dropdown-item"
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</Link>
|
|
||||||
<button className="dropdown-item" onClick={handleShow}>
|
|
||||||
Suspend
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="dropdown-item"
|
|
||||||
type="button"
|
|
||||||
data-bs-toggle="modal"
|
|
||||||
data-bs-target="#managerole-modal"
|
|
||||||
onClick={() => handleConfigData(item.id)}
|
|
||||||
>
|
|
||||||
Manage Role
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
)}
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@ -1,92 +1,96 @@
|
|||||||
|
// AppRoutes.jsx
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
|
import { createBrowserRouter, RouterProvider, Outlet } from "react-router-dom";
|
||||||
import AuthLayout from "../layouts/AuthLayout"
|
|
||||||
|
// Layouts
|
||||||
|
import AuthLayout from "../layouts/AuthLayout";
|
||||||
import HomeLayout from "../layouts/HomeLayout";
|
import HomeLayout from "../layouts/HomeLayout";
|
||||||
|
|
||||||
|
// Authentication Pages
|
||||||
import LoginPage from "../pages/authentication/LoginPage";
|
import LoginPage from "../pages/authentication/LoginPage";
|
||||||
import RegisterPage from "../pages/authentication/RegisterPage";
|
import RegisterPage from "../pages/authentication/RegisterPage";
|
||||||
import ForgotPasswordPage from "../pages/authentication/ForgotPasswordPage";
|
import ForgotPasswordPage from "../pages/authentication/ForgotPasswordPage";
|
||||||
import ResetPasswordPage from "../pages/authentication/ResetPasswordPage";
|
import ResetPasswordPage from "../pages/authentication/ResetPasswordPage";
|
||||||
|
|
||||||
|
// Home & Protected Pages
|
||||||
import Dashboard from "../components/Dashboard/Dashboard";
|
import Dashboard from "../components/Dashboard/Dashboard";
|
||||||
import ProjectList from "../pages/project/ProjectList";
|
import ProjectList from "../pages/project/ProjectList";
|
||||||
import EmployeeList from "../pages/employee/EmployeeList";
|
|
||||||
import NotFound from "../pages/Home/NotFound";
|
|
||||||
import ProtectedRoute from "./ProtectedRoute";
|
|
||||||
import ProjectDetails from "../pages/project/ProjectDetails";
|
import ProjectDetails from "../pages/project/ProjectDetails";
|
||||||
|
import ManageProject from "../components/Project/ManageProject";
|
||||||
|
import EmployeeList from "../pages/employee/EmployeeList";
|
||||||
|
import ManageEmp from "../pages/employee/ManageEmp";
|
||||||
|
import EmployeeProfile from "../pages/employee/EmployeeProfile";
|
||||||
import Inventory from "../pages/project/Inventory";
|
import Inventory from "../pages/project/Inventory";
|
||||||
|
import AttendancePage from "../pages/Activities/AttendancePage";
|
||||||
|
import DailyTask from "../pages/Activities/DailyTask";
|
||||||
import TaskPlannng from "../pages/Activities/TaskPlannng";
|
import TaskPlannng from "../pages/Activities/TaskPlannng";
|
||||||
import Reports from "../pages/reports/Reports";
|
import Reports from "../pages/reports/Reports";
|
||||||
import ImageGallary from "../pages/Gallary/ImageGallary";
|
import ImageGallary from "../pages/Gallary/ImageGallary";
|
||||||
|
import MasterPage from "../pages/master/MasterPage";
|
||||||
import Support from "../pages/support/Support";
|
import Support from "../pages/support/Support";
|
||||||
import Documentation from "../pages/support/Documentation";
|
import Documentation from "../pages/support/Documentation";
|
||||||
import Connect from "../pages/support/Connect";
|
import Connect from "../pages/support/Connect";
|
||||||
import ManageProject from "../components/Project/ManageProject";
|
|
||||||
import ManageEmp from "../pages/employee/ManageEmp";
|
|
||||||
import EmployeeProfile from "../pages/employee/EmployeeProfile";
|
|
||||||
import { ErrorPage } from "../pages/support/ErrorPage";
|
import { ErrorPage } from "../pages/support/ErrorPage";
|
||||||
import MasterPage from "../pages/master/MasterPage";
|
|
||||||
import DailyTask from "../pages/Activities/DailyTask";
|
|
||||||
import AttendancePage from "../pages/Activities/AttendancePage";
|
|
||||||
|
|
||||||
|
// Protected Route Wrapper
|
||||||
|
import ProtectedRoute from "./ProtectedRoute";
|
||||||
|
|
||||||
|
const router = createBrowserRouter(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
element: <AuthLayout />,
|
||||||
|
children: [
|
||||||
|
{ path: "/auth/login", element: <LoginPage /> },
|
||||||
|
{ path: "/auth/reqest/demo", element: <RegisterPage /> },
|
||||||
|
{ path: "/auth/forgot-password", element: <ForgotPasswordPage /> },
|
||||||
|
{ path: "/reset-password", element: <ResetPasswordPage /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
element: <ProtectedRoute />,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
element: <HomeLayout />,
|
||||||
|
children: [
|
||||||
|
{ path: "/", element: <Dashboard /> },
|
||||||
|
{ path: "/dashboard", element: <Dashboard /> },
|
||||||
|
{ path: "/projects", element: <ProjectList /> },
|
||||||
|
{ path: "/projects/:projectId", element: <ProjectDetails /> },
|
||||||
|
{ path: "/project/manage/:projectId", element: <ManageProject /> },
|
||||||
|
{ path: "/employees", element: <EmployeeList /> },
|
||||||
|
{ path: "/employee/:employeeId", element: <EmployeeProfile /> },
|
||||||
|
{ path: "/employee/manage", element: <ManageEmp /> },
|
||||||
|
{ path: "/employee/manage/:employeeId", element: <ManageEmp /> },
|
||||||
|
{ path: "/inventory", element: <Inventory /> },
|
||||||
|
{ path: "/activities/attendance", element: <AttendancePage /> },
|
||||||
|
{ path: "/activities/records", element: <DailyTask /> },
|
||||||
|
{ path: "/activities/task", element: <TaskPlannng /> },
|
||||||
|
{ path: "/activities/reports", element: <Reports /> },
|
||||||
|
{ path: "/activities/gallary", element: <ImageGallary /> },
|
||||||
|
{ path: "/masters", element: <MasterPage /> },
|
||||||
|
{ path: "/help/support", element: <Support /> },
|
||||||
|
{ path: "/help/docs", element: <Documentation /> },
|
||||||
|
{ path: "/help/connect", element: <Connect /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "*",
|
||||||
|
element: <ErrorPage />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{
|
||||||
|
// ✅ Enables the v7 splat path resolution behavior
|
||||||
|
future: {
|
||||||
|
v7_relativeSplatPath: true,
|
||||||
|
v7_startTransition: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const AppRoutes = () => {
|
const AppRoutes = () => {
|
||||||
return (
|
return <RouterProvider router={router} />;
|
||||||
<Router>
|
|
||||||
<Routes>
|
|
||||||
{/* Authentication Routes */}
|
|
||||||
<Route element={<AuthLayout />}>
|
|
||||||
<Route path="/auth/login" element={<LoginPage />} />
|
|
||||||
<Route path="/auth/reqest/demo" element={<RegisterPage />} />
|
|
||||||
<Route
|
|
||||||
path="/auth/forgot-password"
|
|
||||||
element={<ForgotPasswordPage />}
|
|
||||||
/>
|
|
||||||
<Route path="/reset-password" element={<ResetPasswordPage />} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
|
|
||||||
{/* Protected Routes */}
|
|
||||||
<Route element={<ProtectedRoute />}>
|
|
||||||
<Route element={<HomeLayout />}>
|
|
||||||
<Route path="/" element={<Dashboard />} />
|
|
||||||
<Route path="/dashboard" element={<Dashboard />} />
|
|
||||||
<Route path="/projects" element={<ProjectList />} />
|
|
||||||
<Route path="/projects/:projectId" element={<ProjectDetails />} />
|
|
||||||
<Route
|
|
||||||
path="/project/manage/:projectId"
|
|
||||||
element={<ManageProject />}
|
|
||||||
/>
|
|
||||||
<Route path="/employees" element={<EmployeeList />} />
|
|
||||||
<Route path="/employee/:employeeId" element={<EmployeeProfile />} />
|
|
||||||
|
|
||||||
<Route path="/employee/manage" element={<ManageEmp />} />
|
|
||||||
<Route
|
|
||||||
path="/employee/manage/:employeeId"
|
|
||||||
element={<ManageEmp />}
|
|
||||||
/>
|
|
||||||
<Route path="/inventory" element={<Inventory />} />
|
|
||||||
|
|
||||||
<Route path="/activities/attendance" element={<AttendancePage />} />
|
|
||||||
|
|
||||||
<Route path="/activities/records" element={<DailyTask />} />
|
|
||||||
<Route path="/activities/task" element={<TaskPlannng />} />
|
|
||||||
|
|
||||||
<Route path="/activities/reports" element={<Reports />} />
|
|
||||||
|
|
||||||
<Route path="/activities/gallary" element={<ImageGallary />} />
|
|
||||||
<Route path="/masters" element={<MasterPage />} />
|
|
||||||
|
|
||||||
<Route path="/help/support" element={<Support />} />
|
|
||||||
<Route path="/help/docs" element={<Documentation />} />
|
|
||||||
<Route path="/help/connect" element={<Connect />} />
|
|
||||||
</Route>
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
{/* Fallback Route */}
|
|
||||||
<Route path="*" element={<ErrorPage />} />
|
|
||||||
</Routes>
|
|
||||||
</Router>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AppRoutes;
|
export default AppRoutes;
|
||||||
|
@ -3,7 +3,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import axiosRetry from "axios-retry";
|
import axiosRetry from "axios-retry";
|
||||||
import showToast from "../services/toastService";
|
import showToast from "../services/toastService";
|
||||||
const base_Url = process.env.VITE_BASE_URL;
|
const base_Url = process.env.VITE_BASE_URL;
|
||||||
// const base_Url = https://api.marcoaiot.com;
|
// const base_Url = "https://api.marcoaiot.com";
|
||||||
export const axiosClient = axios.create({
|
export const axiosClient = axios.create({
|
||||||
baseURL: base_Url, // Your Web API URL
|
baseURL: base_Url, // Your Web API URL
|
||||||
withCredentials: false, // Required if the API uses cookies
|
withCredentials: false, // Required if the API uses cookies
|
||||||
@ -31,11 +31,8 @@ axiosClient.interceptors.request.use(
|
|||||||
// // Response interceptor to handle responses globally (optional)
|
// // Response interceptor to handle responses globally (optional)
|
||||||
// Add an interceptor to handle expired tokens
|
// Add an interceptor to handle expired tokens
|
||||||
axiosClient.interceptors.response.use(
|
axiosClient.interceptors.response.use(
|
||||||
|
|
||||||
|
|
||||||
(response) => response,
|
(response) => response,
|
||||||
async (error) => {
|
async (error) => {
|
||||||
|
|
||||||
const originalRequest = error.config;
|
const originalRequest = error.config;
|
||||||
|
|
||||||
if (!originalRequest) {
|
if (!originalRequest) {
|
||||||
@ -51,46 +48,46 @@ axiosClient.interceptors.response.use(
|
|||||||
"Connection refused. Please ensure the server is running."
|
"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");
|
||||||
showToast("Server is unreachable. Try again later!", "error");
|
console.log("1 - error fetching refresh token :", error);
|
||||||
}
|
} else {
|
||||||
showToast(
|
showToast(
|
||||||
"Unable to connect to the server. Please try again later.",
|
"Unable to connect to the server. Please try again later.",
|
||||||
"error"
|
"error"
|
||||||
);
|
);
|
||||||
|
}
|
||||||
} else if (error.code === "ERR_NETWORK") {
|
} else if (error.code === "ERR_NETWORK") {
|
||||||
console.error( "Network error: Unable to reach the server." );
|
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");
|
||||||
showToast("Server is unreachable. Try again later!", "error");
|
console.log("2 - error fetching refresh token :", error);
|
||||||
}
|
}
|
||||||
redirectToLogin();
|
redirectToLogin();
|
||||||
} else if (error.code === "ECONNABORTED") {
|
} else if (error.code === "ECONNABORTED") {
|
||||||
console.error( "Request timed out." );
|
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");
|
||||||
showToast("Server is unreachable. Try again later!", "error");
|
console.log("3 - error fetching refresh token :", error);
|
||||||
}
|
} else {
|
||||||
showToast(
|
showToast(
|
||||||
"The request took too long. Please try again later.",
|
"The request took too long. Please try again later.",
|
||||||
"error"
|
"error"
|
||||||
);
|
);
|
||||||
} else if ( error.response )
|
}
|
||||||
{
|
} 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);
|
||||||
showToast("Server is unreachable. Try again later!", "error");
|
} else {
|
||||||
}
|
showToast(error.response.data.message, "error");
|
||||||
showToast(error.response.data.message, "error");
|
}
|
||||||
|
|
||||||
if (error.response.status === 401 && !originalRequest._retry) {
|
if (error.response.status === 401 && !originalRequest._retry) {
|
||||||
originalRequest._retry = true;
|
originalRequest._retry = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Get the refresh token from secure storage
|
// Get the refresh token from secure storage
|
||||||
const refreshToken = localStorage.getItem("refreshToken");
|
const refreshToken = localStorage.getItem("refreshToken");
|
||||||
|
|
||||||
@ -115,11 +112,19 @@ axiosClient.interceptors.response.use(
|
|||||||
// Retry the original request
|
// Retry the original request
|
||||||
return axiosClient(originalRequest);
|
return axiosClient(originalRequest);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
console.log(
|
||||||
|
"5 - error fetching refresh token during refresh call :",
|
||||||
|
error
|
||||||
|
);
|
||||||
// Redirect to login if token refresh fails
|
// Redirect to login if token refresh fails
|
||||||
redirectToLogin();
|
redirectToLogin();
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (error.config.url.indexOf("refresh-token") == -1) {
|
||||||
|
//showToast("Server is unreachable. Try again later!", "error");
|
||||||
|
console.log("6 - error fetching refresh token :", error);
|
||||||
|
}
|
||||||
showToast(
|
showToast(
|
||||||
error.response.data?.message ||
|
error.response.data?.message ||
|
||||||
"An error occurred. Please try again.",
|
"An error occurred. Please try again.",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user