UI Changes in Assign Employee popup, Attendance tabs, Dashboard heading will be same.

This commit is contained in:
Kartik Sharma 2025-09-05 16:53:48 +05:30
parent 5c59ac3115
commit 7ed6a7e5b9
13 changed files with 177 additions and 131 deletions

View File

@ -114,7 +114,10 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
return ( return (
<> <>
<div className="table-responsive text-nowrap h-100" > <div
className="table-responsive text-nowrap h-100"
style={{ minHeight: "200px" }} // 🔹 Ensures fixed height
>
<div className="d-flex text-start align-items-center py-2"> <div className="d-flex text-start align-items-center py-2">
<strong>Date : {formatUTCToLocalTime(todayDate)}</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">
@ -209,7 +212,11 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
</tr> </tr>
))} ))}
{!attendance && ( {!attendance && (
<span className="text-secondary m-4">No employees assigned to the project!</span> <tr>
<td colSpan={6} className="text-center text-secondary" style={{ height: "200px" }}>
No employees assigned to the project!
</td>
</tr>
)} )}
</tbody> </tbody>
</table> </table>
@ -258,7 +265,10 @@ const Attendance = ({ getRole, handleModalData, searchTerm }) => {
)} )}
</> </>
) : ( ) : (
<div className="text-muted my-4"> <div
className="d-flex justify-content-center align-items-center text-muted"
style={{ height: "200px" }}
>
{searchTerm {searchTerm
? "No results found for your search." ? "No results found for your search."
: attendanceList.length === 0 : attendanceList.length === 0

View File

@ -42,7 +42,7 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
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);
const [showPending,setShowPending] = useState(false) const [showPending, setShowPending] = useState(false)
const [isRefreshing, setIsRefreshing] = useState(false); const [isRefreshing, setIsRefreshing] = useState(false);
const [processedData, setProcessedData] = useState([]); const [processedData, setProcessedData] = useState([]);
@ -245,17 +245,16 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
</div> </div>
<div className="col-md-2 m-0 text-end"> <div className="col-md-2 m-0 text-end">
<i <i
className={`bx bx-refresh cursor-pointer fs-4 ${ className={`bx bx-refresh cursor-pointer fs-4 ${isFetching ? "spin" : ""
isFetching ? "spin" : "" }`}
}`}
title="Refresh" title="Refresh"
onClick={() => refetch()} onClick={() => refetch()}
/> />
</div> </div>
</div> </div>
<div className="table-responsive text-nowrap"> <div className="table-responsive text-nowrap" style={{ minHeight: "200px" }}>
{isLoading ? ( {isLoading ? (
<div> <div className="d-flex justify-content-center align-items-center" style={{ height: "200px" }}>
<p className="text-secondary">Loading...</p> <p className="text-secondary">Loading...</p>
</div> </div>
) : filteredSearchData?.length > 0 ? ( ) : filteredSearchData?.length > 0 ? (
@ -284,9 +283,9 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
const previousAttendance = arr[index - 1]; const previousAttendance = arr[index - 1];
const previousDate = previousAttendance const previousDate = previousAttendance
? moment( ? moment(
previousAttendance.checkInTime || previousAttendance.checkInTime ||
previousAttendance.checkOutTime previousAttendance.checkOutTime
).format("YYYY-MM-DD") ).format("YYYY-MM-DD")
: null; : null;
if (!previousDate || currentDate !== previousDate) { if (!previousDate || currentDate !== previousDate) {
@ -346,12 +345,15 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
</tbody> </tbody>
</table> </table>
) : ( ) : (
<div className="my-4"><span className="text-secondary">No Record Available !</span></div> <div className="my-4"><span className="text-secondary">No Record Available !</span></div>
)} )}
</div> </div>
{paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && ( {paginatedAttendances?.length == 0 && filteredSearchData?.length > 0 && (
<div className="my-4"> <div
<span className="text-secondary">No Pending Record Available !</span> className="d-flex justify-content-center align-items-center text-secondary"
style={{ height: "200px" }}
>
No Record Available !
</div> </div>
)} )}
{filteredSearchData.length > ITEMS_PER_PAGE && ( {filteredSearchData.length > ITEMS_PER_PAGE && (
@ -369,9 +371,8 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
(pageNumber) => ( (pageNumber) => (
<li <li
key={pageNumber} key={pageNumber}
className={`page-item ${ className={`page-item ${currentPage === pageNumber ? "active" : ""
currentPage === pageNumber ? "active" : "" }`}
}`}
> >
<button <button
className="page-link" className="page-link"
@ -383,9 +384,8 @@ const AttendanceLog = ({ handleModalData, searchTerm }) => {
) )
)} )}
<li <li
className={`page-item ${ className={`page-item ${currentPage === totalPages ? "disabled" : ""
currentPage === totalPages ? "disabled" : "" }`}
}`}
> >
<button <button
className="page-link" className="page-link"

View File

@ -87,9 +87,9 @@ const Regularization = ({ handleRequest, searchTerm }) => {
}, [employeeHandler]); }, [employeeHandler]);
return ( return (
<div className="table-responsive text-nowrap pb-4"> <div className="table-responsive text-nowrap pb-4" style={{ minHeight: "200px" }}>
{loading ? ( {loading ? (
<div className="my-2"> <div className="d-flex justify-content-center align-items-center" style={{ height: "200px" }}>
<p className="text-secondary">Loading...</p> <p className="text-secondary">Loading...</p>
</div> </div>
) : currentItems?.length > 0 ? ( ) : currentItems?.length > 0 ? (
@ -143,9 +143,14 @@ const Regularization = ({ handleRequest, searchTerm }) => {
</tbody> </tbody>
</table> </table>
) : ( ) : (
<div className="my-4"> <div
className="d-flex justify-content-center align-items-center"
style={{ height: "200px" }}
>
<span className="text-secondary"> <span className="text-secondary">
{searchTerm ? "No results found for your search." : "No Requests Found !"} {searchTerm
? "No results found for your search."
: "No Requests Found !"}
</span> </span>
</div> </div>
)} )}
@ -163,9 +168,8 @@ const Regularization = ({ handleRequest, searchTerm }) => {
{[...Array(totalPages)].map((_, index) => ( {[...Array(totalPages)].map((_, index) => (
<li <li
key={index} key={index}
className={`page-item ${ className={`page-item ${currentPage === index + 1 ? "active" : ""
currentPage === index + 1 ? "active" : "" }`}
}`}
> >
<button <button
className="page-link " className="page-link "
@ -176,9 +180,8 @@ const Regularization = ({ handleRequest, searchTerm }) => {
</li> </li>
))} ))}
<li <li
className={`page-item ${ className={`page-item ${currentPage === totalPages ? "disabled" : ""
currentPage === totalPages ? "disabled" : "" }`}
}`}
> >
<button <button
className="page-link " className="page-link "

View File

@ -98,42 +98,42 @@ const AttendanceOverview = () => {
colors: roles.map((_, i) => flatColors[i % flatColors.length]), colors: roles.map((_, i) => flatColors[i % flatColors.length]),
}; };
return ( return (
<div <div
className="bg-white p-4 rounded shadow d-flex flex-column" className="bg-white p-4 rounded shadow d-flex flex-column"
> >
{/* Header */} {/* Header */}
<div className="d-flex justify-content-between align-items-center mb-3"> <div className="d-flex justify-content-between align-items-center mb-3">
<div className="card-title mb-0 text-start"> <div className="card-title mb-0 text-start">
<h5 className="mb-1">Attendance Overview</h5> <h5 className="mb-1 fw-bold">Attendance Overview</h5>
<p className="card-subtitle">Role-wise present count</p> <p className="card-subtitle">Role-wise present count</p>
</div> </div>
<div className="d-flex gap-2"> <div className="d-flex gap-2">
<select <select
className="form-select form-select-sm" className="form-select form-select-sm"
value={dayRange} value={dayRange}
onChange={(e) => setDayRange(Number(e.target.value))} onChange={(e) => setDayRange(Number(e.target.value))}
> >
<option value={7}>Last 7 Days</option> <option value={7}>Last 7 Days</option>
<option value={15}>Last 15 Days</option> <option value={15}>Last 15 Days</option>
<option value={30}>Last 30 Days</option> <option value={30}>Last 30 Days</option>
</select> </select>
<button <button
className={`btn btn-sm ${view === "chart" ? "btn-primary" : "btn-outline-primary"}`} className={`btn btn-sm ${view === "chart" ? "btn-primary" : "btn-outline-primary"}`}
onClick={() => setView("chart")} onClick={() => setView("chart")}
title="Chart View" title="Chart View"
> >
<i className="bx bx-bar-chart-alt-2"></i> <i className="bx bx-bar-chart-alt-2"></i>
</button> </button>
<button <button
className={`btn btn-sm ${view === "table" ? "btn-primary" : "btn-outline-primary"}`} className={`btn btn-sm ${view === "table" ? "btn-primary" : "btn-outline-primary"}`}
onClick={() => setView("table")} onClick={() => setView("table")}
title="Table View" title="Table View"
> >
<i className="bx bx-task text-success"></i> <i className="bx bx-task text-success"></i>
</button> </button>
</div> </div>
</div> </div>
{/* Content */} {/* Content */}
<div className="flex-grow-1 d-flex align-items-center justify-content-center"> <div className="flex-grow-1 d-flex align-items-center justify-content-center">

View File

@ -19,7 +19,7 @@ const ProjectCompletionChart = () => {
<div className="card h-100"> <div className="card h-100">
<div className="card-header d-flex align-items-start justify-content-between"> <div className="card-header d-flex align-items-start justify-content-between">
<div className="card-title mb-0 text-start"> <div className="card-title mb-0 text-start">
<h5 className="mb-1">Projects</h5> <h5 className="mb-1 fw-bold ">Projects</h5>
<p className="card-subtitle">Projects Completion Status</p> <p className="card-subtitle">Projects Completion Status</p>
</div> </div>
</div> </div>

View File

@ -90,7 +90,7 @@ const ProjectProgressChart = ({
<div className="d-flex flex-wrap justify-content-between align-items-start mb-2"> <div className="d-flex flex-wrap justify-content-between align-items-start mb-2">
{/* Left: Title */} {/* Left: Title */}
<div className="card-title text-start"> <div className="card-title text-start">
<h5 className="mb-1">Project Progress</h5> <h5 className="mb-1 fw-bold">Project Progress</h5>
<p className="card-subtitle">Progress Overview by Project</p> <p className="card-subtitle">Progress Overview by Project</p>
</div> </div>
</div> </div>

View File

@ -51,13 +51,13 @@ const AboutProject = () => {
)} )}
{projects_Details && ( {projects_Details && (
<> <>
<div className="card mb-6"> <div className="card mb-4">
<div className="card-header text-start"> <div className="card-header text-start">
<h6 className="card-action-title mb-0 ps-1"> <h5 className="card-action-title mb-0 ps-1">
{" "} {" "}
<i className="fa fa-building rounded-circle text-primary"></i> <i className="fa fa-building rounded-circle text-primary"></i>
<span className="ms-2">Project Profile</span> <span className="ms-2 fw-bold">Project Profile</span>
</h6> </h5>
</div> </div>
<div className="card-body"> <div className="card-body">
<ul className="list-unstyled my-3 ps-0"> <ul className="list-unstyled my-3 ps-0">

View File

@ -0,0 +1,19 @@
/* For Webkit browsers (Chrome, Edge, Safari) */
.modal-dialog-scrollable::-webkit-scrollbar {
width: 6px; /* smaller width */
}
.modal-dialog-scrollable::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.3); /* scrollbar color */
border-radius: 10px;
}
.modal-dialog-scrollable::-webkit-scrollbar-track {
background: transparent;
}
/* For Firefox */
.modal-dialog-scrollable {
scrollbar-width: thin; /* shrinks scrollbar */
scrollbar-color: rgba(0, 0, 0, 0.3) transparent;
}

View File

@ -4,6 +4,7 @@ import { useAllEmployees } from "../../hooks/useEmployees";
import useSearch from "../../hooks/useSearch"; import useSearch from "../../hooks/useSearch";
import AssignEmployeeTable from "./AssignEmployeeTable"; import AssignEmployeeTable from "./AssignEmployeeTable";
import showToast from "../../services/toastService"; import showToast from "../../services/toastService";
import "./MapUser.css";
const MapUsers = ({ const MapUsers = ({
projectId, projectId,

View File

@ -167,11 +167,11 @@ const ProjectOverview = ({ project }) => {
return ( return (
<div className="card" style={{ minHeight: "490px" }}> <div className="card" style={{ minHeight: "490px" }}>
<div className="card-header text-start"> <div className="card-header text-start">
<h6 className="card-action-title mb-0"> <h5 className="card-action-title mb-0">
{" "} {" "}
<i className="fa fa-line-chart rounded-circle text-primary"></i> <i className="fa fa-line-chart rounded-circle text-primary"></i>
<span className="ms-2">Project Statistics</span> <span className="ms-2 fw-bold">Project Statistics</span>
</h6> </h5>
</div> </div>
<div className="card-body"> <div className="card-body">
<ul className="list-unstyled m-0 p-0"> <ul className="list-unstyled m-0 p-0">

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback } from "react"; import React, { useState, useEffect } from "react";
import { import {
cacheData, cacheData,
clearCacheKey, clearCacheKey,
@ -26,7 +26,7 @@ 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(""); const [searchTerm, setSearchTerm] = useState("");
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const loginUser = getCachedProfileData(); const loginUser = getCachedProfileData();
@ -117,60 +117,70 @@ const AttendancePage = () => {
{ label: "Attendance", link: null }, { label: "Attendance", link: null },
]} ]}
></Breadcrumb> ></Breadcrumb>
<div className="nav-align-top nav-tabs-shadow" >
<ul className="nav nav-tabs" role="tablist"> <div className="nav-align-top nav-tabs-shadow">
<li className="nav-item"> {/* Tabs */}
<button <div className="nav-align-top nav-tabs-shadow bg-white border-bottom">
type="button" <div className="row align-items-center g-0 mb-3 mb-md-0">
{/* Tabs */}
<div className="col-12 col-md">
<ul className="nav nav-tabs" role="tablist">
<li className="nav-item">
<button
type="button"
className={`nav-link ${ className={`nav-link ${
activeTab === "all" ? "active" : "" activeTab === "all" ? "active" : ""
} fs-6`} } fs-6`}
onClick={() => handleTabChange("all")} onClick={() => handleTabChange("all")}
data-bs-toggle="tab" data-bs-toggle="tab"
data-bs-target="#navs-top-home" data-bs-target="#navs-top-home"
> >
Today's Today's
</button> </button>
</li> </li>
<li className="nav-item"> <li className="nav-item">
<button <button
type="button" type="button"
className={`nav-link ${ className={`nav-link ${
activeTab === "logs" ? "active" : "" activeTab === "logs" ? "active" : ""
} fs-6`} } fs-6`}
onClick={() => handleTabChange("logs")} onClick={() => handleTabChange("logs")}
data-bs-toggle="tab" data-bs-toggle="tab"
data-bs-target="#navs-top-profile" data-bs-target="#navs-top-profile"
> >
Logs Logs
</button> </button>
</li> </li>
<li className={`nav-item ${!DoRegularized && "d-none"}`}>
<button <li className={`nav-item ${!DoRegularized ? "d-none" : ""}`}>
type="button" <button
type="button"
className={`nav-link ${ className={`nav-link ${
activeTab === "regularization" ? "active" : "" activeTab === "regularization" ? "active" : ""
} fs-6`} } fs-6`}
onClick={() => handleTabChange("regularization")} onClick={() => handleTabChange("regularization")}
data-bs-toggle="tab" data-bs-toggle="tab"
data-bs-target="#navs-top-messages" data-bs-target="#navs-top-messages"
> >
Regularization Regularization
</button> </button>
</li> </li>
</ul>
</div>
{/* 🔹 Search box placed after Regularization tab */} {/* Single search input that moves */}
<li className="nav-item ms-auto me-3"> <div className="col-12 col-md-auto mt-2 mt-md-0 ms-md-auto px-2">
<input <input
type="text" type="text"
className="form-control form-control-sm mt-1" className="form-control form-control-sm"
placeholder="Search Employee..." placeholder="Search Employee..."
value={searchTerm} value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)} onChange={(e) => setSearchTerm(e.target.value)}
style={{ minWidth: "200px" }} style={{ minWidth: "200px" }}
/> />
</li> </div>
</ul> </div>
</div>
<div className="tab-content attedanceTabs py-0 px-1 px-sm-3"> <div className="tab-content attedanceTabs py-0 px-1 px-sm-3">
{selectedProject ? ( {selectedProject ? (

View File

@ -173,12 +173,12 @@ const DailyTask = () => {
currentSelectedBuilding={filters.selectedBuilding} currentSelectedBuilding={filters.selectedBuilding}
currentSelectedFloors={filters.selectedFloors} currentSelectedFloors={filters.selectedFloors}
currentSelectedActivities={filters.selectedActivities} currentSelectedActivities={filters.selectedActivities}
selectedProject={selectedProject} selectedProject={selectedProject}
/> />
</div> </div>
{/* --- Table --- */} {/* --- Table --- */}
<div className="table-responsive text-nowrap mt-3"> <div className="table-responsive text-nowrap mt-3" style={{ minHeight: "200px" }}>
<table className="table"> <table className="table">
<thead> <thead>
<tr> <tr>
@ -193,14 +193,16 @@ const DailyTask = () => {
<tbody> <tbody>
{taskLoading && ( {taskLoading && (
<tr> <tr>
<td colSpan={6} className="text-center"> <td colSpan={6} className="text-center align-middle" style={{ height: "200px" }}>
<Loader/> <Loader />
</td> </td>
</tr> </tr>
)} )}
{!taskLoading && groupedTasks.length === 0 && ( {!taskLoading && groupedTasks.length === 0 && (
<tr> <tr>
<td colSpan={6} className="text-center">No Reports Found</td> <td colSpan={6} className="text-center align-middle" style={{ height: "200px" }}>
No Reports Found
</td>
</tr> </tr>
)} )}
{!taskLoading && {!taskLoading &&
@ -211,7 +213,7 @@ const DailyTask = () => {
</tr> </tr>
{tasks.map((task, idx) => ( {tasks.map((task, idx) => (
<tr key={task.id || idx}> <tr key={task.id || idx}>
<td className="flex-wrap text-start"> <td className="flex-wrap text-start">
<div>{task.workItem.activityMaster?.activityName || "No Activity Name"}</div> <div>{task.workItem.activityMaster?.activityName || "No Activity Name"}</div>
<div className="text-sm"> <div className="text-sm">
{task.workItem.workArea?.floor?.building?.name} {task.workItem.workArea?.floor?.floorName} {task.workItem.workArea?.areaName} {task.workItem.workArea?.floor?.building?.name} {task.workItem.workArea?.floor?.floorName} {task.workItem.workArea?.areaName}
@ -239,6 +241,7 @@ const DailyTask = () => {
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -80,13 +80,13 @@ const ProjectDetails = () => {
return ( return (
<> <>
<div className="row"> <div className="row">
<div className="col-lg-4 col-md-5 mt-5"> <div className="col-lg-4 col-md-5 mt-2">
<AboutProject></AboutProject> <AboutProject></AboutProject>
<ProjectOverview project={projectId} /> <ProjectOverview project={projectId} />
</div> </div>
<div className="col-lg-8 col-md-7 mt-5"> <div className="col-lg-8 col-md-7 mt-2">
<ProjectProgressChart ShowAllProject="false" DefaultRange="1M" /> <ProjectProgressChart ShowAllProject="false" DefaultRange="1M" />
<div className="mt-5"> <AttendanceOverview /></div> <div className="mt-4"> <AttendanceOverview /></div>
</div> </div>
</div> </div>