@@ -15,72 +15,10 @@ export interface ClientProjectResult { | |||||
projectNo: number; | projectNo: number; | ||||
} | } | ||||
// export interface ClientSubsidiaryProjectResult { | |||||
// projectId: number; | |||||
// projectCode: string; | |||||
// projectName: string; | |||||
// team: string; | |||||
// teamLead: string; | |||||
// expectedStage: string; | |||||
// budgetedManhour: number; | |||||
// spentManhour: number; | |||||
// remainedManhour: number; | |||||
// manhourConsumptionPercentage: number; | |||||
// comingPaymentMilestone: string; | |||||
// } | |||||
export const preloadClientProjects = () => { | export const preloadClientProjects = () => { | ||||
fetchAllClientProjects(); | fetchAllClientProjects(); | ||||
}; | }; | ||||
// export const fetchClientProjects = cache(async () => { | |||||
// return mockProjects; | |||||
// }); | |||||
export const fetchAllClientProjects = cache(async () => { | export const fetchAllClientProjects = cache(async () => { | ||||
return serverFetchJson<ClientProjectResult[]>(`${BASE_API_URL}/dashboard/searchCustomerSubsidiary`); | return serverFetchJson<ClientProjectResult[]>(`${BASE_API_URL}/dashboard/searchCustomerSubsidiary`); | ||||
}); | }); | ||||
// export const fetchAllClientSubsidiaryProjects = cache(async (customerId: number, subsidiaryId: number) => { | |||||
// return serverFetchJson<ClientSubsidiaryProjectResult>( | |||||
// `${BASE_API_URL}/dashboard/searchCustomerSubsidiaryProject/?${customerId}&${subsidiaryId}`, | |||||
// { | |||||
// next: { tags: [`allClientSubsidiaryProjects`] }, | |||||
// }, | |||||
// ); | |||||
// }); | |||||
// const mockProjects: ClientProjectResult[] = [ | |||||
// { | |||||
// id: 1, | |||||
// clientCode: "CUST-001", | |||||
// clientName: "Client A", | |||||
// SubsidiaryClientCode: "N/A", | |||||
// SubsidiaryClientName: "N/A", | |||||
// NoOfProjects: 5, | |||||
// }, | |||||
// { | |||||
// id: 2, | |||||
// clientCode: "CUST-001", | |||||
// clientName: "Client A", | |||||
// SubsidiaryClientCode: "SUBS-001", | |||||
// SubsidiaryClientName: "Subsidiary A", | |||||
// NoOfProjects: 5, | |||||
// }, | |||||
// { | |||||
// id: 3, | |||||
// clientCode: "CUST-001", | |||||
// clientName: "Client A", | |||||
// SubsidiaryClientCode: "SUBS-002", | |||||
// SubsidiaryClientName: "Subsidiary B", | |||||
// NoOfProjects: 3, | |||||
// }, | |||||
// { | |||||
// id: 4, | |||||
// clientCode: "CUST-001", | |||||
// clientName: "Client A", | |||||
// SubsidiaryClientCode: "SUBS-003", | |||||
// SubsidiaryClientName: "Subsidiary C", | |||||
// NoOfProjects: 1, | |||||
// }, | |||||
// ]; |
@@ -0,0 +1,54 @@ | |||||
"use server"; | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||||
import { BASE_API_URL } from "@/config/api"; | |||||
import { Dayjs } from "dayjs"; | |||||
import { cache } from "react"; | |||||
export interface FinancialSummaryByClientResult { | |||||
teamId:number; | |||||
id:number; | |||||
customerCode: string; | |||||
customerName: string; | |||||
projectNo: number; | |||||
totalFee: number; | |||||
totalBudget: number; | |||||
cumulativeExpenditure: number; | |||||
totalInvoiced: number; | |||||
totalReceived: number; | |||||
cashFlowStatus: string; | |||||
cpi: number; | |||||
totalUninvoiced: number; | |||||
} | |||||
export interface FinancialSummaryByProjectResult { | |||||
teamId:number; | |||||
id:number; | |||||
projectCode: string; | |||||
projectName: string; | |||||
customerName: string; | |||||
projectNo: number; | |||||
totalFee: number; | |||||
totalBudget: number; | |||||
cumulativeExpenditure: number; | |||||
totalInvoiced: number; | |||||
totalReceived: number; | |||||
cashFlowStatus: string; | |||||
cpi: number; | |||||
totalUninvoiced: number; | |||||
} | |||||
export const searchFinancialSummaryByClient = cache(async (teamId: number) => { | |||||
return serverFetchJson<FinancialSummaryByClientResult[]>( | |||||
`${BASE_API_URL}/dashboard/searchFinancialSummaryByClient?teamId=${teamId}` | |||||
); | |||||
}); | |||||
export const searchFinancialSummaryByProject = cache(async (teamId: number) => { | |||||
return serverFetchJson<FinancialSummaryByProjectResult[]>( | |||||
`${BASE_API_URL}/dashboard/searchFinancialSummaryByProject?teamId=${teamId}` | |||||
); | |||||
}); |
@@ -0,0 +1,27 @@ | |||||
"use server"; | |||||
import { cache } from "react"; | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||||
import { BASE_API_URL } from "@/config/api"; | |||||
// import "server-only"; | |||||
export interface FinancialSummaryCardResult { | |||||
teamId: number; | |||||
teamName: string; | |||||
projectNo: number; | |||||
totalFee: number; | |||||
totalBudget: number; | |||||
cumulativeExpenditure: number; | |||||
totalInvoiced: number; | |||||
totalReceived: number; | |||||
cashFlowStatus: string; | |||||
cpi: number; | |||||
} | |||||
export const preloadFinancialSummaryCard = () => { | |||||
fetchFinancialSummaryCard(); | |||||
}; | |||||
export const fetchFinancialSummaryCard = cache(async () => { | |||||
return serverFetchJson<FinancialSummaryCardResult[]>(`${BASE_API_URL}/dashboard/searchFinancialSummaryCard`); | |||||
}); |
@@ -0,0 +1,29 @@ | |||||
"use server"; | |||||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||||
import { BASE_API_URL } from "@/config/api"; | |||||
import { Dayjs } from "dayjs"; | |||||
import { cache } from "react"; | |||||
export interface ClientSubsidiaryProjectResult { | |||||
color: string; | |||||
projectId: number; | |||||
projectCode: string; | |||||
projectName: string; | |||||
team: string; | |||||
teamLead: string; | |||||
expectedStage: string; | |||||
budgetedManhour: number; | |||||
spentManhour: number; | |||||
remainedManhour: number; | |||||
manhourConsumptionPercentage: number; | |||||
comingPaymentMilestone: string; | |||||
} | |||||
export const fetchAllTeamProjects = cache(async (teamLeadId: number) => { | |||||
return serverFetchJson<ClientSubsidiaryProjectResult[]>( | |||||
`${BASE_API_URL}/dashboard/searchTeamProject?teamLeadId=${teamLeadId}` | |||||
); | |||||
}); |
@@ -1,10 +1,15 @@ | |||||
import { cache } from "react"; | import { cache } from "react"; | ||||
import { serverFetchJson } from "@/app/utils/fetchUtil"; | |||||
import { BASE_API_URL } from "@/config/api"; | |||||
import "server-only"; | |||||
export interface TeamProjectResult { | export interface TeamProjectResult { | ||||
id: number; | id: number; | ||||
teamId: number; | |||||
teamLeadId: number; | |||||
teamCode: string; | teamCode: string; | ||||
teamName: string; | teamName: string; | ||||
NoOfProjects: number; | |||||
projectNo: number; | |||||
} | } | ||||
export const preloadProjects = () => { | export const preloadProjects = () => { | ||||
@@ -12,32 +17,6 @@ export const preloadProjects = () => { | |||||
}; | }; | ||||
export const fetchTeamProjects = cache(async () => { | export const fetchTeamProjects = cache(async () => { | ||||
return mockProjects; | |||||
return serverFetchJson<TeamProjectResult[]>(`${BASE_API_URL}/dashboard/searchTeamProjectNo`); | |||||
}); | }); | ||||
const mockProjects: TeamProjectResult[] = [ | |||||
{ | |||||
id: 1, | |||||
teamCode: "TEAM-001", | |||||
teamName: "Team A", | |||||
NoOfProjects: 5, | |||||
}, | |||||
{ | |||||
id: 2, | |||||
teamCode: "TEAM-002", | |||||
teamName: "Team B", | |||||
NoOfProjects: 5, | |||||
}, | |||||
{ | |||||
id: 3, | |||||
teamCode: "TEAM-003", | |||||
teamName: "Team C", | |||||
NoOfProjects: 3, | |||||
}, | |||||
{ | |||||
id: 4, | |||||
teamCode: "TEAM-004", | |||||
teamName: "Team D", | |||||
NoOfProjects: 1, | |||||
}, | |||||
]; |
@@ -303,130 +303,6 @@ const ProgressByClient: React.FC<Props> = () => { | |||||
flex:0.1 | flex:0.1 | ||||
}, | }, | ||||
]; | ]; | ||||
const optionstest: ApexOptions = { | |||||
chart: { | |||||
height: 350, | |||||
type: "line", | |||||
}, | |||||
stroke: { | |||||
width: [0, 0, 2, 2], | |||||
}, | |||||
plotOptions: { | |||||
bar: { | |||||
horizontal: false, | |||||
distributed: false, | |||||
}, | |||||
}, | |||||
dataLabels: { | |||||
enabled: false, | |||||
}, | |||||
xaxis: { | |||||
categories: [ | |||||
"Q1", | |||||
"Q2", | |||||
"Q3", | |||||
"Q4", | |||||
"Q5", | |||||
"Q6", | |||||
"Q7", | |||||
"Q8", | |||||
"Q9", | |||||
"Q10", | |||||
"Q11", | |||||
"Q12", | |||||
], | |||||
}, | |||||
yaxis: [ | |||||
{ | |||||
title: { | |||||
text: "Monthly Income and Expenditure(HKD)", | |||||
}, | |||||
min: 0, | |||||
max: 350000, | |||||
tickAmount: 5, | |||||
labels: { | |||||
formatter: function (val) { | |||||
return val.toLocaleString() | |||||
} | |||||
} | |||||
}, | |||||
{ | |||||
show: false, | |||||
seriesName: "Monthly_Expenditure", | |||||
title: { | |||||
text: "Monthly Expenditure (HKD)", | |||||
}, | |||||
min: 0, | |||||
max: 350000, | |||||
tickAmount: 5, | |||||
}, | |||||
{ | |||||
seriesName: "Cumulative_Income", | |||||
opposite: true, | |||||
title: { | |||||
text: "Cumulative Income and Expenditure(HKD)", | |||||
}, | |||||
min: 0, | |||||
max: 850000, | |||||
tickAmount: 5, | |||||
labels: { | |||||
formatter: function (val) { | |||||
return val.toLocaleString() | |||||
} | |||||
} | |||||
}, | |||||
{ | |||||
show: false, | |||||
seriesName: "Cumulative_Expenditure", | |||||
opposite: true, | |||||
title: { | |||||
text: "Cumulative Expenditure (HKD)", | |||||
}, | |||||
min: 0, | |||||
max: 850000, | |||||
tickAmount: 5, | |||||
}, | |||||
], | |||||
grid: { | |||||
borderColor: "#f1f1f1", | |||||
}, | |||||
annotations: {}, | |||||
series: [ | |||||
{ | |||||
name: "Monthly_Income", | |||||
type: "column", | |||||
color: "#ffde91", | |||||
data: [0, 110000, 0, 0, 185000, 0, 0, 189000, 0, 0, 300000, 0], | |||||
}, | |||||
{ | |||||
name: "Monthly_Expenditure", | |||||
type: "column", | |||||
color: "#82b59a", | |||||
data: [ | |||||
0, 160000, 120000, 120000, 55000, 55000, 55000, 55000, 55000, 70000, | |||||
55000, 55000, | |||||
], | |||||
}, | |||||
{ | |||||
name: "Cumulative_Income", | |||||
type: "line", | |||||
color: "#EE6D7A", | |||||
data: [ | |||||
0, 100000, 100000, 100000, 300000, 300000, 300000, 500000, 500000, | |||||
500000, 800000, 800000, | |||||
], | |||||
}, | |||||
{ | |||||
name: "Cumulative_Expenditure", | |||||
type: "line", | |||||
color: "#7cd3f2", | |||||
data: [ | |||||
0, 198000, 240000, 400000, 410000, 430000, 510000, 580000, 600000, | |||||
710000, 730000, 790000, | |||||
], | |||||
}, | |||||
], | |||||
}; | |||||
const options2: ApexOptions = { | const options2: ApexOptions = { | ||||
chart: { | chart: { | ||||
@@ -18,9 +18,13 @@ import { AnyARecord, AnyCnameRecord } from "dns"; | |||||
import SearchBox, { Criterion } from "../SearchBox"; | import SearchBox, { Criterion } from "../SearchBox"; | ||||
import ProgressByTeamSearch from "@/components/ProgressByTeamSearch"; | import ProgressByTeamSearch from "@/components/ProgressByTeamSearch"; | ||||
import { Suspense } from "react"; | import { Suspense } from "react"; | ||||
import { useSearchParams } from 'next/navigation'; | |||||
import { fetchAllTeamProjects} from "@/app/api/teamprojects/actions"; | |||||
// const ReactApexChart = dynamic(() => import('react-apexcharts'), { ssr: false }); | // const ReactApexChart = dynamic(() => import('react-apexcharts'), { ssr: false }); | ||||
const ProgressByTeam: React.FC = () => { | const ProgressByTeam: React.FC = () => { | ||||
const searchParams = useSearchParams(); | |||||
const teamLeadId = searchParams.get('teamLeadId'); | |||||
const [activeTab, setActiveTab] = useState("financialSummary"); | const [activeTab, setActiveTab] = useState("financialSummary"); | ||||
const [SearchCriteria, setSearchCriteria] = React.useState({}); | const [SearchCriteria, setSearchCriteria] = React.useState({}); | ||||
const { t } = useTranslation("dashboard"); | const { t } = useTranslation("dashboard"); | ||||
@@ -44,6 +48,64 @@ const ProgressByTeam: React.FC = () => { | |||||
const [receiptFromDate, setReceiptFromDate] = useState(null); | const [receiptFromDate, setReceiptFromDate] = useState(null); | ||||
const [receiptToDate, setReceiptToDate] = useState(null); | const [receiptToDate, setReceiptToDate] = useState(null); | ||||
const [selectedRows, setSelectedRows] = useState([]); | const [selectedRows, setSelectedRows] = useState([]); | ||||
const [chartProjectName, setChartProjectName]:any[] = useState([]); | |||||
const [chartManhourConsumptionPercentage, setChartManhourConsumptionPercentage]:any[] = useState([]); | |||||
const color = ["#f57f90", "#94f7d6", "#87c5f5", "#ab95f5", "#fcd68b", | |||||
"#f58a9b", "#8ef4d1", "#92caf9", "#a798f9", "#fad287", | |||||
"#f595a6", "#88f1cc", "#9dcff5", "#a39bf5", "#f8de83", | |||||
"#f5a0b1", "#82eec7", "#a8d4f1", "#9f9ef1", "#f6ea7f", | |||||
"#f5abb4", "#7cebca", "#b3d9ed", "#9ba1ed", "#f4f67b", | |||||
"#f5b6b7", "#76e8cd", "#bed6e9", "#97a4e9", "#f2fa77", | |||||
"#f5c1ba", "#70e5d0", "#c9d3e5", "#93a7e5", "#f0fe73", | |||||
"#f5ccbd", "#6ae2d3", "#d4d0e1", "#8faae1", "#eefe6f", | |||||
"#f5d7c0", "#64dfd6", "#dfc5dd", "#8badd5", "#ecfe6b", | |||||
"#f5e2c3", "#5edcd9", "#eabada", "#87b0c9", "#eafc67", | |||||
"#f5edc6", "#58d9dc", "#f5afd6", "#83b3bd", "#e8fc63", | |||||
"#f5f8c9", "#52d6df", "#ffacd2", "#7fb6b1", "#e6fc5f", | |||||
"#f5ffcc", "#4cd3e2", "#ffa9ce", "#7bb9a5", "#e4fc5b", | |||||
"#f2ffcf", "#46d0e5", "#ffa6ca", "#77bc99", "#e2fc57", | |||||
"#efffd2", "#40cde8", "#ffa3c6", "#73bf8d", "#e0fc53", | |||||
"#ecffd5", "#3acaeb", "#ffa0c2", "#6fc281", "#defb4f", | |||||
"#e9ffd8", "#34c7ee", "#ff9dbe", "#6bc575", "#dcfb4b", | |||||
"#e6ffdb", "#2ec4f1", "#ff9aba", "#67c869", "#dafb47", | |||||
"#e3ffde", "#28c1f4", "#ff97b6", "#63cb5d", "#d8fb43", | |||||
"#e0ffe1", "#22bef7", "#ff94b2", "#5fce51", "#d6fb3f", | |||||
"#ddfee4", "#1cbbfa", "#ff91ae", "#5bd145", "#d4fb3b", | |||||
"#dafee7", "#16b8fd", "#ff8eaa", "#57d439", "#d2fb37", | |||||
"#d7feea", "#10b5ff", "#ff8ba6", "#53d72d", "#d0fb33", | |||||
"#d4feed", "#0ab2ff", "#ff88a2", "#4fda21", "#cefb2f", | |||||
"#d1fef0", "#04afff", "#ff859e", "#4bdd15", "#ccfb2b"]; | |||||
const [teamProjectResult, setTeamProjectResult]:any[] = useState([]); | |||||
const fetchData = async () => { | |||||
if (teamLeadId) { | |||||
try { | |||||
const clickResult = await fetchAllTeamProjects( | |||||
Number(teamLeadId)) | |||||
console.log(clickResult) | |||||
setTeamProjectResult(clickResult); | |||||
} catch (error) { | |||||
console.error('Error fetching team projects:', error); | |||||
} | |||||
} | |||||
} | |||||
useEffect(() => { | |||||
const projectName = [] | |||||
const manhourConsumptionPercentage = [] | |||||
for (let i = 0; i < teamProjectResult.length; i++){ | |||||
teamProjectResult[i].color = color[i] | |||||
projectName.push(teamProjectResult[i].projectName) | |||||
manhourConsumptionPercentage.push(teamProjectResult[i].manhourConsumptionPercentage) | |||||
} | |||||
setChartProjectName(projectName) | |||||
setChartManhourConsumptionPercentage(manhourConsumptionPercentage) | |||||
}, [teamProjectResult]); | |||||
useEffect(() => { | |||||
fetchData() | |||||
}, [teamLeadId]); | |||||
const rows = [ | const rows = [ | ||||
{ | { | ||||
id: 1, | id: 1, | ||||
@@ -373,7 +435,35 @@ const ProgressByTeam: React.FC = () => { | |||||
type: "bar", | type: "bar", | ||||
height: 350, | height: 350, | ||||
}, | }, | ||||
colors: ["#f57f90", "#94f7d6", "#87c5f5", "#ab95f5", "#fcd68b"], | |||||
series: [{ | |||||
name: "Project Resource Consumption Percentage", | |||||
data: chartManhourConsumptionPercentage, | |||||
},], | |||||
colors: ["#f57f90", "#94f7d6", "#87c5f5", "#ab95f5", "#fcd68b", | |||||
"#f58a9b", "#8ef4d1", "#92caf9", "#a798f9", "#fad287", | |||||
"#f595a6", "#88f1cc", "#9dcff5", "#a39bf5", "#f8de83", | |||||
"#f5a0b1", "#82eec7", "#a8d4f1", "#9f9ef1", "#f6ea7f", | |||||
"#f5abb4", "#7cebca", "#b3d9ed", "#9ba1ed", "#f4f67b", | |||||
"#f5b6b7", "#76e8cd", "#bed6e9", "#97a4e9", "#f2fa77", | |||||
"#f5c1ba", "#70e5d0", "#c9d3e5", "#93a7e5", "#f0fe73", | |||||
"#f5ccbd", "#6ae2d3", "#d4d0e1", "#8faae1", "#eefe6f", | |||||
"#f5d7c0", "#64dfd6", "#dfc5dd", "#8badd5", "#ecfe6b", | |||||
"#f5e2c3", "#5edcd9", "#eabada", "#87b0c9", "#eafc67", | |||||
"#f5edc6", "#58d9dc", "#f5afd6", "#83b3bd", "#e8fc63", | |||||
"#f5f8c9", "#52d6df", "#ffacd2", "#7fb6b1", "#e6fc5f", | |||||
"#f5ffcc", "#4cd3e2", "#ffa9ce", "#7bb9a5", "#e4fc5b", | |||||
"#f2ffcf", "#46d0e5", "#ffa6ca", "#77bc99", "#e2fc57", | |||||
"#efffd2", "#40cde8", "#ffa3c6", "#73bf8d", "#e0fc53", | |||||
"#ecffd5", "#3acaeb", "#ffa0c2", "#6fc281", "#defb4f", | |||||
"#e9ffd8", "#34c7ee", "#ff9dbe", "#6bc575", "#dcfb4b", | |||||
"#e6ffdb", "#2ec4f1", "#ff9aba", "#67c869", "#dafb47", | |||||
"#e3ffde", "#28c1f4", "#ff97b6", "#63cb5d", "#d8fb43", | |||||
"#e0ffe1", "#22bef7", "#ff94b2", "#5fce51", "#d6fb3f", | |||||
"#ddfee4", "#1cbbfa", "#ff91ae", "#5bd145", "#d4fb3b", | |||||
"#dafee7", "#16b8fd", "#ff8eaa", "#57d439", "#d2fb37", | |||||
"#d7feea", "#10b5ff", "#ff8ba6", "#53d72d", "#d0fb33", | |||||
"#d4feed", "#0ab2ff", "#ff88a2", "#4fda21", "#cefb2f", | |||||
"#d1fef0", "#04afff", "#ff859e", "#4bdd15", "#ccfb2b"], | |||||
plotOptions: { | plotOptions: { | ||||
bar: { | bar: { | ||||
horizontal: true, | horizontal: true, | ||||
@@ -384,13 +474,7 @@ const ProgressByTeam: React.FC = () => { | |||||
enabled: false, | enabled: false, | ||||
}, | }, | ||||
xaxis: { | xaxis: { | ||||
categories: [ | |||||
"Consultancy Project 123", | |||||
"Consultancy Project 456", | |||||
"Construction Project A", | |||||
"Construction Project B", | |||||
"Construction Project C", | |||||
], | |||||
categories: chartProjectName, | |||||
}, | }, | ||||
yaxis: { | yaxis: { | ||||
title: { | title: { | ||||
@@ -414,7 +498,7 @@ const ProgressByTeam: React.FC = () => { | |||||
}; | }; | ||||
const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { | const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { | ||||
const selectedRowsData = rows2.filter((row) => | |||||
const selectedRowsData = teamProjectResult.filter((row:any) => | |||||
newSelectionModel.includes(row.id), | newSelectionModel.includes(row.id), | ||||
); | ); | ||||
console.log(selectedRowsData); | console.log(selectedRowsData); | ||||
@@ -427,7 +511,7 @@ const ProgressByTeam: React.FC = () => { | |||||
if (i === selectedRowsData.length && i > 0) { | if (i === selectedRowsData.length && i > 0) { | ||||
projectArray.push("Remained"); | projectArray.push("Remained"); | ||||
} else if (selectedRowsData.length > 0) { | } else if (selectedRowsData.length > 0) { | ||||
projectArray.push(selectedRowsData[i].project); | |||||
projectArray.push(selectedRowsData[i].projectName); | |||||
totalBudgetManhour += Number(selectedRowsData[i].budgetedManhour); | totalBudgetManhour += Number(selectedRowsData[i].budgetedManhour); | ||||
totalSpent += Number(selectedRowsData[i].spentManhour); | totalSpent += Number(selectedRowsData[i].spentManhour); | ||||
pieChartColorArray.push(selectedRowsData[i].color); | pieChartColorArray.push(selectedRowsData[i].color); | ||||
@@ -485,7 +569,7 @@ const ProgressByTeam: React.FC = () => { | |||||
<div style={{ display: "inline-block", width: "99%" }}> | <div style={{ display: "inline-block", width: "99%" }}> | ||||
<ReactApexChart | <ReactApexChart | ||||
options={options} | options={options} | ||||
series={series} | |||||
series={options.series} | |||||
type="bar" | type="bar" | ||||
height={350} | height={350} | ||||
/> | /> | ||||
@@ -507,7 +591,7 @@ const ProgressByTeam: React.FC = () => { | |||||
style={{ display: "inline-block", width: "99%", marginLeft: 10 }} | style={{ display: "inline-block", width: "99%", marginLeft: 10 }} | ||||
> | > | ||||
<CustomDatagrid | <CustomDatagrid | ||||
rows={rows2} | |||||
rows={teamProjectResult} | |||||
columns={columns2} | columns={columns2} | ||||
columnWidth={200} | columnWidth={200} | ||||
dataGridHeight={300} | dataGridHeight={300} | ||||
@@ -1,11 +1,13 @@ | |||||
"use client"; | "use client"; | ||||
import { ProjectResult } from "@/app/api/projects"; | import { ProjectResult } from "@/app/api/projects"; | ||||
import React, { useMemo, useState } from "react"; | |||||
import React, { useMemo, useState, useCallback } from "react"; | |||||
import SearchBox, { Criterion } from "../SearchBox"; | import SearchBox, { Criterion } from "../SearchBox"; | ||||
import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
import SearchResults, { Column } from "../SearchResults"; | import SearchResults, { Column } from "../SearchResults"; | ||||
import { TeamProjectResult } from "@/app/api/teamprojects"; | import { TeamProjectResult } from "@/app/api/teamprojects"; | ||||
import VisibilityIcon from '@mui/icons-material/Visibility'; | |||||
import { useRouter, useSearchParams } from "next/navigation"; | |||||
interface Props { | interface Props { | ||||
projects: TeamProjectResult[]; | projects: TeamProjectResult[]; | ||||
@@ -15,7 +17,7 @@ type SearchParamNames = keyof SearchQuery; | |||||
const ProgressByClientSearch: React.FC<Props> = ({ projects }) => { | const ProgressByClientSearch: React.FC<Props> = ({ projects }) => { | ||||
const { t } = useTranslation("projects"); | const { t } = useTranslation("projects"); | ||||
const router = useRouter(); | |||||
// If project searching is done on the server-side, then no need for this. | // If project searching is done on the server-side, then no need for this. | ||||
const [filteredProjects, setFilteredProjects] = useState(projects); | const [filteredProjects, setFilteredProjects] = useState(projects); | ||||
@@ -27,13 +29,31 @@ const ProgressByClientSearch: React.FC<Props> = ({ projects }) => { | |||||
[t], | [t], | ||||
); | ); | ||||
const onTaskClick = useCallback(async (teamProjectResult: TeamProjectResult) => { | |||||
try { | |||||
console.log(teamProjectResult) | |||||
router.push( | |||||
`/dashboard/ProjectStatusByTeam?teamLeadId=${teamProjectResult.teamLeadId}` | |||||
); | |||||
} catch (error) { | |||||
console.error('Error fetching team projects:', error); | |||||
} | |||||
}, []); | |||||
const columns = useMemo<Column<TeamProjectResult>[]>( | const columns = useMemo<Column<TeamProjectResult>[]>( | ||||
() => [ | () => [ | ||||
{ | |||||
name: "id", | |||||
label: t("Details"), | |||||
onClick: onTaskClick, | |||||
buttonIcon: <VisibilityIcon />, | |||||
}, | |||||
{ name: "teamCode", label: t("Team Code") }, | { name: "teamCode", label: t("Team Code") }, | ||||
{ name: "teamName", label: t("Team Name") }, | { name: "teamName", label: t("Team Name") }, | ||||
{ name: "NoOfProjects", label: t("No. of Projects") }, | |||||
{ name: "projectNo", label: t("No. of Projects") }, | |||||
], | ], | ||||
[t], | |||||
[onTaskClick, t], | |||||
); | ); | ||||
return ( | return ( | ||||
@@ -41,7 +61,13 @@ const ProgressByClientSearch: React.FC<Props> = ({ projects }) => { | |||||
<SearchBox | <SearchBox | ||||
criteria={searchCriteria} | criteria={searchCriteria} | ||||
onSearch={(query) => { | onSearch={(query) => { | ||||
console.log(query); | |||||
setFilteredProjects( | |||||
projects.filter( | |||||
(cp) => | |||||
cp.teamCode.toLowerCase().includes(query.teamCode.toLowerCase()) && | |||||
cp.teamName.toLowerCase().includes(query.teamName.toLowerCase()) | |||||
), | |||||
); | |||||
}} | }} | ||||
/> | /> | ||||
<SearchResults<TeamProjectResult> | <SearchResults<TeamProjectResult> | ||||
@@ -20,14 +20,14 @@ import { Suspense } from "react"; | |||||
interface Props { | interface Props { | ||||
Title: string; | Title: string; | ||||
TotalActiveProjectNumber: string; | |||||
TotalFees: string; | |||||
TotalBudget: string; | |||||
TotalCumulative: string; | |||||
TotalInvoicedAmount: string; | |||||
TotalReceivedAmount: string; | |||||
TotalActiveProjectNumber: number; | |||||
TotalFees: number; | |||||
TotalBudget: number; | |||||
TotalCumulative: number; | |||||
TotalInvoicedAmount: number; | |||||
TotalReceivedAmount: number; | |||||
CashFlowStatus: string; | CashFlowStatus: string; | ||||
CostPerformanceIndex: string; | |||||
CostPerformanceIndex: number; | |||||
ClickedIndex: number; | ClickedIndex: number; | ||||
Index: number; | Index: number; | ||||
} | } | ||||
@@ -77,42 +77,42 @@ const ProjectFinancialCard: React.FC<Props> = ({ | |||||
Total Active Project | Total Active Project | ||||
</div> | </div> | ||||
<div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | <div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | ||||
{TotalActiveProjectNumber} | |||||
{TotalActiveProjectNumber.toLocaleString()} | |||||
</div> | </div> | ||||
<hr /> | <hr /> | ||||
<div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | ||||
Total Fees | Total Fees | ||||
</div> | </div> | ||||
<div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | <div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | ||||
{TotalFees} | |||||
{TotalFees.toLocaleString()} | |||||
</div> | </div> | ||||
<hr /> | <hr /> | ||||
<div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | ||||
Total Budget | Total Budget | ||||
</div> | </div> | ||||
<div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | <div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | ||||
{TotalBudget} | |||||
{TotalBudget.toLocaleString()} | |||||
</div> | </div> | ||||
<hr /> | <hr /> | ||||
<div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | ||||
Total Cumulative Expenditure | Total Cumulative Expenditure | ||||
</div> | </div> | ||||
<div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | <div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | ||||
{TotalCumulative} | |||||
{TotalCumulative.toLocaleString()} | |||||
</div> | </div> | ||||
<hr /> | <hr /> | ||||
<div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | ||||
Total Invoiced Amount | Total Invoiced Amount | ||||
</div> | </div> | ||||
<div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | <div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | ||||
{TotalInvoicedAmount} | |||||
{TotalInvoicedAmount.toLocaleString()} | |||||
</div> | </div> | ||||
<hr /> | <hr /> | ||||
<div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | ||||
Total Received Amount | Total Received Amount | ||||
</div> | </div> | ||||
<div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | <div className="text-lg font-medium ml-5" style={{ color: "#6b87cf" }}> | ||||
{TotalReceivedAmount} | |||||
{TotalReceivedAmount.toLocaleString()} | |||||
</div> | </div> | ||||
<hr /> | <hr /> | ||||
<div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | <div className="text-sm font-medium ml-5" style={{ color: "#898d8d" }}> | ||||
@@ -18,86 +18,32 @@ import { AnyARecord, AnyCnameRecord } from "dns"; | |||||
import SearchBox, { Criterion } from "../SearchBox"; | import SearchBox, { Criterion } from "../SearchBox"; | ||||
import ProgressByClientSearch from "@/components/ProgressByClientSearch"; | import ProgressByClientSearch from "@/components/ProgressByClientSearch"; | ||||
import { Suspense } from "react"; | import { Suspense } from "react"; | ||||
import { fetchFinancialSummaryCard } from "@/app/api/financialsummary"; | |||||
import { searchFinancialSummaryByClient,searchFinancialSummaryByProject } from "@/app/api/financialsummary/actions"; | |||||
import ProjectFinancialCard from "./ProjectFinancialCard"; | import ProjectFinancialCard from "./ProjectFinancialCard"; | ||||
const ProjectFinancialSummary: React.FC = () => { | const ProjectFinancialSummary: React.FC = () => { | ||||
const [SearchCriteria, setSearchCriteria] = React.useState({}); | const [SearchCriteria, setSearchCriteria] = React.useState({}); | ||||
const { t } = useTranslation("dashboard"); | const { t } = useTranslation("dashboard"); | ||||
const [selectionModel, setSelectionModel]: any[] = React.useState([]); | const [selectionModel, setSelectionModel]: any[] = React.useState([]); | ||||
const projectFinancialData = [ | |||||
{ | |||||
id: 1, | |||||
title: "All Teams", | |||||
activeProject: "147", | |||||
fees: "22,800,000.00", | |||||
budget: "18,240,000.00", | |||||
cumulativeExpenditure: "17,950,000.00", | |||||
invoicedAmount: "18,240,000.00", | |||||
receivedAmount: "10,900,000.00", | |||||
cashFlowStatus: "Negative", | |||||
CPI: "0.69", | |||||
}, | |||||
{ | |||||
id: 2, | |||||
title: "XXX Team", | |||||
activeProject: "25", | |||||
fees: "1,500,000.00", | |||||
budget: "1,200,000.00", | |||||
cumulativeExpenditure: "1,250,000.00", | |||||
invoicedAmount: "900,000.00", | |||||
receivedAmount: "650,000.00", | |||||
cashFlowStatus: "Negative", | |||||
CPI: "0.72", | |||||
}, | |||||
{ | |||||
id: 3, | |||||
title: "YYY Team", | |||||
activeProject: "35", | |||||
fees: "5,000,000.00", | |||||
budget: "4,000,000.00", | |||||
cumulativeExpenditure: "3,200,000.00", | |||||
invoicedAmount: "3,500,000.00", | |||||
receivedAmount: "3,500,000.00", | |||||
cashFlowStatus: "Positive", | |||||
CPI: "1.09", | |||||
}, | |||||
{ | |||||
id: 4, | |||||
title: "ZZZ Team", | |||||
activeProject: "50", | |||||
fees: "3,500,000.00", | |||||
budget: "2,800,000.00", | |||||
cumulativeExpenditure: "5,600,000.00", | |||||
invoicedAmount: "2,500,000.00", | |||||
receivedAmount: "2,200,000.00", | |||||
cashFlowStatus: "Negative", | |||||
CPI: "0.45", | |||||
}, | |||||
{ | |||||
id: 5, | |||||
title: "AAA Team", | |||||
activeProject: "15", | |||||
fees: "4,800,000.00", | |||||
budget: "3,840,000.00", | |||||
cumulativeExpenditure: "2,500,000.00", | |||||
invoicedAmount: "1,500,000.00", | |||||
receivedAmount: "750,000.00", | |||||
cashFlowStatus: "Negative", | |||||
CPI: "0.60", | |||||
}, | |||||
{ | |||||
id: 6, | |||||
title: "BBB Team", | |||||
activeProject: "22", | |||||
fees: "8,000,000.00", | |||||
budget: "6,400,000.00", | |||||
cumulativeExpenditure: "5,400,000.00", | |||||
invoicedAmount: "4,000,000.00", | |||||
receivedAmount: "3,800,000.00", | |||||
cashFlowStatus: "Negative", | |||||
CPI: "0.74", | |||||
}, | |||||
]; | |||||
const [projectFinancialData, setProjectFinancialData]: any[] = React.useState([]); | |||||
const [clientFinancialRows, setClientFinancialRows]: any[] = React.useState([]); | |||||
const [projectFinancialRows, setProjectFinancialRows]: any[] = React.useState([]); | |||||
const fetchData = async () => { | |||||
const financialSummaryCard = await fetchFinancialSummaryCard(); | |||||
setProjectFinancialData(financialSummaryCard) | |||||
} | |||||
const fetchTableData = async (teamId:any) => { | |||||
const financialSummaryByClient = await searchFinancialSummaryByClient(teamId); | |||||
const financialSummaryByProject = await searchFinancialSummaryByProject(teamId); | |||||
console.log(financialSummaryByClient) | |||||
console.log(financialSummaryByProject) | |||||
setClientFinancialRows(financialSummaryByClient) | |||||
setProjectFinancialRows(financialSummaryByProject) | |||||
} | |||||
useEffect(() => { | |||||
fetchData() | |||||
}, []); | |||||
const rows0 = [{id: 1,projectCode:"M1201",projectName:"Consultancy Project C", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "01/05/2024", client:"Client A", subsidiary:"N/A"}, | const rows0 = [{id: 1,projectCode:"M1201",projectName:"Consultancy Project C", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "01/05/2024", client:"Client A", subsidiary:"N/A"}, | ||||
{id: 2,projectCode:"M1321",projectName:"Consultancy Project CCC", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "20/01/2024", client:"Client E", subsidiary:"Subsidiary B"}, | {id: 2,projectCode:"M1321",projectName:"Consultancy Project CCC", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "20/01/2024", client:"Client E", subsidiary:"Subsidiary B"}, | ||||
@@ -115,45 +61,46 @@ const ProjectFinancialSummary: React.FC = () => { | |||||
{id: 5,projectCode:"M1354",projectName:"Consultancy Project BBB", team:"YYY", teamLeader:"YYY", startDate:"01/02/2023", targetEndDate: "31/01/2024", client:"Client D", subsidiary:"Subsidiary C"} | {id: 5,projectCode:"M1354",projectName:"Consultancy Project BBB", team:"YYY", teamLeader:"YYY", startDate:"01/02/2023", targetEndDate: "31/01/2024", client:"Client D", subsidiary:"Subsidiary C"} | ||||
] | ] | ||||
const projectFinancialRows = [{id: 1,projectCode:"M1354",projectName:"Consultanct Project BBB",clientName:"Client D",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"} | |||||
] | |||||
// const projectFinancialRows = [{id: 1,projectCode:"M1354",projectName:"Consultanct Project BBB",clientName:"Client D",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"} | |||||
// ] | |||||
const clientFinancialRows =[{id: 1,clientCode:"Cust-02",clientName:"Client B",totalProjectInvolved:"1",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"}, | |||||
{id: 2,clientCode:"Cust-03",clientName:"Client C",totalProjectInvolved:"1",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"}, | |||||
{id: 3,clientCode:"Cust-04",clientName:"Client D",totalProjectInvolved:"4",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"} | |||||
] | |||||
// const clientFinancialRows =[{id: 1,clientCode:"Cust-02",clientName:"Client B",totalProjectInvolved:"1",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"}, | |||||
// {id: 2,clientCode:"Cust-03",clientName:"Client C",totalProjectInvolved:"1",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"}, | |||||
// {id: 3,clientCode:"Cust-04",clientName:"Client D",totalProjectInvolved:"4",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"} | |||||
// ] | |||||
const [isCardClickedIndex, setIsCardClickedIndex] = React.useState(0); | const [isCardClickedIndex, setIsCardClickedIndex] = React.useState(0); | ||||
const [selectedTeamData, setSelectedTeamData]: any[] = React.useState(rows0); | const [selectedTeamData, setSelectedTeamData]: any[] = React.useState(rows0); | ||||
const handleCardClick = (r: any) => { | const handleCardClick = (r: any) => { | ||||
setIsCardClickedIndex(r); | |||||
if (r === 0) { | |||||
setSelectedTeamData(rows0); | |||||
} else if (r === 1) { | |||||
setSelectedTeamData(rows1); | |||||
} else if (r === 2) { | |||||
setSelectedTeamData(rows2); | |||||
} | |||||
fetchTableData(r.teamId) | |||||
// setIsCardClickedIndex(r); | |||||
// if (r === 0) { | |||||
// setSelectedTeamData(rows0); | |||||
// } else if (r === 1) { | |||||
// setSelectedTeamData(rows1); | |||||
// } else if (r === 2) { | |||||
// setSelectedTeamData(rows2); | |||||
// } | |||||
}; | }; | ||||
const columns = [ | const columns = [ | ||||
{ | { | ||||
id: 'clientCode', | |||||
field: 'clientCode', | |||||
id: 'customerCode', | |||||
field: 'customerCode', | |||||
headerName: "Client Code", | headerName: "Client Code", | ||||
flex: 0.7, | flex: 0.7, | ||||
}, | }, | ||||
{ | { | ||||
id: 'clientName', | |||||
field: 'clientName', | |||||
id: 'customerName', | |||||
field: 'customerName', | |||||
headerName: "Client Name", | headerName: "Client Name", | ||||
flex: 1, | flex: 1, | ||||
}, | }, | ||||
{ | { | ||||
id: 'totalProjectInvolved', | |||||
field: 'totalProjectInvolved', | |||||
id: 'projectNo', | |||||
field: 'projectNo', | |||||
headerName: "Total Project Involved", | headerName: "Total Project Involved", | ||||
flex: 1, | flex: 1, | ||||
}, | }, | ||||
@@ -163,6 +110,7 @@ const ProjectFinancialSummary: React.FC = () => { | |||||
headerName: "Cash Flow Status", | headerName: "Cash Flow Status", | ||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
console.log(params.row) | |||||
if (params.row.cashFlowStatus === "Positive") { | if (params.row.cashFlowStatus === "Positive") { | ||||
return ( | return ( | ||||
<span className="text-lime-500">{params.row.cashFlowStatus}</span> | <span className="text-lime-500">{params.row.cashFlowStatus}</span> | ||||
@@ -192,13 +140,13 @@ const ProjectFinancialSummary: React.FC = () => { | |||||
}, | }, | ||||
}, | }, | ||||
{ | { | ||||
id: 'totalFees', | |||||
field: 'totalFees', | |||||
id: 'totalFee', | |||||
field: 'totalFee', | |||||
headerName: "Total Fees (HKD)", | headerName: "Total Fees (HKD)", | ||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
return ( | return ( | ||||
<span>${params.row.totalFees}</span> | |||||
<span>${params.row.totalFee}</span> | |||||
) | ) | ||||
}, | }, | ||||
}, | }, | ||||
@@ -214,46 +162,46 @@ const ProjectFinancialSummary: React.FC = () => { | |||||
}, | }, | ||||
}, | }, | ||||
{ | { | ||||
id: 'totalCumulativeExpenditure', | |||||
field: 'totalCumulativeExpenditure', | |||||
id: 'cumulativeExpenditure', | |||||
field: 'cumulativeExpenditure', | |||||
headerName: "Total Cumulative Expenditure (HKD)", | headerName: "Total Cumulative Expenditure (HKD)", | ||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
return ( | return ( | ||||
<span>${params.row.totalCumulativeExpenditure}</span> | |||||
<span>${params.row.cumulativeExpenditure}</span> | |||||
) | ) | ||||
}, | }, | ||||
}, | }, | ||||
{ | { | ||||
id: 'totalInvoicedAmount', | |||||
field: 'totalInvoicedAmount', | |||||
id: 'totalInvoiced', | |||||
field: 'totalInvoiced', | |||||
headerName: "Total Invoiced Amount (HKD)", | headerName: "Total Invoiced Amount (HKD)", | ||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
return ( | return ( | ||||
<span>${params.row.totalInvoicedAmount}</span> | |||||
<span>${params.row.totalInvoiced}</span> | |||||
) | ) | ||||
}, | }, | ||||
}, | }, | ||||
{ | { | ||||
id: 'totalUnInvoicedAmount', | |||||
field: 'totalUnInvoicedAmount', | |||||
id: 'totalUnInvoiced', | |||||
field: 'totalUnInvoiced', | |||||
headerName: "Total Un-invoiced Amount (HKD)", | headerName: "Total Un-invoiced Amount (HKD)", | ||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
return ( | return ( | ||||
<span>${params.row.totalUnInvoicedAmount}</span> | |||||
<span>${params.row.totalUninvoiced}</span> | |||||
) | ) | ||||
}, | }, | ||||
}, | }, | ||||
{ | { | ||||
id: 'totalReceivedAmount', | |||||
field: 'totalReceivedAmount', | |||||
id: 'totalReceived', | |||||
field: 'totalReceived', | |||||
headerName: "Total Received Amount (HKD)", | headerName: "Total Received Amount (HKD)", | ||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
return ( | return ( | ||||
<span>${params.row.totalReceivedAmount}</span> | |||||
<span>${params.row.totalReceived}</span> | |||||
) | ) | ||||
}, | }, | ||||
}, | }, | ||||
@@ -322,8 +270,8 @@ const columns2 = [ | |||||
flex: 1, | flex: 1, | ||||
}, | }, | ||||
{ | { | ||||
id: 'clientName', | |||||
field: 'clientName', | |||||
id: 'customerName', | |||||
field: 'customerName', | |||||
headerName: "Client Name", | headerName: "Client Name", | ||||
flex: 1, | flex: 1, | ||||
}, | }, | ||||
@@ -365,7 +313,7 @@ const columns2 = [ | |||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
return ( | return ( | ||||
<span>${params.row.totalFees}</span> | |||||
<span>${params.row.totalFee}</span> | |||||
) | ) | ||||
}, | }, | ||||
}, | }, | ||||
@@ -387,7 +335,7 @@ const columns2 = [ | |||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
return ( | return ( | ||||
<span>${params.row.totalCumulativeExpenditure}</span> | |||||
<span>${params.row.cumulativeExpenditure}</span> | |||||
) | ) | ||||
}, | }, | ||||
}, | }, | ||||
@@ -398,7 +346,7 @@ const columns2 = [ | |||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
return ( | return ( | ||||
<span>${params.row.totalInvoicedAmount}</span> | |||||
<span>${params.row.totalInvoiced}</span> | |||||
) | ) | ||||
}, | }, | ||||
}, | }, | ||||
@@ -409,7 +357,7 @@ const columns2 = [ | |||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
return ( | return ( | ||||
<span>${params.row.totalUnInvoicedAmount}</span> | |||||
<span>${params.row.totalUninvoiced}</span> | |||||
) | ) | ||||
}, | }, | ||||
}, | }, | ||||
@@ -420,7 +368,7 @@ const columns2 = [ | |||||
flex: 1, | flex: 1, | ||||
renderCell: (params:any) => { | renderCell: (params:any) => { | ||||
return ( | return ( | ||||
<span>${params.row.totalReceivedAmount}</span> | |||||
<span>${params.row.totalReceived}</span> | |||||
) | ) | ||||
}, | }, | ||||
}, | }, | ||||
@@ -438,9 +386,9 @@ const columns2 = [ | |||||
<Card> | <Card> | ||||
<CardHeader className="text-slate-500" title="Active Project Financial Status"/> | <CardHeader className="text-slate-500" title="Active Project Financial Status"/> | ||||
<div className="ml-10 mr-10" style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'start'}}> | <div className="ml-10 mr-10" style={{ display: 'flex', flexWrap: 'wrap', justifyContent: 'start'}}> | ||||
{projectFinancialData.map((record, index) => ( | |||||
<div className="hover:cursor-pointer ml-4 mt-5 mb-4 inline-block" key={index} onClick={(r) => handleCardClick(index)}> | |||||
<ProjectFinancialCard Title={record.title} TotalActiveProjectNumber={record.activeProject} TotalFees={record.fees} TotalBudget={record.budget} TotalCumulative={record.cumulativeExpenditure} TotalInvoicedAmount={record.invoicedAmount} TotalReceivedAmount={record.receivedAmount} CashFlowStatus={record.cashFlowStatus} CostPerformanceIndex={record.CPI} ClickedIndex={isCardClickedIndex} Index={index}/> | |||||
{projectFinancialData.map((record:any, index:any) => ( | |||||
<div className="hover:cursor-pointer ml-4 mt-5 mb-4 inline-block" key={index} onClick={(r) => handleCardClick(record)}> | |||||
<ProjectFinancialCard Title={record.teamName} TotalActiveProjectNumber={record.projectNo} TotalFees={record.totalFee} TotalBudget={record.totalBudget} TotalCumulative={record.cumulativeExpenditure} TotalInvoicedAmount={record.totalInvoiced} TotalReceivedAmount={record.totalReceived} CashFlowStatus={record.cashFlowStatus} CostPerformanceIndex={record.cpi} ClickedIndex={isCardClickedIndex} Index={index}/> | |||||
</div> | </div> | ||||
))} | ))} | ||||
</div> | </div> | ||||