diff --git a/src/app/(main)/analytics/ProjectPandLReport/page.tsx b/src/app/(main)/analytics/ProjectPandLReport/page.tsx
new file mode 100644
index 0000000..156cc3d
--- /dev/null
+++ b/src/app/(main)/analytics/ProjectPandLReport/page.tsx
@@ -0,0 +1,30 @@
+import { Metadata } from "next";
+import { Suspense } from "react";
+import { I18nProvider, getServerI18n } from "@/i18n";
+import { fetchProjects } from "@/app/api/projects";
+import GenerateProjectPandLReport from "@/components/GenerateProjectPandLReport";
+import { Typography } from "@mui/material";
+
+export const metadata: Metadata = {
+ title: "Project Cash Flow Report",
+};
+
+const ProjectPandLReport: React.FC = async () => {
+ const { t } = await getServerI18n("reports");
+ fetchProjects();
+
+ return (
+ <>
+
+ {t("Project P&L Report")}
+
+
+ }>
+
+
+
+ >
+ );
+};
+
+export default ProjectPandLReport;
diff --git a/src/components/GenerateProjectPandLReport/GenerateProjectPandLReport.tsx b/src/components/GenerateProjectPandLReport/GenerateProjectPandLReport.tsx
new file mode 100644
index 0000000..2fb5d63
--- /dev/null
+++ b/src/components/GenerateProjectPandLReport/GenerateProjectPandLReport.tsx
@@ -0,0 +1,63 @@
+"use client";
+
+import React, { useMemo } from "react";
+import SearchBox, { Criterion } from "../SearchBox";
+import { useTranslation } from "react-i18next";
+import { ProjectResult } from "@/app/api/projects";
+import { ProjectPandLReportFilter } from "@/app/api/reports";
+import { fetchProjectPandLReport } from "@/app/api/reports/actions";
+import { downloadFile } from "@/app/utils/commonUtil";
+import { dateTypeCombo } from "@/app/utils/comboUtil";
+import { FormHelperText } from "@mui/material";
+import { errorDialog, errorDialogWithContent } from "../Swal/CustomAlerts";
+
+interface Props {
+ projects: ProjectResult[];
+}
+
+type SearchQuery = Partial>;
+type SearchParamNames = keyof SearchQuery;
+
+const GenerateProjectPandLReport: React.FC = ({ projects }) => {
+ const { t } = useTranslation("report");
+ const projectCombo = projects.map(project => `${project.code} - ${project.name}`)
+
+ const searchCriteria: Criterion[] = useMemo(
+ () => [
+ { label: t("Project *"), paramName: "project", type: "select", options: projectCombo, needAll: false},
+ { label: t("Start Month *"), label2: t("End Month *"), paramName: "startMonth", type: "dateRange", needMonth: true },
+
+ ],
+ [t],
+ );
+
+ return (
+ <>
+ {
+
+ if (query.project.length > 0 && query.project.toLocaleLowerCase() !== "all") {
+ const projectIndex = projectCombo.findIndex(project => project === query.project)
+ console.log(projects[projectIndex].id, query.startMonth, query.startMonthTo)
+ if(projects[projectIndex].id != null && query.startMonth != "" && query.startMonthTo != undefined){
+ const response = await fetchProjectPandLReport({ projectId: projects[projectIndex].id, startMonth: query.startMonth, endMonth: query.startMonthTo })
+ if (response) {
+ downloadFile(new Uint8Array(response.blobValue), response.filename!!)
+ }
+ }else{
+ errorDialogWithContent(t("Download Fail"),
+ t(`Please check the required field`), t)
+ .then(() => {
+ window.location.reload()
+ })
+ }
+ }
+ }}
+ formType={"download"}
+ />
+ >
+ );
+};
+
+export default GenerateProjectPandLReport;
\ No newline at end of file
diff --git a/src/components/GenerateProjectPandLReport/GenerateProjectPandLReportLoading.tsx b/src/components/GenerateProjectPandLReport/GenerateProjectPandLReportLoading.tsx
new file mode 100644
index 0000000..04826a4
--- /dev/null
+++ b/src/components/GenerateProjectPandLReport/GenerateProjectPandLReportLoading.tsx
@@ -0,0 +1,38 @@
+import Card from "@mui/material/Card";
+import CardContent from "@mui/material/CardContent";
+import Skeleton from "@mui/material/Skeleton";
+import Stack from "@mui/material/Stack";
+import React from "react";
+
+// Can make this nicer
+export const GenerateProjectPandLReportLoading: React.FC = () => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
+
+export default GenerateProjectPandLReportLoading;
\ No newline at end of file
diff --git a/src/components/GenerateProjectPandLReport/GenerateProjectPandLReportWrapper.tsx b/src/components/GenerateProjectPandLReport/GenerateProjectPandLReportWrapper.tsx
new file mode 100644
index 0000000..00ca669
--- /dev/null
+++ b/src/components/GenerateProjectPandLReport/GenerateProjectPandLReportWrapper.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+import GenerateProjectPandLReportLoading from "./GenerateProjectPandLReportLoading";
+import { fetchProjects } from "@/app/api/projects";
+import GenerateProjectPandLReport from "./GenerateProjectPandLReport";
+
+interface SubComponents {
+ Loading: typeof GenerateProjectPandLReportLoading;
+}
+
+const GenerateProjectPandLReportWrapper: React.FC & SubComponents = async () => {
+ const projects = await fetchProjects();
+
+ return ;
+};
+
+GenerateProjectPandLReportWrapper.Loading = GenerateProjectPandLReportLoading;
+
+export default GenerateProjectPandLReportWrapper;
\ No newline at end of file
diff --git a/src/components/GenerateProjectPandLReport/index.ts b/src/components/GenerateProjectPandLReport/index.ts
new file mode 100644
index 0000000..b56feba
--- /dev/null
+++ b/src/components/GenerateProjectPandLReport/index.ts
@@ -0,0 +1 @@
+export { default } from "./GenerateProjectPandLReportWrapper";
\ No newline at end of file
diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx
index a50b3a0..0ed436c 100644
--- a/src/components/NavigationContent/NavigationContent.tsx
+++ b/src/components/NavigationContent/NavigationContent.tsx
@@ -175,7 +175,7 @@ const NavigationContent: React.FC = ({ abilities }) => {
{
icon: ,
label: "Project P&L Report",
- path: "/analytics/ProjectPLReport",
+ path: "/analytics/ProjectPandLReport",
},
{
icon: ,