138 lines
3.7 KiB
TypeScript
138 lines
3.7 KiB
TypeScript
// import { getProductById } from "@/app/utils/api/productOfprojectsApi";
|
||
import { DataTableLayout, ColumnDef } from "ikoncomponents";
|
||
import React, { useEffect } from "react";
|
||
import { Project } from "../../../types/project";
|
||
import ResourceForm from "../resourceForm";
|
||
import { ProductOfProject, ResourceAllocationDto } from "@/app/utils/interface/productOfProject";
|
||
import { getProductsApi } from "@/app/utils/api/productOfProjectApi";
|
||
import { getScheduleApi } from "@/app/utils/api/projectApi";
|
||
import { getProductById } from "@/app/utils/api/productOfprojectsApi";
|
||
import { getResourceAllocations } from "@/app/utils/api/productsResourceAllocation";
|
||
|
||
|
||
interface ProductResourceTabContentProps {
|
||
productIdentifier: string;
|
||
}
|
||
|
||
interface ResourceData {
|
||
staff: string;
|
||
role: string;
|
||
grade: string;
|
||
// cost?: number | undefined;
|
||
[key: string]: string | number; // Allows dynamic month columns
|
||
}
|
||
|
||
|
||
|
||
export default function ResourcesTab({ project }: { project: ProductOfProject }) {
|
||
const [productData, setProductData] = React.useState<ProductOfProject | null>(project);
|
||
const [resourceModalOpen, setResourceModalOpen] = React.useState<boolean>(false);
|
||
|
||
useEffect(() => {
|
||
const fetchdata = async () => {
|
||
const response = await getProductsApi(project.projectIdentifier);
|
||
const scheduleResponse= await getScheduleApi(project.projectIdentifier);
|
||
response[0].scheduleData = scheduleResponse;
|
||
response[0].resourceDataWithAllocation = await getResourceAllocations(response[0].productIdentifier);
|
||
|
||
setProductData(response[0])
|
||
}
|
||
fetchdata();
|
||
|
||
}, []);
|
||
debugger
|
||
const columnsProductDetails: ColumnDef<ResourceData>[] = [
|
||
{
|
||
accessorKey: "staff",
|
||
header: () => (
|
||
<div className={"text-center"}>Staff</div>
|
||
),
|
||
},
|
||
{
|
||
accessorKey: "role",
|
||
header: () => (
|
||
<div className={"text-center"}>Role</div>
|
||
),
|
||
},
|
||
{
|
||
accessorKey: "grade",
|
||
header: () => (
|
||
<div className={"text-center"}>Grade</div>
|
||
),
|
||
},
|
||
{
|
||
accessorKey: "task",
|
||
header: "Task"
|
||
},
|
||
];
|
||
const resourceAllocation = productData?.resourceDataWithAllocation;
|
||
const months = getMonthsFromAllocation(resourceAllocation ?? []);
|
||
for(const i in months){
|
||
columnsProductDetails.push({
|
||
accessorKey: months[i] as keyof ResourceData,
|
||
header: months[i]
|
||
})
|
||
}
|
||
|
||
const tableData = convertToTableRows(resourceAllocation)
|
||
|
||
return (
|
||
<>
|
||
|
||
{!productData?.scheduleData?.task ? (
|
||
<div className="text-center mt-10">
|
||
<p>No Resource</p>
|
||
</div>
|
||
) : (
|
||
<DataTableLayout
|
||
data={tableData}
|
||
columns={columnsProductDetails}
|
||
extraTools={{
|
||
keyExtractor: (row: ResourceData) => row.staff,
|
||
totalPages: 0,
|
||
currentPage: 0,
|
||
actionNode: <ResourceForm productData={productData} />,
|
||
}}
|
||
/>
|
||
)}
|
||
|
||
|
||
</>
|
||
|
||
);
|
||
}
|
||
|
||
function convertToTableRows(data: ResourceAllocationDto[] | undefined): ResourceData[] {
|
||
if(!data){
|
||
return [];
|
||
}
|
||
return data.map(item => {
|
||
const row: ResourceData = {
|
||
staff: item.employeeName,
|
||
role: item.role,
|
||
grade: String(item.gradeId),
|
||
task: item.taskName
|
||
};
|
||
|
||
// Merge allocation months (Nov_2025, Dec_2025, etc.)
|
||
Object.entries(item.allocation ?? {}).forEach(([month, value]) => {
|
||
row[month] = (value as number) ?? 0;
|
||
});
|
||
|
||
return row;
|
||
});
|
||
}
|
||
|
||
export function getMonthsFromAllocation(data: ResourceAllocationDto[] | undefined): string[] {
|
||
if (!Array.isArray(data) || data.length === 0) return [];
|
||
|
||
const firstItem = data[0];
|
||
return firstItem?.allocation
|
||
? Object.keys(firstItem.allocation)
|
||
: [];
|
||
}
|
||
|
||
|
||
|
||
|