Merge branch 'main' of https://git.marcoaiot.com/admin/marco.pms.web into UI_Changes_PMS
This commit is contained in:
commit
8f8cbf27ef
@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useEmployeeAttendacesLog } from "../../hooks/useAttendance";
|
import { useEmployeeAttendacesLog } from "../../hooks/useAttendance";
|
||||||
import { convertShortTime } from "../../utils/dateUtils";
|
import { convertShortTime, formatUTCToLocalTime } from "../../utils/dateUtils";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { THRESH_HOLD } from "../../utils/constants";
|
import { THRESH_HOLD } from "../../utils/constants";
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ const AttendLogs = ({ Id }) => {
|
|||||||
<p>
|
<p>
|
||||||
Attendance logs for{" "}
|
Attendance logs for{" "}
|
||||||
{logs[0]?.employee?.firstName + " " + logs[0]?.employee?.lastName}{" "}
|
{logs[0]?.employee?.firstName + " " + logs[0]?.employee?.lastName}{" "}
|
||||||
on {logs[0]?.activityTime.slice(0, 10)}{" "}
|
on {formatUTCToLocalTime(logs[0]?.activityTime)}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -156,7 +156,7 @@ const AttendLogs = ({ Id }) => {
|
|||||||
.sort((a, b) => b.id - a.id)
|
.sort((a, b) => b.id - a.id)
|
||||||
.map((log, index) => (
|
.map((log, index) => (
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td>{log.activityTime.slice(0, 10)}</td>
|
<td>{formatUTCToLocalTime(log.activityTime)}</td>
|
||||||
<td>{convertShortTime(log.activityTime)}</td>
|
<td>{convertShortTime(log.activityTime)}</td>
|
||||||
<td>
|
<td>
|
||||||
{whichActivityPerform(log.activity, log.activityTime)}
|
{whichActivityPerform(log.activity, log.activityTime)}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import Avatar from "../common/Avatar";
|
import Avatar from "../common/Avatar";
|
||||||
import { convertShortTime } from "../../utils/dateUtils";
|
import { convertShortTime, formatUTCToLocalTime } from "../../utils/dateUtils";
|
||||||
import RenderAttendanceStatus from "./RenderAttendanceStatus";
|
import RenderAttendanceStatus from "./RenderAttendanceStatus";
|
||||||
import usePagination from "../../hooks/usePagination";
|
import usePagination from "../../hooks/usePagination";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
@ -10,7 +10,7 @@ import { useAttendance } from "../../hooks/useAttendance";
|
|||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import { useSelectedproject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
|
||||||
const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
@ -21,7 +21,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
// const selectedProject = useSelector(
|
// const selectedProject = useSelector(
|
||||||
// (store) => store.localVariables.projectId
|
// (store) => store.localVariables.projectId
|
||||||
// );
|
// );
|
||||||
const selectedProject = useSelectedproject();
|
const selectedProject = useSelectedProject();
|
||||||
const {
|
const {
|
||||||
attendance,
|
attendance,
|
||||||
loading: attLoading,
|
loading: attLoading,
|
||||||
@ -116,7 +116,7 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
|
|||||||
<>
|
<>
|
||||||
<div className="table-responsive text-nowrap h-100" >
|
<div className="table-responsive text-nowrap h-100" >
|
||||||
<div className="d-flex text-start align-items-center py-2">
|
<div className="d-flex text-start align-items-center py-2">
|
||||||
<strong>Date : {todayDate.toLocaleDateString("en-GB")}</strong>
|
<strong>Date : {formatUTCToLocalTime(todayDate)}</strong>
|
||||||
<div className="form-check form-switch text-start m-0 ms-5">
|
<div className="form-check form-switch text-start m-0 ms-5">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
@ -6,11 +6,12 @@ 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";
|
||||||
import DateRangePicker from "../common/DateRangePicker";
|
import DateRangePicker from "../common/DateRangePicker";
|
||||||
import { clearCacheKey, getCachedData, useSelectedproject } from "../../slices/apiDataManager";
|
import { clearCacheKey, getCachedData, useSelectedProject } from "../../slices/apiDataManager";
|
||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import AttendanceRepository from "../../repositories/AttendanceRepository";
|
import AttendanceRepository from "../../repositories/AttendanceRepository";
|
||||||
import { useAttendancesLogs } from "../../hooks/useAttendance";
|
import { useAttendancesLogs } from "../../hooks/useAttendance";
|
||||||
import { queryClient } from "../../layouts/AuthLayout";
|
import { queryClient } from "../../layouts/AuthLayout";
|
||||||
|
import { ITEMS_PER_PAGE } from "../../utils/constants";
|
||||||
|
|
||||||
const usePagination = (data, itemsPerPage) => {
|
const usePagination = (data, itemsPerPage) => {
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
@ -37,7 +38,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
// const selectedProject = useSelector(
|
// const selectedProject = useSelector(
|
||||||
// (store) => store.localVariables.projectId
|
// (store) => store.localVariables.projectId
|
||||||
// );
|
// );
|
||||||
const selectedProject = useSelectedproject();
|
const selectedProject = useSelectedProject();
|
||||||
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
|
const [dateRange, setDateRange] = useState({ startDate: "", endDate: "" });
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@ -353,7 +354,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
|
|||||||
<span className="text-secondary">No Pending Record Available !</span>
|
<span className="text-secondary">No Pending Record Available !</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{filteredSearchData.length > 10 && (
|
{filteredSearchData.length > ITEMS_PER_PAGE && (
|
||||||
<nav aria-label="Page ">
|
<nav aria-label="Page ">
|
||||||
<ul className="pagination pagination-sm justify-content-end py-1">
|
<ul className="pagination pagination-sm justify-content-end py-1">
|
||||||
<li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>
|
<li className={`page-item ${currentPage === 1 ? "disabled" : ""}`}>
|
||||||
|
@ -9,7 +9,7 @@ import { markAttendance } from "../../slices/apiSlice/attedanceLogsSlice";
|
|||||||
import showToast from "../../services/toastService";
|
import showToast from "../../services/toastService";
|
||||||
import { checkIfCurrentDate } from "../../utils/dateUtils";
|
import { checkIfCurrentDate } from "../../utils/dateUtils";
|
||||||
import { useMarkAttendance } from "../../hooks/useAttendance";
|
import { useMarkAttendance } from "../../hooks/useAttendance";
|
||||||
import { useSelectedproject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
|
||||||
const createSchema = (modeldata) => {
|
const createSchema = (modeldata) => {
|
||||||
return z
|
return z
|
||||||
@ -43,9 +43,8 @@ const createSchema = (modeldata) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const CheckCheckOutmodel = ({ modeldata, closeModal, handleSubmitForm }) => {
|
const CheckInCheckOut = ({ modeldata, closeModal, handleSubmitForm }) => {
|
||||||
// const projectId = useSelector((store) => store.localVariables.projectId);
|
const projectId = useSelectedProject();
|
||||||
const projectId = useSelectedproject();
|
|
||||||
const { mutate: MarkAttendance } = useMarkAttendance();
|
const { mutate: MarkAttendance } = useMarkAttendance();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const coords = usePositionTracker();
|
const coords = usePositionTracker();
|
||||||
@ -174,7 +173,7 @@ const CheckCheckOutmodel = ({ modeldata, closeModal, handleSubmitForm }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default CheckCheckOutmodel;
|
export default CheckInCheckOut;
|
||||||
|
|
||||||
const schemaReg = z.object({
|
const schemaReg = z.object({
|
||||||
description: z.string().min(1, { message: "please give reason!" }),
|
description: z.string().min(1, { message: "please give reason!" }),
|
||||||
|
@ -15,7 +15,7 @@ import {useDispatch, useSelector} from "react-redux";
|
|||||||
import {useProfile} from "../../hooks/useProfile";
|
import {useProfile} from "../../hooks/useProfile";
|
||||||
import {refreshData, setProjectId} from "../../slices/localVariablesSlice";
|
import {refreshData, setProjectId} from "../../slices/localVariablesSlice";
|
||||||
import InfraTable from "../Project/Infrastructure/InfraTable";
|
import InfraTable from "../Project/Infrastructure/InfraTable";
|
||||||
import { useSelectedproject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
import Loader from "../common/Loader";
|
import Loader from "../common/Loader";
|
||||||
|
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ const InfraPlanning = () =>
|
|||||||
const {profile: LoggedUser, refetch : fetchData} = useProfile()
|
const {profile: LoggedUser, refetch : fetchData} = useProfile()
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
// const selectedProject = useSelector((store)=>store.localVariables.projectId)
|
// const selectedProject = useSelector((store)=>store.localVariables.projectId)
|
||||||
const selectedProject = useSelectedproject();
|
const selectedProject = useSelectedProject();
|
||||||
const {projectInfra, isLoading, error} = useProjectInfra( selectedProject )
|
const {projectInfra, isLoading, error} = useProjectInfra( selectedProject )
|
||||||
|
|
||||||
|
|
||||||
@ -35,15 +35,15 @@ const InfraPlanning = () =>
|
|||||||
const reloadedData = useSelector( ( store ) => store.localVariables.reload )
|
const reloadedData = useSelector( ( store ) => store.localVariables.reload )
|
||||||
|
|
||||||
|
|
||||||
useEffect( () =>
|
// useEffect( () =>
|
||||||
{
|
// {
|
||||||
if (reloadedData)
|
// if (reloadedData)
|
||||||
{
|
// {
|
||||||
refetch()
|
// refetch()
|
||||||
dispatch( refreshData( false ) )
|
// dispatch( refreshData( false ) )
|
||||||
}
|
// }
|
||||||
|
|
||||||
},[reloadedData])
|
// },[reloadedData])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
|
<div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
|
||||||
|
@ -7,13 +7,13 @@ import { useRegularizationRequests } from "../../hooks/useAttendance";
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import usePagination from "../../hooks/usePagination";
|
import usePagination from "../../hooks/usePagination";
|
||||||
import eventBus from "../../services/eventBus";
|
import eventBus from "../../services/eventBus";
|
||||||
import { cacheData, clearCacheKey, useSelectedproject } from "../../slices/apiDataManager";
|
import { cacheData, clearCacheKey, useSelectedProject } from "../../slices/apiDataManager";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
const Regularization = ({ handleRequest, searchTerm }) => {
|
const Regularization = ({ handleRequest, searchTerm }) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
// var selectedProject = useSelector((store) => store.localVariables.projectId);
|
// var selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||||
const selectedProject = useSelectedproject();
|
const selectedProject = useSelectedProject();
|
||||||
const [regularizesList, setregularizedList] = useState([]);
|
const [regularizesList, setregularizedList] = useState([]);
|
||||||
const { regularizes, loading, error, refetch } =
|
const { regularizes, loading, error, refetch } =
|
||||||
useRegularizationRequests(selectedProject);
|
useRegularizationRequests(selectedProject);
|
||||||
|
@ -4,7 +4,7 @@ import useAttendanceStatus, { ACTIONS } from '../../hooks/useAttendanceStatus';
|
|||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { usePositionTracker } from '../../hooks/usePositionTracker';
|
import { usePositionTracker } from '../../hooks/usePositionTracker';
|
||||||
import {markCurrentAttendance} from '../../slices/apiSlice/attendanceAllSlice';
|
import {markCurrentAttendance} from '../../slices/apiSlice/attendanceAllSlice';
|
||||||
import {cacheData, getCachedData, useSelectedproject} from '../../slices/apiDataManager';
|
import {cacheData, getCachedData, useSelectedProject} from '../../slices/apiDataManager';
|
||||||
import showToast from '../../services/toastService';
|
import showToast from '../../services/toastService';
|
||||||
import { useMarkAttendance } from '../../hooks/useAttendance';
|
import { useMarkAttendance } from '../../hooks/useAttendance';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
@ -18,7 +18,7 @@ const {mutate:MarkAttendance,isPending} = useMarkAttendance()
|
|||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
// const projectId = useSelector((store)=>store.localVariables.projectId)
|
// const projectId = useSelector((store)=>store.localVariables.projectId)
|
||||||
const projectId = useSelectedproject();
|
const projectId = useSelectedProject();
|
||||||
const {latitude,longitude} = usePositionTracker();
|
const {latitude,longitude} = usePositionTracker();
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
import React, { useEffect, useState, useMemo } from "react";
|
import React, { useEffect, useState, useMemo } from "react";
|
||||||
import { DirectoryRepository } from "../../repositories/DirectoryRepository";
|
import { DirectoryRepository } from "../../repositories/DirectoryRepository";
|
||||||
import NoteCardDirectoryEditable from "./NoteCardDirectoryEditable";
|
import NoteCardDirectoryEditable from "./NoteCardDirectoryEditable";
|
||||||
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
|
||||||
|
const NotesCardViewDirectory = ({
|
||||||
|
notes,
|
||||||
|
setNotesForFilter,
|
||||||
|
searchText,
|
||||||
|
filterAppliedNotes,
|
||||||
|
}) => {
|
||||||
|
const projectId = useSelectedProject();
|
||||||
|
|
||||||
const NotesCardViewDirectory = ({ notes, setNotesForFilter, searchText, filterAppliedNotes }) => {
|
|
||||||
const [allNotes, setAllNotes] = useState([]);
|
const [allNotes, setAllNotes] = useState([]);
|
||||||
const [filteredNotes, setFilteredNotes] = useState([]);
|
const [filteredNotes, setFilteredNotes] = useState([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
@ -13,13 +21,15 @@ const NotesCardViewDirectory = ({ notes, setNotesForFilter, searchText, filterAp
|
|||||||
const pageSize = 20;
|
const pageSize = 20;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchNotes();
|
if (projectId) {
|
||||||
}, []);
|
fetchNotes(projectId);
|
||||||
|
}
|
||||||
|
}, [projectId]);
|
||||||
|
|
||||||
const fetchNotes = async () => {
|
const fetchNotes = async (projId) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const response = await DirectoryRepository.GetNotes(1000, 1);
|
const response = await DirectoryRepository.GetNotes(1000, 1, projId); // ✅ pass projectId
|
||||||
const fetchedNotes = response.data?.data || [];
|
const fetchedNotes = response.data?.data || [];
|
||||||
setAllNotes(fetchedNotes);
|
setAllNotes(fetchedNotes);
|
||||||
setNotesForFilter(fetchedNotes)
|
setNotesForFilter(fetchedNotes)
|
||||||
@ -122,7 +132,7 @@ const NotesCardViewDirectory = ({ notes, setNotesForFilter, searchText, filterAp
|
|||||||
prevNotes.map((n) => (n.id === updatedNote.id ? updatedNote : n))
|
prevNotes.map((n) => (n.id === updatedNote.id ? updatedNote : n))
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
onNoteDelete={() => fetchNotes()}
|
onNoteDelete={() => fetchNotes(projectId)} // ✅ reload with projectId
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -126,7 +126,7 @@ const EmpAttendance = ({ employee }) => {
|
|||||||
className="dataTables_length text-start py-2 d-flex justify-content-between "
|
className="dataTables_length text-start py-2 d-flex justify-content-between "
|
||||||
id="DataTables_Table_0_length"
|
id="DataTables_Table_0_length"
|
||||||
>
|
>
|
||||||
<div className="col-md-3 my-0 ">
|
<div className="col-md-4 my-0 ">
|
||||||
<DateRangePicker
|
<DateRangePicker
|
||||||
DateDifference="30"
|
DateDifference="30"
|
||||||
onRangeChange={setDateRange}
|
onRangeChange={setDateRange}
|
||||||
|
@ -59,20 +59,20 @@ const EmpBanner = ({ profile, loggedInUser }) => {
|
|||||||
</h4>
|
</h4>
|
||||||
<ul className="list-inline mb-0 d-flex align-items-center flex-wrap justify-content-sm-start justify-content-center gap-4 mt-4">
|
<ul className="list-inline mb-0 d-flex align-items-center flex-wrap justify-content-sm-start justify-content-center gap-4 mt-4">
|
||||||
<li className="list-inline-item">
|
<li className="list-inline-item">
|
||||||
<i className="icon-base bx bx-crown me-2 align-top"></i>
|
<i className="icon-base bx bx-crown me-1 align-top"></i>
|
||||||
<span className="fw-medium">
|
<span className="fw-medium">
|
||||||
{profile?.jobRole || <em>NA</em>}
|
{profile?.jobRole || <em>NA</em>}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li className="list-inline-item">
|
<li className="list-inline-item">
|
||||||
<i className="icon-base bx bx-phone me-2 align-top"></i>
|
<i className="icon-base bx bx-phone me-0 align-top"></i>
|
||||||
<span className="fw-medium">
|
<span className="fw-medium">
|
||||||
{" "}
|
{" "}
|
||||||
{profile?.phoneNumber || <em>NA</em>}
|
{profile?.phoneNumber || <em>NA</em>}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li className="list-inline-item">
|
<li className="list-inline-item">
|
||||||
<i className="icon-base bx bx-calendar me-2 align-top"></i>
|
<i className="icon-base bx bx-calendar me-0 align-top"></i>
|
||||||
<span className="fw-medium">
|
<span className="fw-medium">
|
||||||
{" "}
|
{" "}
|
||||||
Joined on{" "}
|
Joined on{" "}
|
||||||
@ -85,6 +85,7 @@ const EmpBanner = ({ profile, loggedInUser }) => {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul className="list-inline mb-0 d-flex align-items-center flex-wrap justify-content-sm-start justify-content-center mt-4">
|
<ul className="list-inline mb-0 d-flex align-items-center flex-wrap justify-content-sm-start justify-content-center mt-4">
|
||||||
|
{profile?.isActive && ( // ✅ show only if active
|
||||||
<li className="list-inline-item">
|
<li className="list-inline-item">
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm btn-primary btn-block"
|
className="btn btn-sm btn-primary btn-block"
|
||||||
@ -93,8 +94,10 @@ const EmpBanner = ({ profile, loggedInUser }) => {
|
|||||||
Edit Profile
|
Edit Profile
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
)}
|
||||||
|
|
||||||
<li className="list-inline-item">
|
<li className="list-inline-item">
|
||||||
{profile?.id == loggedInUser?.employeeInfo?.id && (
|
{profile?.id === loggedInUser?.employeeInfo?.id && (
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm btn-outline-primary btn-block"
|
className="btn btn-sm btn-outline-primary btn-block"
|
||||||
onClick={() => openChangePassword()}
|
onClick={() => openChangePassword()}
|
||||||
|
@ -105,6 +105,7 @@ const ExpenseFilterPanel = ({ onApply, handleGroupBy }) => {
|
|||||||
startField="startDate"
|
startField="startDate"
|
||||||
endField="endDate"
|
endField="endDate"
|
||||||
resetSignal={resetKey}
|
resetSignal={resetKey}
|
||||||
|
defaultRange={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
cacheData,
|
cacheData,
|
||||||
clearAllCache,
|
clearAllCache,
|
||||||
getCachedData,
|
getCachedData,
|
||||||
useSelectedproject,
|
useSelectedProject,
|
||||||
} from "../../slices/apiDataManager";
|
} from "../../slices/apiDataManager";
|
||||||
import AuthRepository from "../../repositories/AuthRepository";
|
import AuthRepository from "../../repositories/AuthRepository";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
@ -101,7 +101,7 @@ const Header = () => {
|
|||||||
|
|
||||||
const { projectNames, loading: projectLoading, fetchData } = useProjectName();
|
const { projectNames, loading: projectLoading, fetchData } = useProjectName();
|
||||||
|
|
||||||
const selectedProject = useSelectedproject();
|
const selectedProject = useSelectedProject();
|
||||||
|
|
||||||
const projectsForDropdown = isDashboardPath
|
const projectsForDropdown = isDashboardPath
|
||||||
? projectNames
|
? projectNames
|
||||||
|
@ -8,7 +8,7 @@ import { MANAGE_PROJECT } from "../../utils/constants";
|
|||||||
import GlobalModel from "../common/GlobalModel";
|
import GlobalModel from "../common/GlobalModel";
|
||||||
import ManageProjectInfo from "./ManageProjectInfo";
|
import ManageProjectInfo from "./ManageProjectInfo";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
import { useSelectedproject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
|
||||||
const AboutProject = () => {
|
const AboutProject = () => {
|
||||||
const [IsOpenModal, setIsOpenModal] = useState(false);
|
const [IsOpenModal, setIsOpenModal] = useState(false);
|
||||||
@ -21,7 +21,7 @@ const AboutProject = () => {
|
|||||||
|
|
||||||
// *** MODIFIED LINE: Get projectId from Redux store using useSelector ***
|
// *** MODIFIED LINE: Get projectId from Redux store using useSelector ***
|
||||||
// const projectId = useSelector((store) => store.localVariables.projectId);
|
// const projectId = useSelector((store) => store.localVariables.projectId);
|
||||||
const projectId = useSelectedproject();
|
const projectId = useSelectedProject();
|
||||||
|
|
||||||
const manageProject = useHasUserPermission(MANAGE_PROJECT);
|
const manageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||||
const { projects_Details, isLoading, error, refetch } = useProjectDetails(projectId); // Pass projectId from useSelector
|
const { projects_Details, isLoading, error, refetch } = useProjectDetails(projectId); // Pass projectId from useSelector
|
||||||
|
@ -15,7 +15,7 @@ import {
|
|||||||
cacheData,
|
cacheData,
|
||||||
clearCacheKey,
|
clearCacheKey,
|
||||||
getCachedData,
|
getCachedData,
|
||||||
useSelectedproject,
|
useSelectedProject,
|
||||||
} from "../../slices/apiDataManager";
|
} from "../../slices/apiDataManager";
|
||||||
import { useProjectDetails, useProjectInfra } from "../../hooks/useProjects";
|
import { useProjectDetails, useProjectInfra } from "../../hooks/useProjects";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
@ -27,7 +27,7 @@ import GlobalModel from "../common/GlobalModel";
|
|||||||
const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) =>
|
const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) =>
|
||||||
{
|
{
|
||||||
// const projectId = useSelector((store)=>store.localVariables.projectId)
|
// const projectId = useSelector((store)=>store.localVariables.projectId)
|
||||||
const projectId = useSelectedproject();
|
const projectId = useSelectedProject();
|
||||||
const reloadedData = useSelector((store) => store.localVariables.reload);
|
const reloadedData = useSelector((store) => store.localVariables.reload);
|
||||||
const [ expandedBuildings, setExpandedBuildings ] = useState( [] );
|
const [ expandedBuildings, setExpandedBuildings ] = useState( [] );
|
||||||
const {projectInfra,isLoading,error} = useProjectInfra(projectId)
|
const {projectInfra,isLoading,error} = useProjectInfra(projectId)
|
||||||
|
@ -18,12 +18,12 @@ import {
|
|||||||
useEmployeesByProjectAllocated,
|
useEmployeesByProjectAllocated,
|
||||||
useManageProjectAllocation,
|
useManageProjectAllocation,
|
||||||
} from "../../hooks/useProjects";
|
} from "../../hooks/useProjects";
|
||||||
import { useSelectedproject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
|
||||||
const Teams = () => {
|
const Teams = () => {
|
||||||
// const {projectId} = useParams()
|
// const {projectId} = useParams()
|
||||||
// const projectId = useSelector((store)=>store.localVariables.projectId)
|
// const projectId = useSelector((store)=>store.localVariables.projectId)
|
||||||
const projectId = useSelectedproject();
|
const projectId = useSelectedProject();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const { data, loading } = useMaster();
|
const { data, loading } = useMaster();
|
||||||
|
@ -96,19 +96,19 @@ const EditProfile = ({ TenantId,onClose }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-sm-6 mt-1">
|
<div className="col-sm-6 mt-1">
|
||||||
<Label htmlFor="domainName" required>Domain Name</Label>
|
<Label htmlFor="domainName" >Domain Name</Label>
|
||||||
<input id="domainName" type="text" className="form-control form-control-sm" {...register("domainName")} />
|
<input id="domainName" type="text" className="form-control form-control-sm" {...register("domainName")} />
|
||||||
{errors.domainName && <div className="danger-text">{errors.domainName.message}</div>}
|
{errors.domainName && <div className="danger-text">{errors.domainName.message}</div>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-sm-6 mt-1">
|
<div className="col-sm-6 mt-1">
|
||||||
<Label htmlFor="taxId" required>Tax ID</Label>
|
<Label htmlFor="taxId" >Tax ID</Label>
|
||||||
<input id="taxId" type="text" className="form-control form-control-sm" {...register("taxId")} />
|
<input id="taxId" type="text" className="form-control form-control-sm" {...register("taxId")} />
|
||||||
{errors.taxId && <div className="danger-text">{errors.taxId.message}</div>}
|
{errors.taxId && <div className="danger-text">{errors.taxId.message}</div>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-sm-6 mt-1">
|
<div className="col-sm-6 mt-1">
|
||||||
<Label htmlFor="officeNumber" required>Office Number</Label>
|
<Label htmlFor="officeNumber" >Office Number</Label>
|
||||||
<input id="officeNumber" type="text" className="form-control form-control-sm" {...register("officeNumber")} />
|
<input id="officeNumber" type="text" className="form-control form-control-sm" {...register("officeNumber")} />
|
||||||
{errors.officeNumber && <div className="danger-text">{errors.officeNumber.message}</div>}
|
{errors.officeNumber && <div className="danger-text">{errors.officeNumber.message}</div>}
|
||||||
</div>
|
</div>
|
||||||
|
@ -73,7 +73,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-sm-6">
|
<div className="col-sm-6">
|
||||||
<Label htmlFor="officeNumber" required>
|
<Label htmlFor="officeNumber" >
|
||||||
Office Number
|
Office Number
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<input
|
||||||
@ -87,7 +87,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-sm-6">
|
<div className="col-sm-6">
|
||||||
<Label htmlFor="domainName" required>
|
<Label htmlFor="domainName" >
|
||||||
Domain Name
|
Domain Name
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<input
|
||||||
@ -101,7 +101,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-sm-6">
|
<div className="col-sm-6">
|
||||||
<Label htmlFor="taxId" required>
|
<Label htmlFor="taxId" >
|
||||||
Tax ID
|
Tax ID
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<input
|
||||||
@ -138,8 +138,10 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
|
|||||||
</Label>
|
</Label>
|
||||||
|
|
||||||
<select
|
<select
|
||||||
className="form-select form-select-sm"
|
id="organizationSize"
|
||||||
{...register("organizationSize")}
|
className="form-select shadow-none border py-1 px-2"
|
||||||
|
style={{ fontSize: "0.875rem" }} // Bootstrap's small text size
|
||||||
|
{...register("organizationSize", { required: "Organization size is required" })}
|
||||||
>
|
>
|
||||||
{orgSize.map((org) => (
|
{orgSize.map((org) => (
|
||||||
<option key={org.val} value={org.val}>
|
<option key={org.val} value={org.val}>
|
||||||
@ -147,17 +149,20 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
|
|||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
{errors.organizationSize && (
|
{errors.organizationSize && (
|
||||||
<div className="danger-text">{errors.organizationSize.message}</div>
|
<div className="danger-text">{errors.organizationSize.message}</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className="col-sm-6">
|
<div className="col-sm-6">
|
||||||
<Label htmlFor="industryId" required>
|
<Label htmlFor="industryId" required>
|
||||||
Industry
|
Industry
|
||||||
</Label>
|
</Label>
|
||||||
<select
|
<select
|
||||||
className="form-select form-select-sm"
|
id="industryId"
|
||||||
|
className="form-select shadow-none border py-1 px-2 small"
|
||||||
{...register("industryId")}
|
{...register("industryId")}
|
||||||
>
|
>
|
||||||
{industryLoading ? (
|
{industryLoading ? (
|
||||||
@ -177,9 +182,9 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
|
|||||||
|
|
||||||
<div className="col-sm-6">
|
<div className="col-sm-6">
|
||||||
<Label htmlFor="reference">Reference</Label>
|
<Label htmlFor="reference">Reference</Label>
|
||||||
|
|
||||||
<select
|
<select
|
||||||
className="form-select form-select-sm"
|
id="reference"
|
||||||
|
className="form-select shadow-none border py-1 px-2 small"
|
||||||
{...register("reference")}
|
{...register("reference")}
|
||||||
>
|
>
|
||||||
{reference.map((org) => (
|
{reference.map((org) => (
|
||||||
@ -193,6 +198,7 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className="col-sm-12">
|
<div className="col-sm-12">
|
||||||
<Label htmlFor="description">Description</Label>
|
<Label htmlFor="description">Description</Label>
|
||||||
<textarea
|
<textarea
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import React, { useState,useCallback } from "react";
|
import React, { useState, useCallback, useEffect } from "react";
|
||||||
import { FormProvider, useForm, useFormContext } from "react-hook-form";
|
import { FormProvider, useForm, useFormContext } from "react-hook-form";
|
||||||
import { defaultFilterValues, filterSchema } from "./TenantSchema";
|
import { defaultFilterValues, filterSchema } from "./TenantSchema";
|
||||||
import Label from "../common/Label";
|
import Label from "../common/Label";
|
||||||
@ -8,6 +8,7 @@ import { useIndustries } from "../../hooks/useTenant";
|
|||||||
import { reference, TENANT_STATUS } from "../../utils/constants";
|
import { reference, TENANT_STATUS } from "../../utils/constants";
|
||||||
import { DateRangePicker1 } from "../common/DateRangePicker";
|
import { DateRangePicker1 } from "../common/DateRangePicker";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
|
||||||
const TenantFilterPanel = ({ onApply }) => {
|
const TenantFilterPanel = ({ onApply }) => {
|
||||||
const [resetKey, setResetKey] = useState(0);
|
const [resetKey, setResetKey] = useState(0);
|
||||||
@ -36,6 +37,13 @@ const [resetKey, setResetKey] = useState(0);
|
|||||||
[onApply, handleClosePanel]
|
[onApply, handleClosePanel]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// ✅ Close popup when navigating to another component
|
||||||
|
const location = useLocation();
|
||||||
|
useEffect(() => {
|
||||||
|
handleClosePanel();
|
||||||
|
}, [location]);
|
||||||
|
|
||||||
const onClear = useCallback(() => {
|
const onClear = useCallback(() => {
|
||||||
reset(defaultFilterValues);
|
reset(defaultFilterValues);
|
||||||
setResetKey((prev) => prev + 1); // triggers DateRangePicker reset
|
setResetKey((prev) => prev + 1); // triggers DateRangePicker reset
|
||||||
|
@ -11,12 +11,12 @@ export const newTenantSchema = z.object({
|
|||||||
.regex(/^[A-Za-z]+$/, { message: "Last Name should contain only letters!" }),
|
.regex(/^[A-Za-z]+$/, { message: "Last Name should contain only letters!" }),
|
||||||
email: z.string().trim().email("Invalid email address"),
|
email: z.string().trim().email("Invalid email address"),
|
||||||
description: z.string().trim().optional(),
|
description: z.string().trim().optional(),
|
||||||
domainName: z.string().trim().nonempty("Domain name is required"),
|
domainName: z.string().trim().optional(),
|
||||||
billingAddress: z.string().trim().nonempty("Billing address is required"),
|
billingAddress: z.string().trim().nonempty("Billing address is required"),
|
||||||
taxId: z.string().trim().nonempty("Tax ID is required"),
|
taxId: z.string().trim().optional(),
|
||||||
logoImage: z.string().trim().optional(),
|
logoImage: z.string().trim().optional(),
|
||||||
organizationName: z.string().trim().nonempty("Organization name is required"),
|
organizationName: z.string().trim().nonempty("Organization name is required"),
|
||||||
officeNumber: z.string().trim().nonempty("Office number is required"),
|
officeNumber: z.string().trim().optional(),
|
||||||
contactNumber: z.string().trim()
|
contactNumber: z.string().trim()
|
||||||
.nonempty("Contact number is required")
|
.nonempty("Contact number is required")
|
||||||
.regex(/^\+?[1-9]\d{7,14}$/, "Enter a valid contact number"),
|
.regex(/^\+?[1-9]\d{7,14}$/, "Enter a valid contact number"),
|
||||||
@ -141,11 +141,11 @@ lastName: z
|
|||||||
.min(1, { message: "Last Name is required!" })
|
.min(1, { message: "Last Name is required!" })
|
||||||
.regex(/^[A-Za-z]+$/, { message: "Last Name should contain only letters!" }),
|
.regex(/^[A-Za-z]+$/, { message: "Last Name should contain only letters!" }),
|
||||||
description: z.string().trim().optional(),
|
description: z.string().trim().optional(),
|
||||||
domainName: z.string().trim().min(1, { message: "Domain Name is required!" }),
|
domainName: z.string().trim().optional(),
|
||||||
billingAddress: z.string().trim().min(1, { message: "Billing Address is required!" }),
|
billingAddress: z.string().trim().min(1, { message: "Billing Address is required!" }),
|
||||||
taxId: z.string().trim().min(1, { message: "Tax ID is required!" }),
|
taxId: z.string().trim().optional(),
|
||||||
logoImage: z.string().optional(),
|
logoImage: z.string().optional(),
|
||||||
officeNumber: z.string().trim().min(1, { message: "Office Number is required!" }),
|
officeNumber: z.string().trim().optional(),
|
||||||
contactNumber: z.string().trim()
|
contactNumber: z.string().trim()
|
||||||
.nonempty("Contact number is required")
|
.nonempty("Contact number is required")
|
||||||
.regex(/^\+?[1-9]\d{7,14}$/, "Enter a valid contact number"),
|
.regex(/^\+?[1-9]\d{7,14}$/, "Enter a valid contact number"),
|
||||||
|
@ -46,6 +46,12 @@ const DateRangePicker = ({
|
|||||||
};
|
};
|
||||||
}, [onRangeChange, DateDifference, endDateMode]);
|
}, [onRangeChange, DateDifference, endDateMode]);
|
||||||
|
|
||||||
|
const handleIconClick = () => {
|
||||||
|
if (inputRef.current) {
|
||||||
|
inputRef.current._flatpickr.open(); // directly opens flatpickr
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`col-${sm} col-sm-${md} px-1`}>
|
<div className={`col-${sm} col-sm-${md} px-1`}>
|
||||||
<input
|
<input
|
||||||
@ -57,7 +63,7 @@ const DateRangePicker = ({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<i
|
<i
|
||||||
className="bx bx-calendar calendar-icon cursor-pointer position-relative top-50 translate-middle-y "
|
className="bx bx-calendar calendar-icon cursor-pointer position-relative top-50 translate-middle-y " onClick={handleIconClick}
|
||||||
style={{ right: "22px", bottom: "-8px" }}
|
style={{ right: "22px", bottom: "-8px" }}
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
const FilterIcon = ({
|
const FilterIcon = ({
|
||||||
taskListData,
|
taskListData,
|
||||||
@ -7,15 +8,26 @@ const FilterIcon = ({
|
|||||||
currentSelectedFloors,
|
currentSelectedFloors,
|
||||||
currentSelectedActivities,
|
currentSelectedActivities,
|
||||||
}) => {
|
}) => {
|
||||||
|
const selectedProject = useSelector((store) => store.localVariables.projectId);
|
||||||
|
|
||||||
const [selectedBuilding, setSelectedBuilding] = useState(currentSelectedBuilding || "");
|
const [selectedBuilding, setSelectedBuilding] = useState(currentSelectedBuilding || "");
|
||||||
const [selectedFloors, setSelectedFloors] = useState(currentSelectedFloors || []);
|
const [selectedFloors, setSelectedFloors] = useState(currentSelectedFloors || []);
|
||||||
const [selectedActivities, setSelectedActivities] = useState(currentSelectedActivities || []);
|
const [selectedActivities, setSelectedActivities] = useState(currentSelectedActivities || []);
|
||||||
|
|
||||||
|
const [appliedBuilding, setAppliedBuilding] = useState(currentSelectedBuilding || "");
|
||||||
|
const [appliedFloors, setAppliedFloors] = useState(currentSelectedFloors || []);
|
||||||
|
const [appliedActivities, setAppliedActivities] = useState(currentSelectedActivities || []);
|
||||||
|
|
||||||
|
// Reset filters whenever inputs OR projectId changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSelectedBuilding(currentSelectedBuilding || "");
|
setSelectedBuilding(currentSelectedBuilding || "");
|
||||||
setSelectedFloors(currentSelectedFloors || []);
|
setSelectedFloors(currentSelectedFloors || []);
|
||||||
setSelectedActivities(currentSelectedActivities || []);
|
setSelectedActivities(currentSelectedActivities || []);
|
||||||
}, [currentSelectedBuilding, currentSelectedFloors, currentSelectedActivities]);
|
|
||||||
|
setAppliedBuilding(currentSelectedBuilding || "");
|
||||||
|
setAppliedFloors(currentSelectedFloors || []);
|
||||||
|
setAppliedActivities(currentSelectedActivities || []);
|
||||||
|
}, [currentSelectedBuilding, currentSelectedFloors, currentSelectedActivities, selectedProject]);
|
||||||
|
|
||||||
const getUniqueFilterValues = (key, overrideBuilding, overrideFloors) => {
|
const getUniqueFilterValues = (key, overrideBuilding, overrideFloors) => {
|
||||||
if (!taskListData) return [];
|
if (!taskListData) return [];
|
||||||
@ -61,12 +73,11 @@ const FilterIcon = ({
|
|||||||
} else if (filterType === "floor") {
|
} else if (filterType === "floor") {
|
||||||
if (updatedFloors.includes(value)) {
|
if (updatedFloors.includes(value)) {
|
||||||
updatedFloors = updatedFloors.filter((floor) => floor !== value);
|
updatedFloors = updatedFloors.filter((floor) => floor !== value);
|
||||||
|
const validActivities = getUniqueFilterValues("activity", updatedBuilding, updatedFloors);
|
||||||
|
updatedActivities = updatedActivities.filter((act) => validActivities.includes(act));
|
||||||
} else {
|
} else {
|
||||||
updatedFloors.push(value);
|
updatedFloors.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const validActivities = getUniqueFilterValues("activity", updatedBuilding, updatedFloors);
|
|
||||||
updatedActivities = updatedActivities.filter((act) => validActivities.includes(act));
|
|
||||||
} else if (filterType === "activity") {
|
} else if (filterType === "activity") {
|
||||||
if (updatedActivities.includes(value)) {
|
if (updatedActivities.includes(value)) {
|
||||||
updatedActivities = updatedActivities.filter((act) => act !== value);
|
updatedActivities = updatedActivities.filter((act) => act !== value);
|
||||||
@ -78,12 +89,20 @@ const FilterIcon = ({
|
|||||||
setSelectedBuilding(updatedBuilding);
|
setSelectedBuilding(updatedBuilding);
|
||||||
setSelectedFloors(updatedFloors);
|
setSelectedFloors(updatedFloors);
|
||||||
setSelectedActivities(updatedActivities);
|
setSelectedActivities(updatedActivities);
|
||||||
|
};
|
||||||
|
|
||||||
|
const applyFilters = () => {
|
||||||
|
setAppliedBuilding(selectedBuilding);
|
||||||
|
setAppliedFloors(selectedFloors);
|
||||||
|
setAppliedActivities(selectedActivities);
|
||||||
|
|
||||||
onApplyFilters({
|
onApplyFilters({
|
||||||
selectedBuilding: updatedBuilding,
|
selectedBuilding,
|
||||||
selectedFloors: updatedFloors,
|
selectedFloors,
|
||||||
selectedActivities: updatedActivities,
|
selectedActivities,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById("filterDropdown").click();
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearAllFilters = () => {
|
const clearAllFilters = () => {
|
||||||
@ -91,6 +110,10 @@ const FilterIcon = ({
|
|||||||
setSelectedFloors([]);
|
setSelectedFloors([]);
|
||||||
setSelectedActivities([]);
|
setSelectedActivities([]);
|
||||||
|
|
||||||
|
setAppliedBuilding("");
|
||||||
|
setAppliedFloors([]);
|
||||||
|
setAppliedActivities([]);
|
||||||
|
|
||||||
onApplyFilters({
|
onApplyFilters({
|
||||||
selectedBuilding: "",
|
selectedBuilding: "",
|
||||||
selectedFloors: [],
|
selectedFloors: [],
|
||||||
@ -98,21 +121,51 @@ const FilterIcon = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Count applied filters
|
||||||
|
const appliedFilterCount =
|
||||||
|
(appliedBuilding ? 1 : 0) + appliedFloors.length + appliedActivities.length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dropdown" style={{marginLeft:"-14px"}}>
|
<div className="dropdown" style={{ marginLeft: "-14px", position: "relative" }}>
|
||||||
<a
|
<a
|
||||||
className="dropdown-toggle hide-arrow cursor-pointer"
|
className="dropdown-toggle hide-arrow cursor-pointer"
|
||||||
id="filterDropdown"
|
id="filterDropdown"
|
||||||
data-bs-toggle="dropdown"
|
data-bs-toggle="dropdown"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
>
|
>
|
||||||
{/* <i className="bx bx-slider-alt ms-1" /> */}
|
<div style={{ position: "relative", display: "inline-block" }}>
|
||||||
<i
|
<i
|
||||||
className="bx bx-slider-alt"
|
className="bx bx-slider-alt"
|
||||||
style={{ color: selectedBuilding || selectedFloors.length > 0 || selectedActivities.length > 0 ? "#7161EF" : "gray" }}
|
style={{
|
||||||
|
color: appliedFilterCount > 0 ? "#7161EF" : "gray",
|
||||||
|
fontSize: "20px",
|
||||||
|
}}
|
||||||
></i>
|
></i>
|
||||||
|
{appliedFilterCount > 0 && (
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: "-11px",
|
||||||
|
right: "-6px",
|
||||||
|
backgroundColor: "#FFC107", // yellow
|
||||||
|
color: "white",
|
||||||
|
fontSize: "10px",
|
||||||
|
fontWeight: "bold",
|
||||||
|
borderRadius: "50%",
|
||||||
|
width: "18px",
|
||||||
|
height: "18px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
border: "1px solid white",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{appliedFilterCount}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
className="dropdown-menu p-2 mt-2"
|
className="dropdown-menu p-2 mt-2"
|
||||||
aria-labelledby="filterDropdown"
|
aria-labelledby="filterDropdown"
|
||||||
@ -205,45 +258,30 @@ const FilterIcon = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Action Buttons */}
|
{/* Action Buttons */}
|
||||||
<li><hr className="my-1" /></li>
|
<li>
|
||||||
{(selectedBuilding || selectedFloors.length > 0 || selectedActivities.length > 0) && (
|
<hr className="my-1" />
|
||||||
<li className="d-flex justify-content-end gap-2 px-2">
|
</li>
|
||||||
|
{(appliedFilterCount > 0 ||
|
||||||
|
selectedBuilding ||
|
||||||
|
selectedFloors.length > 0 ||
|
||||||
|
selectedActivities.length > 0) && (
|
||||||
|
<li className="d-flex justify-content-end gap-2 px-2 mt-2 mb-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-sm"
|
className="btn btn-secondary btn-sm py-0 px-2"
|
||||||
style={{
|
|
||||||
backgroundColor: "#7161EF",
|
|
||||||
color: "white",
|
|
||||||
fontSize: "13px",
|
|
||||||
padding: "4px 16px",
|
|
||||||
borderRadius: "8px",
|
|
||||||
boxShadow: "0 1px 4px rgba(0,0,0,0.1)"
|
|
||||||
}}
|
|
||||||
onClick={clearAllFilters}
|
onClick={clearAllFilters}
|
||||||
>
|
>
|
||||||
Clear
|
Clear
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-sm"
|
className="btn btn-primary btn-sm py-0 px-2"
|
||||||
style={{
|
onClick={applyFilters}
|
||||||
backgroundColor: "#7161EF",
|
|
||||||
color: "white",
|
|
||||||
fontSize: "13px",
|
|
||||||
padding: "4px 16px",
|
|
||||||
borderRadius: "8px",
|
|
||||||
boxShadow: "0 1px 4px rgba(0,0,0,0.1)"
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
document.getElementById("filterDropdown").click();
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Apply
|
Apply
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -222,15 +222,12 @@ const CreateActivity = ({ onClose }) => {
|
|||||||
|
|
||||||
<div className="col-12 text-end mt-3">
|
<div className="col-12 text-end mt-3">
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="button" // ✅ change to button
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" className="btn btn-sm btn-primary">
|
|
||||||
{isLoading ? "Please Wait" : "Submit"}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -66,16 +66,16 @@ useEffect(() => {
|
|||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
|
<form className="row g-2" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<div className="col-12 col-md-12 text-start">
|
<div className="col-12 col-md-12">
|
||||||
<Label className="form-label" required>Category Name</Label>
|
<label className="form-label">Category Name</label>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
{...register("name")}
|
{...register("name")}
|
||||||
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
|
className={`form-control ${errors.name ? 'is-invalids' : ''}`}
|
||||||
/>
|
/>
|
||||||
{errors.name && <p className="text-danger">{errors.name.message}</p>}
|
{errors.name && <p className="text-danger">{errors.name.message}</p>}
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 col-md-12 text-start">
|
<div className="col-12 col-md-12">
|
||||||
<Label className="form-label" htmlFor="description" required>Description</Label>
|
<label className="form-label" htmlFor="description">Description</label>
|
||||||
<textarea
|
<textarea
|
||||||
rows="3"
|
rows="3"
|
||||||
{...register("description")}
|
{...register("description")}
|
||||||
@ -93,18 +93,20 @@ useEffect(() => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 text-end">
|
<div className="col-12 text-center">
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||||
|
{isLoading ? "Please Wait..." : "Submit"}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="button" // ✅ not reset
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={() => {
|
||||||
aria-label="Close"
|
resetForm(); // clear inputs
|
||||||
|
onClose?.(); // close modal from parent
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" className="btn btn-sm btn-primary">
|
|
||||||
{isLoading? "Please Wait...":"Submit"}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -93,18 +93,20 @@ useEffect(() => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 text-end">
|
<div className="col-12 text-center">
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||||
|
{isLoading ? "Please Wait..." : "Submit"}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="button" // ✅ not reset
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={() => {
|
||||||
aria-label="Close"
|
resetForm(); // clear inputs
|
||||||
|
onClose?.(); // close modal from parent
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" className="btn btn-sm btn-primary">
|
|
||||||
{isLoading? "Please Wait...":"Submit"}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -119,18 +119,20 @@ const CreateJobRole = ({onClose}) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 text-end">
|
<div className="col-12 text-center">
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||||
|
{isLoading ? "Please Wait..." : "Submit"}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="button" // ✅ change from reset → button
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={() => {
|
||||||
aria-label="Close"
|
resetForm(); // optional: clears form
|
||||||
|
onClose?.(); // ✅ close modal via parent
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" className="btn btn-sm btn-primary">
|
|
||||||
{isLoading? "Please Wait...":"Submit"}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -229,18 +229,17 @@ const CreateRole = ({ modalType, onClose }) => {
|
|||||||
|
|
||||||
|
|
||||||
{masterFeatures && (
|
{masterFeatures && (
|
||||||
<div className="col-12 text-end">
|
<div className="col-12 text-center">
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||||
|
{isLoading ? "Please Wait..." : "Submit"}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="button"
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={onClose}
|
||||||
aria-label="Close"
|
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" className="btn btn-sm btn-primary">
|
|
||||||
{isLoading ? "Please Wait..." : "Submit"}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -109,12 +109,17 @@ useEffect(() => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 text-end">
|
<div className="col-12 text-center">
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||||
|
{isLoading ? "Please Wait..." : "Submit"}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="button" // ✅ not reset
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={() => {
|
||||||
aria-label="Close"
|
resetForm(); // clear inputs
|
||||||
|
onClose?.(); // close modal from parent
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
@ -34,13 +34,15 @@ const DeleteMaster = ({ master, onClose }) => {
|
|||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="button" // ✅ not reset
|
||||||
className="btn btn-label-secondary"
|
className="btn btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={() => {
|
||||||
aria-label="Close"
|
onClose?.(); // properly close modal
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -239,8 +239,8 @@ const UpdateActivity = ({ activityData, onClose }) => {
|
|||||||
{/* Submit / Cancel */}
|
{/* Submit / Cancel */}
|
||||||
<div className="col-12 text-end mt-3">
|
<div className="col-12 text-end mt-3">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button" // ✅ change to button
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
|
@ -112,12 +112,17 @@ useEffect(() => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 text-end">
|
<div className="col-12 text-center">
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||||
|
{isLoading ? "Please Wait..." : "Submit"}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button" // ✅ not reset
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={() => {
|
||||||
aria-label="Close"
|
resetForm(); // clear inputs
|
||||||
|
onClose?.(); // close modal from parent
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
@ -112,12 +112,17 @@ useEffect(() => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 text-end">
|
<div className="col-12 text-center">
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||||
|
{isLoading ? "Please Wait..." : "Submit"}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button" // ✅ not reset
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={() => {
|
||||||
aria-label="Close"
|
resetForm(); // clear inputs
|
||||||
|
onClose?.(); // close modal from parent
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
@ -128,12 +128,14 @@ const [descriptionLength, setDescriptionLength] = useState(data?.description?.le
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 text-end">
|
<div className="col-12 text-center">
|
||||||
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||||
|
{isLoading ? "Please Wait..." : "Submit"}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={onClose} // 👈 This will now close the popup
|
||||||
aria-label="Close"
|
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
@ -143,6 +145,7 @@ const [descriptionLength, setDescriptionLength] = useState(data?.description?.le
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
|
@ -279,13 +279,11 @@ const EditMaster = ({ master, onClose }) => {
|
|||||||
<div className="col-12 text-end">
|
<div className="col-12 text-end">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={onClose}
|
||||||
aria-label="Close"
|
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" className="btn btn-sm btn-primary"> {isLoading ? "Please Wait..." : "Submit"}</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -121,13 +121,13 @@ useEffect(() => {
|
|||||||
{isLoading ? "Please Wait..." : "Submit"}
|
{isLoading ? "Please Wait..." : "Submit"}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="reset"
|
type="button"
|
||||||
className="btn btn-sm btn-label-secondary"
|
className="btn btn-sm btn-label-secondary"
|
||||||
data-bs-dismiss="modal"
|
onClick={onClose}
|
||||||
aria-label="Close"
|
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
@ -71,8 +71,19 @@ const ManagePaymentMode = ({ data = null, onClose }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="col-12 text-center">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="btn btn-sm btn-primary me-3"
|
||||||
|
disabled={isPending || Updating}
|
||||||
|
>
|
||||||
|
{isPending || Updating ? "Please Wait..." : Updating ? "Update" : "Submit"}
|
||||||
|
</button>
|
||||||
<div className="col-12 text-end">
|
<div className="col-12 text-end">
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-sm btn-label-secondary"
|
||||||
|
onClick={onClose} // ✅ call onClose here
|
||||||
type="reset"
|
type="reset"
|
||||||
className="btn btn-sm btn-label-secondary me-3"
|
className="btn btn-sm btn-label-secondary me-3"
|
||||||
data-bs-dismiss="modal"
|
data-bs-dismiss="modal"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { cacheData, getCachedData, useSelectedproject } from "../slices/apiDataManager";
|
import { cacheData, getCachedData, useSelectedProject } from "../slices/apiDataManager";
|
||||||
import AttendanceRepository from "../repositories/AttendanceRepository";
|
import AttendanceRepository from "../repositories/AttendanceRepository";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import showToast from "../services/toastService";
|
import showToast from "../services/toastService";
|
||||||
@ -143,8 +143,7 @@ export const useRegularizationRequests = (projectId) => {
|
|||||||
|
|
||||||
export const useMarkAttendance = () => {
|
export const useMarkAttendance = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
// const selectedProject = useSelector((store)=>store.localVariables.projectId)
|
const selectedProject = useSelectedProject();
|
||||||
const selectedProject = useSelectedproject();
|
|
||||||
const selectedDateRange = useSelector((store)=>store.localVariables.defaultDateRange)
|
const selectedDateRange = useSelector((store)=>store.localVariables.defaultDateRange)
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
|
@ -17,13 +17,13 @@ const cleanFilter = (filter) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// moment.utc() to get consistent UTC ISO strings
|
// moment.utc() to get consistent UTC ISO strings
|
||||||
if (!cleaned.startDate) {
|
// if (!cleaned.startDate) {
|
||||||
cleaned.startDate = moment.utc().subtract(7, "days").startOf("day").toISOString();
|
// cleaned.startDate = moment.utc().subtract(7, "days").startOf("day").toISOString();
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!cleaned.endDate) {
|
// if (!cleaned.endDate) {
|
||||||
cleaned.endDate = moment.utc().startOf("day").toISOString();
|
// cleaned.endDate = moment.utc().startOf("day").toISOString();
|
||||||
}
|
// }
|
||||||
|
|
||||||
return cleaned;
|
return cleaned;
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
clearCacheKey,
|
clearCacheKey,
|
||||||
getCachedData,
|
getCachedData,
|
||||||
getCachedProfileData,
|
getCachedProfileData,
|
||||||
useSelectedproject,
|
useSelectedProject,
|
||||||
} from "../../slices/apiDataManager";
|
} from "../../slices/apiDataManager";
|
||||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||||
import AttendanceLog from "../../components/Activities/AttendcesLogs";
|
import AttendanceLog from "../../components/Activities/AttendcesLogs";
|
||||||
@ -26,11 +26,11 @@ import { useQueryClient } from "@tanstack/react-query";
|
|||||||
const AttendancePage = () => {
|
const AttendancePage = () => {
|
||||||
const [activeTab, setActiveTab] = useState("all");
|
const [activeTab, setActiveTab] = useState("all");
|
||||||
const [ShowPending, setShowPending] = useState(false);
|
const [ShowPending, setShowPending] = useState(false);
|
||||||
const [searchTerm, setSearchTerm] = useState(""); // 🔹 New state for search
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const loginUser = getCachedProfileData();
|
const loginUser = getCachedProfileData();
|
||||||
// const selectedProject = useSelector((store) => store.localVariables.projectId);
|
|
||||||
const selectedProject = useSelectedproject();
|
const selectedProject = useSelectedProject();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const [attendances, setAttendances] = useState();
|
const [attendances, setAttendances] = useState();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useMemo, useRef, useState } from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
import { useDispatch } from "react-redux";
|
import { useDispatch } from "react-redux";
|
||||||
import { useTaskList } from "../../hooks/useTasks";
|
import { useTaskList } from "../../hooks/useTasks";
|
||||||
import { useProjectName } from "../../hooks/useProjects";
|
import { useProjectName } from "../../hooks/useProjects";
|
||||||
@ -13,13 +13,13 @@ import SubTask from "../../components/Activities/SubTask";
|
|||||||
import { formatNumber, formatUTCToLocalTime } from "../../utils/dateUtils";
|
import { formatNumber, formatUTCToLocalTime } from "../../utils/dateUtils";
|
||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import { APPROVE_TASK, ASSIGN_REPORT_TASK } from "../../utils/constants";
|
import { APPROVE_TASK, ASSIGN_REPORT_TASK } from "../../utils/constants";
|
||||||
import { useSelectedproject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import Loader from "../../components/common/Loader";
|
import Loader from "../../components/common/Loader";
|
||||||
|
|
||||||
const DailyTask = () => {
|
const DailyTask = () => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const selectedProject = useSelectedproject();
|
const selectedProject = useSelectedProject();
|
||||||
const { projectNames } = useProjectName();
|
const { projectNames } = useProjectName();
|
||||||
const ApprovedTaskRights = useHasUserPermission(APPROVE_TASK);
|
const ApprovedTaskRights = useHasUserPermission(APPROVE_TASK);
|
||||||
const ReportTaskRights = useHasUserPermission(ASSIGN_REPORT_TASK);
|
const ReportTaskRights = useHasUserPermission(ASSIGN_REPORT_TASK);
|
||||||
@ -41,10 +41,20 @@ const DailyTask = () => {
|
|||||||
// Ensure project is set
|
// Ensure project is set
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!selectedProject && projectNames.length > 0) {
|
if (!selectedProject && projectNames.length > 0) {
|
||||||
|
debugger
|
||||||
dispatch(setProjectId(projectNames[0].id));
|
dispatch(setProjectId(projectNames[0].id));
|
||||||
}
|
}
|
||||||
}, [selectedProject, projectNames, dispatch]);
|
}, [selectedProject, projectNames, dispatch]);
|
||||||
|
|
||||||
|
// 🔹 Reset filters when project changes
|
||||||
|
useEffect(() => {
|
||||||
|
setFilters({
|
||||||
|
selectedBuilding: "",
|
||||||
|
selectedFloors: [],
|
||||||
|
selectedActivities: [],
|
||||||
|
});
|
||||||
|
}, [selectedProject]);
|
||||||
|
|
||||||
// Memoized filtering
|
// Memoized filtering
|
||||||
const filteredTasks = useMemo(() => {
|
const filteredTasks = useMemo(() => {
|
||||||
if (!TaskList) return [];
|
if (!TaskList) return [];
|
||||||
@ -163,6 +173,7 @@ const DailyTask = () => {
|
|||||||
currentSelectedBuilding={filters.selectedBuilding}
|
currentSelectedBuilding={filters.selectedBuilding}
|
||||||
currentSelectedFloors={filters.selectedFloors}
|
currentSelectedFloors={filters.selectedFloors}
|
||||||
currentSelectedActivities={filters.selectedActivities}
|
currentSelectedActivities={filters.selectedActivities}
|
||||||
|
selectedProject={selectedProject}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -4,21 +4,19 @@ import InfraPlanning from "../../components/Activities/InfraPlanning";
|
|||||||
import { useProjectName } from "../../hooks/useProjects";
|
import { useProjectName } from "../../hooks/useProjects";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { setProjectId } from "../../slices/localVariablesSlice";
|
import { setProjectId } from "../../slices/localVariablesSlice";
|
||||||
import { useSelectedproject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
|
|
||||||
const TaskPlannng = () => {
|
const TaskPlannng = () => {
|
||||||
const selectedProject = useSelectedproject();
|
const selectedProject = useSelectedProject();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { projectNames, loading: projectLoading } = useProjectName();
|
const { projectNames = [], loading: projectLoading } = useProjectName();
|
||||||
|
|
||||||
const initialized = useRef(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!initialized.current && projectNames.length > 0 && !selectedProject?.id) {
|
if (!selectedProject) {
|
||||||
dispatch(setProjectId(projectNames[0].id));
|
dispatch(setProjectId(projectNames[0].id));
|
||||||
initialized.current = true;
|
|
||||||
}
|
}
|
||||||
}, [projectNames, selectedProject, dispatch]);
|
}, [projectNames, selectedProject?.id, dispatch]);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
|
@ -210,7 +210,7 @@ const LoginPage = () => {
|
|||||||
Login With Password
|
Login With Password
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<Link to="/auth/reqest/demo" className="registration-link">
|
<Link to="/market/enquire" className="registration-link">
|
||||||
Request a Demo
|
Request a Demo
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
|
@ -18,7 +18,7 @@ import {
|
|||||||
VIEW_ALL_EMPLOYEES,
|
VIEW_ALL_EMPLOYEES,
|
||||||
VIEW_TEAM_MEMBERS,
|
VIEW_TEAM_MEMBERS,
|
||||||
} from "../../utils/constants";
|
} from "../../utils/constants";
|
||||||
import { clearCacheKey, useSelectedproject } from "../../slices/apiDataManager";
|
import { clearCacheKey, useSelectedProject } from "../../slices/apiDataManager";
|
||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import SuspendEmp from "../../components/Employee/SuspendEmp"; // Keep if you use SuspendEmp
|
import SuspendEmp from "../../components/Employee/SuspendEmp"; // Keep if you use SuspendEmp
|
||||||
import {
|
import {
|
||||||
@ -41,7 +41,7 @@ const EmployeeList = () => {
|
|||||||
// const selectedProjectId = useSelector(
|
// const selectedProjectId = useSelector(
|
||||||
// (store) => store.localVariables.projectId
|
// (store) => store.localVariables.projectId
|
||||||
// );
|
// );
|
||||||
const selectedProjectId = useSelectedproject();
|
const selectedProjectId = useSelectedProject();
|
||||||
const { projectNames, loading: projectLoading, fetchData } = useProjectName();
|
const { projectNames, loading: projectLoading, fetchData } = useProjectName();
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
@ -122,13 +122,16 @@ const MasterPage = () => {
|
|||||||
onChange={(e) => dispatch(changeMaster(e.target.value))}
|
onChange={(e) => dispatch(changeMaster(e.target.value))}
|
||||||
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 py-1 px-2"
|
||||||
|
style={{ fontSize: "0.875rem", height: "32px", width: "150px" }}
|
||||||
value={selectedMaster}
|
value={selectedMaster}
|
||||||
>
|
>
|
||||||
{isLoading && (<option value={null}>Loading...</option>)}
|
{isLoading && <option value="">Loading...</option>}
|
||||||
{(!isLoading && data) && data?.map((item) => (
|
{!isLoading &&
|
||||||
|
data?.map((item) => (
|
||||||
<option key={item.id} value={item.name}>{item.name}</option>
|
<option key={item.id} value={item.name}>
|
||||||
|
{item.name}
|
||||||
|
</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
cacheData,
|
cacheData,
|
||||||
clearCacheKey,
|
clearCacheKey,
|
||||||
getCachedData,
|
getCachedData,
|
||||||
useSelectedproject,
|
useSelectedProject,
|
||||||
} from "../../slices/apiDataManager";
|
} from "../../slices/apiDataManager";
|
||||||
import "./ProjectDetails.css";
|
import "./ProjectDetails.css";
|
||||||
import {
|
import {
|
||||||
@ -29,7 +29,7 @@ import { setProjectId } from "../../slices/localVariablesSlice";
|
|||||||
|
|
||||||
const ProjectDetails = () => {
|
const ProjectDetails = () => {
|
||||||
|
|
||||||
const projectId = useSelectedproject()
|
const projectId = useSelectedProject()
|
||||||
|
|
||||||
const { projectNames, fetchData } = useProjectName();
|
const { projectNames, fetchData } = useProjectName();
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
@ -34,6 +34,8 @@ export const DirectoryRepository = {
|
|||||||
DeleteNote: (id, isActive) =>
|
DeleteNote: (id, isActive) =>
|
||||||
api.delete(`/api/directory/note/${id}?active=${isActive}`),
|
api.delete(`/api/directory/note/${id}?active=${isActive}`),
|
||||||
|
|
||||||
GetNotes: (pageSize, pageNumber) =>
|
GetNotes: (pageSize, pageNumber, projectId) =>
|
||||||
api.get(`/api/directory/notes?pageSize=${pageSize}&pageNumber=${pageNumber}`),
|
api.get(
|
||||||
|
`/api/directory/notes?pageSize=${pageSize}&pageNumber=${pageNumber}&projectId=${projectId}`
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { api } from "../utils/axiosClient";
|
import { api } from "../utils/axiosClient";
|
||||||
|
|
||||||
export const MarketRepository = {
|
export const MarketRepository = {
|
||||||
requestDemo: (data) => api.post("/api/market/inquiry", data),
|
requestDemo: (data) => api.post("/api/market/enquire", data),
|
||||||
getIndustries: () => api.get("api/market/industries"),
|
getIndustries: () => api.get("api/market/industries"),
|
||||||
};
|
};
|
||||||
|
@ -52,7 +52,7 @@ const router = createBrowserRouter(
|
|||||||
children: [
|
children: [
|
||||||
{ path: "/auth/login", element: <LoginPage /> },
|
{ path: "/auth/login", element: <LoginPage /> },
|
||||||
{ path: "/auth/login-otp", element: <LoginWithOtp /> },
|
{ path: "/auth/login-otp", element: <LoginWithOtp /> },
|
||||||
{ path: "/auth/reqest/demo", element: <RegisterPage /> },
|
{ path: "/market/enquire", element: <RegisterPage /> },
|
||||||
{ path: "/auth/forgot-password", element: <ForgotPasswordPage /> },
|
{ path: "/auth/forgot-password", element: <ForgotPasswordPage /> },
|
||||||
{ path: "/reset-password", element: <ResetPasswordPage /> },
|
{ path: "/reset-password", element: <ResetPasswordPage /> },
|
||||||
{ path: "/legal-info", element: <LegalInfoCard /> },
|
{ path: "/legal-info", element: <LegalInfoCard /> },
|
||||||
|
@ -33,13 +33,12 @@ export const clearAllCache = () => {
|
|||||||
export const cacheProfileData = ( data) => {
|
export const cacheProfileData = ( data) => {
|
||||||
store.dispatch(setLoginUserPermmisions(data));
|
store.dispatch(setLoginUserPermmisions(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get cached data
|
// Get cached data
|
||||||
export const getCachedProfileData = () => {
|
export const getCachedProfileData = () => {
|
||||||
return store.getState().globalVariables.loginUser;
|
return store.getState().globalVariables.loginUser;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useSelectedproject = () => {
|
export const useSelectedProject = () => {
|
||||||
const selectedProject = useSelector((store)=> store.localVariables.projectId);
|
const selectedProject = useSelector((store)=> store.localVariables.projectId);
|
||||||
var project = localStorage.getItem("project");
|
var project = localStorage.getItem("project");
|
||||||
if(project){
|
if(project){
|
||||||
@ -47,7 +46,7 @@ export const useSelectedproject = () => {
|
|||||||
} else{
|
} else{
|
||||||
return selectedProject
|
return selectedProject
|
||||||
}
|
}
|
||||||
// return project ? selectedProject
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user