Added columns in jobs list and implementing functionality for daysleft.
This commit is contained in:
parent
08f06b9da2
commit
f4b791b430
@ -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) => <div className="text-start ">{e?.project?.name}</div>,
|
||||
isAlwaysVisible: true,
|
||||
className: "text-start d-none d-sm-table-cell",
|
||||
},
|
||||
|
||||
{
|
||||
key: "employee",
|
||||
label: "Team",
|
||||
getValue: (e) => <EmployeeAvatarGroup employees={e.assignees} />,
|
||||
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 (
|
||||
<span className={`badge bg-${badgeColor}`} style={{ fontSize: "12px" }}>
|
||||
{statusName}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
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 (
|
||||
<span className={`badge bg-${color}`} style={{ fontSize: "12px" }}>
|
||||
{days !== null ? `${days} days` : "N/A"}
|
||||
</span>
|
||||
);
|
||||
},
|
||||
isAlwaysVisible: true,
|
||||
className: "text-start d-none d-sm-table-cell"
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
@ -58,24 +58,7 @@ const Jobs = () => {
|
||||
</OffcanvasComponent>
|
||||
<div className="card page-min-h my-2 px-4">
|
||||
<div className="row">
|
||||
<div className="col-12 py-2 d-flex justify-content-between ">
|
||||
<div>
|
||||
{" "}
|
||||
<select
|
||||
className="form-select form-select-sm"
|
||||
value={selectedProject}
|
||||
onChange={(e) => setSelectedProject(e.target.value)}
|
||||
>
|
||||
<option disabled selected>
|
||||
Select Poject
|
||||
</option>
|
||||
{data?.data?.map((project) => (
|
||||
<option key={project.id} value={project.id}>
|
||||
{project.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="col-12 py-2 d-flex justify-content-end ">
|
||||
<div className="px-2">
|
||||
<button
|
||||
className="btn btn-sm btn-primary"
|
||||
|
||||
@ -134,7 +134,7 @@ const ManageJob = ({ Job }) => {
|
||||
/>
|
||||
</div>
|
||||
<div className="col-12 col-md-6 mb-2 mb-md-4">
|
||||
<Label required>End Date</Label>
|
||||
<Label required>Select Employee</Label>
|
||||
<PmsEmployeeInputTag
|
||||
control={control}
|
||||
name="assignees"
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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 };
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user