From f4b791b430685551f97900fc9ce3a5482877b255 Mon Sep 17 00:00:00 2001 From: Kartik Sharma Date: Sat, 15 Nov 2025 15:06:44 +0530 Subject: [PATCH] Added columns in jobs list and implementing functionality for daysleft. --- src/components/ServiceProject/JobList.jsx | 67 +++++++++++++-------- src/components/ServiceProject/Jobs.jsx | 19 +----- src/components/ServiceProject/ManageJob.jsx | 2 +- src/hooks/useServiceProject.jsx | 4 +- src/utils/appUtils.js | 25 ++++++++ 5 files changed, 70 insertions(+), 47 deletions(-) diff --git a/src/components/ServiceProject/JobList.jsx b/src/components/ServiceProject/JobList.jsx index a58fdd85..e6d073d2 100644 --- a/src/components/ServiceProject/JobList.jsx +++ b/src/components/ServiceProject/JobList.jsx @@ -1,5 +1,5 @@ import React, { useState } from "react"; -import { getNextBadgeColor } from "../../utils/appUtils"; +import { daysLeft, getNextBadgeColor } from "../../utils/appUtils"; import { useServiceProjectJobs } from "../../hooks/useServiceProject"; import { ITEMS_PER_PAGE } from "../../utils/constants"; import EmployeeAvatarGroup from "../common/EmployeeAvatarGroup"; @@ -37,36 +37,51 @@ const JobList = ({ filterByProject }) => { isAlwaysVisible: true, className: "text-start", }, - { - key: "project", - label: "Project", - getValue: (e) =>
{e?.project?.name}
, - isAlwaysVisible: true, - className: "text-start d-none d-sm-table-cell", - }, - - { - key: "employee", - label: "Team", - getValue: (e) => , - isAlwaysVisible: true, - className: "text-start d-none d-sm-table-cell", - }, - - { - key: "startDate", - label: "Start Date", - getValue: (e) => formatUTCToLocalTime(e.startDate), - isAlwaysVisible: true, - className: "text-center d-none d-sm-table-cell ", - }, { key: "dueDate", - label: "Due To", + label: "Due On", getValue: (e) => formatUTCToLocalTime(e.startDate), isAlwaysVisible: true, - className: "text-center d-none d-sm-table-cell", + className: "text-start d-none d-sm-table-cell", }, + { + key: "status", + label: "Status", + getValue: (e) => { + const statusName = e?.status?.displayName || "N/A"; + const statusColorMap = { + Assigned: "label-primary", + Pending: "label-warning", + Completed: "label-success", + Cancelled: "label-danger", + }; + + const badgeColor = statusColorMap[statusName] || "label-secondary"; + + return ( + + {statusName} + + ); + }, + isAlwaysVisible: true, + className: "text-start d-none d-sm-table-cell", + }, + { + key: "daysLeft", + label: "Days Left", + getValue: (e) => { + const { days, color } = daysLeft(e.startDate, e.dueDate); + + return ( + + {days !== null ? `${days} days` : "N/A"} + + ); + }, + isAlwaysVisible: true, + className: "text-start d-none d-sm-table-cell" + } ]; return ( diff --git a/src/components/ServiceProject/Jobs.jsx b/src/components/ServiceProject/Jobs.jsx index 6870c7d0..e0906f79 100644 --- a/src/components/ServiceProject/Jobs.jsx +++ b/src/components/ServiceProject/Jobs.jsx @@ -58,24 +58,7 @@ const Jobs = () => {
-
-
- {" "} - -
+
- + { return allPages.length + pageNumber; }, }); -}; +}; export const useJobTags = () => { return useQuery({ queryKey: ["Job_Tags"], @@ -215,7 +215,7 @@ export const useCreateServiceProjectJob = (onSuccessCallback) => { return await ServiceProjectRepository.CreateJob(payload); }, onSuccess: (data, variables) => { - queryClient.invalidateQueries({ queryKey: [""] }); + queryClient.invalidateQueries({ queryKey: ["serviceProjectJobs"] }); if (onSuccessCallback) onSuccessCallback(); showToast("Job Created successfully", "success"); diff --git a/src/utils/appUtils.js b/src/utils/appUtils.js index 1c681809..250d3488 100644 --- a/src/utils/appUtils.js +++ b/src/utils/appUtils.js @@ -203,3 +203,28 @@ export function getNextBadgeColor(type = "label") { colorIndex = (colorIndex + 1) % badgeColors.length; return `rounded-pill text-bg-${color}`; } + +export function daysLeft(startDate, dueDate) { + if (!startDate || !dueDate) { + return { days: null, color: "label-secondary" }; + } + + const start = new Date(startDate); + const due = new Date(dueDate); + + const today = new Date(); + const diffTime = due.getTime() - today.getTime(); + const days = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); + + let color = "label-primary"; // default + + if (days < 0) { + color = "label-danger"; // overdue → red + } else if (days <= 15) { + color = "label-warning"; // near due → yellow + } else { + color = "label-primary"; // safe range + } + + return { days, color }; +}