Correction in weidget.
This commit is contained in:
parent
e10a6ff14c
commit
e8886577d8
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -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">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user