Sfoglia il codice sorgente

Merge commit '959a7684850e853fcf680a76aac5cbae56b58fc3' into David_Branch

tags/Baseline_30082024_FRONTEND_UAT
MSI\User 1 anno fa
parent
commit
0cc7246d60
8 ha cambiato i file con 189 aggiunte e 110 eliminazioni
  1. +15
    -2
      src/app/api/invoices/actions.ts
  2. +19
    -3
      src/components/InvoiceSearch/InvoiceSearch.tsx
  3. +25
    -14
      src/components/ProgressByClient/ProgressByClient.tsx
  4. +26
    -18
      src/components/ProgressByTeam/ProgressByTeam.tsx
  5. +17
    -14
      src/components/ProjectCashFlow/ProjectCashFlow.tsx
  6. +12
    -0
      src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx
  7. +26
    -15
      src/components/ProjectResourceConsumptionRanking/ProjectResourceConsumptionRanking.tsx
  8. +49
    -44
      src/components/ProjectResourceSummary/ProjectResourceSummary.tsx

+ 15
- 2
src/app/api/invoices/actions.ts Vedi File

@@ -1,6 +1,6 @@
"use server"

import { serverFetchJson, serverFetchString } from "@/app/utils/fetchUtil";
import { serverFetchJson, serverFetchString, serverFetchWithNoContent } from "@/app/utils/fetchUtil";
import { BASE_API_URL } from "@/config/api";
import { revalidateTag } from "next/cache";
import { cache } from "react";
@@ -117,4 +117,17 @@ export const updateInvoice = async (data: any) => {
revalidateTag("invoices")
return updateInvoice;
}
}

export const deleteInvoice = async (id: number) => {
const invoice = await serverFetchWithNoContent(
`${BASE_API_URL}/invoices/${id}`,
{
method: "DELETE",
headers: { "Content-Type": "application/json" },
},
);

revalidateTag("invoices");
return invoice;
};

+ 19
- 3
src/components/InvoiceSearch/InvoiceSearch.tsx Vedi File

@@ -8,8 +8,8 @@ import EditNote from "@mui/icons-material/EditNote";
import { moneyFormatter } from "@/app/utils/formatUtil"
import { Button, ButtonGroup, Stack, Tab, Tabs, TabsProps, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, TextField, CardContent, Typography, Divider, Card } from "@mui/material";
import FileUploadIcon from '@mui/icons-material/FileUpload';
import { importIssuedInovice, importReceivedInovice, updateInvoice } from "@/app/api/invoices/actions";
import { errorDialogWithContent, successDialog } from "../Swal/CustomAlerts";
import { deleteInvoice, importIssuedInovice, importReceivedInovice, updateInvoice } from "@/app/api/invoices/actions";
import { deleteDialog, errorDialogWithContent, successDialog } from "../Swal/CustomAlerts";
import { invoiceList, issuedInvoiceList, issuedInvoiceSearchForm, receivedInvoiceList, receivedInvoiceSearchForm } from "@/app/api/invoices";
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
import { GridCellParams, GridColDef, GridEventListener, GridRowId, GridRowModes, GridRowModesModel } from "@mui/x-data-grid";
@@ -43,7 +43,7 @@ type SearchQuery2 = Partial<Omit<receivedInvoiceSearchForm, "id">>;
type SearchParamNames2 = keyof SearchQuery2;

