Correction in weidget.

This commit is contained in:
Kartik Sharma 2025-12-13 16:36:47 +05:30
parent e10a6ff14c
commit e8886577d8
4 changed files with 86 additions and 50 deletions

View File

@ -1,4 +1,4 @@
import React from "react"; import React, { useEffect, useRef, useState } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { useJobsProgression } from "../../hooks/useDashboard_Data"; import { useJobsProgression } from "../../hooks/useDashboard_Data";
import { SpinnerLoader } from "../common/Loader"; import { SpinnerLoader } from "../common/Loader";
@ -7,55 +7,90 @@ import { useServiceProject } from "../../hooks/useServiceProject";
const ServiceJobs = () => { const ServiceJobs = () => {
const { projectId } = useParams(); const { projectId } = useParams();
const { data, isLoading, isError } = useJobsProgression(projectId); const { data, isLoading, isError } = useJobsProgression(projectId);
const jobs = data || {}; const jobs = data || {};
const { data: projectData, isLoading: projectLoading } = useServiceProject(projectId);
const { data: projectData, isLoading: projectLoading } =
useServiceProject(projectId);
const [activeTab, setActiveTab] = useState("tab-new");
// 👇 prevents re-running auto logic after first load
const hasInitializedTab = useRef(false);
const tabMapping = [ const tabMapping = [
{ id: "tab-new", label: "My Jobs", key: "myJobs" }, { id: "tab-new", label: "My Jobs", key: "myJobs" },
{ id: "tab-preparing", label: "Assigned", key: "assignedJobs" },
{ id: "tab-shipping", label: "In Progress", key: "inProgressJobs" }, { id: "tab-shipping", label: "In Progress", key: "inProgressJobs" },
{ id: "tab-preparing", label: "Assigned", key: "assignedJobs" },
]; ];
/* ---------- INITIAL TAB SELECTION ONLY ---------- */
useEffect(() => {
if (hasInitializedTab.current || !jobs) return;
if (jobs.myJobs?.length > 0) {
setActiveTab("tab-new");
} else if (jobs.inProgressJobs?.length > 0) {
setActiveTab("tab-shipping");
} else {
setActiveTab("tab-preparing");
}
hasInitializedTab.current = true;
}, [jobs]);
return ( return (
<div className=""> <div>
<div className="card page-min-h"> <div className="card page-min-h">
{/* Header */}
<div className="card-header d-flex justify-content-between"> <div className="card-header d-flex justify-content-between">
<div className="card-title mb-0 text-start"> <div className="card-title mb-0 text-start">
<h5 className="mb-1 fw-bold">Service Jobs</h5> <h5 className="mb-1 fw-bold">Service Jobs</h5>
<p className="card-subtitle"> <p className="card-subtitle">
{projectLoading ? "Loading..." : projectData?.name || "All Projects"} {projectLoading
? "Loading..."
: projectData?.name || "All Projects"}
</p> </p>
</div> </div>
</div> </div>
<div className="card-body p-0"> <div className="card-body p-0">
<div className="nav-align-top"> <div className="nav-align-top">
{/* Tabs */}
{/* ---------------- Tabs ---------------- */} <ul className="nav nav-tabs nav-fill rounded-0 timeline-indicator-advanced">
<ul className="nav nav-tabs nav-fill rounded-0 timeline-indicator-advanced" role="tablist"> {tabMapping.map((tab) => (
{tabMapping.map((t, index) => ( <li className="nav-item" key={tab.id}>
<li className="nav-item" key={t.id}>
<button <button
className={`nav-link ${index === 0 ? "active" : ""}`} type="button"
data-bs-toggle="tab" className={`nav-link ${
data-bs-target={`#${t.id}`} activeTab === tab.id ? "active" : ""
}`}
onClick={() => setActiveTab(tab.id)}
> >
{t.label} {tab.label}
</button> </button>
</li> </li>
))} ))}
</ul> </ul>
{/* ---------------- Tab Content ---------------- */} {/* Content */}
<div className="tab-content border-0 mx-1 text-start"> <div className="tab-content border-0 mx-1 text-start">
{isLoading && ( {isLoading && (
<div className="text-center" style={{ height: "250px", display: "flex", justifyContent: "center", alignItems: "center" }}> <div
className="text-center"
style={{
height: "250px",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<SpinnerLoader /> <SpinnerLoader />
</div> </div>
)} )}
{isError && ( {isError && (
<p <p
className="text-center" className="text-center"
@ -69,19 +104,19 @@ const ServiceJobs = () => {
> >
No data found No data found
</p> </p>
)} )}
{!isLoading && {!isLoading &&
!isError && !isError &&
tabMapping.map((t, index) => { tabMapping.map((tab) => {
const list = jobs[t.key] || []; const list = jobs[tab.key] || [];
return ( return (
<div <div
key={t.id} key={tab.id}
className={`tab-pane fade ${index === 0 ? "show active" : ""}`} className={`tab-pane fade ${
id={t.id} activeTab === tab.id ? "show active" : ""
}`}
> >
{list.length === 0 ? ( {list.length === 0 ? (
<p <p
@ -96,24 +131,19 @@ const ServiceJobs = () => {
> >
No jobs found No jobs found
</p> </p>
) : ( ) : (
<div className="job-scroll-wrapper"> <div className="job-scroll-wrapper">
{list.map((job, i) => ( {list.map((job, index) => (
<React.Fragment key={i}> <React.Fragment key={index}>
<ul className="timeline mb-0"> <ul className="timeline mb-0">
{/* Assigned By */}
<li className="timeline-item ps-6 border-left-dashed"> <li className="timeline-item ps-6 border-left-dashed">
<span className="timeline-indicator-advanced timeline-indicator-success border-0 shadow-none"> <span className="timeline-indicator-advanced timeline-indicator-success border-0 shadow-none">
<i className="bx bx-check-circle"></i> <i className="bx bx-check-circle"></i>
</span> </span>
<div className="timeline-event ps-1"> <div className="timeline-event ps-1">
<div className="timeline-header"> <small className="text-success text-uppercase">
<small className="text-success text-uppercase"> Assigned By
Assigned By </small>
</small>
</div>
<h6 className="my-50">{job.assignedBy}</h6> <h6 className="my-50">{job.assignedBy}</h6>
<p className="text-body mb-0"> <p className="text-body mb-0">
{formatUTCToLocalTime(job.assignedAt)} {formatUTCToLocalTime(job.assignedAt)}
@ -121,23 +151,23 @@ const ServiceJobs = () => {
</div> </div>
</li> </li>
{/* Project */}
<li className="timeline-item ps-6 border-transparent"> <li className="timeline-item ps-6 border-transparent">
<span className="timeline-indicator-advanced timeline-indicator-primary border-0 shadow-none"> <span className="timeline-indicator-advanced timeline-indicator-primary border-0 shadow-none">
<i className="bx bx-map"></i> <i className="bx bx-map"></i>
</span> </span>
<div className="timeline-event ps-1"> <div className="timeline-event ps-1">
<div className="timeline-header"> <small className="text-primary text-uppercase">
<small className="text-primary text-uppercase">Project</small> Project
</div> </small>
<h6 className="my-50">{job.project}</h6> <h6 className="my-50">{job.project}</h6>
<p className="text-body mb-0">{job.title}</p> <p className="text-body mb-0">
{job.title}
</p>
</div> </div>
</li> </li>
</ul> </ul>
{/* Divider */} {index < list.length - 1 && (
{i < list.length - 1 && (
<div className="border-1 border-light border-top border-dashed my-4"></div> <div className="border-1 border-light border-top border-dashed my-4"></div>
)} )}
</React.Fragment> </React.Fragment>

View File

@ -9,6 +9,8 @@ const ReportsDonutCard = ({
donutClass = "", donutClass = "",
footer = "Team members present on the site", footer = "Team members present on the site",
chartColor, chartColor,
legend1 = "Completed",
legend2 = "Pending"
}) => { }) => {
return ( return (
<div className="border-top card border-primary py-4 px-2"> <div className="border-top card border-primary py-4 px-2">
@ -24,7 +26,10 @@ const ReportsDonutCard = ({
completed={value} completed={value}
total={total} total={total}
/> />
<ReportsLegend /> <ReportsLegend
legend1={legend1}
legend2={legend2}
/>
</div> </div>
</div> </div>

View File

@ -1,19 +1,14 @@
const ReportsLegend = () => { const ReportsLegend = ({legend1, legend2}) => {
return ( return (
<div className=" d-inline-flex flex-column text-start gap-2 pe-5"> <div className=" d-inline-flex flex-column text-start gap-2 pe-5">
<div className=" d-flex align-items-center gap-2"> <div className=" d-flex align-items-center gap-2">
<span className="reports-legend-color reports-legend-green"></span> <span className="reports-legend-color reports-legend-green"></span>
<span>Completed</span> <span>{legend1}</span>
</div> </div>
<div className=" d-flex align-items-center gap-2"> <div className=" d-flex align-items-center gap-2">
<span className="reports-legend-color reports-legend-blue"></span> <span className="reports-legend-color reports-legend-blue"></span>
<span>In Progress</span> <span>{legend2}</span>
</div>
<div className=" d-flex align-items-center gap-2">
<span className="reports-legend-color reports-legend-gray"></span>
<span>Pending</span>
</div> </div>
</div> </div>
); );

View File

@ -24,6 +24,8 @@ const ReportDPR = ({ project, date }) => {
title={"TODAY'S ATTENDANCE"} title={"TODAY'S ATTENDANCE"}
total={data?.totalEmployees} total={data?.totalEmployees}
value={data?.todaysAttendances} value={data?.todaysAttendances}
legend1="Today's Attendance"
legend2="Total Employees"
/> />
<ReportsDonutCard <ReportsDonutCard
title={"DAILY TASKS COMPLETED"} title={"DAILY TASKS COMPLETED"}
@ -31,6 +33,8 @@ const ReportDPR = ({ project, date }) => {
value={data?.totalPlannedWork} value={data?.totalPlannedWork}
chartColor={"blue"} chartColor={"blue"}
footer="" footer=""
legend1="Completed Work"
legend2="Planned Work"
/> />
<ReportsDonutCard <ReportsDonutCard
@ -39,6 +43,8 @@ const ReportDPR = ({ project, date }) => {
value={data?.totalCompletedWork} value={data?.totalCompletedWork}
chartColor={"green"} chartColor={"green"}
footer="" footer=""
legend1="Completed Work"
legend2="Planned Work"
/> />
<div className="border-top card border-warning py-4 px-2"> <div className="border-top card border-warning py-4 px-2">