const InvoiceSearch: React.FC<Props> = ({ issuedInvoice, receivedInvoice, invoices }) => {
console.log(invoices)
// console.log(invoices)
const { t } = useTranslation("invoices");
const [tabIndex, setTabIndex] = useState(0);

@@ -268,6 +268,19 @@ const InvoiceSearch: React.FC<Props> = ({ issuedInvoice, receivedInvoice, invoic
// setSelectedRow([]);
};

const handleDeleteInvoice = useCallback(() => {
deleteDialog(async() => {
//console.log(selectedRow[0])
await deleteInvoice(selectedRow[0].id!!)
setDialogOpen(false);
const result = await successDialog("Delete Success", t);
if (result) {
window.location.reload()
}
}, t)
}, [selectedRow]);


const handleSaveDialog = async () => {
// setDialogOpen(false);
await updateInvoice(selectedRow[0])
@@ -562,6 +575,9 @@ const InvoiceSearch: React.FC<Props> = ({ issuedInvoice, receivedInvoice, invoic
/>
</DialogContent>
<DialogActions>
<Button onClick={handleDeleteInvoice} color="error">
{t("Delete")}
</Button>
<Button onClick={handleCloseDialog} color="primary">
{t("Cancel")}
</Button>


+ 25
- 14
src/components/ProgressByClient/ProgressByClient.tsx Vedi File

@@ -300,6 +300,7 @@ const ProgressByClient: React.FC<Props> = () => {
id: "budgetedManhour",
field: "budgetedManhour",
headerName: t("Budgeted Manhours"),
type: "number",
minWidth: 70,
renderCell: (params: any) => {
return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>;
@@ -309,6 +310,7 @@ const ProgressByClient: React.FC<Props> = () => {
id: "spentManhour",
field: "spentManhour",
headerName: t("Spent Manhours"),
type: "number",
renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return (
@@ -325,6 +327,7 @@ const ProgressByClient: React.FC<Props> = () => {
id: "remainedManhour",
field: "remainedManhour",
headerName: t("Remained Manhours"),
type: "number",
renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return (
@@ -397,6 +400,14 @@ const ProgressByClient: React.FC<Props> = () => {
legend: {
show: false,
},
tooltip: {
enabled: true,
y: {
formatter: function (val) {
return val.toFixed(1) + "%";
}
}
},
responsive: [
{
breakpoint: 480,
@@ -431,11 +442,11 @@ const ProgressByClient: React.FC<Props> = () => {
<div style="width: auto;">
<span style="font-weight: bold;">${projectCode} - ${projectName}</span>
<br>
${t("Budget Manhours")}: ${budgetManhours} hours
${t("Budget Manhours")}: ${budgetManhours.toFixed(2)} hours
<br>
${t("Spent Manhours")}: ${spentManhours} hours
${t("Spent Manhours")}: ${spentManhours.toFixed(2)} hours
<br>
Percentage: ${value}%
Percentage: ${value.toFixed(1)}%
</div>
`;

@@ -707,9 +718,9 @@ const ProgressByClient: React.FC<Props> = () => {
</div>
<div
className="mt-2 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{projectBudgetManhour}</span>
<span style={{ margin: "5%" }}>{projectBudgetManhour}</span>
</div>
</div>
<hr />
@@ -718,13 +729,13 @@ const ProgressByClient: React.FC<Props> = () => {
className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Actual Manhours Spent")}</span>
<span style={{ margin: "5%" }}>{t("Actual Manhours Spent")}</span>
</div>
<div
className="mt-2 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{actualManhourSpent}</span>
<span style={{ margin: "5%" }}>{actualManhourSpent}</span>
</div>
</div>
<hr />
@@ -733,13 +744,13 @@ const ProgressByClient: React.FC<Props> = () => {
className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Remained Manhours")}</span>
<span style={{ margin: "5%" }}>{t("Remained Manhours")}</span>
</div>
<div
className="mt-2 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{remainedManhour}</span>
<span style={{ margin: "5%" }}>{remainedManhour}</span>
</div>
</div>
<hr />
@@ -748,13 +759,13 @@ const ProgressByClient: React.FC<Props> = () => {
className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Last Update")}</span>
<span style={{ margin: "5%" }}>{t("Last Update")}</span>
</div>
<div
className="mt-2 mb-5 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{lastUpdate}</span>
<span style={{ margin: "5%" }}>{lastUpdate}</span>
</div>
</div>
</Card>


+ 26
- 18
src/components/ProgressByTeam/ProgressByTeam.tsx Vedi File

@@ -335,6 +335,7 @@ const ProgressByTeam: React.FC = () => {
field: "budgetedManhour",
headerName: t("Budgeted Manhours"),
minWidth: 70,
type: "number",
renderCell: (params: any) => {
return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>;
}
@@ -343,6 +344,7 @@ const ProgressByTeam: React.FC = () => {
id: "spentManhour",
field: "spentManhour",
headerName: t("Spent Manhours"),
type: "number",
renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return (
@@ -358,6 +360,7 @@ const ProgressByTeam: React.FC = () => {
id: "remainedManhour",
field: "remainedManhour",
headerName: t("Remained Manhours"),
type: "number",
renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return (
@@ -474,6 +477,14 @@ const ProgressByTeam: React.FC = () => {
legend: {
show: false,
},
tooltip: {
enabled: true,
y: {
formatter: function (val) {
return val.toFixed(1) + "%";
}
}
},
responsive: [
{
breakpoint: 480,
@@ -507,12 +518,9 @@ const ProgressByTeam: React.FC = () => {
const tooltipContent = `
<div style="width: auto;">
<span style="font-weight: bold;">${projectCode} - ${projectName}</span>
<br>
${t("Budget Manhours")}: ${budgetManhours} hours
<br>
${t("Spent Manhours")}: ${spentManhours} hours
<br>
Percentage: ${value}%
<br>${t("Budget Manhours")}:${budgetManhours.toFixed(2)} hours
<br>${t("Spent Manhours")}:${spentManhours.toFixed(2)} hours
<br>Percentage:${value.toFixed(1)}%
</div>
`;

@@ -816,13 +824,13 @@ const ProgressByTeam: React.FC = () => {
className="mt-5 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Project Budget Manhours")}</span>
<span style={{ margin: "5%" }}>{t("Project Budget Manhours")}</span>
</div>
<div
className="mt-2 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{projectBudgetManhour}</span>
<span style={{ margin: "5%" }}>{projectBudgetManhour}</span>
</div>
</div>
<hr />
@@ -831,13 +839,13 @@ const ProgressByTeam: React.FC = () => {
className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Actual Manhours Spent")}</span>
<span style={{ margin: "5%" }}>{t("Actual Manhours Spent")}</span>
</div>
<div
className="mt-2 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{actualManhourSpent}</span>
<span style={{ margin: "5%" }}>{actualManhourSpent}</span>
</div>
</div>
<hr />
@@ -846,13 +854,13 @@ const ProgressByTeam: React.FC = () => {
className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Remained Manhours")}</span>
<span style={{ margin: "5%" }}>{t("Remained Manhours")}</span>
</div>
<div
className="mt-2 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{remainedManhour}</span>
<span style={{ margin: "5%" }}>{remainedManhour}</span>
</div>
</div>
<hr />
@@ -861,13 +869,13 @@ const ProgressByTeam: React.FC = () => {
className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Last Update")}</span>
<span style={{ margin: "5%" }}>{t("Last Update")}</span>
</div>
<div
className="mt-2 mb-5 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{lastUpdate}</span>
<span style={{ margin: "5%" }}>{lastUpdate}</span>
</div>
</div>
</Card>


+ 17
- 14
src/components/ProjectCashFlow/ProjectCashFlow.tsx Vedi File

@@ -297,6 +297,7 @@ const ProjectCashFlow: React.FC = () => {
field: "expenditure",
headerName: t("Expenditure (HKD)"),
flex: 0.6,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.expenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -308,6 +309,7 @@ const ProjectCashFlow: React.FC = () => {
field: "income",
headerName: t("Income (HKD)"),
flex: 0.6,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.income.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -319,6 +321,7 @@ const ProjectCashFlow: React.FC = () => {
field: "balance",
headerName: t("Cash Flow Balance (HKD)"),
flex: 0.6,
type: "number",
renderCell: (params:any) => {
if (params.row.balance < 0) {
return (
@@ -876,8 +879,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Total Project Fee")}
</div>
<div
className="text-lg font-medium ml-5"
style={{ color: "#6b87cf" }}
className="text-lg font-medium mx-5"
style={{ color: "#6b87cf", textAlign: "right" }}
>
${totalFee.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div>
@@ -889,8 +892,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Total Invoiced Amount")}
</div>
<div
className="text-lg font-medium ml-5"
style={{ color: "#6b87cf" }}
className="text-lg font-medium mx-5"
style={{ color: "#6b87cf", textAlign: "right" }}
>
${totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div>
@@ -902,8 +905,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Total Received Amount")}
</div>
<div
className="text-lg font-medium ml-5"
style={{ color: "#6b87cf" }}
className="text-lg font-medium mx-5"
style={{ color: "#6b87cf", textAlign: "right" }}
>
${totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div>
@@ -915,8 +918,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Accounts Receivable")}
</div>
<div
className="text-lg font-medium ml-5 mb-2"
style={{ color: "#6b87cf" }}
className="text-lg font-medium mx-5 mb-2"
style={{ color: "#6b87cf", textAlign: "right" }}
>
${receivable.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div>
@@ -951,8 +954,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Total Budget")}
</div>
<div
className="text-lg font-medium ml-5"
style={{ color: "#6b87cf" }}
className="text-lg font-medium mx-5"
style={{ color: "#6b87cf", textAlign: "right" }}
>
${totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div>
@@ -964,8 +967,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Total Cumulative Expenditure")}
</div>
<div
className="text-lg font-medium ml-5"
style={{ color: "#6b87cf" }}
className="text-lg font-medium mx-5"
style={{ color: "#6b87cf", textAlign: "right" }}
>
${totalExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div>
@@ -977,8 +980,8 @@ const ProjectCashFlow: React.FC = () => {
{t("Remaining Budget")}
</div>
<div
className="text-lg font-medium ml-5 mb-2"
style={{ color: "#6b87cf" }}
className="text-lg font-medium mx-5 mb-2"
style={{ color: "#6b87cf", textAlign: "right" }}
>
${expenditureReceivable.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
</div>


+ 12
- 0
src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx Vedi File

@@ -211,6 +211,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'totalFee',
headerName: t("Total Fees")+t("HKD"),
minWidth:50,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.totalFee.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -222,6 +223,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'totalBudget',
headerName: t("Total Budget")+t("HKD"),
minWidth:50,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -233,6 +235,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'cumulativeExpenditure',
headerName: t("Total Cumulative Expenditure")+t("HKD"),
minWidth:280,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.cumulativeExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -244,6 +247,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'totalInvoiced',
headerName: t("Total Invoiced Amount")+t("HKD"),
minWidth:250,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -255,6 +259,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'totalUnInvoiced',
headerName: t("Total Un-Invoiced Amount")+t("HKD"),
minWidth:250,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.totalUninvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -266,6 +271,7 @@ const ProjectFinancialSummary: React.FC = () => {
field: 'totalReceived',
headerName: t("Total Received Amount")+t("HKD"),
minWidth:250,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -426,6 +432,7 @@ const columns2 = [
id: 'totalFees',
field: 'totalFees',
headerName: t("Total Fees")+t("HKD"),
type: "number",
minWidth:50,
renderCell: (params:any) => {
return (
@@ -438,6 +445,7 @@ const columns2 = [
field: 'totalBudget',
headerName: t("Total Budget")+t("HKD"),
minWidth:50,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.totalBudget.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -449,6 +457,7 @@ const columns2 = [
field: 'totalCumulativeExpenditure',
headerName: t("Total Cumulative Expenditure")+t("HKD"),
minWidth:250,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.cumulativeExpenditure.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -460,6 +469,7 @@ const columns2 = [
field: 'totalInvoicedAmount',
headerName: t("Total Invoiced Amount")+t("HKD"),
minWidth:250,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.totalInvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -471,6 +481,7 @@ const columns2 = [
field: 'totalUnInvoicedAmount',
headerName: t("Total Un-Invoiced Amount")+t("HKD"),
minWidth:250,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.totalUninvoiced.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>
@@ -482,6 +493,7 @@ const columns2 = [
field: 'totalReceivedAmount',
headerName: t("Total Received Amount") +t("HKD"),
minWidth:250,
type: "number",
renderCell: (params:any) => {
return (
<span>${params.row.totalReceived.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>


+ 26
- 15
src/components/ProjectResourceConsumptionRanking/ProjectResourceConsumptionRanking.tsx Vedi File

@@ -419,6 +419,7 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
field: "budgetedManhour",
headerName: t("Budgeted Manhours"),
minWidth: 70,
type: "number",
renderCell: (params: any) => {
return <span>{params.row.budgetedManhour.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</span>;
}
@@ -427,6 +428,7 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
id: "spentManhour",
field: "spentManhour",
headerName: t("Spent Manhours"),
type: "number",
renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return (
@@ -442,6 +444,7 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
id: "remainedManhour",
field: "remainedManhour",
headerName: t("Remained Manhours"),
type: "number",
renderCell: (params: any) => {
if (params.row.budgetedManhour - params.row.spentManhour <= 0) {
return (
@@ -558,6 +561,14 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
legend: {
show: false,
},
tooltip: {
enabled: true,
y: {
formatter: function (val) {
return val.toFixed(1) + "%";
}
}
},
responsive: [
{
breakpoint: 480,
@@ -592,11 +603,11 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
<div style="width: 250px;">
<span style="font-weight: bold;">${projectCode} - ${projectName}</span>
<br>
${t("Budget Manhours")}: ${budgetManhours} ${t("hours")}
${t("Budget Manhours")}: ${budgetManhours.toFixed(2)} ${t("hours")}
<br>
${t("Spent Manhours")}: ${spentManhours} ${t("hours")}
${t("Spent Manhours")}: ${spentManhours.toFixed(2)} ${t("hours")}
<br>
Percentage: ${value}%
Percentage: ${value.toFixed(1)}%
</div>
`;

@@ -934,13 +945,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
className="mt-5 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Project Budget Manhours")}</span>
<span style={{ margin: "5%" }}>{t("Project Budget Manhours")}</span>
</div>
<div
className="mt-2 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{projectBudgetManhour}</span>
<span style={{ margin: "5%" }}>{projectBudgetManhour}</span>
</div>
</div>
<hr />
@@ -949,13 +960,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Actual Manhours Spent")}</span>
<span style={{ margin: "5%" }}>{t("Actual Manhours Spent")}</span>
</div>
<div
className="mt-2 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{actualManhourSpent}</span>
<span style={{ margin: "5%" }}>{actualManhourSpent}</span>
</div>
</div>
<hr />
@@ -964,13 +975,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Remained Manhours")}</span>
<span style={{ margin: "5%" }}>{t("Remained Manhours")}</span>
</div>
<div
className="mt-2 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{remainedManhour}</span>
<span style={{ margin: "5%" }}>{remainedManhour}</span>
</div>
</div>
<hr />
@@ -979,13 +990,13 @@ const ProjectResourceConsumptionRanking: React.FC = () => {
className="mt-2 text-lg font-medium"
style={{ color: "#898d8d" }}
>
<span style={{ marginLeft: "5%" }}>{t("Last Update")}</span>
<span style={{ margin: "5%" }}>{t("Last Update")}</span>
</div>
<div
className="mt-2 mb-5 text-2xl font-extrabold"
style={{ color: "#6b87cf" }}
style={{ color: "#6b87cf", textAlign: "right" }}
>
<span style={{ marginLeft: "5%" }}>{lastUpdate}</span>
<span style={{ margin: "5%" }}>{lastUpdate}</span>
</div>
</div>
</Card>


+ 49
- 44
src/components/ProjectResourceSummary/ProjectResourceSummary.tsx Vedi File

@@ -234,6 +234,11 @@ const ProjectResourceSummary: React.FC = () => {
// createTaskData("1.1 Preparation of preliminary...","-","-","172.00","-","54.00","-","42.00","-","12.00","-","3.00","-","283.00"),
// ];

const colBaseStyle:any = {fontSize:13, textAlign:"right"};
const headerBaseStyle:any = {fontSize:11, minWidth:30, textAlign:"right"}
const infoHeaderStyle:any = { fontSize:"1em", fontWeight:"bold"};//, textAlign: "right"};
const infoDataStyle:any = { fontSize:"1em"};//, textAlign: "right"};

function Row(props:any) {
const { row } = props;
const [open, setOpen] = React.useState(false);
@@ -253,19 +258,19 @@ const ProjectResourceSummary: React.FC = () => {
)}
</TableCell>
<TableCell style={{fontSize:13}}>{row.stage}</TableCell>
<TableCell style={{fontSize:13}}>{row.taskCount}</TableCell>
<TableCell style={{fontSize:13, color:"#808aff"}}>{row.g1Planned.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#69dbac"}}>{row.g1Actual.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#808aff"}}>{row.g2Planned.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#69dbac"}}>{row.g2Actual.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#808aff"}}>{row.g3Planned.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#69dbac"}}>{row.g3Actual.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#808aff"}}>{row.g4Planned.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#69dbac"}}>{row.g4Actual.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#808aff"}}>{row.g5Planned.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#69dbac"}}>{row.g5Actual.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#808aff"}}>{row.totalPlanned.toFixed(2)}</TableCell>
<TableCell style={{fontSize:13, color:"#69dbac"}}>{row.totalActual.toFixed(2)}</TableCell>
<TableCell style={colBaseStyle}>{row.taskCount}</TableCell>
<TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.g1Planned.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.g1Actual.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.g2Planned.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.g2Actual.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.g3Planned.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.g3Actual.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.g4Planned.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.g4Actual.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.g5Planned.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.g5Actual.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#808aff"}}>{row.totalPlanned.toFixed(2)}</TableCell>
<TableCell style={{...colBaseStyle, color:"#69dbac"}}>{row.totalActual.toFixed(2)}</TableCell>
</TableRow>
{row.task.map((taskRow:any) => (
<TableRow key={taskRow[0]} style={{backgroundColor:"#f0f3f7"}} className="border-t-2 border-b-0 border-l-0 border-r-0 border-solid border-slate-300">
@@ -622,92 +627,92 @@ const columns2 = [
<CardHeader className="text-slate-500" title= {t("Project Information")}/>
<div className="ml-6 mr-6">
<div style={{ display: "inline-block", width: "33%"}}>
<div style={{fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u>
{t("Project")}
</u>
</div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
{projectName}
</div>
</div>
<div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u>
{t("Project Fee")}
</u>
</div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
HKD ${projectFee.toFixed(2)}
</div>
</div>
<div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u>
{t("Total Budget")}
</u>
</div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
HKD ${projectBudget.toFixed(2)}
</div>
</div>
<div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u>
{t("Cumulative Expenditure")}
</u>
</div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
HKD ${expenditure.toFixed(2)}
</div>
</div>
<div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u>
{t("Remaining Budget")}
</u>
</div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
HKD ${remainingBudget.toFixed(2)}
</div>
</div>
<div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u>
{t("Status")}
</u>
</div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
{t(status)}
</div>
</div>
<div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u>
{t("Planned Resources")}
</u>
</div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
{plannedResources.toFixed(2)} {t("Manhours")}
</div>
</div>
<div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u>
{t("Actual Resources Spent")}
</u>
</div>
<div style={{fontSize:"1em"}}>
<div style={infoDataStyle}>
{(actualResourcesSpent ?? 0).toFixed(2)} {t("Manhours")} ({(actualResourcesSpent/plannedResources*100).toFixed(2)}%)
</div>
</div>
<div style={{ display: "inline-block", width: "33%"}}>
<div style={{ fontSize:"1em", fontWeight:"bold"}}>
<div style={infoHeaderStyle}>
<u>
{t("Remaining Resources")}
</u>
</div>
<div style={{fontSize:"1em"}} className={"mb-5"}>
<div style={infoDataStyle} className={"mb-5"}>
{(remainingResources ?? 0).toFixed(2)} {t("Manhours")} ({(remainingResources/plannedResources*100).toFixed(2)}%)
</div>
</div>
@@ -748,19 +753,19 @@ const columns2 = [
<TableRow className="border-t-2 border-b-0 border-l-0 border-r-0 border-solid border-slate-300">
<TableCell style={{minWidth:30}}/>
<TableCell style={{fontSize:11, minWidth:150}}>{t("Stage")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30}}>{t("Task Count")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{fontSize:11, minWidth:30, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={headerBaseStyle}>{t("Task Count")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#808aff"}}>{t("Planned")}</TableCell>
<TableCell style={{...headerBaseStyle, color:"#69dbac"}}>{t("Actual")}</TableCell>
</TableRow>
</TableHead>
<TableBody>


Caricamento…
Annulla
Salva