diff --git a/next.config.js b/next.config.js index 82f670f..85c5fb6 100644 --- a/next.config.js +++ b/next.config.js @@ -1,10 +1,10 @@ /** @type {import('next').NextConfig} */ const nextConfig = { - // eslint: { - // // Warning: This allows production builds to successfully complete even if - // // your project has ESLint errors. - // ignoreDuringBuilds: true, - // }, -} + // eslint: { + // // Warning: This allows production builds to successfully complete even if + // // your project has ESLint errors. + // ignoreDuringBuilds: true, + // }, +}; -module.exports = nextConfig +module.exports = nextConfig; diff --git a/src/app/(main)/dashboard/CompanyTeamCashFlow/page.tsx b/src/app/(main)/dashboard/CompanyTeamCashFlow/page.tsx index df5365e..3a6079d 100644 --- a/src/app/(main)/dashboard/CompanyTeamCashFlow/page.tsx +++ b/src/app/(main)/dashboard/CompanyTeamCashFlow/page.tsx @@ -3,25 +3,23 @@ import { I18nProvider } from "@/i18n"; import DashboardPage from "@/components/DashboardPage/DashboardPage"; import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; -import { Suspense} from "react"; +import { Suspense } from "react"; import Tabs, { TabsProps } from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; import Typography from "@mui/material/Typography"; -import CompanyTeamCashFlowComponent from '@/components/CompanyTeamCashFlow' +import CompanyTeamCashFlowComponent from "@/components/CompanyTeamCashFlow"; export const metadata: Metadata = { title: "Project Status by Client", }; - const CompanyTeamCashFlow: React.FC = () => { - return ( Company / Team Cash Flow - + ); }; diff --git a/src/app/(main)/dashboard/ProjectCashFlow/page.tsx b/src/app/(main)/dashboard/ProjectCashFlow/page.tsx index e0e1402..2e87f44 100644 --- a/src/app/(main)/dashboard/ProjectCashFlow/page.tsx +++ b/src/app/(main)/dashboard/ProjectCashFlow/page.tsx @@ -3,19 +3,17 @@ import { I18nProvider } from "@/i18n"; import DashboardPage from "@/components/DashboardPage/DashboardPage"; import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; -import { Suspense} from "react"; +import { Suspense } from "react"; import Tabs, { TabsProps } from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; import Typography from "@mui/material/Typography"; -import ProjectCashFlowComponent from '@/components/ProjectCashFlow' +import ProjectCashFlowComponent from "@/components/ProjectCashFlow"; export const metadata: Metadata = { title: "Project Status by Client", }; - const ProjectCashFlow: React.FC = () => { - return ( @@ -24,7 +22,7 @@ const ProjectCashFlow: React.FC = () => { {/* }> */} - + ); }; diff --git a/src/app/(main)/dashboard/ProjectFinancialSummary/page.tsx b/src/app/(main)/dashboard/ProjectFinancialSummary/page.tsx index 090ef2d..3549f77 100644 --- a/src/app/(main)/dashboard/ProjectFinancialSummary/page.tsx +++ b/src/app/(main)/dashboard/ProjectFinancialSummary/page.tsx @@ -3,7 +3,7 @@ import { I18nProvider } from "@/i18n"; import DashboardPage from "@/components/DashboardPage/DashboardPage"; import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; -import { Suspense} from "react"; +import { Suspense } from "react"; import Tabs, { TabsProps } from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; import Typography from "@mui/material/Typography"; @@ -13,15 +13,13 @@ export const metadata: Metadata = { title: "Project Status by Client", }; - const ProjectFinancialSummary: React.FC = () => { - return ( Project Financial Summary - + ); }; diff --git a/src/app/(main)/dashboard/ProjectStatusByClient/page.tsx b/src/app/(main)/dashboard/ProjectStatusByClient/page.tsx index ef95fff..4ca47da 100644 --- a/src/app/(main)/dashboard/ProjectStatusByClient/page.tsx +++ b/src/app/(main)/dashboard/ProjectStatusByClient/page.tsx @@ -3,7 +3,7 @@ import { I18nProvider } from "@/i18n"; import DashboardPage from "@/components/DashboardPage/DashboardPage"; import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; -import { Suspense} from "react"; +import { Suspense } from "react"; import Tabs, { TabsProps } from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; import Typography from "@mui/material/Typography"; @@ -13,18 +13,16 @@ export const metadata: Metadata = { title: "Project Status by Client", }; - const ProjectStatusByClient: React.FC = () => { - return ( Project Status by Client }> - + - + ); }; diff --git a/src/app/(main)/dashboard/StaffUtilization/page.tsx b/src/app/(main)/dashboard/StaffUtilization/page.tsx index 9293008..2ddea02 100644 --- a/src/app/(main)/dashboard/StaffUtilization/page.tsx +++ b/src/app/(main)/dashboard/StaffUtilization/page.tsx @@ -3,7 +3,7 @@ import { I18nProvider } from "@/i18n"; import DashboardPage from "@/components/DashboardPage/DashboardPage"; import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; -import { Suspense} from "react"; +import { Suspense } from "react"; import Tabs, { TabsProps } from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; import Typography from "@mui/material/Typography"; @@ -13,15 +13,13 @@ export const metadata: Metadata = { title: "Project Status by Client", }; - const StaffUtilization: React.FC = () => { - return ( Staff Utilization - + ); }; diff --git a/src/app/(main)/dashboard/page.tsx b/src/app/(main)/dashboard/page.tsx index 3958988..5f3d40b 100644 --- a/src/app/(main)/dashboard/page.tsx +++ b/src/app/(main)/dashboard/page.tsx @@ -3,7 +3,7 @@ import { I18nProvider } from "@/i18n"; import DashboardPage from "@/components/DashboardPage/DashboardPage"; import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; -import { Suspense} from "react"; +import { Suspense } from "react"; import Tabs, { TabsProps } from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; @@ -11,12 +11,8 @@ export const metadata: Metadata = { title: "Dashboard", }; - const Dashboard: React.FC = () => { - - return ( -
test
- ); + return
test
; }; export default Dashboard; diff --git a/src/app/(main)/home/page.tsx b/src/app/(main)/home/page.tsx index 3d95845..a710195 100644 --- a/src/app/(main)/home/page.tsx +++ b/src/app/(main)/home/page.tsx @@ -9,8 +9,8 @@ export const metadata: Metadata = { const Home: React.FC = async () => { return ( - - + + ); }; diff --git a/src/app/api/cashflow/index.ts b/src/app/api/cashflow/index.ts index 9b79d52..978a61e 100644 --- a/src/app/api/cashflow/index.ts +++ b/src/app/api/cashflow/index.ts @@ -34,6 +34,6 @@ const mockProjects: CashFlow[] = [ startDateTo: "5", targetEndDate: "s", client: "ss", - subsidiary:"ss", - } + subsidiary: "ss", + }, ]; diff --git a/src/app/api/claims/index.ts b/src/app/api/claims/index.ts index cfb2554..f012bcc 100644 --- a/src/app/api/claims/index.ts +++ b/src/app/api/claims/index.ts @@ -24,7 +24,7 @@ const mockClaims: ClaimResult[] = [ id: 1, created: "2023-11-22", name: "Consultancy Project A", - cost: 121.00, + cost: 121.0, type: "Expense", status: "Not Submitted", remarks: "", @@ -33,7 +33,7 @@ const mockClaims: ClaimResult[] = [ id: 2, created: "2023-11-30", name: "Consultancy Project A", - cost: 4300.00, + cost: 4300.0, type: "Expense", status: "Waiting for Approval", remarks: "", @@ -42,7 +42,7 @@ const mockClaims: ClaimResult[] = [ id: 3, created: "2023-12-12", name: "Construction Project C", - cost: 3675.00, + cost: 3675.0, type: "Petty Cash", status: "Rejected", remarks: "Duplicate Claim Form", diff --git a/src/components/AppBar/AppBar.tsx b/src/components/AppBar/AppBar.tsx index 2942050..a38d2bd 100644 --- a/src/components/AppBar/AppBar.tsx +++ b/src/components/AppBar/AppBar.tsx @@ -16,7 +16,7 @@ const AppBar: React.FC = ({ avatarImageSrc, profileName }) => { - + diff --git a/src/components/AssignedProjectGrid/AssignedProjectGrid.tsx b/src/components/AssignedProjectGrid/AssignedProjectGrid.tsx index fa5d7b2..a41fc77 100644 --- a/src/components/AssignedProjectGrid/AssignedProjectGrid.tsx +++ b/src/components/AssignedProjectGrid/AssignedProjectGrid.tsx @@ -1,15 +1,26 @@ -import * as React from 'react'; -import { Card, CardHeader, CardContent, SxProps, Theme, Tabs, Tab, Box, Typography, Grid, Link} from '@mui/material'; -import { DataGrid, GridColDef } from '@mui/x-data-grid'; -import { darken, lighten, styled } from '@mui/material/styles'; -import { ThemeProvider } from '@emotion/react'; -import { TAB_THEME } from '@/theme/colorConst'; -import AllProjectGrid from '../UserWorkspacePage/ProjectGrid'; - +import * as React from "react"; +import { + Card, + CardHeader, + CardContent, + SxProps, + Theme, + Tabs, + Tab, + Box, + Typography, + Grid, + Link, +} from "@mui/material"; +import { DataGrid, GridColDef } from "@mui/x-data-grid"; +import { darken, lighten, styled } from "@mui/material/styles"; +import { ThemeProvider } from "@emotion/react"; +import { TAB_THEME } from "@/theme/colorConst"; +import AllProjectGrid from "../UserWorkspacePage/ProjectGrid"; interface AssignedProjectGridProps { Title?: string; - // rows: any[]; + // rows: any[]; // columns: any[]; columnWidth?: number; Style?: boolean; @@ -47,7 +58,7 @@ function CustomTabPanel(props: TabPanelProps) { function a11yProps(index: number) { return { id: `simple-tab-${index}`, - 'aria-controls': `simple-tabpanel-${index}`, + "aria-controls": `simple-tabpanel-${index}`, }; } @@ -72,67 +83,117 @@ const AssignedProjectGrid: React.FC = ({ // return { ...row }; // }); - const getBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.7) : lighten(color, 0.7); + const getBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.7) : lighten(color, 0.7); - const getHoverBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.6) : lighten(color, 0.6); + const getHoverBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.6) : lighten(color, 0.6); - const getSelectedBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.5) : lighten(color, 0.5); + const getSelectedBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.5) : lighten(color, 0.5); - const getSelectedHoverBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.4) : lighten(color, 0.4); + const getSelectedHoverBackgroundColor = ( + color: string, + mode: "light" | "dark", + ) => (mode === "dark" ? darken(color, 0.4) : lighten(color, 0.4)); const StyledDataGrid = styled(DataGrid)(({ theme }) => ({ - '& .super-app-theme--Open': { - backgroundColor: getBackgroundColor(theme.palette.info.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.info.main, theme.palette.mode) + "& .super-app-theme--Open": { + backgroundColor: getBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.info.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.info.main, theme.palette.mode) - } - } }, - '& .super-app-theme--finish': { - backgroundColor: getBackgroundColor(theme.palette.success.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.success.main, theme.palette.mode) + "& .super-app-theme--finish": { + backgroundColor: getBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.success.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.success.main, theme.palette.mode) - } - } }, - '& .super-app-theme--danger': { - backgroundColor: getBackgroundColor(theme.palette.warning.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.warning.main, theme.palette.mode) + "& .super-app-theme--danger": { + backgroundColor: getBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.warning.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.warning.main, theme.palette.mode) - } - } }, - '& .super-app-theme--warning': { - backgroundColor: getBackgroundColor(theme.palette.error.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.error.main, theme.palette.mode) + "& .super-app-theme--warning": { + backgroundColor: getBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.error.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.error.main, theme.palette.mode) - } - } - } + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + }, + }, + }, })); const [value, setValue] = React.useState(0); @@ -142,20 +203,30 @@ const AssignedProjectGrid: React.FC = ({ }; return ( -
- - {Title && } - -
- - - - - - - - - {/* +
+ + {Title && } + +
+ + + + + + + + + {/* Item {value} @@ -164,12 +235,12 @@ const AssignedProjectGrid: React.FC = ({ Item {value} */} - -
-
- -
-
+
+
+
+ +
+
); }; diff --git a/src/components/ClaimSearch/ClaimSearch.tsx b/src/components/ClaimSearch/ClaimSearch.tsx index aa08db1..6ab02cf 100644 --- a/src/components/ClaimSearch/ClaimSearch.tsx +++ b/src/components/ClaimSearch/ClaimSearch.tsx @@ -39,7 +39,12 @@ const ClaimSearch: React.FC = ({ claims }) => { label: t("Status"), paramName: "status", type: "select", - options: ["Not Submitted", "Waiting for Approval", "Approved", "Rejected"] + options: [ + "Not Submitted", + "Waiting for Approval", + "Approved", + "Rejected", + ], }, { label: t("Remarks"), @@ -80,10 +85,7 @@ const ClaimSearch: React.FC = ({ claims }) => { console.log(query); }} /> - - items={filteredClaims} - columns={columns} - /> + items={filteredClaims} columns={columns} /> ); }; diff --git a/src/components/CompanyTeamCashFlow/CompanyTeamCashFlow.tsx b/src/components/CompanyTeamCashFlow/CompanyTeamCashFlow.tsx index fb935df..6d255a4 100644 --- a/src/components/CompanyTeamCashFlow/CompanyTeamCashFlow.tsx +++ b/src/components/CompanyTeamCashFlow/CompanyTeamCashFlow.tsx @@ -1,129 +1,131 @@ "use client"; import * as React from "react"; import Grid from "@mui/material/Grid"; -import { useState,useEffect, useMemo } from 'react' +import { useState, useEffect, useMemo } from "react"; import Paper from "@mui/material/Paper"; import { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; -import {Card,CardHeader} from '@mui/material'; +import { Card, CardHeader } from "@mui/material"; import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; -import CustomDatagrid from '../CustomDatagrid/CustomDatagrid'; -import ReactApexChart from 'react-apexcharts'; -import { ApexOptions } from 'apexcharts'; -import { GridColDef, GridRowSelectionModel} from '@mui/x-data-grid'; -import ReportProblemIcon from '@mui/icons-material/ReportProblem'; -import dynamic from 'next/dynamic'; -import '../../app/global.css'; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; import { AnyARecord, AnyCnameRecord } from "dns"; import SearchBox, { Criterion } from "../SearchBox"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; import { Suspense } from "react"; import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; -import {Input,Label} from "reactstrap"; -import Select, {components} from 'react-select' +import { Input, Label } from "reactstrap"; +import Select, { components } from "react-select"; const CompanyTeamCashFlow: React.FC = () => { - const todayDate = new Date; - const [selectionModel, setSelectionModel] : any[] = React.useState([]); - const [cashFlowYear, setCashFlowYear] : any[] = React.useState(todayDate.getFullYear()); + const todayDate = new Date(); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const [cashFlowYear, setCashFlowYear]: any[] = React.useState( + todayDate.getFullYear(), + ); const teamOptions = [ - { value: 1, label: 'XXX Team' }, - { value: 2, label: 'YYY Team' }, - { value: 3, label: 'ZZZ Team' } - ] + { value: 1, label: "XXX Team" }, + { value: 2, label: "YYY Team" }, + { value: 3, label: "ZZZ Team" }, + ]; const columns = [ { - id: 'projectCode', - field: 'projectCode', + id: "projectCode", + field: "projectCode", headerName: "Project Code", flex: 1, - }, - { - id: 'projectName', - field: 'projectName', + }, + { + id: "projectName", + field: "projectName", headerName: "Project Name", flex: 1, - }, - { - id: 'team', - field: 'team', - headerName: "Team", - flex: 1, - }, - { - id: 'teamLeader', - field: 'teamLeader', - headerName: "Team Leader", - flex: 1, - }, - { - id: 'startDate', - field: 'startDate', - headerName: "Start Date", - flex: 1, - }, - { - id: 'targetEndDate', - field: 'targetEndDate', - headerName: "Target End Date", - flex: 1, - }, - { - id: 'client', - field: 'client', - headerName: "Client", - flex: 1, - }, - { - id: 'subsidiary', - field: 'subsidiary', - headerName: "Subsidiary", - flex: 1, - }, + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 1, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, + }, + { + id: "startDate", + field: "startDate", + headerName: "Start Date", + flex: 1, + }, + { + id: "targetEndDate", + field: "targetEndDate", + headerName: "Target End Date", + flex: 1, + }, + { + id: "client", + field: "client", + headerName: "Client", + flex: 1, + }, + { + id: "subsidiary", + field: "subsidiary", + headerName: "Subsidiary", + flex: 1, + }, ]; const ledgerColumns = [ { - id: 'date', - field: 'date', + id: "date", + field: "date", headerName: "Date", flex: 0.5, - }, - { - id: 'expenditure', - field: 'expenditure', + }, + { + id: "expenditure", + field: "expenditure", headerName: "Expenditure (HKD)", flex: 0.6, - }, - { - id: 'income', - field: 'income', - headerName: "Income (HKD)", - flex: 0.6, - }, - { - id: 'cashFlowBalance', - field: 'cashFlowBalance', - headerName: "Cash Flow Balance (HKD)", - flex: 0.6, - }, - { - id: 'remarks', - field: 'remarks', - headerName: "Remarks", - flex: 1, - }, + }, + { + id: "income", + field: "income", + headerName: "Income (HKD)", + flex: 0.6, + }, + { + id: "cashFlowBalance", + field: "cashFlowBalance", + headerName: "Cash Flow Balance (HKD)", + flex: 0.6, + }, + { + id: "remarks", + field: "remarks", + headerName: "Remarks", + flex: 1, + }, ]; const options: ApexOptions = { chart: { height: 350, - type: 'line', + type: "line", }, stroke: { - width: [0, 0, 2, 2] + width: [0, 0, 2, 2], }, plotOptions: { bar: { @@ -132,152 +134,171 @@ const CompanyTeamCashFlow: React.FC = () => { }, }, dataLabels: { - enabled: false + enabled: false, }, xaxis: { categories: [ - 'Q1', - 'Q2', - 'Q3', - 'Q4', - 'Q5', - 'Q6', - 'Q7', - 'Q8', - 'Q9', - 'Q10', - 'Q11', - 'Q12', + "Q1", + "Q2", + "Q3", + "Q4", + "Q5", + "Q6", + "Q7", + "Q8", + "Q9", + "Q10", + "Q11", + "Q12", ], }, yaxis: [ - { title: { - text: 'Monthly Income and Expenditure(HKD)' + text: "Monthly Income and Expenditure(HKD)", }, min: 0, max: 3700000, - tickAmount: 5 + tickAmount: 5, }, { - show:false, - seriesName: 'Monthly_Expenditure', + show: false, + seriesName: "Monthly_Expenditure", title: { - text: 'Monthly Expenditure (HKD)' + text: "Monthly Expenditure (HKD)", }, min: 0, max: 3700000, - tickAmount: 5 + tickAmount: 5, }, { - seriesName: 'Cumulative_Income', + seriesName: "Cumulative_Income", opposite: true, title: { - text: 'Cumulative Income and Expenditure(HKD)' + text: "Cumulative Income and Expenditure(HKD)", }, min: 0, max: 21000000, - tickAmount: 5 + tickAmount: 5, }, { - show:false, - seriesName: 'Cumulative_Expenditure', + show: false, + seriesName: "Cumulative_Expenditure", opposite: true, title: { - text: 'Cumulative Expenditure (HKD)' + text: "Cumulative Expenditure (HKD)", }, min: 0, max: 21000000, - tickAmount: 5 - } - ], + tickAmount: 5, + }, + ], grid: { - borderColor: '#f1f1f1', + borderColor: "#f1f1f1", }, - annotations: { - }, - series:[ + annotations: {}, + series: [ { - name:"Monthly_Income", - type:"column", + name: "Monthly_Income", + type: "column", color: "#ffde91", - data:[1280000,170000,3600000,2400000,1000000,1800000,1800000,1200000,1250000,1200000,600000,2400000], + data: [ + 1280000, 170000, 3600000, 2400000, 1000000, 1800000, 1800000, 1200000, + 1250000, 1200000, 600000, 2400000, + ], }, { - name:"Monthly_Expenditure", - type:"column", + name: "Monthly_Expenditure", + type: "column", color: "#82b59a", - data:[1200000,1400000,2000000,1400000,1450000,1800000,1200000,1400000,1200000,1600000,2000000,1600000] + data: [ + 1200000, 1400000, 2000000, 1400000, 1450000, 1800000, 1200000, + 1400000, 1200000, 1600000, 2000000, 1600000, + ], }, { - name:"Cumulative_Income", - type:"line", + name: "Cumulative_Income", + type: "line", color: "#EE6D7A", - data:[500000,3000000,7000000,9000000,10000000,13000000,14000000,16000000,17000000,17500000,18000000,20000000] + data: [ + 500000, 3000000, 7000000, 9000000, 10000000, 13000000, 14000000, + 16000000, 17000000, 17500000, 18000000, 20000000, + ], }, { - name:"Cumulative_Expenditure", - type:"line", + name: "Cumulative_Expenditure", + type: "line", color: "#7cd3f2", - data:[400000,2800000,4000000,5200000,7100000,8000000,10000000,11000000,12100000,14000000,15400000,17200000] - } - ] + data: [ + 400000, 2800000, 4000000, 5200000, 7100000, 8000000, 10000000, + 11000000, 12100000, 14000000, 15400000, 17200000, + ], + }, + ], }; return ( <> - -
- - - -
-
- - -
-
- -
-
- -
-
- -
-
- +
+
+ +
+
+ +
+
+ +
+
+ - - {t("M1001")} - - - {t("M1301")} - - - {t("M1354")} - + @@ -50,20 +42,16 @@ const ClaimDetails: React.FC = () => { {t("Expense Type")} - + - + {/* diff --git a/src/components/CreateClaim/ClaimInputGrid.tsx b/src/components/CreateClaim/ClaimInputGrid.tsx index eeb43a9..1231001 100644 --- a/src/components/CreateClaim/ClaimInputGrid.tsx +++ b/src/components/CreateClaim/ClaimInputGrid.tsx @@ -8,22 +8,29 @@ import { Suspense } from "react"; import Button from "@mui/material/Button"; import Stack from "@mui/material/Stack"; import Link from "next/link"; -import { t } from 'i18next'; -import { Box, Container, Modal, Select, SelectChangeEvent, Typography } from "@mui/material"; -import { Close } from '@mui/icons-material'; -import AddIcon from '@mui/icons-material/Add'; -import EditIcon from '@mui/icons-material/Edit'; -import DeleteIcon from '@mui/icons-material/DeleteOutlined'; -import SaveIcon from '@mui/icons-material/Save'; -import CancelIcon from '@mui/icons-material/Close'; -import AddPhotoAlternateOutlinedIcon from '@mui/icons-material/AddPhotoAlternateOutlined'; -import ImageNotSupportedOutlinedIcon from '@mui/icons-material/ImageNotSupportedOutlined'; -import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; -import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import { t } from "i18next"; +import { + Box, + Container, + Modal, + Select, + SelectChangeEvent, + Typography, +} from "@mui/material"; +import { Close } from "@mui/icons-material"; +import AddIcon from "@mui/icons-material/Add"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/DeleteOutlined"; +import SaveIcon from "@mui/icons-material/Save"; +import CancelIcon from "@mui/icons-material/Close"; +import AddPhotoAlternateOutlinedIcon from "@mui/icons-material/AddPhotoAlternateOutlined"; +import ImageNotSupportedOutlinedIcon from "@mui/icons-material/ImageNotSupportedOutlined"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import Swal from "sweetalert2"; import { msg } from "../Swal/CustomAlerts"; import React from "react"; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; import { GridRowsProp, GridRowModesModel, @@ -39,14 +46,14 @@ import { GridRowEditStopReasons, GridEditInputCell, GridValueSetterParams, -} from '@mui/x-data-grid'; +} from "@mui/x-data-grid"; import { LocalizationProvider } from "@mui/x-date-pickers"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import dayjs from "dayjs"; import { Props } from "react-intl/src/components/relative"; import palette from "@/theme/devias-material-kit/palette"; -const weekdays = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']; +const weekdays = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]; interface BottomBarProps { getCostTotal: () => number; @@ -81,58 +88,67 @@ const BottomBar = (props: BottomBarProps) => { const handleAddClick = () => { const id = newId; setNewId(newId - 1); - setRows((oldRows) => [...oldRows, { id, projectCode: '', task: '', isNew: true }]); + setRows((oldRows) => [ + ...oldRows, + { id, projectCode: "", task: "", isNew: true }, + ]); setRowModesModel((oldModel) => ({ ...oldModel, - [id]: { mode: GridRowModes.Edit, fieldToFocus: 'projectCode' }, + [id]: { mode: GridRowModes.Edit, fieldToFocus: "projectCode" }, })); }; const totalColDef = { - flex:1, + flex: 1, // style: {color:getCostTotal('mon')>24?"red":"black"} }; - const TotalCell = ({value}: Props) => { + const TotalCell = ({ value }: Props) => { const [invalid, setInvalid] = useState(false); - useEffect(()=> { + useEffect(() => { const newInvalid = (value ?? 0) < 0; setInvalid(newInvalid); }, [value]); return ( - + $ {value} ); - } + }; return (
-
- +
+ Total: - +
-
); -} +}; const EditFooter = (props: EditFooterProps) => { return ( -
+
Total: test
); -} +}; interface ClaimInputGridProps { onClose?: () => void; @@ -144,30 +160,34 @@ const initialRows: GridRowsProp = [ date: new Date(), description: "Taxi to client office", cost: 169.5, - document: 'taxi_receipt.jpg', + document: "taxi_receipt.jpg", }, { id: 2, - date: dayjs().add(-14, 'days').toDate(), + date: dayjs().add(-14, "days").toDate(), description: "MTR fee to Kowloon Bay Office", cost: 15.5, - document: 'octopus_invoice.jpg', + document: "octopus_invoice.jpg", }, { id: 3, - date: dayjs().add(-44, 'days').toDate(), + date: dayjs().add(-44, "days").toDate(), description: "Starbucks", cost: 504, }, ]; const ClaimInputGrid: React.FC = ({ ...props }) => { - const [rows, setRows] = useState(initialRows); const [day, setDay] = useState(dayjs()); - const [rowModesModel, setRowModesModel] = React.useState({}); + const [rowModesModel, setRowModesModel] = React.useState( + {}, + ); - const handleRowEditStop: GridEventListener<'rowEditStop'> = (params, event) => { + const handleRowEditStop: GridEventListener<"rowEditStop"> = ( + params, + event, + ) => { if (params.reason === GridRowEditStopReasons.rowFocusOut) { event.defaultMuiPrevented = true; } @@ -178,7 +198,6 @@ const ClaimInputGrid: React.FC = ({ ...props }) => { }; const handleSaveClick = (id: GridRowId) => () => { - setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } }); }; @@ -211,21 +230,21 @@ const ClaimInputGrid: React.FC = ({ ...props }) => { const getCostTotal = () => { let sum = 0; rows.forEach((row) => { - sum += row['cost']??0; + sum += row["cost"] ?? 0; }); return sum; }; - const commonGridColConfig : any = { - type: 'number', + const commonGridColConfig: any = { + type: "number", // sortable: false, //width: 100, flex: 1, - align: 'left', - headerAlign: 'left', + align: "left", + headerAlign: "left", // headerClassName: 'header', editable: true, - renderEditCell: (value : any) => ( + renderEditCell: (value: any) => ( = ({ ...props }) => { const columns: GridColDef[] = [ { - field: 'actions', - type: 'actions', - headerName: 'Actions', + field: "actions", + type: "actions", + headerName: "Actions", width: 100, - cellClassName: 'actions', + cellClassName: "actions", getActions: ({ id }) => { const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; if (isInEditMode) { return [ } title="Save" label="Save" sx={{ - color: 'primary.main', + color: "primary.main", }} onClick={handleSaveClick(id)} />, } title="Cancel" label="Cancel" @@ -271,6 +292,7 @@ const ClaimInputGrid: React.FC = ({ ...props }) => { return [ } title="Edit" label="Edit" @@ -279,74 +301,80 @@ const ClaimInputGrid: React.FC = ({ ...props }) => { color="inherit" />, } onClick={handleDeleteClick(id)} - sx={{color:"red"}} + sx={{ color: "red" }} />, ]; }, }, { - field: 'date', - headerName: 'Invoice Date', + field: "date", + headerName: "Invoice Date", // width: 220, flex: 1, editable: true, - type: 'date', + type: "date", }, { - field: 'description', - headerName: 'Description', + field: "description", + headerName: "Description", // width: 220, flex: 2, editable: true, - type: 'string', + type: "string", }, { - field: 'cost', - headerName: 'Cost (HKD)', + field: "cost", + headerName: "Cost (HKD)", editable: true, - type: 'number', + type: "number", valueFormatter: (params) => { - return `$ ${params.value??0}`; + return `$ ${params.value ?? 0}`; }, }, { - field: 'document', - headerName: 'Supporting Document', - type: 'string', + field: "document", + headerName: "Supporting Document", + type: "string", editable: true, flex: 2, renderCell: (params) => { - return params.value? - ( + return params.value ? ( {params.value} - ) : - (No Documents) + ) : ( + No Documents + ); }, renderEditCell: (params) => { - return params.value? - ( + return params.value ? ( - - {params.value} - - - + + {params.value} + + ) : ( - - ) + ); }, }, ]; @@ -355,27 +383,27 @@ const ClaimInputGrid: React.FC = ({ ...props }) => { = ({ ...props }) => { disableRowSelectionOnClick={true} disableColumnMenu={true} hideFooterPagination={true} - slots={{ - // footer: EditFooter, - }} - slotProps={{ - // footer: { setDay, setRows, setRowModesModel }, - }} + slots={ + { + // footer: EditFooter, + } + } + slotProps={ + { + // footer: { setDay, setRows, setRowModesModel }, + } + } initialState={{ pagination: { paginationModel: { pageSize: 100 } }, }} /> - - ); -} +}; export default ClaimInputGrid; diff --git a/src/components/CustomCardGrid/CustomCardGrid.tsx b/src/components/CustomCardGrid/CustomCardGrid.tsx index de4ddd6..22454a2 100644 --- a/src/components/CustomCardGrid/CustomCardGrid.tsx +++ b/src/components/CustomCardGrid/CustomCardGrid.tsx @@ -1,11 +1,18 @@ -import * as React from 'react'; -import { Card, CardHeader, CardContent, SxProps, Theme, Grid } from '@mui/material'; -import { DataGrid, GridColDef } from '@mui/x-data-grid'; -import { darken, lighten, styled } from '@mui/material/styles'; -import { PROJECT_CARD_STYLE } from '@/theme/colorConst'; -import { useRef, useEffect, useState } from 'react'; -import Swal from 'sweetalert2'; -import styledcmp from 'styled-components'; +import * as React from "react"; +import { + Card, + CardHeader, + CardContent, + SxProps, + Theme, + Grid, +} from "@mui/material"; +import { DataGrid, GridColDef } from "@mui/x-data-grid"; +import { darken, lighten, styled } from "@mui/material/styles"; +import { PROJECT_CARD_STYLE } from "@/theme/colorConst"; +import { useRef, useEffect, useState } from "react"; +import Swal from "sweetalert2"; +import styledcmp from "styled-components"; const CardWrapper = styledcmp.div` /* Styles for the card when not hovered */ @@ -23,7 +30,7 @@ const CardWrapper = styledcmp.div` interface CustomCardGridProps { Title?: string; cardsPerRow?: number; - rows?: any[]; + rows?: any[]; columns?: any[]; items: any[]; columnWidth?: number; @@ -46,73 +53,124 @@ const CustomCardGrid: React.FC = ({ dataGridHeight, ...props }) => { - const getBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.7) : lighten(color, 0.7); + const getBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.7) : lighten(color, 0.7); - const getHoverBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.6) : lighten(color, 0.6); + const getHoverBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.6) : lighten(color, 0.6); - const getSelectedBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.5) : lighten(color, 0.5); + const getSelectedBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.5) : lighten(color, 0.5); - const getSelectedHoverBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.4) : lighten(color, 0.4); + const getSelectedHoverBackgroundColor = ( + color: string, + mode: "light" | "dark", + ) => (mode === "dark" ? darken(color, 0.4) : lighten(color, 0.4)); const StyledCard = styled(Card)(({ theme }) => ({ - '& .super-app-theme--Open': { - backgroundColor: getBackgroundColor(theme.palette.info.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.info.main, theme.palette.mode) + "& .super-app-theme--Open": { + backgroundColor: getBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.info.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.info.main, theme.palette.mode) - } - } }, - '& .super-app-theme--finish': { - backgroundColor: getBackgroundColor(theme.palette.success.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.success.main, theme.palette.mode) + "& .super-app-theme--finish": { + backgroundColor: getBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.success.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.success.main, theme.palette.mode) - } - } }, - '& .super-app-theme--danger': { - backgroundColor: getBackgroundColor(theme.palette.warning.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.warning.main, theme.palette.mode) + "& .super-app-theme--danger": { + backgroundColor: getBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.warning.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.warning.main, theme.palette.mode) - } - } }, - '& .super-app-theme--warning': { - backgroundColor: getBackgroundColor(theme.palette.error.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.error.main, theme.palette.mode) + "& .super-app-theme--warning": { + backgroundColor: getBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.error.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.error.main, theme.palette.mode) - } - } - } + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + }, + }, + }, })); const CardItem = (item: any) => { const cardItem = item.item as Record; - return props.cardStyle?? ( - // + return ( + props.cardStyle ?? ( + // {Object.keys(cardItem).map((key) => ( @@ -122,28 +180,36 @@ const CustomCardGrid: React.FC = ({ ))} - // + // + ) ); }; const containerRef = useRef(null!); const [cardMargin, setCardMargin] = useState(1.5); - + useEffect(() => { console.log(CardItem); const resizeHandler = () => { const containerWidth = containerRef.current.offsetWidth; const cardCount = items.length; - const rootSize = parseFloat(getComputedStyle(document.documentElement).fontSize); - setCardMargin((containerWidth - cardsPerRow * (rootSize * parseInt(PROJECT_CARD_STYLE.width.slice(0, -3),10))) /(2 * cardsPerRow)); + const rootSize = parseFloat( + getComputedStyle(document.documentElement).fontSize, + ); + setCardMargin( + (containerWidth - + cardsPerRow * + (rootSize * parseInt(PROJECT_CARD_STYLE.width.slice(0, -3), 10))) / + (2 * cardsPerRow), + ); // Set the cardMargin value using style={{margin: `${cardMargin}px`, ...PROJECT_CARD_STYLE}} }; - - window.addEventListener('resize', resizeHandler); - + + window.addEventListener("resize", resizeHandler); + resizeHandler(); // Initial calculation - + // Swal.fire({ // title: 'Error! ', // text: `Card Count is ${items.length}`, @@ -152,16 +218,19 @@ const CustomCardGrid: React.FC = ({ // }) return () => { - window.removeEventListener('resize', resizeHandler); + window.removeEventListener("resize", resizeHandler); }; }, [items]); return ( -
+
{/*

width is {containerRef.current == null? "idk":containerRef.current.offsetWidth}, margin is {cardMargin}

*/} {items.map((item, index) => (
- {props.cardStyle? props.cardStyle(item) : } + {props.cardStyle ? props.cardStyle(item) : }
))}
diff --git a/src/components/CustomDatagrid/CustomDatagrid.tsx b/src/components/CustomDatagrid/CustomDatagrid.tsx index 718c2ce..151e90d 100644 --- a/src/components/CustomDatagrid/CustomDatagrid.tsx +++ b/src/components/CustomDatagrid/CustomDatagrid.tsx @@ -1,13 +1,13 @@ "use client"; -import * as React from 'react'; -import { Card, CardHeader, CardContent, SxProps, Theme } from '@mui/material'; -import { DataGrid, GridColDef, GridRowSelectionModel} from '@mui/x-data-grid'; -import { darken, lighten, styled } from '@mui/material/styles'; -import { useState } from 'react' +import * as React from "react"; +import { Card, CardHeader, CardContent, SxProps, Theme } from "@mui/material"; +import { DataGrid, GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import { darken, lighten, styled } from "@mui/material/styles"; +import { useState } from "react"; interface CustomDatagridProps { Title?: string; - rows: any[]; + rows: any[]; columns: any[]; columnWidth?: number; Style?: boolean; @@ -15,7 +15,9 @@ interface CustomDatagridProps { dataGridHeight?: number; [key: string]: any; checkboxSelection?: boolean; - onRowSelectionModelChange?: (newSelectionModel: GridRowSelectionModel) => void; + onRowSelectionModelChange?: ( + newSelectionModel: GridRowSelectionModel, + ) => void; selectionModel?: any; } @@ -44,200 +46,262 @@ const CustomDatagrid: React.FC = ({ }); // Event handler to be called when the selection changes - const handleSelectionModelChange = (newSelectionModel: GridRowSelectionModel) => { + const handleSelectionModelChange = ( + newSelectionModel: GridRowSelectionModel, + ) => { // setSelectionModel(newSelectionModel); // To log selected row data, filter rows based on the new selection model const selectedRowsData = rows.filter((row) => - newSelectionModel.includes(row.id) + newSelectionModel.includes(row.id), ); console.log(selectedRowsData); }; - const getBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.7) : lighten(color, 0.7); + const getBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.7) : lighten(color, 0.7); - const getHoverBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.6) : lighten(color, 0.6); + const getHoverBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.6) : lighten(color, 0.6); - const getSelectedBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.5) : lighten(color, 0.5); + const getSelectedBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.5) : lighten(color, 0.5); - const getSelectedHoverBackgroundColor = (color: string, mode: 'light' | 'dark') => - mode === 'dark' ? darken(color, 0.4) : lighten(color, 0.4); + const getSelectedHoverBackgroundColor = ( + color: string, + mode: "light" | "dark", + ) => (mode === "dark" ? darken(color, 0.4) : lighten(color, 0.4)); const StyledDataGrid = styled(DataGrid)(({ theme }) => ({ - '& .super-app-theme--Open': { - backgroundColor: getBackgroundColor(theme.palette.info.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.info.main, theme.palette.mode) + "& .super-app-theme--Open": { + backgroundColor: getBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.info.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.info.main, theme.palette.mode) - } - } }, - '& .super-app-theme--finish': { - backgroundColor: getBackgroundColor(theme.palette.success.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.success.main, theme.palette.mode) + "& .super-app-theme--finish": { + backgroundColor: getBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.success.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.success.main, theme.palette.mode) - } - } }, - '& .super-app-theme--danger': { - backgroundColor: getBackgroundColor(theme.palette.warning.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.warning.main, theme.palette.mode) + "& .super-app-theme--danger": { + backgroundColor: getBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.warning.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.warning.main, theme.palette.mode) - } - } }, - '& .super-app-theme--warning': { - backgroundColor: getBackgroundColor(theme.palette.error.main, theme.palette.mode), - '&:hover': { - backgroundColor: getHoverBackgroundColor(theme.palette.error.main, theme.palette.mode) + "& .super-app-theme--warning": { + backgroundColor: getBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), }, - '&.Mui-selected': { - backgroundColor: getSelectedBackgroundColor(theme.palette.error.main, theme.palette.mode), - '&:hover': { - backgroundColor: getSelectedHoverBackgroundColor(theme.palette.error.main, theme.palette.mode) - } - } - } + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + }, + }, + }, })); return ( -
+
{Title ? ( - - {Title && } - - {Style ? ( - - ) : ( - - )} + + {Title && } + + {Style ? ( + + ) : ( + + )} - ) - : (Style ? ( - - ) : ( - - ))} + + ) : Style ? ( + + ) : ( + + )}
); }; diff --git a/src/components/CustomModal/CustomModal.tsx b/src/components/CustomModal/CustomModal.tsx index 840c22a..1004213 100644 --- a/src/components/CustomModal/CustomModal.tsx +++ b/src/components/CustomModal/CustomModal.tsx @@ -1,11 +1,21 @@ -import * as React from 'react'; -import { Card, CardHeader, CardContent, SxProps, Theme, Grid, Modal, Typography, Button } from '@mui/material'; -import { DataGrid, GridColDef } from '@mui/x-data-grid'; -import { darken, lighten, styled } from '@mui/material/styles'; -import { PROJECT_MODAL_STYLE } from '@/theme/colorConst'; -import { useRef, useEffect, useState } from 'react'; -import Swal from 'sweetalert2'; -import styledcmp from 'styled-components'; +import * as React from "react"; +import { + Card, + CardHeader, + CardContent, + SxProps, + Theme, + Grid, + Modal, + Typography, + Button, +} from "@mui/material"; +import { DataGrid, GridColDef } from "@mui/x-data-grid"; +import { darken, lighten, styled } from "@mui/material/styles"; +import { PROJECT_MODAL_STYLE } from "@/theme/colorConst"; +import { useRef, useEffect, useState } from "react"; +import Swal from "sweetalert2"; +import styledcmp from "styled-components"; const CardWrapper = styledcmp.div` /* Styles for the card when not hovered */ @@ -28,35 +38,44 @@ interface CustomModalProps { } const CustomModal: React.FC = ({ ...props }) => { - const ModalContent = () => { return ( // -
- - {props.title??"Modal Title"} - - - Modal Content - -
- - -
+
+ + {props.title ?? "Modal Title"} + + + Modal Content + +
+ +
+
// ); }; return ( - {props.modalStyle? : } + {props.modalStyle ? : } ); }; - -export default CustomModal; \ No newline at end of file + +export default CustomModal; diff --git a/src/components/CustomSearchForm/CustomSearchForm.tsx b/src/components/CustomSearchForm/CustomSearchForm.tsx index 8f15d26..c005887 100644 --- a/src/components/CustomSearchForm/CustomSearchForm.tsx +++ b/src/components/CustomSearchForm/CustomSearchForm.tsx @@ -1,5 +1,5 @@ "use client"; -import React, { useState, FC } from 'react'; +import React, { useState, FC } from "react"; import { Stack, Typography, @@ -15,16 +15,16 @@ import { InputLabel, Select, MenuItem, - ThemeProvider -} from '@mui/material'; -import { useForm, Controller } from 'react-hook-form'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; -import dayjs from 'dayjs'; -import SearchIcon from '@mui/icons-material/Search'; -import RefreshIcon from '@mui/icons-material/Refresh'; -import { DemoItem } from '@mui/x-date-pickers/internals/demo'; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; + ThemeProvider, +} from "@mui/material"; +import { useForm, Controller } from "react-hook-form"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import dayjs from "dayjs"; +import SearchIcon from "@mui/icons-material/Search"; +import RefreshIcon from "@mui/icons-material/Refresh"; +import { DemoItem } from "@mui/x-date-pickers/internals/demo"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; interface Field { id: any; @@ -50,29 +50,38 @@ interface SearchFormProps { sx?: any; } -const FormComponent: FC = ({ fields, onSubmit, resetForm, sx }) => { +const FormComponent: FC = ({ + fields, + onSubmit, + resetForm, + sx, +}) => { const { reset, register, handleSubmit, control } = useForm(); const [fromDate, setFromDate] = useState(null); - const [dayRangeFromDate, setDayRangeFromDate] = useState(null); - const [dayRangeToDate, setDayRangeToDate] = useState(null); + const [dayRangeFromDate, setDayRangeFromDate] = useState( + null, + ); + const [dayRangeToDate, setDayRangeToDate] = useState( + null, + ); const [value, setValue] = useState<{ [key: string]: any }>({}); const [checkbox1, setCheckbox1] = useState(false); const handleFormSubmit = (data: any) => { if (fromDate != null || fromDate != undefined) { - data.fromDate = dayjs(fromDate).format('YYYY-MM-DD'); + data.fromDate = dayjs(fromDate).format("YYYY-MM-DD"); } if (value !== null) { - data.dropdownCombo = value + data.dropdownCombo = value; } if (value !== null) { data.checkbox = checkbox1; } if (dayRangeFromDate != null || dayRangeFromDate != undefined) { - data.dayRangeFromDate = dayjs(dayRangeFromDate).format('YYYY-MM-DD'); + data.dayRangeFromDate = dayjs(dayRangeFromDate).format("YYYY-MM-DD"); } if (dayRangeToDate != null || dayRangeToDate != undefined) { - data.dayRangeToDate = dayjs(dayRangeToDate).format('YYYY-MM-DD'); + data.dayRangeToDate = dayjs(dayRangeToDate).format("YYYY-MM-DD"); } onSubmit(data); }; @@ -82,8 +91,8 @@ const FormComponent: FC = ({ fields, onSubmit, resetForm, sx resetForm(); setFromDate(null); fields.forEach((field) => { - if (typeof(field.setValue) === "function") { - field.setValue(typeof (field.value) === "boolean" ? false : null); + if (typeof field.setValue === "function") { + field.setValue(typeof field.value === "boolean" ? false : null); } else if (Array.isArray(field.setValue)) { field.setValue.forEach((setFunc) => { setFunc(null); @@ -96,11 +105,21 @@ const FormComponent: FC = ({ fields, onSubmit, resetForm, sx
{fields.map((field) => { - if (field.type === 'dropdown') { + if (field.type === "dropdown") { return ( - + - {field.label} + + {field.label} + = ({ fields, onSubmit, resetForm, sx }} > {field.options?.map((option) => ( - - {option.id !== undefined ? option.label : JSON.stringify(option)} + {option.id !== undefined + ? option.label + : JSON.stringify(option)} ))} @@ -128,19 +149,27 @@ const FormComponent: FC = ({ fields, onSubmit, resetForm, sx ); - } else if (field.type === 'date') { + } else if (field.type === "date") { return ( - + { setFromDate(newValue); }} @@ -149,16 +178,24 @@ const FormComponent: FC = ({ fields, onSubmit, resetForm, sx ); - } else if (field.type === 'checkbox') { + } else if (field.type === "checkbox") { return ( - + { - if (typeof field.setValue === 'function') { + if (typeof field.setValue === "function") { field.setValue(event.target.checked); setCheckbox1(event.target.checked); } @@ -166,102 +203,176 @@ const FormComponent: FC = ({ fields, onSubmit, resetForm, sx color="primary" /> } - label={{field.label}} + label={ + + {field.label} + + } /> - ) - } else if (field.type === 'dateRange') { + ); + } else if (field.type === "dateRange") { return ( - + - setDayRangeFromDate(newValue)} - /> + setDayRangeFromDate(newValue)} + /> - - To - + + To + - setDayRangeToDate(newValue)} - /> - + setDayRangeToDate(newValue)} + /> - ) + ); } return ( - + ); })} - + - - - + ); }; -const CustomSearchForm: FC = ({ applySearch, fields, title, sx }) => { +const CustomSearchForm: FC = ({ + applySearch, + fields, + title, + sx, +}) => { const Title = title || "Searching Criteria"; const handleSubmit = (data: any) => { if (applySearch) { applySearch(data); } else { - console.log('applySearch function is null'); + console.log("applySearch function is null"); } }; const handleFormReset = () => { - console.log('Form Reset'); + console.log("Form Reset"); }; return ( - - - - + + + + ); }; diff --git a/src/components/DashboardPage/DashboardPage.tsx b/src/components/DashboardPage/DashboardPage.tsx index 4307976..d3d70c7 100644 --- a/src/components/DashboardPage/DashboardPage.tsx +++ b/src/components/DashboardPage/DashboardPage.tsx @@ -1,12 +1,12 @@ -"use client" +"use client"; import Grid from "@mui/material/Grid"; import Paper from "@mui/material/Paper"; import { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; import PageTitle from "../PageTitle/PageTitle"; import DashboardTabButton from "./DashboardTabButton"; -import { ThemeProvider } from '@mui/material/styles'; -import theme from '../../theme'; +import { ThemeProvider } from "@mui/material/styles"; +import theme from "../../theme"; import Tabs, { TabsProps } from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; import React, { useCallback, useState } from "react"; @@ -38,7 +38,7 @@ const DashboardPage: React.FC = () => { {tabIndex === 2 && } - {/* + {/* diff --git a/src/components/DashboardPage/DashboardTabButton.tsx b/src/components/DashboardPage/DashboardTabButton.tsx index dda77c6..1f95098 100644 --- a/src/components/DashboardPage/DashboardTabButton.tsx +++ b/src/components/DashboardPage/DashboardTabButton.tsx @@ -1,6 +1,6 @@ "use client"; import Grid from "@mui/material/Grid"; -import { useState,useCallback} from 'react' +import { useState, useCallback } from "react"; import Paper from "@mui/material/Paper"; import { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; @@ -8,22 +8,22 @@ import PageTitle from "../PageTitle/PageTitle"; import ProgressByClient from "./ProgressByClient"; import Tabs, { TabsProps } from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; -import '../../app/global.css'; +import "../../app/global.css"; const DashboardTabButton: React.FC = () => { - const [activeTab, setActiveTab] = useState('financialSummary'); + const [activeTab, setActiveTab] = useState("financialSummary"); const { t } = useTranslation("dashboard"); const renderContent = () => { switch (activeTab) { - case 'financialSummary': + case "financialSummary": return
Project Financial Summary
; - case 'cashFlow': + case "cashFlow": return
Project Cash Flow
; - case 'progressByClient': - return ; - case 'resourceUtilization': + case "progressByClient": + return ; + case "resourceUtilization": return
Project Resource Utilization
; - case 'staffUtilization': + case "staffUtilization": return
Staff Utilization
; default: return
Project Financial Summary
; @@ -37,40 +37,40 @@ const DashboardTabButton: React.FC = () => { [], ); return ( - // - //
- // {activeTab !== 'financialSummary' ? - // : - // - // } - // {activeTab !== 'cashFlow' ? - // : - // - // } - // {activeTab !== 'progressByClient' ? - // : - // - // } - // {activeTab !== 'resourceUtilization' ? - // : - // - // } - // {activeTab !== 'staffUtilization' ? - // : - // - // } - //
- //
- // {renderContent()} - //
- //
- - - - - - - + // + //
+ // {activeTab !== 'financialSummary' ? + // : + // + // } + // {activeTab !== 'cashFlow' ? + // : + // + // } + // {activeTab !== 'progressByClient' ? + // : + // + // } + // {activeTab !== 'resourceUtilization' ? + // : + // + // } + // {activeTab !== 'staffUtilization' ? + // : + // + // } + //
+ //
+ // {renderContent()} + //
+ //
+ + + + + + + ); }; diff --git a/src/components/DashboardPage/ProgressByClient.tsx b/src/components/DashboardPage/ProgressByClient.tsx index b69fede..6475c03 100644 --- a/src/components/DashboardPage/ProgressByClient.tsx +++ b/src/components/DashboardPage/ProgressByClient.tsx @@ -1,76 +1,160 @@ - import * as React from "react"; import Grid from "@mui/material/Grid"; -import { useState,useEffect, useMemo } from 'react' +import { useState, useEffect, useMemo } from "react"; import Paper from "@mui/material/Paper"; import { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; -import {Card,CardHeader} from '@mui/material'; +import { Card, CardHeader } from "@mui/material"; import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; -import CustomDatagrid from '../CustomDatagrid/CustomDatagrid'; -import ReactApexChart from 'react-apexcharts'; -import { ApexOptions } from 'apexcharts'; -import { GridColDef, GridRowSelectionModel} from '@mui/x-data-grid'; -import ReportProblemIcon from '@mui/icons-material/ReportProblem'; -import dynamic from 'next/dynamic'; -import '../../app/global.css'; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; import { AnyARecord } from "dns"; import SearchBox, { Criterion } from "../SearchBox"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; import { Suspense } from "react"; const ProgressByClient: React.FC = () => { - const [activeTab, setActiveTab] = useState('financialSummary'); - const [SearchCriteria, setSearchCriteria] = React.useState({}) + const [activeTab, setActiveTab] = useState("financialSummary"); + const [SearchCriteria, setSearchCriteria] = React.useState({}); const { t } = useTranslation("dashboard"); - const [clientCode, setClientCode] = useState(''); - const [clientName, setClientName] = useState(''); - const [subsidiaryClientCode, setSubsidiaryClientCode] = useState(''); - const [subsidiaryClientName, setSubsidiaryClientName] = useState(''); - const [projectArray, setProjectArray] : any[] = useState([]); - const [percentageArray, setPercentageArray] : any[] = useState([]); - const [selectionModel, setSelectionModel] : any[] = React.useState([]); - const [dropdownDemo, setDropdownDemo] = useState(''); + const [clientCode, setClientCode] = useState(""); + const [clientName, setClientName] = useState(""); + const [subsidiaryClientCode, setSubsidiaryClientCode] = useState(""); + const [subsidiaryClientName, setSubsidiaryClientName] = useState(""); + const [projectArray, setProjectArray]: any[] = useState([]); + const [percentageArray, setPercentageArray]: any[] = useState([]); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const [dropdownDemo, setDropdownDemo] = useState(""); const [dateDemo, setDateDemo] = useState(null); const [checkboxDemo, setCheckboxDemo] = useState(false); const [receiptFromDate, setReceiptFromDate] = useState(null); const [receiptToDate, setReceiptToDate] = useState(null); const [selectedRows, setSelectedRows] = useState([]); - const rows = [{id: 1,clientCode:"CUST-001",clientName:"Client A", clientSubsidiaryCode:"N/A", clientSubsidiaryName:"N/A", noOfProjects:"5"}, - {id: 2,clientCode:"CUST-001",clientName:"Client A", clientSubsidiaryCode:"SUBS-001", clientSubsidiaryName:"Subsidiary A", noOfProjects:"5"}, - {id: 3,clientCode:"CUST-001",clientName:"Client A", clientSubsidiaryCode:"SUBS-002", clientSubsidiaryName:"Subsidiary B", noOfProjects:"3"}, - {id: 4,clientCode:"CUST-001",clientName:"Client A", clientSubsidiaryCode:"SUBS-003", clientSubsidiaryName:"Subsidiary C", noOfProjects:"1"} - ] - const rows2 = [{id: 1,project:"Consultancy Project 123",team:"XXX", teamLeader:"XXX", currentStage:"Contract Documentation", budgetedManhour:"200.00",spentManhour:"120.00",remainedManhour:"80.00",comingPaymentMilestone:"31/03/2024",alert:false}, - {id: 2,project:"Consultancy Project 456",team:"XXX", teamLeader:"XXX", currentStage:"Report Preparation", budgetedManhour:"400.00",spentManhour:"200.00",remainedManhour:"200.00",comingPaymentMilestone:"20/02/2024",alert:false}, - {id: 3,project:"Construction Project A",team:"YYY", teamLeader:"YYY", currentStage:"Construction", budgetedManhour:"187.50",spentManhour:"200.00",remainedManhour:"12.50",comingPaymentMilestone:"13/12/2023",alert:true}, - {id: 4,project:"Construction Project B",team:"XXX", teamLeader:"XXX", currentStage:"Post Construction", budgetedManhour:"100.00",spentManhour:"40.00",remainedManhour:"60.00",comingPaymentMilestone:"05/01/2024",alert:false}, - {id: 5,project:"Construction Project C",team:"YYY", teamLeader:"YYY", currentStage:"Construction", budgetedManhour:"300.00",spentManhour:"150.00",remainedManhour:"150.00",comingPaymentMilestone:"31/03/2024",alert:false}, - ] + const rows = [ + { + id: 1, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "N/A", + clientSubsidiaryName: "N/A", + noOfProjects: "5", + }, + { + id: 2, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-001", + clientSubsidiaryName: "Subsidiary A", + noOfProjects: "5", + }, + { + id: 3, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-002", + clientSubsidiaryName: "Subsidiary B", + noOfProjects: "3", + }, + { + id: 4, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-003", + clientSubsidiaryName: "Subsidiary C", + noOfProjects: "1", + }, + ]; + const rows2 = [ + { + id: 1, + project: "Consultancy Project 123", + team: "XXX", + teamLeader: "XXX", + currentStage: "Contract Documentation", + budgetedManhour: "200.00", + spentManhour: "120.00", + remainedManhour: "80.00", + comingPaymentMilestone: "31/03/2024", + alert: false, + }, + { + id: 2, + project: "Consultancy Project 456", + team: "XXX", + teamLeader: "XXX", + currentStage: "Report Preparation", + budgetedManhour: "400.00", + spentManhour: "200.00", + remainedManhour: "200.00", + comingPaymentMilestone: "20/02/2024", + alert: false, + }, + { + id: 3, + project: "Construction Project A", + team: "YYY", + teamLeader: "YYY", + currentStage: "Construction", + budgetedManhour: "187.50", + spentManhour: "200.00", + remainedManhour: "12.50", + comingPaymentMilestone: "13/12/2023", + alert: true, + }, + { + id: 4, + project: "Construction Project B", + team: "XXX", + teamLeader: "XXX", + currentStage: "Post Construction", + budgetedManhour: "100.00", + spentManhour: "40.00", + remainedManhour: "60.00", + comingPaymentMilestone: "05/01/2024", + alert: false, + }, + { + id: 5, + project: "Construction Project C", + team: "YYY", + teamLeader: "YYY", + currentStage: "Construction", + budgetedManhour: "300.00", + spentManhour: "150.00", + remainedManhour: "150.00", + comingPaymentMilestone: "31/03/2024", + alert: false, + }, + ]; const columns = [ - { - id: 'clientCode', - field: 'clientCode', - headerName: "Client Code", - flex: 1, + { + id: "clientCode", + field: "clientCode", + headerName: "Client Code", + flex: 1, }, { - id: 'clientName', - field: 'clientName', - headerName: "Client Name", - flex: 1, + id: "clientName", + field: "clientName", + headerName: "Client Name", + flex: 1, }, { - id: 'clientSubsidiaryCode', - field: 'clientSubsidiaryCode', + id: "clientSubsidiaryCode", + field: "clientSubsidiaryCode", headerName: "Client Subsidiary Code", flex: 1, }, { - id: 'noOfProjects', - field: 'noOfProjects', + id: "noOfProjects", + field: "noOfProjects", headerName: "No. of Projects", flex: 1, }, @@ -78,99 +162,119 @@ const ProgressByClient: React.FC = () => { const columns2 = [ { - id: 'project', - field: 'project', + id: "project", + field: "project", headerName: "Project", flex: 1, - }, - { - id: 'team', - field: 'team', + }, + { + id: "team", + field: "team", headerName: "Team", flex: 1, - }, - { - id: 'teamLeader', - field: 'teamLeader', - headerName: "Team Leader", - flex: 1, - }, - { - id: 'currentStage', - field: 'currentStage', - headerName: "Current Stage", - flex: 1, - }, - { - id: 'budgetedManhour', - field: 'budgetedManhour', - headerName: "Budgeted Manhour", - flex: 1, - }, - { - id: 'spentManhour', - field: 'spentManhour', - headerName: "Spent Manhour", - renderCell: (params:any) => { - if (params.row.budgetedManhour - params.row.spentManhour <= 0) { - return( - {params.row.spentManhour} - ) - } else { - return ( - {params.row.spentManhour} - ) - } }, - flex: 1, - }, - { - id: 'remainedManhour', - field: 'remainedManhour', - headerName: "Remained Manhour", - renderCell: (params:any) => { - if (params.row.budgetedManhour - params.row.spentManhour <= 0) { - return( - ({params.row.remainedManhour}) - ) - } else { - return ( - {params.row.remainedManhour} - ) - } + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, }, - flex: 1, - }, - { - id: 'comingPaymentMilestone', - field: 'comingPaymentMilestone', - headerName: "Coming Payment Milestone", - flex: 1, - }, - { - id: 'alert', - field: 'alert', - headerName: "Alert", - renderCell: (params:any) => { - if (params.row.alert === true) { - return ( - - ) - } else { - return ( - - ) - } + { + id: "currentStage", + field: "currentStage", + headerName: "Current Stage", + flex: 1, + }, + { + id: "budgetedManhour", + field: "budgetedManhour", + headerName: "Budgeted Manhour", + flex: 1, + }, + { + id: "spentManhour", + field: "spentManhour", + headerName: "Spent Manhour", + renderCell: (params: any) => { + if (params.row.budgetedManhour - params.row.spentManhour <= 0) { + return ( + {params.row.spentManhour} + ); + } else { + return {params.row.spentManhour}; + } + }, + flex: 1, + }, + { + id: "remainedManhour", + field: "remainedManhour", + headerName: "Remained Manhour", + renderCell: (params: any) => { + if (params.row.budgetedManhour - params.row.spentManhour <= 0) { + return ( + ({params.row.remainedManhour}) + ); + } else { + return {params.row.remainedManhour}; + } + }, + flex: 1, + }, + { + id: "comingPaymentMilestone", + field: "comingPaymentMilestone", + headerName: "Coming Payment Milestone", + flex: 1, + }, + { + id: "alert", + field: "alert", + headerName: "Alert", + renderCell: (params: any) => { + if (params.row.alert === true) { + return ( + + + + ); + } else { + return ; + } + }, + flex: 1, }, - flex: 1, - }, -]; + ]; const InputFields = [ - { id: "clientCode", label: "Client Code", type: 'text', value: clientCode, setValue: setClientCode }, - { id: "clientName", label: "Client Name", type: 'text', value: clientName, setValue: setClientName }, - { id: "subsidiaryClientCode", label: "Subsidiary Client Code", type:'text', value:subsidiaryClientCode, setValue: setSubsidiaryClientCode}, - { id: "subsidiaryClientName", label: "Subsidiary Client Name", type:'text', value:subsidiaryClientName, setValue: setSubsidiaryClientName}, + { + id: "clientCode", + label: "Client Code", + type: "text", + value: clientCode, + setValue: setClientCode, + }, + { + id: "clientName", + label: "Client Name", + type: "text", + value: clientName, + setValue: setClientName, + }, + { + id: "subsidiaryClientCode", + label: "Subsidiary Client Code", + type: "text", + value: subsidiaryClientCode, + setValue: setSubsidiaryClientCode, + }, + { + id: "subsidiaryClientName", + label: "Subsidiary Client Name", + type: "text", + value: subsidiaryClientName, + setValue: setSubsidiaryClientName, + }, // { id: 'dropdownDemo', label: "dropdownDemo", type: 'dropdown', options: [{id:"1", label:"1"}], value: dropdownDemo, setValue: setDropdownDemo }, // { id: 'dateDemo', label:'dateDemo', type: 'date', value: dateDemo, setValue: setDateDemo }, // { id: 'checkboxDemo', label:'checkboxDemo', type: 'checkbox', value: checkboxDemo, setValue: setCheckboxDemo }, @@ -178,54 +282,66 @@ const ProgressByClient: React.FC = () => { // setValue: [setReceiptFromDate, setReceiptToDate],type: 'dateRange' }, ]; - const stageDeadline = ["31/03/2024","20/02/2024","01/12/2023","05/01/2024","31/03/2023"] + const stageDeadline = [ + "31/03/2024", + "20/02/2024", + "01/12/2023", + "05/01/2024", + "31/03/2023", + ]; - const series2: ApexAxisChartSeries | ApexNonAxisChartSeries = [{ - data: [17.1, 28.6, 5.7, 48.6], - }]; + const series2: ApexAxisChartSeries | ApexNonAxisChartSeries = [ + { + data: [17.1, 28.6, 5.7, 48.6], + }, + ]; - const series: ApexAxisChartSeries | ApexNonAxisChartSeries = [{ - name: 'Current Stage Completion Percentage', - data: [80, 55, 40, 65, 70], - }]; - - const options2 : ApexOptions = { + const series: ApexAxisChartSeries | ApexNonAxisChartSeries = [ + { + name: "Current Stage Completion Percentage", + data: [80, 55, 40, 65, 70], + }, + ]; + + const options2: ApexOptions = { chart: { - type: 'donut', + type: "donut", }, plotOptions: { pie: { - donut:{ - labels:{ - show:false, - } - } + donut: { + labels: { + show: false, + }, + }, }, }, labels: [projectArray], legend: { show: false, }, - responsive: [{ - breakpoint: 480, - options: { - chart: { - width: 200 + responsive: [ + { + breakpoint: 480, + options: { + chart: { + width: 200, + }, + legend: { + position: "bottom", + show: false, + }, }, - legend: { - position: 'bottom', - show:false - } - } - }] - } - + }, + ], + }; + const options: ApexOptions = { chart: { - type: 'bar', - height: 350 + type: "bar", + height: 350, }, - colors: ['#FF4560', '#00E396', '#008FFB', '#775DD0', '#FEB019'], + colors: ["#FF4560", "#00E396", "#008FFB", "#775DD0", "#FEB019"], plotOptions: { bar: { horizontal: true, @@ -233,91 +349,93 @@ const ProgressByClient: React.FC = () => { }, }, dataLabels: { - enabled: false + enabled: false, }, xaxis: { categories: [ - 'Consultancy Project 123', - 'Consultancy Project 456', - 'Construction Project A', - 'Construction Project B', - 'Construction Project C', + "Consultancy Project 123", + "Consultancy Project 456", + "Construction Project A", + "Construction Project B", + "Construction Project C", ], }, yaxis: { title: { - text: 'Projects' + text: "Projects", }, labels: { - maxWidth: 200, + maxWidth: 200, style: { - cssClass: 'apexcharts-yaxis-label', + cssClass: "apexcharts-yaxis-label", }, }, }, title: { - text: 'Current Stage Completion Percentage', - align: 'center' + text: "Current Stage Completion Percentage", + align: "center", }, grid: { - borderColor: '#f1f1f1', + borderColor: "#f1f1f1", }, - annotations: { - } + annotations: {}, }; - + const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { const selectedRowsData = rows2.filter((row) => - newSelectionModel.includes(row.id) + newSelectionModel.includes(row.id), ); - console.log(selectedRowsData) - const projectArray:any[] = [] - let otherPercentage = 100 - let totalBudgetManhour = 0 - const percentageArray = [] + console.log(selectedRowsData); + const projectArray: any[] = []; + let otherPercentage = 100; + let totalBudgetManhour = 0; + const percentageArray = []; for (let i = 0; i <= selectedRowsData.length; i++) { if (i === selectedRowsData.length) { - projectArray.push("Other") + projectArray.push("Other"); } else { - projectArray.push(selectedRowsData[i].project) - totalBudgetManhour += Number(selectedRowsData[i].budgetedManhour) + projectArray.push(selectedRowsData[i].project); + totalBudgetManhour += Number(selectedRowsData[i].budgetedManhour); } } for (let i = 0; i <= selectedRowsData.length; i++) { if (i === selectedRowsData.length) { - percentageArray.push(otherPercentage) + percentageArray.push(otherPercentage); } else { - let percentage = ((Number(selectedRowsData[i].spentManhour) / totalBudgetManhour) * 100).toFixed(1) - percentageArray.push(Number(percentage)) - otherPercentage -= Number(percentage) + const percentage = ( + (Number(selectedRowsData[i].spentManhour) / totalBudgetManhour) * + 100 + ).toFixed(1); + percentageArray.push(Number(percentage)); + otherPercentage -= Number(percentage); } } - setSelectionModel(newSelectionModel) - setProjectArray(projectArray) - setPercentageArray(percentageArray) + setSelectionModel(newSelectionModel); + setProjectArray(projectArray); + setPercentageArray(percentageArray); }; const applySearch = (data: any) => { - console.log(data) - setSearchCriteria(data) - } + console.log(data); + setSearchCriteria(data); + }; return ( - - {/* */} - {/* */} -
- - - -
- -
- {/*
+ + {/* */} + {/* */} +
+ + + +
+ +
+ {/*

Stage Deadline

{stageDeadline.map((date, index) => { const marginTop = index === 0 ? 25 : 20; @@ -326,26 +444,49 @@ const ProgressByClient: React.FC = () => { ); })}
*/} - -
- -
-
-
-
-
- - - - - - + +
+
- + + +
+
+ + + + + + +
+
); }; diff --git a/src/components/EnterTimesheet/EnterTimesheetModal.tsx b/src/components/EnterTimesheet/EnterTimesheetModal.tsx index 87d9529..841881a 100644 --- a/src/components/EnterTimesheet/EnterTimesheetModal.tsx +++ b/src/components/EnterTimesheet/EnterTimesheetModal.tsx @@ -8,14 +8,14 @@ import PageTitle from "../PageTitle/PageTitle"; import { Suspense } from "react"; import Button from "@mui/material/Button"; import Stack from "@mui/material/Stack"; -import { Add } from '@mui/icons-material'; +import { Add } from "@mui/icons-material"; import Link from "next/link"; -import { t } from 'i18next'; +import { t } from "i18next"; import { Card, Modal, Typography } from "@mui/material"; import CustomModal from "../CustomModal/CustomModal"; import { PROJECT_MODAL_STYLE } from "@/theme/colorConst"; import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; -import { DataGrid } from '@mui/x-data-grid'; +import { DataGrid } from "@mui/x-data-grid"; import TimesheetInputGrid from "./TimesheetInputGrid"; interface EnterTimesheetModalProps { @@ -24,55 +24,75 @@ interface EnterTimesheetModalProps { modalStyle?: any; } -const EnterTimesheetModal: React.FC = ({ ...props }) => { +const EnterTimesheetModal: React.FC = ({ + ...props +}) => { const [lockConfirm, setLockConfirm] = useState(false); const columns = [ { - id: 'projectCode', - field: 'projectCode', + id: "projectCode", + field: "projectCode", headerName: "Project Code and Name", flex: 1, }, { - id: 'task', - field: 'task', - headerName: "Task", - flex: 1, + id: "task", + field: "task", + headerName: "Task", + flex: 1, }, ]; - const rows = [{ - id: 1, projectCode: "M1001", task: "1.2" + const rows = [ + { + id: 1, + projectCode: "M1001", + task: "1.2", }, { - id: 2, projectCode: "M1301", task: "1.1" - }]; + id: 2, + projectCode: "M1301", + task: "1.1", + }, + ]; return ( -
- {/* +
+ {/*
Timesheet Input
*/} - - {/* */} - + + {/* */} + -
- - -
+
+ +
+
); }; diff --git a/src/components/EnterTimesheet/TimesheetInputGrid.tsx b/src/components/EnterTimesheet/TimesheetInputGrid.tsx index f772fa2..bc64c50 100644 --- a/src/components/EnterTimesheet/TimesheetInputGrid.tsx +++ b/src/components/EnterTimesheet/TimesheetInputGrid.tsx @@ -8,20 +8,27 @@ import { Suspense } from "react"; import Button from "@mui/material/Button"; import Stack from "@mui/material/Stack"; import Link from "next/link"; -import { t } from 'i18next'; -import { Box, Container, Modal, Select, SelectChangeEvent, Typography } from "@mui/material"; -import { Close } from '@mui/icons-material'; -import AddIcon from '@mui/icons-material/Add'; -import EditIcon from '@mui/icons-material/Edit'; -import DeleteIcon from '@mui/icons-material/DeleteOutlined'; -import SaveIcon from '@mui/icons-material/Save'; -import CancelIcon from '@mui/icons-material/Close'; -import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; -import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import { t } from "i18next"; +import { + Box, + Container, + Modal, + Select, + SelectChangeEvent, + Typography, +} from "@mui/material"; +import { Close } from "@mui/icons-material"; +import AddIcon from "@mui/icons-material/Add"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/DeleteOutlined"; +import SaveIcon from "@mui/icons-material/Save"; +import CancelIcon from "@mui/icons-material/Close"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import Swal from "sweetalert2"; import { msg } from "../Swal/CustomAlerts"; import React from "react"; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; import { GridRowsProp, GridRowModesModel, @@ -37,17 +44,17 @@ import { GridRowEditStopReasons, GridEditInputCell, GridValueSetterParams, -} from '@mui/x-data-grid'; +} from "@mui/x-data-grid"; import { LocalizationProvider } from "@mui/x-date-pickers"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import dayjs from "dayjs"; import { Props } from "react-intl/src/components/relative"; -const weekdays = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']; +const weekdays = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]; interface BottomBarProps { getHoursTotal: (column: string) => number; - setLockConfirm: (newLock: (oldLock: Boolean) => Boolean) => void; + setLockConfirm: (newLock: (oldLock: boolean) => boolean) => void; setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; setRowModesModel: ( newModel: (oldModel: GridRowModesModel) => GridRowModesModel, @@ -76,13 +83,16 @@ const EditToolbar = (props: EditToolbarProps) => { const handleClickLeft = () => { if (selectedDate) { - const newDate = selectedDate.add(-7, 'day'); + const newDate = selectedDate.add(-7, "day"); setSelectedDate(newDate); } }; const handleClickRight = () => { if (selectedDate) { - const newDate = selectedDate.add(7, 'day') > dayjs()? dayjs(): selectedDate.add(7, 'day'); + const newDate = + selectedDate.add(7, "day") > dayjs() + ? dayjs() + : selectedDate.add(7, "day"); setSelectedDate(newDate); } }; @@ -98,24 +108,40 @@ const EditToolbar = (props: EditToolbarProps) => { return ( -
- - Timesheet Input - - -
); -} +}; const BottomBar = (props: BottomBarProps) => { const { setRows, setRowModesModel, getHoursTotal, setLockConfirm } = props; @@ -126,75 +152,84 @@ const BottomBar = (props: BottomBarProps) => { const handleAddClick = () => { const id = newId; setNewId(newId - 1); - setRows((oldRows) => [...oldRows, { id, projectCode: '', task: '', isNew: true }]); + setRows((oldRows) => [ + ...oldRows, + { id, projectCode: "", task: "", isNew: true }, + ]); setRowModesModel((oldModel) => ({ ...oldModel, - [id]: { mode: GridRowModes.Edit, fieldToFocus: 'projectCode' }, + [id]: { mode: GridRowModes.Edit, fieldToFocus: "projectCode" }, })); }; const totalColDef = { - flex:1, + flex: 1, // style: {color:getHoursTotal('mon')>24?"red":"black"} }; - const TotalCell = ({value}: Props) => { + const TotalCell = ({ value }: Props) => { const [invalid, setInvalid] = useState(false); - useEffect(()=> { - const newInvalid = (value??0)>24; + useEffect(() => { + const newInvalid = (value ?? 0) > 24; setInvalid(newInvalid); }, [value]); return ( - + {value} ); - } + }; const checkUnlockConfirmBtn = () => { // setLockConfirm((oldLock)=> valid); - setLockConfirm((oldLock)=> weekdays.every(weekday => { - getHoursTotal(weekday) <= 24 - })); - } + setLockConfirm((oldLock) => + weekdays.every((weekday) => { + getHoursTotal(weekday) <= 24; + }), + ); + }; return (
-
- +
+ Total: - - - - - - - + + + + + + +
-
); -} - +}; const EditFooter = (props: EditFooterProps) => { return ( -
+
Total: ssss
); -} +}; interface TimesheetInputGridProps { - setLockConfirm: (newLock: (oldLock: Boolean) => Boolean) => void; + setLockConfirm: (newLock: (oldLock: boolean) => boolean) => void; onClose?: () => void; } @@ -213,30 +248,37 @@ const initialRows: GridRowsProp = [ }, ]; -const options=["M1001", "M1301", "M1354", "M1973"]; -const options2=[ +const options = ["M1001", "M1301", "M1354", "M1973"]; +const options2 = [ "1.1 - Preparation of preliminary Cost Estimate / Cost Plan", "1.2 - Cash flow forecast", "1.3 - Cost studies fo alterative design solutions", "1.4 = Attend design co-ordination / project review meetings", - "1.5 - Prepare / Review RIC"]; + "1.5 - Prepare / Review RIC", +]; -const getDateForHeader = (date : dayjs.Dayjs, weekday : number) => { +const getDateForHeader = (date: dayjs.Dayjs, weekday: number) => { if (date.day() == 0) { - return date.add((weekday - date.day() - 7), 'day').format('DD MMM'); + return date.add(weekday - date.day() - 7, "day").format("DD MMM"); } else { - return date.add(weekday - date.day(), 'day').format('DD MMM'); + return date.add(weekday - date.day(), "day").format("DD MMM"); } -} - -const TimesheetInputGrid: React.FC = ({ ...props }) => { +}; +const TimesheetInputGrid: React.FC = ({ + ...props +}) => { const [rows, setRows] = useState(initialRows); const [day, setDay] = useState(dayjs()); - const [rowModesModel, setRowModesModel] = React.useState({}); + const [rowModesModel, setRowModesModel] = React.useState( + {}, + ); const { setLockConfirm } = props; - const handleRowEditStop: GridEventListener<'rowEditStop'> = (params, event) => { + const handleRowEditStop: GridEventListener<"rowEditStop"> = ( + params, + event, + ) => { if (params.reason === GridRowEditStopReasons.rowFocusOut) { event.defaultMuiPrevented = true; } @@ -247,7 +289,6 @@ const TimesheetInputGrid: React.FC = ({ ...props }) => }; const handleSaveClick = (id: GridRowId) => () => { - setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } }); }; @@ -277,23 +318,23 @@ const TimesheetInputGrid: React.FC = ({ ...props }) => setRowModesModel(newRowModesModel); }; - const getHoursTotal = (column : any) => { + const getHoursTotal = (column: any) => { let sum = 0; rows.forEach((row) => { - sum += row[column]??0; + sum += row[column] ?? 0; }); return sum; }; - const weekdayColConfig : any = { - type: 'number', + const weekdayColConfig: any = { + type: "number", // sortable: false, //width: 100, flex: 1, - align: 'left', - headerAlign: 'left', + align: "left", + headerAlign: "left", editable: true, - renderEditCell: (value : any) => ( + renderEditCell: (value: any) => ( = ({ ...props }) => const columns: GridColDef[] = [ { - field: 'actions', - type: 'actions', - headerName: 'Actions', + field: "actions", + type: "actions", + headerName: "Actions", width: 100, - cellClassName: 'actions', + cellClassName: "actions", getActions: ({ id }) => { const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; if (isInEditMode) { return [ } title="Save" label="Save" sx={{ - color: 'primary.main', + color: "primary.main", }} onClick={handleSaveClick(id)} />, } title="Cancel" label="Cancel" @@ -339,6 +382,7 @@ const TimesheetInputGrid: React.FC = ({ ...props }) => return [ } title="Edit" label="Edit" @@ -347,100 +391,89 @@ const TimesheetInputGrid: React.FC = ({ ...props }) => color="inherit" />, } onClick={handleDeleteClick(id)} - sx={{color:"red"}} + sx={{ color: "red" }} />, ]; }, }, { - field: 'projectCode', - headerName: 'Project Code', + field: "projectCode", + headerName: "Project Code", // width: 220, flex: 2, editable: true, - type: 'singleSelect', + type: "singleSelect", valueOptions: options, }, { - field: 'task', - headerName: 'Task', + field: "task", + headerName: "Task", // width: 220, flex: 3, editable: true, - type: 'singleSelect', + type: "singleSelect", valueOptions: options2, }, { // Mon - field: 'mon', + field: "mon", ...weekdayColConfig, renderHeader: () => { - return ( -
Mon - {getDateForHeader(day, 1)}
- ); + return
Mon - {getDateForHeader(day, 1)}
; }, }, { // Tue - field: 'tue', + field: "tue", ...weekdayColConfig, renderHeader: () => { - return ( -
Tue - {getDateForHeader(day, 2)}
- ); + return
Tue - {getDateForHeader(day, 2)}
; }, }, { // Wed - field: 'wed', + field: "wed", ...weekdayColConfig, renderHeader: () => { - return ( -
Wed - {getDateForHeader(day, 3)}
- ); + return
Wed - {getDateForHeader(day, 3)}
; }, }, { // Thu - field: 'thu', + field: "thu", ...weekdayColConfig, renderHeader: () => { - return ( -
Thu - {getDateForHeader(day, 4)}
- ); + return
Thu - {getDateForHeader(day, 4)}
; }, }, { // Fri - field: 'fri', + field: "fri", ...weekdayColConfig, renderHeader: () => { - return ( -
Fri - {getDateForHeader(day, 5)}
- ); + return
Fri - {getDateForHeader(day, 5)}
; }, }, { // Sat - field: 'sat', + field: "sat", ...weekdayColConfig, renderHeader: () => { - return ( -
Sat - {getDateForHeader(day, 6)}
- ); + return
Sat - {getDateForHeader(day, 6)}
; }, }, { // Sun - field: 'sun', + field: "sun", ...weekdayColConfig, renderHeader: () => { return ( -
Sun - {getDateForHeader(day, 7)}
+
Sun - {getDateForHeader(day, 7)}
); }, }, @@ -457,22 +490,22 @@ const TimesheetInputGrid: React.FC = ({ ...props }) => @@ -498,14 +531,18 @@ const TimesheetInputGrid: React.FC = ({ ...props }) => initialState={{ pagination: { paginationModel: { pageSize: 100 } }, }} - sx={{flex:1}} + sx={{ flex: 1 }} /> - ); -} +}; export default TimesheetInputGrid; diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx index fdbe44a..77a018f 100644 --- a/src/components/NavigationContent/NavigationContent.tsx +++ b/src/components/NavigationContent/NavigationContent.tsx @@ -7,11 +7,11 @@ import ListItemText from "@mui/material/ListItemText"; import ListItemIcon from "@mui/material/ListItemIcon"; import WorkHistory from "@mui/icons-material/WorkHistory"; import Dashboard from "@mui/icons-material/Dashboard"; -import SummarizeIcon from '@mui/icons-material/Summarize'; -import PaymentsIcon from '@mui/icons-material/Payments'; -import AccountTreeIcon from '@mui/icons-material/AccountTree'; +import SummarizeIcon from "@mui/icons-material/Summarize"; +import PaymentsIcon from "@mui/icons-material/Payments"; +import AccountTreeIcon from "@mui/icons-material/AccountTree"; import RequestQuote from "@mui/icons-material/RequestQuote"; -import PeopleIcon from '@mui/icons-material/People'; +import PeopleIcon from "@mui/icons-material/People"; import Task from "@mui/icons-material/Task"; import Assignment from "@mui/icons-material/Assignment"; import Settings from "@mui/icons-material/Settings"; @@ -22,8 +22,8 @@ import Typography from "@mui/material/Typography"; import { usePathname } from "next/navigation"; import Link from "next/link"; import { NAVIGATION_CONTENT_WIDTH } from "@/config/uiConfig"; -import ArrowCircleLeftOutlinedIcon from '@mui/icons-material/ArrowCircleLeftOutlined'; -import ArrowCircleLeftRoundedIcon from '@mui/icons-material/ArrowCircleLeftRounded'; +import ArrowCircleLeftOutlinedIcon from "@mui/icons-material/ArrowCircleLeftOutlined"; +import ArrowCircleLeftRoundedIcon from "@mui/icons-material/ArrowCircleLeftRounded"; interface NavigationItem { icon: React.ReactNode; @@ -34,17 +34,55 @@ interface NavigationItem { const navigationItems: NavigationItem[] = [ { icon: , label: "User Workspace", path: "/home" }, - { icon: , label: "Dashboard", path: "", children: [ - { icon: , label: "Project Financial Summary", path: "/dashboard/ProjectFinancialSummary" }, - { icon: , label: "Company / Team Cash Flow", path: "/dashboard/CompanyTeamCashFlow" }, - { icon: , label: "Project Cash Flow", path: "/dashboard/ProjectCashFlow" }, - { icon: , label: "Project Status by Client", path: "/dashboard/ProjectStatusByClient" }, - { icon: , label: "Staff Utilization", path: "/dashboard/StaffUtilization" }, - ]}, - { icon: , label: "Staff Reimbursement", path: "/staffReimbursement", children: [ - { icon: , label: "ClaimApproval", path: "/staffReimbursement/ClaimApproval"}, - { icon: , label: "ClaimSummary", path: "/staffReimbursement/ClaimSummary"} - ] }, + { + icon: , + label: "Dashboard", + path: "", + children: [ + { + icon: , + label: "Project Financial Summary", + path: "/dashboard/ProjectFinancialSummary", + }, + { + icon: , + label: "Company / Team Cash Flow", + path: "/dashboard/CompanyTeamCashFlow", + }, + { + icon: , + label: "Project Cash Flow", + path: "/dashboard/ProjectCashFlow", + }, + { + icon: , + label: "Project Status by Client", + path: "/dashboard/ProjectStatusByClient", + }, + { + icon: , + label: "Staff Utilization", + path: "/dashboard/StaffUtilization", + }, + ], + }, + { + icon: , + label: "Staff Reimbursement", + path: "/staffReimbursement", + children: [ + { + icon: , + label: "ClaimApproval", + path: "/staffReimbursement/ClaimApproval", + }, + { + icon: , + label: "ClaimSummary", + path: "/staffReimbursement/ClaimSummary", + }, + ], + }, { icon: , label: "Project Management", path: "/projects" }, { icon: , label: "Task Template", path: "/tasks" }, { icon: , label: "Invoice", path: "/invoice" }, @@ -58,10 +96,10 @@ const NavigationContent: React.FC = () => { const [openItems, setOpenItems] = React.useState([]); const toggleItem = (path: string) => { - setOpenItems(prevOpenItems => + setOpenItems((prevOpenItems) => prevOpenItems.includes(path) - ? prevOpenItems.filter(item => item !== path) - : [...prevOpenItems, path] + ? prevOpenItems.filter((item) => item !== path) + : [...prevOpenItems, path], ); }; @@ -84,25 +122,27 @@ const NavigationContent: React.FC = () => { {item.children && isOpen && ( - {item.children.map(child => renderNavigationItem(child))} + {item.children.map((child) => renderNavigationItem(child))} )} ); }; - + return ( {/* Replace this with company logo and/or name */} - TSMS + + TSMS + {/* */} - {navigationItems.map(item => renderNavigationItem(item))} + {navigationItems.map((item) => renderNavigationItem(item))} {/* {navigationItems.map(({ icon, label, path }, index) => { return ( = ({ BigTitle, SecondTitle = '', ThirdTitle = '', FourthTitle = ''}) => { +const PageTitle: React.FC = ({ + BigTitle, + SecondTitle = "", + ThirdTitle = "", + FourthTitle = "", +}) => { const { t } = useTranslation("dashboard"); return ( - -
-

{BigTitle}

   -
   -

Overview

  -

{">"}

  -

{BigTitle}

  - {SecondTitle !== '' ? -

{">"} 

- : ""} - {SecondTitle !== '' ? -

{SecondTitle} 

- : ""} - {ThirdTitle !== '' ? -

{">"} 

- : ""} - {ThirdTitle !== '' ? -

{ThirdTitle} 

- : ""} - {FourthTitle !== '' ? -

{">"} 

- : ""} - {FourthTitle !== '' ? -

{FourthTitle} 

- : ""} -
-
+ +
+

+ {BigTitle} +

+    +
+    +

+ Overview +

+   +

+ {">"} +

+   +

+ {BigTitle} +

+   + {SecondTitle !== "" ? ( +

+ {">"}  +

+ ) : ( + "" + )} + {SecondTitle !== "" ? ( +

+ {SecondTitle}  +

+ ) : ( + "" + )} + {ThirdTitle !== "" ? ( +

+ {">"}  +

+ ) : ( + "" + )} + {ThirdTitle !== "" ? ( +

+ {ThirdTitle}  +

+ ) : ( + "" + )} + {FourthTitle !== "" ? ( +

+ {">"}  +

+ ) : ( + "" + )} + {FourthTitle !== "" ? ( +

+ {FourthTitle}  +

+ ) : ( + "" + )} +
+
); }; diff --git a/src/components/ProgressByClient/ProgressByClient.tsx b/src/components/ProgressByClient/ProgressByClient.tsx index 80e1a2f..939f5d3 100644 --- a/src/components/ProgressByClient/ProgressByClient.tsx +++ b/src/components/ProgressByClient/ProgressByClient.tsx @@ -1,84 +1,175 @@ "use client"; import * as React from "react"; import Grid from "@mui/material/Grid"; -import { useState,useEffect, useMemo } from 'react' +import { useState, useEffect, useMemo } from "react"; import Paper from "@mui/material/Paper"; import { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; -import {Card,CardHeader} from '@mui/material'; +import { Card, CardHeader } from "@mui/material"; import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; -import CustomDatagrid from '../CustomDatagrid/CustomDatagrid'; -import ReactApexChart from 'react-apexcharts'; -import { ApexOptions } from 'apexcharts'; -import { GridColDef, GridRowSelectionModel} from '@mui/x-data-grid'; -import ReportProblemIcon from '@mui/icons-material/ReportProblem'; -import dynamic from 'next/dynamic'; -import '../../app/global.css'; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; import { AnyARecord, AnyCnameRecord } from "dns"; import SearchBox, { Criterion } from "../SearchBox"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; import { Suspense } from "react"; const ProgressByClient: React.FC = () => { - const [activeTab, setActiveTab] = useState('financialSummary'); - const [SearchCriteria, setSearchCriteria] = React.useState({}) + const [activeTab, setActiveTab] = useState("financialSummary"); + const [SearchCriteria, setSearchCriteria] = React.useState({}); const { t } = useTranslation("dashboard"); - const [clientCode, setClientCode] = useState(''); - const [clientName, setClientName] = useState(''); - const [subsidiaryClientCode, setSubsidiaryClientCode] = useState(''); - const [subsidiaryClientName, setSubsidiaryClientName] = useState(''); - const [projectArray, setProjectArray] : any[] = useState([]); - const [percentageArray, setPercentageArray] : any[] = useState([]); - const [colorArray, setColorArray] : any[] = useState([]); - const [selectionModel, setSelectionModel] : any[] = React.useState([]); - const [pieChartColor, setPieChartColor] : any[] = React.useState([]); - const [totalSpentPercentage, setTotalSpentPercentage] : any = React.useState(); - const [projectBudgetManhour, setProjectBudgetManhour] :any = React.useState('-'); - const [actualManhourSpent, setActualManhourSpent] :any = React.useState('-'); - const [remainedManhour, setRemainedManhour] :any = React.useState('-'); - const [lastUpdate, setLastUpdate] :any = React.useState('-'); - const [dropdownDemo, setDropdownDemo] = useState(''); + const [clientCode, setClientCode] = useState(""); + const [clientName, setClientName] = useState(""); + const [subsidiaryClientCode, setSubsidiaryClientCode] = useState(""); + const [subsidiaryClientName, setSubsidiaryClientName] = useState(""); + const [projectArray, setProjectArray]: any[] = useState([]); + const [percentageArray, setPercentageArray]: any[] = useState([]); + const [colorArray, setColorArray]: any[] = useState([]); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const [pieChartColor, setPieChartColor]: any[] = React.useState([]); + const [totalSpentPercentage, setTotalSpentPercentage]: any = React.useState(); + const [projectBudgetManhour, setProjectBudgetManhour]: any = + React.useState("-"); + const [actualManhourSpent, setActualManhourSpent]: any = React.useState("-"); + const [remainedManhour, setRemainedManhour]: any = React.useState("-"); + const [lastUpdate, setLastUpdate]: any = React.useState("-"); + const [dropdownDemo, setDropdownDemo] = useState(""); const [dateDemo, setDateDemo] = useState(null); const [checkboxDemo, setCheckboxDemo] = useState(false); const [receiptFromDate, setReceiptFromDate] = useState(null); const [receiptToDate, setReceiptToDate] = useState(null); const [selectedRows, setSelectedRows] = useState([]); - const rows = [{id: 1,clientCode:"CUST-001",clientName:"Client A", clientSubsidiaryCode:"N/A", clientSubsidiaryName:"N/A", noOfProjects:"5"}, - {id: 2,clientCode:"CUST-001",clientName:"Client A", clientSubsidiaryCode:"SUBS-001", clientSubsidiaryName:"Subsidiary A", noOfProjects:"5"}, - {id: 3,clientCode:"CUST-001",clientName:"Client A", clientSubsidiaryCode:"SUBS-002", clientSubsidiaryName:"Subsidiary B", noOfProjects:"3"}, - {id: 4,clientCode:"CUST-001",clientName:"Client A", clientSubsidiaryCode:"SUBS-003", clientSubsidiaryName:"Subsidiary C", noOfProjects:"1"} - ] + const rows = [ + { + id: 1, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "N/A", + clientSubsidiaryName: "N/A", + noOfProjects: "5", + }, + { + id: 2, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-001", + clientSubsidiaryName: "Subsidiary A", + noOfProjects: "5", + }, + { + id: 3, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-002", + clientSubsidiaryName: "Subsidiary B", + noOfProjects: "3", + }, + { + id: 4, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-003", + clientSubsidiaryName: "Subsidiary C", + noOfProjects: "1", + }, + ]; //['#f57f90', '#94f7d6', '#87c5f5', '#ab95f5', '#fcd68b'] - const rows2 = [{id: 1,project:"Consultancy Project 123",team:"XXX", teamLeader:"XXX", currentStage:"Contract Documentation", budgetedManhour:"200.00",spentManhour:"120.00",remainedManhour:"80.00",comingPaymentMilestone:"31/03/2024",alert:false,color:"#f57f90"}, - {id: 2,project:"Consultancy Project 456",team:"XXX", teamLeader:"XXX", currentStage:"Report Preparation", budgetedManhour:"400.00",spentManhour:"200.00",remainedManhour:"200.00",comingPaymentMilestone:"20/02/2024",alert:false,color:"#94f7d6"}, - {id: 3,project:"Construction Project A",team:"YYY", teamLeader:"YYY", currentStage:"Construction", budgetedManhour:"187.50",spentManhour:"200.00",remainedManhour:"12.50",comingPaymentMilestone:"13/12/2023",alert:true,color:"#87c5f5"}, - {id: 4,project:"Construction Project B",team:"XXX", teamLeader:"XXX", currentStage:"Post Construction", budgetedManhour:"100.00",spentManhour:"40.00",remainedManhour:"60.00",comingPaymentMilestone:"05/01/2024",alert:false,color:"#ab95f5"}, - {id: 5,project:"Construction Project C",team:"YYY", teamLeader:"YYY", currentStage:"Construction", budgetedManhour:"300.00",spentManhour:"150.00",remainedManhour:"150.00",comingPaymentMilestone:"31/03/2024",alert:false,color:"#fcd68b"}, - ] + const rows2 = [ + { + id: 1, + project: "Consultancy Project 123", + team: "XXX", + teamLeader: "XXX", + currentStage: "Contract Documentation", + budgetedManhour: "200.00", + spentManhour: "120.00", + remainedManhour: "80.00", + comingPaymentMilestone: "31/03/2024", + alert: false, + color: "#f57f90", + }, + { + id: 2, + project: "Consultancy Project 456", + team: "XXX", + teamLeader: "XXX", + currentStage: "Report Preparation", + budgetedManhour: "400.00", + spentManhour: "200.00", + remainedManhour: "200.00", + comingPaymentMilestone: "20/02/2024", + alert: false, + color: "#94f7d6", + }, + { + id: 3, + project: "Construction Project A", + team: "YYY", + teamLeader: "YYY", + currentStage: "Construction", + budgetedManhour: "187.50", + spentManhour: "200.00", + remainedManhour: "12.50", + comingPaymentMilestone: "13/12/2023", + alert: true, + color: "#87c5f5", + }, + { + id: 4, + project: "Construction Project B", + team: "XXX", + teamLeader: "XXX", + currentStage: "Post Construction", + budgetedManhour: "100.00", + spentManhour: "40.00", + remainedManhour: "60.00", + comingPaymentMilestone: "05/01/2024", + alert: false, + color: "#ab95f5", + }, + { + id: 5, + project: "Construction Project C", + team: "YYY", + teamLeader: "YYY", + currentStage: "Construction", + budgetedManhour: "300.00", + spentManhour: "150.00", + remainedManhour: "150.00", + comingPaymentMilestone: "31/03/2024", + alert: false, + color: "#fcd68b", + }, + ]; const columns = [ - { - id: 'clientCode', - field: 'clientCode', - headerName: "Client Code", - flex: 1, + { + id: "clientCode", + field: "clientCode", + headerName: "Client Code", + flex: 1, }, { - id: 'clientName', - field: 'clientName', - headerName: "Client Name", - flex: 1, + id: "clientName", + field: "clientName", + headerName: "Client Name", + flex: 1, }, { - id: 'clientSubsidiaryCode', - field: 'clientSubsidiaryCode', + id: "clientSubsidiaryCode", + field: "clientSubsidiaryCode", headerName: "Client Subsidiary Code", flex: 1, }, { - id: 'noOfProjects', - field: 'noOfProjects', + id: "noOfProjects", + field: "noOfProjects", headerName: "No. of Projects", flex: 1, }, @@ -86,110 +177,139 @@ const ProgressByClient: React.FC = () => { const columns2 = [ { - id:"color", - field:'color', - headerName:'', - renderCell: (params:any) => { + id: "color", + field: "color", + headerName: "", + renderCell: (params: any) => { return ( - - ) + + ); }, - flex:0.1, + flex: 0.1, }, { - id: 'project', - field: 'project', + id: "project", + field: "project", headerName: "Project", flex: 1, - }, - { - id: 'team', - field: 'team', + }, + { + id: "team", + field: "team", headerName: "Team", flex: 0.8, - }, - { - id: 'teamLeader', - field: 'teamLeader', - headerName: "Team Leader", - flex: 0.8, - }, - { - id: 'currentStage', - field: 'currentStage', - headerName: "Current Stage", - flex: 1, - }, - { - id: 'budgetedManhour', - field: 'budgetedManhour', - headerName: "Budgeted Manhour", - flex: 0.8, - }, - { - id: 'spentManhour', - field: 'spentManhour', - headerName: "Spent Manhour", - renderCell: (params:any) => { - if (params.row.budgetedManhour - params.row.spentManhour <= 0) { - return( - {params.row.spentManhour} - ) - } else { - return ( - {params.row.spentManhour} - ) - } }, - flex: 0.8, - }, - { - id: 'remainedManhour', - field: 'remainedManhour', - headerName: "Remained Manhour", - renderCell: (params:any) => { - if (params.row.budgetedManhour - params.row.spentManhour <= 0) { - return( - ({params.row.remainedManhour}) - ) - } else { - return ( - {params.row.remainedManhour} - ) - } + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 0.8, }, - flex: 1, - }, - { - id: 'comingPaymentMilestone', - field: 'comingPaymentMilestone', - headerName: "Coming Payment Milestone", - flex: 1, - }, - { - id: 'alert', - field: 'alert', - headerName: "Alert", - renderCell: (params:any) => { - if (params.row.alert === true) { - return ( - - ) - } else { - return ( - - ) - } + { + id: "currentStage", + field: "currentStage", + headerName: "Current Stage", + flex: 1, + }, + { + id: "budgetedManhour", + field: "budgetedManhour", + headerName: "Budgeted Manhour", + flex: 0.8, }, - flex: 0.2, - }, -]; + { + id: "spentManhour", + field: "spentManhour", + headerName: "Spent Manhour", + renderCell: (params: any) => { + if (params.row.budgetedManhour - params.row.spentManhour <= 0) { + return ( + {params.row.spentManhour} + ); + } else { + return {params.row.spentManhour}; + } + }, + flex: 0.8, + }, + { + id: "remainedManhour", + field: "remainedManhour", + headerName: "Remained Manhour", + renderCell: (params: any) => { + if (params.row.budgetedManhour - params.row.spentManhour <= 0) { + return ( + ({params.row.remainedManhour}) + ); + } else { + return {params.row.remainedManhour}; + } + }, + flex: 1, + }, + { + id: "comingPaymentMilestone", + field: "comingPaymentMilestone", + headerName: "Coming Payment Milestone", + flex: 1, + }, + { + id: "alert", + field: "alert", + headerName: "Alert", + renderCell: (params: any) => { + if (params.row.alert === true) { + return ( + + + + ); + } else { + return ; + } + }, + flex: 0.2, + }, + ]; const InputFields = [ - { id: "clientCode", label: "Client Code", type: 'text', value: clientCode, setValue: setClientCode }, - { id: "clientName", label: "Client Name", type: 'text', value: clientName, setValue: setClientName }, - { id: "subsidiaryClientCode", label: "Subsidiary Client Code", type:'text', value:subsidiaryClientCode, setValue: setSubsidiaryClientCode}, - { id: "subsidiaryClientName", label: "Subsidiary Client Name", type:'text', value:subsidiaryClientName, setValue: setSubsidiaryClientName}, + { + id: "clientCode", + label: "Client Code", + type: "text", + value: clientCode, + setValue: setClientCode, + }, + { + id: "clientName", + label: "Client Name", + type: "text", + value: clientName, + setValue: setClientName, + }, + { + id: "subsidiaryClientCode", + label: "Subsidiary Client Code", + type: "text", + value: subsidiaryClientCode, + setValue: setSubsidiaryClientCode, + }, + { + id: "subsidiaryClientName", + label: "Subsidiary Client Name", + type: "text", + value: subsidiaryClientName, + setValue: setSubsidiaryClientName, + }, // { id: 'dropdownDemo', label: "dropdownDemo", type: 'dropdown', options: [{id:"1", label:"1"}], value: dropdownDemo, setValue: setDropdownDemo }, // { id: 'dateDemo', label:'dateDemo', type: 'date', value: dateDemo, setValue: setDateDemo }, // { id: 'checkboxDemo', label:'checkboxDemo', type: 'checkbox', value: checkboxDemo, setValue: setCheckboxDemo }, @@ -197,73 +317,85 @@ const ProgressByClient: React.FC = () => { // setValue: [setReceiptFromDate, setReceiptToDate],type: 'dateRange' }, ]; - const stageDeadline = ["31/03/2024","20/02/2024","01/12/2023","05/01/2024","31/03/2023"] + const stageDeadline = [ + "31/03/2024", + "20/02/2024", + "01/12/2023", + "05/01/2024", + "31/03/2023", + ]; + + const series2: ApexAxisChartSeries | ApexNonAxisChartSeries = [ + { + data: [17.1, 28.6, 5.7, 48.6], + }, + ]; - const series2: ApexAxisChartSeries | ApexNonAxisChartSeries = [{ - data: [17.1, 28.6, 5.7, 48.6], - }]; + const series: ApexAxisChartSeries | ApexNonAxisChartSeries = [ + { + name: "Current Stage Completion Percentage", + data: [80, 55, 40, 65, 70], + }, + ]; - const series: ApexAxisChartSeries | ApexNonAxisChartSeries = [{ - name: 'Current Stage Completion Percentage', - data: [80, 55, 40, 65, 70], - }]; - - const options2 : ApexOptions = { + const options2: ApexOptions = { chart: { - type: 'donut', + type: "donut", }, colors: colorArray, plotOptions: { pie: { - donut:{ - labels:{ - show:true, - name:{ - show:true, + donut: { + labels: { + show: true, + name: { + show: true, }, - value:{ - show:true, + value: { + show: true, fontWeight: 500, - fontSize: '30px', + fontSize: "30px", color: "#3e98c7", }, - total:{ + total: { show: true, showAlways: true, - label: 'Spent', - fontFamily: 'sans-serif', + label: "Spent", + fontFamily: "sans-serif", formatter: function (val) { - return totalSpentPercentage + "%" - } - } - } - } + return totalSpentPercentage + "%"; + }, + }, + }, + }, }, }, labels: projectArray, legend: { show: false, }, - responsive: [{ - breakpoint: 480, - options: { - chart: { - width: 200 + responsive: [ + { + breakpoint: 480, + options: { + chart: { + width: 200, + }, + legend: { + position: "bottom", + show: false, + }, }, - legend: { - position: 'bottom', - show:false - } - } - }] - } - + }, + ], + }; + const options: ApexOptions = { chart: { - type: 'bar', - height: 350 + type: "bar", + height: 350, }, - colors: ['#f57f90', '#94f7d6', '#87c5f5', '#ab95f5', '#fcd68b'], + colors: ["#f57f90", "#94f7d6", "#87c5f5", "#ab95f5", "#fcd68b"], plotOptions: { bar: { horizontal: true, @@ -271,107 +403,116 @@ const ProgressByClient: React.FC = () => { }, }, dataLabels: { - enabled: false + enabled: false, }, xaxis: { categories: [ - 'Consultancy Project 123', - 'Consultancy Project 456', - 'Construction Project A', - 'Construction Project B', - 'Construction Project C', + "Consultancy Project 123", + "Consultancy Project 456", + "Construction Project A", + "Construction Project B", + "Construction Project C", ], }, yaxis: { title: { - text: 'Projects' + text: "Projects", }, labels: { - maxWidth: 200, + maxWidth: 200, style: { - cssClass: 'apexcharts-yaxis-label', + cssClass: "apexcharts-yaxis-label", }, }, }, title: { - text: 'Current Stage Completion Percentage', - align: 'center' + text: "Current Stage Completion Percentage", + align: "center", }, grid: { - borderColor: '#f1f1f1', + borderColor: "#f1f1f1", }, - annotations: { - } + annotations: {}, }; - + const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { const selectedRowsData = rows2.filter((row) => - newSelectionModel.includes(row.id) + newSelectionModel.includes(row.id), ); - console.log(selectedRowsData) - const projectArray = [] - const pieChartColorArray = [] - let totalSpent = 0 - let totalBudgetManhour = 0 - const percentageArray = [] + console.log(selectedRowsData); + const projectArray = []; + const pieChartColorArray = []; + let totalSpent = 0; + let totalBudgetManhour = 0; + const percentageArray = []; for (let i = 0; i <= selectedRowsData.length; i++) { if (i === selectedRowsData.length && i > 0) { - projectArray.push("Remained") + projectArray.push("Remained"); } else if (selectedRowsData.length > 0) { - projectArray.push(selectedRowsData[i].project) - totalBudgetManhour += Number(selectedRowsData[i].budgetedManhour) - totalSpent += Number(selectedRowsData[i].spentManhour) - pieChartColorArray.push(selectedRowsData[i].color) + projectArray.push(selectedRowsData[i].project); + totalBudgetManhour += Number(selectedRowsData[i].budgetedManhour); + totalSpent += Number(selectedRowsData[i].spentManhour); + pieChartColorArray.push(selectedRowsData[i].color); } } for (let i = 0; i <= selectedRowsData.length; i++) { if (i === selectedRowsData.length && i > 0) { - const remainedManhour = (totalBudgetManhour - totalSpent) - percentageArray.push(Number(((remainedManhour / totalBudgetManhour) * 100).toFixed(1))) + const remainedManhour = totalBudgetManhour - totalSpent; + percentageArray.push( + Number(((remainedManhour / totalBudgetManhour) * 100).toFixed(1)), + ); } else if (selectedRowsData.length > 0) { - let percentage = ((Number(selectedRowsData[i].spentManhour) / totalBudgetManhour) * 100).toFixed(1) - percentageArray.push(Number(percentage)) + const percentage = ( + (Number(selectedRowsData[i].spentManhour) / totalBudgetManhour) * + 100 + ).toFixed(1); + percentageArray.push(Number(percentage)); } } - setProjectBudgetManhour(totalBudgetManhour.toFixed(2)) - setActualManhourSpent(totalSpent.toFixed(2)) - setRemainedManhour((totalBudgetManhour - totalSpent).toFixed(2)) - setLastUpdate(new Date().toLocaleDateString('en-GB')) - setSelectionModel(newSelectionModel) - console.log(projectArray) - setProjectArray(projectArray) - setPercentageArray(percentageArray) - console.log(percentageArray) - setTotalSpentPercentage(((totalSpent/totalBudgetManhour)*100).toFixed(1)) + setProjectBudgetManhour(totalBudgetManhour.toFixed(2)); + setActualManhourSpent(totalSpent.toFixed(2)); + setRemainedManhour((totalBudgetManhour - totalSpent).toFixed(2)); + setLastUpdate(new Date().toLocaleDateString("en-GB")); + setSelectionModel(newSelectionModel); + console.log(projectArray); + setProjectArray(projectArray); + setPercentageArray(percentageArray); + console.log(percentageArray); + setTotalSpentPercentage( + ((totalSpent / totalBudgetManhour) * 100).toFixed(1), + ); if (projectArray.length > 0 && projectArray.includes("Remained")) { const nonLastRecordColors = pieChartColorArray; - setColorArray([...nonLastRecordColors.slice(0, projectArray.length - 1), "#a3a3a3"]); + setColorArray([ + ...nonLastRecordColors.slice(0, projectArray.length - 1), + "#a3a3a3", + ]); } else { setColorArray(pieChartColorArray); } }; const applySearch = (data: any) => { - console.log(data) - setSearchCriteria(data) - } + console.log(data); + setSearchCriteria(data); + }; return ( - - {/* */} - {/* */} -
- - - -
- -
- {/*
+ + {/* */} + {/* */} +
+ + + +
+ +
+ {/*

Stage Deadline

{stageDeadline.map((date, index) => { const marginTop = index === 0 ? 25 : 20; @@ -380,54 +521,122 @@ const ProgressByClient: React.FC = () => { ); })}
*/} - -
- -
-
-
+ +
+ +
+ + +
+
+ + + + {percentageArray.length === 0 && ( +
+ Please select the project you want to check. +
+ )} + {percentageArray.length > 0 && ( + + )} +
+
+ + +
+
+ Project Budget Manhour +
+
+ {projectBudgetManhour} +
+
+
+
+
+ Actual Manhour Spent +
+
+ {actualManhourSpent} +
+
+
+
+
+ Remained Manhour +
+
+ {remainedManhour} +
-
- - - - {percentageArray.length === 0 &&( -
Please select the project you want to check.
- )} - {percentageArray.length > 0 &&( - - )} -
-
- - -
-
Project Budget Manhour
-
{projectBudgetManhour}
-
-
-
-
Actual Manhour Spent
-
{actualManhourSpent}
-
-
-
-
Remained Manhour
-
{remainedManhour}
-
-
-
-
Last Update
-
{lastUpdate}
-
-
-
+
+
+
+ Last Update +
+
+ {lastUpdate} +
- + + +
+
); }; diff --git a/src/components/ProgressCashFlowSearch/ProgressCashFlowSearch.tsx b/src/components/ProgressCashFlowSearch/ProgressCashFlowSearch.tsx index 6787b57..845c874 100644 --- a/src/components/ProgressCashFlowSearch/ProgressCashFlowSearch.tsx +++ b/src/components/ProgressCashFlowSearch/ProgressCashFlowSearch.tsx @@ -6,9 +6,9 @@ import SearchBox, { Criterion } from "../SearchBox"; import { useTranslation } from "react-i18next"; import SearchResults, { Column } from "../SearchResults"; import { CashFlow } from "@/app/api/cashflow"; -import CustomDatagrid from '../CustomDatagrid/CustomDatagrid'; -import { GridColDef, GridRowSelectionModel} from '@mui/x-data-grid'; -import ProjectCashFlow from '../ProjectCashFlow' +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ProjectCashFlow from "../ProjectCashFlow"; interface Props { projects: CashFlow[]; @@ -16,70 +16,101 @@ interface Props { type SearchQuery = Partial>; type SearchParamNames = keyof SearchQuery; -const ProgressByClientSearch: React.FC = ({ projects}) => { +const ProgressByClientSearch: React.FC = ({ projects }) => { const { t } = useTranslation("projects"); - const [selectionModel, setSelectionModel] : any[] = React.useState([]); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); const columns = [ { - id: 'projectCode', - field: 'projectCode', + id: "projectCode", + field: "projectCode", headerName: "Project Code", flex: 1, - }, - { - id: 'projectName', - field: 'projectName', + }, + { + id: "projectName", + field: "projectName", headerName: "Project Name", flex: 1, - }, - { - id: 'team', - field: 'team', - headerName: "Team", - flex: 1, - }, - { - id: 'teamLeader', - field: 'teamLeader', - headerName: "Team Leader", - flex: 1, - }, - { - id: 'startDate', - field: 'startDate', - headerName: "Start Date", - flex: 1, - }, - { - id: 'targetEndDate', - field: 'targetEndDate', - headerName: "Target End Date", - flex: 1, - }, - { - id: 'client', - field: 'client', - headerName: "Client", - flex: 1, - }, - { - id: 'subsidiary', - field: 'subsidiary', - headerName: "Subsidiary", - flex: 1, - }, -]; - const rows = [{id: 1,projectCode:"M1001",projectName:"Consultancy Project A", team:"XXX", teamLeader:"XXX", startDate:"01/07/2022", targetEndDate: "01/04/2024", client:"Client B", subsidiary:"N/A"}, - {id: 2,projectCode:"M1301",projectName:"Consultancy Project AAAA", team:"XXX", teamLeader:"XXX", startDate:"01/09/2022", targetEndDate: "20/02/2024", client:"Client C", subsidiary:"Subsidiary A"}, - {id: 3,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 [selectedTeamData, setSelectedTeamData] : any[] = React.useState(rows); + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 1, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, + }, + { + id: "startDate", + field: "startDate", + headerName: "Start Date", + flex: 1, + }, + { + id: "targetEndDate", + field: "targetEndDate", + headerName: "Target End Date", + flex: 1, + }, + { + id: "client", + field: "client", + headerName: "Client", + flex: 1, + }, + { + id: "subsidiary", + field: "subsidiary", + headerName: "Subsidiary", + flex: 1, + }, + ]; + const rows = [ + { + id: 1, + projectCode: "M1001", + projectName: "Consultancy Project A", + team: "XXX", + teamLeader: "XXX", + startDate: "01/07/2022", + targetEndDate: "01/04/2024", + client: "Client B", + subsidiary: "N/A", + }, + { + id: 2, + projectCode: "M1301", + projectName: "Consultancy Project AAAA", + team: "XXX", + teamLeader: "XXX", + startDate: "01/09/2022", + targetEndDate: "20/02/2024", + client: "Client C", + subsidiary: "Subsidiary A", + }, + { + id: 3, + 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 [selectedTeamData, setSelectedTeamData]: any[] = React.useState(rows); const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { - const selectedRowsData = selectedTeamData.filter((row:any) => - newSelectionModel.includes(row.id) + const selectedRowsData = selectedTeamData.filter((row: any) => + newSelectionModel.includes(row.id), ); - console.log(selectedRowsData) - } + console.log(selectedRowsData); + }; // If project searching is done on the server-side, then no need for this. const [filteredProjects, setFilteredProjects] = useState(projects); @@ -88,7 +119,12 @@ const ProgressByClientSearch: React.FC = ({ projects}) => { () => [ { label: "Project Code", paramName: "projectCode", type: "text" }, { label: "Project Name", paramName: "projectName", type: "text" }, - { label: "Start Date From",label2: "Start Date To", paramName: "startDateFrom", type: "dateRange" }, + { + label: "Start Date From", + label2: "Start Date To", + paramName: "startDateFrom", + type: "dateRange", + }, ], [t], ); diff --git a/src/components/ProjectCashFlow/ProjectCashFlow.tsx b/src/components/ProjectCashFlow/ProjectCashFlow.tsx index fe614cb..5eb455c 100644 --- a/src/components/ProjectCashFlow/ProjectCashFlow.tsx +++ b/src/components/ProjectCashFlow/ProjectCashFlow.tsx @@ -1,121 +1,123 @@ "use client"; import * as React from "react"; import Grid from "@mui/material/Grid"; -import { useState,useEffect, useMemo } from 'react' +import { useState, useEffect, useMemo } from "react"; import Paper from "@mui/material/Paper"; import { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; -import {Card,CardHeader} from '@mui/material'; +import { Card, CardHeader } from "@mui/material"; import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; -import CustomDatagrid from '../CustomDatagrid/CustomDatagrid'; -import ReactApexChart from 'react-apexcharts'; -import { ApexOptions } from 'apexcharts'; -import { GridColDef, GridRowSelectionModel} from '@mui/x-data-grid'; -import ReportProblemIcon from '@mui/icons-material/ReportProblem'; -import dynamic from 'next/dynamic'; -import '../../app/global.css'; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; import { AnyARecord, AnyCnameRecord } from "dns"; import SearchBox, { Criterion } from "../SearchBox"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; import { Suspense } from "react"; import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; -import {Input,Label} from "reactstrap"; +import { Input, Label } from "reactstrap"; const ProjectCashFlow: React.FC = () => { - const todayDate = new Date; - const [selectionModel, setSelectionModel] : any[] = React.useState([]); - const [cashFlowYear, setCashFlowYear] : any[] = React.useState(todayDate.getFullYear()); + const todayDate = new Date(); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const [cashFlowYear, setCashFlowYear]: any[] = React.useState( + todayDate.getFullYear(), + ); const columns = [ { - id: 'projectCode', - field: 'projectCode', + id: "projectCode", + field: "projectCode", headerName: "Project Code", flex: 1, - }, - { - id: 'projectName', - field: 'projectName', + }, + { + id: "projectName", + field: "projectName", headerName: "Project Name", flex: 1, - }, - { - id: 'team', - field: 'team', - headerName: "Team", - flex: 1, - }, - { - id: 'teamLeader', - field: 'teamLeader', - headerName: "Team Leader", - flex: 1, - }, - { - id: 'startDate', - field: 'startDate', - headerName: "Start Date", - flex: 1, - }, - { - id: 'targetEndDate', - field: 'targetEndDate', - headerName: "Target End Date", - flex: 1, - }, - { - id: 'client', - field: 'client', - headerName: "Client", - flex: 1, - }, - { - id: 'subsidiary', - field: 'subsidiary', - headerName: "Subsidiary", - flex: 1, - }, + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 1, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, + }, + { + id: "startDate", + field: "startDate", + headerName: "Start Date", + flex: 1, + }, + { + id: "targetEndDate", + field: "targetEndDate", + headerName: "Target End Date", + flex: 1, + }, + { + id: "client", + field: "client", + headerName: "Client", + flex: 1, + }, + { + id: "subsidiary", + field: "subsidiary", + headerName: "Subsidiary", + flex: 1, + }, ]; const ledgerColumns = [ { - id: 'date', - field: 'date', + id: "date", + field: "date", headerName: "Date", flex: 0.5, - }, - { - id: 'expenditure', - field: 'expenditure', + }, + { + id: "expenditure", + field: "expenditure", headerName: "Expenditure (HKD)", flex: 0.6, - }, - { - id: 'income', - field: 'income', - headerName: "Income (HKD)", - flex: 0.6, - }, - { - id: 'cashFlowBalance', - field: 'cashFlowBalance', - headerName: "Cash Flow Balance (HKD)", - flex: 0.6, - }, - { - id: 'remarks', - field: 'remarks', - headerName: "Remarks", - flex: 1, - }, + }, + { + id: "income", + field: "income", + headerName: "Income (HKD)", + flex: 0.6, + }, + { + id: "cashFlowBalance", + field: "cashFlowBalance", + headerName: "Cash Flow Balance (HKD)", + flex: 0.6, + }, + { + id: "remarks", + field: "remarks", + headerName: "Remarks", + flex: 1, + }, ]; const options: ApexOptions = { chart: { height: 350, - type: 'line', + type: "line", }, stroke: { - width: [0, 0, 2, 2] + width: [0, 0, 2, 2], }, plotOptions: { bar: { @@ -124,160 +126,167 @@ const ProjectCashFlow: React.FC = () => { }, }, dataLabels: { - enabled: false + enabled: false, }, xaxis: { categories: [ - 'Q1', - 'Q2', - 'Q3', - 'Q4', - 'Q5', - 'Q6', - 'Q7', - 'Q8', - 'Q9', - 'Q10', - 'Q11', - 'Q12', + "Q1", + "Q2", + "Q3", + "Q4", + "Q5", + "Q6", + "Q7", + "Q8", + "Q9", + "Q10", + "Q11", + "Q12", ], }, yaxis: [ - { title: { - text: 'Monthly Income and Expenditure(HKD)' + text: "Monthly Income and Expenditure(HKD)", }, min: 0, max: 350000, - tickAmount: 5 + tickAmount: 5, }, { - show:false, - seriesName: 'Monthly_Expenditure', + show: false, + seriesName: "Monthly_Expenditure", title: { - text: 'Monthly Expenditure (HKD)' + text: "Monthly Expenditure (HKD)", }, min: 0, max: 350000, - tickAmount: 5 + tickAmount: 5, }, { - seriesName: 'Cumulative_Income', + seriesName: "Cumulative_Income", opposite: true, title: { - text: 'Cumulative Income and Expenditure(HKD)' + text: "Cumulative Income and Expenditure(HKD)", }, min: 0, max: 850000, - tickAmount: 5 + tickAmount: 5, }, { - show:false, - seriesName: 'Cumulative_Expenditure', + show: false, + seriesName: "Cumulative_Expenditure", opposite: true, title: { - text: 'Cumulative Expenditure (HKD)' + text: "Cumulative Expenditure (HKD)", }, min: 0, max: 850000, - tickAmount: 5 - } - ], + tickAmount: 5, + }, + ], grid: { - borderColor: '#f1f1f1', + borderColor: "#f1f1f1", }, - annotations: { - }, - series:[ + annotations: {}, + series: [ { - name:"Monthly_Income", - type:"column", + name: "Monthly_Income", + type: "column", color: "#ffde91", - data:[0,110000,0,0,185000,0,0,189000,0,0,300000,0], + data: [0, 110000, 0, 0, 185000, 0, 0, 189000, 0, 0, 300000, 0], }, { - name:"Monthly_Expenditure", - type:"column", + name: "Monthly_Expenditure", + type: "column", color: "#82b59a", - data:[0,160000,120000,120000,55000,55000,55000,55000,55000,70000,55000,55000] + data: [ + 0, 160000, 120000, 120000, 55000, 55000, 55000, 55000, 55000, 70000, + 55000, 55000, + ], }, { - name:"Cumulative_Income", - type:"line", + name: "Cumulative_Income", + type: "line", color: "#EE6D7A", - data:[0,100000,100000,100000,300000,300000,300000,500000,500000,500000,800000,800000] + data: [ + 0, 100000, 100000, 100000, 300000, 300000, 300000, 500000, 500000, + 500000, 800000, 800000, + ], }, { - name:"Cumulative_Expenditure", - type:"line", + name: "Cumulative_Expenditure", + type: "line", color: "#7cd3f2", - data:[0,198000,240000,400000,410000,430000,510000,580000,600000,710000,730000,790000] - } - ] + data: [ + 0, 198000, 240000, 400000, 410000, 430000, 510000, 580000, 600000, + 710000, 730000, 790000, + ], + }, + ], }; const accountsReceivableOptions: ApexOptions = { - colors: ["#20E647"], - series: [80], - chart: { - height: 350, - type: 'radialBar', + colors: ["#20E647"], + series: [80], + chart: { + height: 350, + type: "radialBar", + }, + plotOptions: { + radialBar: { + hollow: { + size: "70%", + background: "#ffffff", }, - plotOptions: { - radialBar: { - hollow: { - size: '70%', - background: "#ffffff" - }, - track: { - dropShadow: { - enabled: true, - top: 2, - left: 0, - blur: 4, - opacity: 0.15 - } - }, - dataLabels: { - name:{ - show:false, - }, - value: { - color: "#3e98c7", - fontSize: "3em", - show: true - } - }, + track: { + dropShadow: { + enabled: true, + top: 2, + left: 0, + blur: 4, + opacity: 0.15, }, }, - fill: { - type: "gradient", - gradient: { - shade: "dark", - type: "vertical", - gradientToColors: ["#87D4F9"], - stops: [0, 100] - } - }, - stroke: { - lineCap: "round" + dataLabels: { + name: { + show: false, + }, + value: { + color: "#3e98c7", + fontSize: "3em", + show: true, + }, }, - labels: ['AccountsReceivable'], + }, + }, + fill: { + type: "gradient", + gradient: { + shade: "dark", + type: "vertical", + gradientToColors: ["#87D4F9"], + stops: [0, 100], + }, + }, + stroke: { + lineCap: "round", + }, + labels: ["AccountsReceivable"], }; const expenditureOptions: ApexOptions = { colors: ["#20E647"], series: [95], - chart: { + chart: { height: 350, - type: 'radialBar', + type: "radialBar", }, plotOptions: { radialBar: { hollow: { - size: '70%', - background: "#ffffff" + size: "70%", + background: "#ffffff", }, track: { dropShadow: { @@ -285,18 +294,18 @@ const ProjectCashFlow: React.FC = () => { top: 2, left: 0, blur: 4, - opacity: 0.15 - } + opacity: 0.15, + }, }, dataLabels: { - name:{ - show:false, + name: { + show: false, }, value: { color: "#3e98c7", fontSize: "3em", - show: true - } + show: true, + }, }, }, }, @@ -306,132 +315,322 @@ const ProjectCashFlow: React.FC = () => { shade: "dark", type: "vertical", gradientToColors: ["#87D4F9"], - stops: [0, 100] - } + stops: [0, 100], + }, }, stroke: { - lineCap: "round" + lineCap: "round", }, - labels: ['AccountsReceivable'], -}; + labels: ["AccountsReceivable"], + }; - const rows = [{id: 1,projectCode:"M1001",projectName:"Consultancy Project A", team:"XXX", teamLeader:"XXX", startDate:"01/07/2022", targetEndDate: "01/04/2024", client:"Client B", subsidiary:"N/A"}, - {id: 2,projectCode:"M1301",projectName:"Consultancy Project AAAA", team:"XXX", teamLeader:"XXX", startDate:"01/09/2022", targetEndDate: "20/02/2024", client:"Client C", subsidiary:"Subsidiary A"}, - {id: 3,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 rows = [ + { + id: 1, + projectCode: "M1001", + projectName: "Consultancy Project A", + team: "XXX", + teamLeader: "XXX", + startDate: "01/07/2022", + targetEndDate: "01/04/2024", + client: "Client B", + subsidiary: "N/A", + }, + { + id: 2, + projectCode: "M1301", + projectName: "Consultancy Project AAAA", + team: "XXX", + teamLeader: "XXX", + startDate: "01/09/2022", + targetEndDate: "20/02/2024", + client: "Client C", + subsidiary: "Subsidiary A", + }, + { + id: 3, + 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 ledgerRows = [{id: 1,date:"Feb 2023",expenditure:"-", income:"100,000.00", cashFlowBalance:"100,000.00", remarks:"Payment Milestone 1 (10%)"}, - {id: 2,date:"Feb 2023",expenditure:"160,000.00", income:"-", cashFlowBalance:"(60,000.00)", remarks:"Monthly Manpower Expenditure"}, - {id: 3,date:"Mar 2023",expenditure:"160,000.00", income:"-", cashFlowBalance:"(180,000.00)", remarks:"Monthly Manpower Expenditure"}, - {id: 4,date:"Apr 2023",expenditure:"120,000.00", income:"-", cashFlowBalance:"(300,000.00)", remarks:"Monthly Manpower Expenditure"}, - {id: 5,date:"May 2023",expenditure:"-", income:"200,000.00", cashFlowBalance:"(100,000.00)", remarks:"Payment Milestone 2 (20%)"}, - {id: 6,date:"May 2023",expenditure:"40,000.00", income:"-", cashFlowBalance:"(140,000.00)", remarks:"Monthly Manpower Expenditure"} - ] + const ledgerRows = [ + { + id: 1, + date: "Feb 2023", + expenditure: "-", + income: "100,000.00", + cashFlowBalance: "100,000.00", + remarks: "Payment Milestone 1 (10%)", + }, + { + id: 2, + date: "Feb 2023", + expenditure: "160,000.00", + income: "-", + cashFlowBalance: "(60,000.00)", + remarks: "Monthly Manpower Expenditure", + }, + { + id: 3, + date: "Mar 2023", + expenditure: "160,000.00", + income: "-", + cashFlowBalance: "(180,000.00)", + remarks: "Monthly Manpower Expenditure", + }, + { + id: 4, + date: "Apr 2023", + expenditure: "120,000.00", + income: "-", + cashFlowBalance: "(300,000.00)", + remarks: "Monthly Manpower Expenditure", + }, + { + id: 5, + date: "May 2023", + expenditure: "-", + income: "200,000.00", + cashFlowBalance: "(100,000.00)", + remarks: "Payment Milestone 2 (20%)", + }, + { + id: 6, + date: "May 2023", + expenditure: "40,000.00", + income: "-", + cashFlowBalance: "(140,000.00)", + remarks: "Monthly Manpower Expenditure", + }, + ]; - const [projectData, setProjectData] : any[] = React.useState(rows); - const [ledgerData, setLedgerData] : any[] = React.useState(ledgerRows); + const [projectData, setProjectData]: any[] = React.useState(rows); + const [ledgerData, setLedgerData]: any[] = React.useState(ledgerRows); const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { - const selectedRowsData = projectData.filter((row:any) => - newSelectionModel.includes(row.id) + const selectedRowsData = projectData.filter((row: any) => + newSelectionModel.includes(row.id), ); - console.log(selectedRowsData) - } + console.log(selectedRowsData); + }; return ( <> }> - + - - -
- - - -
-
- - -
-
- -
-
- -
- -
-
-
-
-
+ + +
- - + + +
+
+ + +
+
+ +
+
+ +
- -
Total A. Receivable
-
1,000,000.00

-
Amount Received
-
800,000.00

-
Remaining Balance
-
200,000.00
-
- + options={options} + series={options.series} + type="line" + height="auto" + /> +
+
-
-
+
+
- - - - -
Budgeted Expenditure
-
800,000.00

-
Actual Expenditure
-
760,000.00

-
Remaining Balance
-
40,000.00
-
+ + + + +
+ Total A. Receivable +
+
+ 1,000,000.00 +
+
+
+ Amount Received +
+
+ 800,000.00 +
+
+
+ Remaining Balance +
+
+ 200,000.00 +
+
-
-
- - - -
- +
+
+ + + + + +
+ Budgeted Expenditure +
+
+ 800,000.00 +
+
+
+ Actual Expenditure +
+
+ 760,000.00 +
+
+
+ Remaining Balance +
+
+ 40,000.00
-
-
-
+ + +
+
+ + + +
+ +
+
+
+
+
); }; diff --git a/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx b/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx index b03e019..25ff90e 100644 --- a/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx +++ b/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx @@ -1,75 +1,173 @@ import * as React from "react"; import Grid from "@mui/material/Grid"; -import { useState,useEffect, useMemo } from 'react' +import { useState, useEffect, useMemo } from "react"; import Paper from "@mui/material/Paper"; import { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; -import {Card,CardHeader} from '@mui/material'; +import { Card, CardHeader } from "@mui/material"; import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; -import CustomDatagrid from '../CustomDatagrid/CustomDatagrid'; -import ReactApexChart from 'react-apexcharts'; -import { ApexOptions } from 'apexcharts'; -import { GridColDef, GridRowSelectionModel} from '@mui/x-data-grid'; -import ReportProblemIcon from '@mui/icons-material/ReportProblem'; -import dynamic from 'next/dynamic'; -import '../../app/global.css'; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; import { AnyARecord, AnyCnameRecord } from "dns"; import SearchBox, { Criterion } from "../SearchBox"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; import { Suspense } from "react"; interface Props { - Title: string; - TotalActiveProjectNumber: string; - TotalFees: string; - TotalBudget: string; - TotalCumulative: string; - TotalInvoicedAmount: string; - TotalReceivedAmount: string; - CashFlowStatus: string; - CostPerformanceIndex: string; - ClickedIndex: number; - Index: number; - } + Title: string; + TotalActiveProjectNumber: string; + TotalFees: string; + TotalBudget: string; + TotalCumulative: string; + TotalInvoicedAmount: string; + TotalReceivedAmount: string; + CashFlowStatus: string; + CostPerformanceIndex: string; + ClickedIndex: number; + Index: number; +} -const ProjectFinancialCard: React.FC = ({Title,TotalActiveProjectNumber,TotalFees,TotalBudget,TotalCumulative,TotalInvoicedAmount,TotalReceivedAmount,CashFlowStatus,CostPerformanceIndex,ClickedIndex,Index}) => { - const [SearchCriteria, setSearchCriteria] = React.useState({}) - const { t } = useTranslation("dashboard"); - const borderColor = CashFlowStatus === "Negative" ? "border-red-300 border-solid" : "border-green-200 border-solid" - const selectedBackgroundColor = ClickedIndex === Index ? "rgb(235 235 235)" : "rgb(255 255 255)" - console.log(ClickedIndex) - console.log(Index) - return ( - -
{Title}

-
Total Active Project
-
{TotalActiveProjectNumber}

-
Total Fees
-
{TotalFees}

-
Total Budget
-
{TotalBudget}

-
Total Cumulative Expenditure
-
{TotalCumulative}

-
Total Invoiced Amount
-
{TotalInvoicedAmount}

-
Total Received Amount
-
{TotalReceivedAmount}

-
Cash Flow Status
- {CashFlowStatus === "Negative" && ( - <>
{CashFlowStatus}

- )} - {CashFlowStatus === "Positive" && ( - <>
{CashFlowStatus}

- )} -
Cost Performance Index (CPI)
- {Number(CostPerformanceIndex) < 1 && ( - <>
{CostPerformanceIndex}
- )} - {Number(CostPerformanceIndex) >= 1 && ( - <>
{CostPerformanceIndex}
- )} -
- ); - }; - - export default ProjectFinancialCard; \ No newline at end of file +const ProjectFinancialCard: React.FC = ({ + Title, + TotalActiveProjectNumber, + TotalFees, + TotalBudget, + TotalCumulative, + TotalInvoicedAmount, + TotalReceivedAmount, + CashFlowStatus, + CostPerformanceIndex, + ClickedIndex, + Index, +}) => { + const [SearchCriteria, setSearchCriteria] = React.useState({}); + const { t } = useTranslation("dashboard"); + const borderColor = + CashFlowStatus === "Negative" + ? "border-red-300 border-solid" + : "border-green-200 border-solid"; + const selectedBackgroundColor = + ClickedIndex === Index ? "rgb(235 235 235)" : "rgb(255 255 255)"; + console.log(ClickedIndex); + console.log(Index); + return ( + +
+ {Title} +
+
+
+ Total Active Project +
+
+ {TotalActiveProjectNumber} +
+
+
+ Total Fees +
+
+ {TotalFees} +
+
+
+ Total Budget +
+
+ {TotalBudget} +
+
+
+ Total Cumulative Expenditure +
+
+ {TotalCumulative} +
+
+
+ Total Invoiced Amount +
+
+ {TotalInvoicedAmount} +
+
+
+ Total Received Amount +
+
+ {TotalReceivedAmount} +
+
+
+ Cash Flow Status +
+ {CashFlowStatus === "Negative" && ( + <> +
+ {CashFlowStatus} +
+
+ + )} + {CashFlowStatus === "Positive" && ( + <> +
+ {CashFlowStatus} +
+
+ + )} +
+ Cost Performance Index (CPI) +
+ {Number(CostPerformanceIndex) < 1 && ( + <> +
+ {CostPerformanceIndex} +
+ + )} + {Number(CostPerformanceIndex) >= 1 && ( + <> +
+ {CostPerformanceIndex} +
+ + )} +
+ ); +}; + +export default ProjectFinancialCard; diff --git a/src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx b/src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx index f497e5b..bded6dd 100644 --- a/src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx +++ b/src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx @@ -1,19 +1,19 @@ "use client"; import * as React from "react"; import Grid from "@mui/material/Grid"; -import { useState,useEffect, useMemo } from 'react' +import { useState, useEffect, useMemo } from "react"; import Paper from "@mui/material/Paper"; import { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; -import {Card,CardHeader} from '@mui/material'; +import { Card, CardHeader } from "@mui/material"; import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; -import CustomDatagrid from '../CustomDatagrid/CustomDatagrid'; -import ReactApexChart from 'react-apexcharts'; -import { ApexOptions } from 'apexcharts'; -import { GridColDef, GridRowSelectionModel} from '@mui/x-data-grid'; -import ReportProblemIcon from '@mui/icons-material/ReportProblem'; -import dynamic from 'next/dynamic'; -import '../../app/global.css'; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; import { AnyARecord, AnyCnameRecord } from "dns"; import SearchBox, { Criterion } from "../SearchBox"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; @@ -21,251 +21,453 @@ import { Suspense } from "react"; import ProjectFinancialCard from "./ProjectFinancialCard"; const ProjectFinancialSummary: React.FC = () => { - const [SearchCriteria, setSearchCriteria] = React.useState({}) + const [SearchCriteria, setSearchCriteria] = React.useState({}); 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"} - ] + { + 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 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: 3,projectCode:"M1001",projectName:"Consultancy Project A", team:"YYY", teamLeader:"YYY", startDate:"01/07/2022", targetEndDate: "01/04/2024", client:"Client B", subsidiary:"N/A"}, - {id: 4,projectCode:"M1301",projectName:"Consultancy Project AAAA", team:"YYY", teamLeader:"YYY", startDate:"01/09/2022", targetEndDate: "20/02/2024", client:"Client C", subsidiary:"Subsidiary A"}, - {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 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: 3, + projectCode: "M1001", + projectName: "Consultancy Project A", + team: "YYY", + teamLeader: "YYY", + startDate: "01/07/2022", + targetEndDate: "01/04/2024", + client: "Client B", + subsidiary: "N/A", + }, + { + id: 4, + projectCode: "M1301", + projectName: "Consultancy Project AAAA", + team: "YYY", + teamLeader: "YYY", + startDate: "01/09/2022", + targetEndDate: "20/02/2024", + client: "Client C", + subsidiary: "Subsidiary A", + }, + { + 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 rows1 = [{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"}, - ] + const rows1 = [ + { + 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", + }, + ]; - const rows2 = [{id: 3,projectCode:"M1001",projectName:"Consultancy Project A", team:"YYY", teamLeader:"YYY", startDate:"01/07/2022", targetEndDate: "01/04/2024", client:"Client B", subsidiary:"N/A"}, - {id: 4,projectCode:"M1301",projectName:"Consultancy Project AAAA", team:"YYY", teamLeader:"YYY", startDate:"01/09/2022", targetEndDate: "20/02/2024", client:"Client C", subsidiary:"Subsidiary A"}, - {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 rows2 = [ + { + id: 3, + projectCode: "M1001", + projectName: "Consultancy Project A", + team: "YYY", + teamLeader: "YYY", + startDate: "01/07/2022", + targetEndDate: "01/04/2024", + client: "Client B", + subsidiary: "N/A", + }, + { + id: 4, + projectCode: "M1301", + projectName: "Consultancy Project AAAA", + team: "YYY", + teamLeader: "YYY", + startDate: "01/09/2022", + targetEndDate: "20/02/2024", + client: "Client C", + subsidiary: "Subsidiary A", + }, + { + 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,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", totalUnReceivedAmount:"0.00"} - ] + const projectFinancialRows = [ + { + id: 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", + totalUnReceivedAmount: "0.00", + }, + ]; const [isCardClickedIndex, setIsCardClickedIndex] = React.useState(0); - const [selectedTeamData, setSelectedTeamData] : any[] = React.useState(rows0); + const [selectedTeamData, setSelectedTeamData]: any[] = React.useState(rows0); - const handleCardClick = (r:any) => { - setIsCardClickedIndex(r) - if (r === 0) { - setSelectedTeamData(rows0) - } else if (r === 1) { - setSelectedTeamData(rows1) - } else if (r === 2) { - setSelectedTeamData(rows2) - } - + const handleCardClick = (r: any) => { + setIsCardClickedIndex(r); + if (r === 0) { + setSelectedTeamData(rows0); + } else if (r === 1) { + setSelectedTeamData(rows1); + } else if (r === 2) { + setSelectedTeamData(rows2); + } }; - const columns = [ { - id: 'projectCode', - field: 'projectCode', + id: "projectCode", + field: "projectCode", headerName: "Project Code", flex: 1, - }, - { - id: 'projectName', - field: 'projectName', + }, + { + id: "projectName", + field: "projectName", headerName: "Project Name", flex: 1, - }, - { - id: 'team', - field: 'team', - headerName: "Team", - flex: 1, - }, - { - id: 'teamLeader', - field: 'teamLeader', - headerName: "Team Leader", - flex: 1, - }, - { - id: 'startDate', - field: 'startDate', - headerName: "Start Date", - flex: 1, - }, - { - id: 'targetEndDate', - field: 'targetEndDate', - headerName: "Target End Date", - flex: 1, - }, - { - id: 'client', - field: 'client', - headerName: "Client", - flex: 1, - }, - { - id: 'subsidiary', - field: 'subsidiary', - headerName: "Subsidiary", - flex: 1, - }, -]; + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 1, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, + }, + { + id: "startDate", + field: "startDate", + headerName: "Start Date", + flex: 1, + }, + { + id: "targetEndDate", + field: "targetEndDate", + headerName: "Target End Date", + flex: 1, + }, + { + id: "client", + field: "client", + headerName: "Client", + flex: 1, + }, + { + id: "subsidiary", + field: "subsidiary", + headerName: "Subsidiary", + flex: 1, + }, + ]; -const columns2 = [ - { - id: 'cashFlowStatus', - field: 'cashFlowStatus', - headerName: "Cash Flow Status", - flex: 1, - renderCell: (params:any) => { - if (params.row.cashFlowStatus === "Positive") { - return ( - {params.row.cashFlowStatus} - ) - } else if (params.row.cashFlowStatus === "Negative") { - return ( - {params.row.cashFlowStatus} - ) - } - }, -}, -{ - id: 'cpi', - field: 'cpi', - headerName: "CPI", - flex: 0.7, - renderCell: (params:any) => { - if (params.row.cpi >= 1) { - return ( - {params.row.cpi} - ) - } else if (params.row.cpi < 1) { - return ( - {params.row.cpi} - ) - } - }, -}, -{ - id: 'totalFees', - field: 'totalFees', - headerName: "Total Fees (HKD)", - flex: 1, - renderCell: (params:any) => { - return ( - ${params.row.totalFees} - ) - }, -}, -{ - id: 'totalBudget', - field: 'totalBudget', - headerName: "Total Budget (HKD)", - flex: 1, - renderCell: (params:any) => { - return ( - ${params.row.totalBudget} - ) -}, -}, -{ - id: 'totalCumulativeExpenditure', - field: 'totalCumulativeExpenditure', - headerName: "Total Cumulative Expenditure (HKD)", - flex: 1, - renderCell: (params:any) => { - return ( - ${params.row.totalCumulativeExpenditure} - ) - }, -}, -{ - id: 'totalInvoicedAmount', - field: 'totalInvoicedAmount', - headerName: "Total Invoiced Amount (HKD)", - flex: 1, - renderCell: (params:any) => { - return ( - ${params.row.totalInvoicedAmount} - ) - }, -}, -{ - id: 'totalUnInvoicedAmount', - field: 'totalUnInvoicedAmount', - headerName: "Total Un-invoiced Amount (HKD)", - flex: 1, - renderCell: (params:any) => { - return ( - ${params.row.totalUnInvoicedAmount} - ) - }, -}, -{ - id: 'totalReceivedAmount', - field: 'totalReceivedAmount', - headerName: "Total Received Amount (HKD)", - flex: 1, - renderCell: (params:any) => { - return ( - ${params.row.totalReceivedAmount} - ) - }, -}, -{ - id: 'totalUnReceivedAmount', - field: 'totalUnReceivedAmount', - headerName: "Total Un-received Amount (HKD)", - flex: 1, - renderCell: (params:any) => { - return ( - ${params.row.totalUnReceivedAmount} - ) - }, -}, -]; + const columns2 = [ + { + id: "cashFlowStatus", + field: "cashFlowStatus", + headerName: "Cash Flow Status", + flex: 1, + renderCell: (params: any) => { + if (params.row.cashFlowStatus === "Positive") { + return ( + {params.row.cashFlowStatus} + ); + } else if (params.row.cashFlowStatus === "Negative") { + return ( + {params.row.cashFlowStatus} + ); + } + }, + }, + { + id: "cpi", + field: "cpi", + headerName: "CPI", + flex: 0.7, + renderCell: (params: any) => { + if (params.row.cpi >= 1) { + return {params.row.cpi}; + } else if (params.row.cpi < 1) { + return {params.row.cpi}; + } + }, + }, + { + id: "totalFees", + field: "totalFees", + headerName: "Total Fees (HKD)", + flex: 1, + renderCell: (params: any) => { + return ${params.row.totalFees}; + }, + }, + { + id: "totalBudget", + field: "totalBudget", + headerName: "Total Budget (HKD)", + flex: 1, + renderCell: (params: any) => { + return ${params.row.totalBudget}; + }, + }, + { + id: "totalCumulativeExpenditure", + field: "totalCumulativeExpenditure", + headerName: "Total Cumulative Expenditure (HKD)", + flex: 1, + renderCell: (params: any) => { + return ${params.row.totalCumulativeExpenditure}; + }, + }, + { + id: "totalInvoicedAmount", + field: "totalInvoicedAmount", + headerName: "Total Invoiced Amount (HKD)", + flex: 1, + renderCell: (params: any) => { + return ${params.row.totalInvoicedAmount}; + }, + }, + { + id: "totalUnInvoicedAmount", + field: "totalUnInvoicedAmount", + headerName: "Total Un-invoiced Amount (HKD)", + flex: 1, + renderCell: (params: any) => { + return ${params.row.totalUnInvoicedAmount}; + }, + }, + { + id: "totalReceivedAmount", + field: "totalReceivedAmount", + headerName: "Total Received Amount (HKD)", + flex: 1, + renderCell: (params: any) => { + return ${params.row.totalReceivedAmount}; + }, + }, + { + id: "totalUnReceivedAmount", + field: "totalUnReceivedAmount", + headerName: "Total Un-received Amount (HKD)", + flex: 1, + renderCell: (params: any) => { + return ${params.row.totalUnReceivedAmount}; + }, + }, + ]; const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { - const selectedRowsData = selectedTeamData.filter((row:any) => - newSelectionModel.includes(row.id) + const selectedRowsData = selectedTeamData.filter((row: any) => + newSelectionModel.includes(row.id), ); - console.log(selectedRowsData) - } + console.log(selectedRowsData); + }; return ( - - - -
- {projectFinancialData.map((record, index) => ( -
handleCardClick(index)}> - -
- ))} -
-
- - -
- -
-
- - -
- -
-
-
+ + + +
+ {projectFinancialData.map((record, index) => ( +
handleCardClick(index)} + > + +
+ ))} +
+
+ + +
+ +
+
+ + +
+ +
+
+
); }; diff --git a/src/components/StaffUtilization/StaffUtilization.tsx b/src/components/StaffUtilization/StaffUtilization.tsx index 355a3e6..623e37a 100644 --- a/src/components/StaffUtilization/StaffUtilization.tsx +++ b/src/components/StaffUtilization/StaffUtilization.tsx @@ -1,34 +1,34 @@ "use client"; import * as React from "react"; import Grid from "@mui/material/Grid"; -import { useState,useEffect, useMemo } from 'react' +import { useState, useEffect, useMemo } from "react"; import Paper from "@mui/material/Paper"; import { TFunction } from "i18next"; import { useTranslation } from "react-i18next"; -import {Card,CardHeader} from '@mui/material'; +import { Card, CardHeader } from "@mui/material"; import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; -import CustomDatagrid from '../CustomDatagrid/CustomDatagrid'; -import ReactApexChart from 'react-apexcharts'; -import { ApexOptions } from 'apexcharts'; -import { GridColDef, GridRowSelectionModel} from '@mui/x-data-grid'; -import ReportProblemIcon from '@mui/icons-material/ReportProblem'; -import dynamic from 'next/dynamic'; -import '../../app/global.css'; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; import { AnyARecord, AnyCnameRecord } from "dns"; import SearchBox, { Criterion } from "../SearchBox"; import ProgressByClientSearch from "@/components/ProgressByClientSearch"; import { Suspense } from "react"; import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; -import {Input,Label} from "reactstrap"; -import Select, {components} from 'react-select'; -import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; -import dayjs, { Dayjs } from 'dayjs'; -import isBetweenPlugin from 'dayjs/plugin/isBetween'; -import { PickersDay, PickersDayProps } from '@mui/x-date-pickers/PickersDay'; -import { styled } from '@mui/material/styles'; +import { Input, Label } from "reactstrap"; +import Select, { components } from "react-select"; +import { DateCalendar } from "@mui/x-date-pickers/DateCalendar"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import dayjs, { Dayjs } from "dayjs"; +import isBetweenPlugin from "dayjs/plugin/isBetween"; +import { PickersDay, PickersDayProps } from "@mui/x-date-pickers/PickersDay"; +import { styled } from "@mui/material/styles"; dayjs.extend(isBetweenPlugin); interface CustomPickerDayProps extends PickersDayProps { @@ -37,29 +37,29 @@ interface CustomPickerDayProps extends PickersDayProps { } const CustomPickersDay = styled(PickersDay, { - shouldForwardProp: (prop) => prop !== 'isSelected' && prop !== 'isHovered', + shouldForwardProp: (prop) => prop !== "isSelected" && prop !== "isHovered", })(({ theme, isSelected, isHovered, day }) => ({ borderRadius: 0, ...(isSelected && { backgroundColor: theme.palette.primary.main, color: theme.palette.primary.contrastText, - '&:hover, &:focus': { + "&:hover, &:focus": { backgroundColor: theme.palette.primary.main, }, }), ...(isHovered && { backgroundColor: theme.palette.primary[theme.palette.mode], - '&:hover, &:focus': { + "&:hover, &:focus": { backgroundColor: theme.palette.primary[theme.palette.mode], }, }), ...(day.day() === 0 && { - borderTopLeftRadius: '50%', - borderBottomLeftRadius: '50%', + borderTopLeftRadius: "50%", + borderBottomLeftRadius: "50%", }), ...(day.day() === 6 && { - borderTopRightRadius: '50%', - borderBottomRightRadius: '50%', + borderTopRightRadius: "50%", + borderBottomRightRadius: "50%", }), })) as React.ComponentType; @@ -68,7 +68,7 @@ const isInSameWeek = (dayA: Dayjs, dayB: Dayjs | null | undefined) => { return false; } - return dayA.isSame(dayB, 'week'); + return dayA.isSame(dayB, "week"); }; function Day( @@ -93,126 +93,188 @@ function Day( } const StaffUtilization: React.FC = () => { - const todayDate = new Date; - const firstDayOfWeek = new Date; - const lastDayOfWeek = new Date; + const todayDate = new Date(); + const firstDayOfWeek = new Date(); + const lastDayOfWeek = new Date(); firstDayOfWeek.setDate(todayDate.getDate() - todayDate.getDay() + 1); lastDayOfWeek.setDate(todayDate.getDate() - todayDate.getDay() + 7); - const firstDayOfMonth = new Date(todayDate.getFullYear(), todayDate.getMonth(), 1); - const lastDayOfMonth = new Date(todayDate.getFullYear(), todayDate.getMonth() + 1, 0); - const [firstDayOfWeekString, setFirstDayOfWeekString] = React.useState(dayjs(firstDayOfWeek).format('DD MMM YYYY')); - const [lastDayOfWeekString, setLastDayOfWeekString] = React.useState(dayjs(lastDayOfWeek).format('DD MMM YYYY')); - const [firstDayOfMonthString, setFirstDayOfMonthString] = React.useState(dayjs(firstDayOfMonth).format('DD MMM YYYY')); - const [lastDayOfMonthString, setLastDayOfMonthString] = React.useState(dayjs(lastDayOfMonth).format('DD MMM YYYY')) - const [selectionModel, setSelectionModel] : any[] = React.useState([]); - const [manHoursSpentPeriod, setManHoursSpentPeriod] : any[] = React.useState(firstDayOfWeekString + " to " + lastDayOfWeekString); - const [teamTotalManhoursSpentSelect, setTeamTotalManhoursSpentSelect] :any = React.useState("Weekly") - const [staffGradeManhoursSpentSelect, setStaffGradeManhoursSpentSelect] :any = React.useState("Weekly") - const [individualStaffManhoursSpentSelect, setIndividualStaffManhoursSpentSelect] :any = React.useState("Daily") - const weekDates :any[] = []; - const monthDates :any[] = []; + const firstDayOfMonth = new Date( + todayDate.getFullYear(), + todayDate.getMonth(), + 1, + ); + const lastDayOfMonth = new Date( + todayDate.getFullYear(), + todayDate.getMonth() + 1, + 0, + ); + const [firstDayOfWeekString, setFirstDayOfWeekString] = React.useState( + dayjs(firstDayOfWeek).format("DD MMM YYYY"), + ); + const [lastDayOfWeekString, setLastDayOfWeekString] = React.useState( + dayjs(lastDayOfWeek).format("DD MMM YYYY"), + ); + const [firstDayOfMonthString, setFirstDayOfMonthString] = React.useState( + dayjs(firstDayOfMonth).format("DD MMM YYYY"), + ); + const [lastDayOfMonthString, setLastDayOfMonthString] = React.useState( + dayjs(lastDayOfMonth).format("DD MMM YYYY"), + ); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const [manHoursSpentPeriod, setManHoursSpentPeriod]: any[] = React.useState( + firstDayOfWeekString + " to " + lastDayOfWeekString, + ); + const [teamTotalManhoursSpentSelect, setTeamTotalManhoursSpentSelect]: any = + React.useState("Weekly"); + const [staffGradeManhoursSpentSelect, setStaffGradeManhoursSpentSelect]: any = + React.useState("Weekly"); + const [ + individualStaffManhoursSpentSelect, + setIndividualStaffManhoursSpentSelect, + ]: any = React.useState("Daily"); + const weekDates: any[] = []; + const monthDates: any[] = []; const currentDate = dayjs(); - const sixMonthsAgo = currentDate.subtract(6, 'month'); + const sixMonthsAgo = currentDate.subtract(6, "month"); for (let i = 0; i < 7; i++) { - const currentDate = new Date(firstDayOfWeek); - currentDate.setDate(firstDayOfWeek.getDate() + i); - const formattedDate = dayjs(currentDate).format('DD MMM (ddd)'); - weekDates.push(formattedDate); + const currentDate = new Date(firstDayOfWeek); + currentDate.setDate(firstDayOfWeek.getDate() + i); + const formattedDate = dayjs(currentDate).format("DD MMM (ddd)"); + weekDates.push(formattedDate); } - for (let date = sixMonthsAgo.clone(); date.isBefore(currentDate, 'month'); date = date.add(1, 'month')) { - monthDates.push(date.format('MM-YYYY')); + for ( + let date = sixMonthsAgo.clone(); + date.isBefore(currentDate, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); } - monthDates.push(currentDate.format('MM-YYYY')); -// for (let i = firstDayOfMonth.getDate(); i <= lastDayOfMonth.getDate(); i++) { -// const currentDate = new Date(todayDate.getFullYear(), todayDate.getMonth(), i); -// const formattedDate = dayjs(currentDate).format('DD MMM'); -// monthDates.push(formattedDate); -// } - const [teamTotalManhoursSpentPeriod, setTeamTotalManhoursSpentPeriod] : any[] = React.useState(weekDates) - const [teamTotalManhoursByStaffGrade, setTeamTotalManhoursByStaffGrade] : any[] = React.useState(weekDates) - const [individualStaffManhoursSpentPeriod, setIndividualStaffManhoursSpentPeriod] : any[] = React.useState(weekDates) - const [teamTotalManhoursSpentPlanData, setTeamTotalManhoursSpentPlanData] : any[] = React.useState([42,42,42,42,42,0,0]) - const [teamTotalManhoursSpentActualData, setTeamTotalManhoursSpentActualData] : any[] = React.useState([45,42,60,42,58,0,0]) + monthDates.push(currentDate.format("MM-YYYY")); + // for (let i = firstDayOfMonth.getDate(); i <= lastDayOfMonth.getDate(); i++) { + // const currentDate = new Date(todayDate.getFullYear(), todayDate.getMonth(), i); + // const formattedDate = dayjs(currentDate).format('DD MMM'); + // monthDates.push(formattedDate); + // } + const [teamTotalManhoursSpentPeriod, setTeamTotalManhoursSpentPeriod]: any[] = + React.useState(weekDates); + const [ + teamTotalManhoursByStaffGrade, + setTeamTotalManhoursByStaffGrade, + ]: any[] = React.useState(weekDates); + const [ + individualStaffManhoursSpentPeriod, + setIndividualStaffManhoursSpentPeriod, + ]: any[] = React.useState(weekDates); + const [ + teamTotalManhoursSpentPlanData, + setTeamTotalManhoursSpentPlanData, + ]: any[] = React.useState([42, 42, 42, 42, 42, 0, 0]); + const [ + teamTotalManhoursSpentActualData, + setTeamTotalManhoursSpentActualData, + ]: any[] = React.useState([45, 42, 60, 42, 58, 0, 0]); const [hoveredDay, setHoveredDay] = React.useState(null); const [value, setValue] = React.useState(dayjs()); - const [weeklyValueByStaffGrade, setWeeklyValueByStaffGrade] = React.useState(dayjs()); - const [weeklyValueByIndividualStaff, setWeeklyValueByIndividualStaff] = React.useState(dayjs()); - const [staffGradeManhoursSpentValue, setStaffGradeManhoursSpentValue] = React.useState(dayjs()); - const [totalManHoursMonthlyFromValue, setTotalManHoursMonthlyFromValue] = React.useState(dayjs(new Date).subtract(6, 'month')); - const [totalManHoursMonthlyToValue, setTotalManHoursMonthlyToValue] = React.useState(dayjs()); - const [totalManHoursByStaffGradeMonthlyFromValue, setTotalManHoursByStaffGradeMonthlyFromValue] = React.useState(dayjs(new Date).subtract(6, 'month')); - const [totalManHoursByStaffGradeMonthlyToValue, setTotalManHoursByStaffGradeMonthlyToValue] = React.useState(dayjs()); - const [totalManHoursByIndividualStaffMonthlyFromValue, setTotalManHoursByIndividualStaffMonthlyFromValue] = React.useState(dayjs(new Date).subtract(6, 'month')); - const [totalManHoursByIndividualStaffMonthlyToValue, setTotalManHoursByIndividualStaffMonthlyToValue] = React.useState(dayjs()); - const [totalManHoursByIndividualStaffDailyFromValue, setTotalManHoursByIndividualStaffDailyFromValue] = React.useState(dayjs(new Date).subtract(6, 'day')); - const [totalManHoursByIndividualStaffDailyToValue, setTotalManHoursByIndividualStaffDailyToValue] = React.useState(dayjs()); + const [weeklyValueByStaffGrade, setWeeklyValueByStaffGrade] = + React.useState(dayjs()); + const [weeklyValueByIndividualStaff, setWeeklyValueByIndividualStaff] = + React.useState(dayjs()); + const [staffGradeManhoursSpentValue, setStaffGradeManhoursSpentValue] = + React.useState(dayjs()); + const [totalManHoursMonthlyFromValue, setTotalManHoursMonthlyFromValue] = + React.useState(dayjs(new Date()).subtract(6, "month")); + const [totalManHoursMonthlyToValue, setTotalManHoursMonthlyToValue] = + React.useState(dayjs()); + const [ + totalManHoursByStaffGradeMonthlyFromValue, + setTotalManHoursByStaffGradeMonthlyFromValue, + ] = React.useState(dayjs(new Date()).subtract(6, "month")); + const [ + totalManHoursByStaffGradeMonthlyToValue, + setTotalManHoursByStaffGradeMonthlyToValue, + ] = React.useState(dayjs()); + const [ + totalManHoursByIndividualStaffMonthlyFromValue, + setTotalManHoursByIndividualStaffMonthlyFromValue, + ] = React.useState(dayjs(new Date()).subtract(6, "month")); + const [ + totalManHoursByIndividualStaffMonthlyToValue, + setTotalManHoursByIndividualStaffMonthlyToValue, + ] = React.useState(dayjs()); + const [ + totalManHoursByIndividualStaffDailyFromValue, + setTotalManHoursByIndividualStaffDailyFromValue, + ] = React.useState(dayjs(new Date()).subtract(6, "day")); + const [ + totalManHoursByIndividualStaffDailyToValue, + setTotalManHoursByIndividualStaffDailyToValue, + ] = React.useState(dayjs()); const [totalManHoursMaxValue, setTotalManHoursMaxValue] = React.useState(75); - const teamOptions = [ - { value: 1, label: 'XXX Team' }, - { value: 2, label: 'YYY Team' }, - { value: 3, label: 'ZZZ Team' } - ] + { value: 1, label: "XXX Team" }, + { value: 2, label: "YYY Team" }, + { value: 3, label: "ZZZ Team" }, + ]; const columns = [ { - id: 'projectCode', - field: 'projectCode', + id: "projectCode", + field: "projectCode", headerName: "Project Code", flex: 1, - }, - { - id: 'projectName', - field: 'projectName', + }, + { + id: "projectName", + field: "projectName", headerName: "Project Name", flex: 1, - }, - { - id: 'team', - field: 'team', - headerName: "Team", - flex: 1, - }, - { - id: 'teamLeader', - field: 'teamLeader', - headerName: "Team Leader", - flex: 1, - }, - { - id: 'startDate', - field: 'startDate', - headerName: "Start Date", - flex: 1, - }, - { - id: 'targetEndDate', - field: 'targetEndDate', - headerName: "Target End Date", - flex: 1, - }, - { - id: 'client', - field: 'client', - headerName: "Client", - flex: 1, - }, - { - id: 'subsidiary', - field: 'subsidiary', - headerName: "Subsidiary", - flex: 1, - }, + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 1, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, + }, + { + id: "startDate", + field: "startDate", + headerName: "Start Date", + flex: 1, + }, + { + id: "targetEndDate", + field: "targetEndDate", + headerName: "Target End Date", + flex: 1, + }, + { + id: "client", + field: "client", + headerName: "Client", + flex: 1, + }, + { + id: "subsidiary", + field: "subsidiary", + headerName: "Subsidiary", + flex: 1, + }, ]; const options: ApexOptions = { chart: { height: 350, - type: 'line', + type: "line", }, stroke: { - width: [2, 2] + width: [2, 2], }, plotOptions: { bar: { @@ -221,50 +283,48 @@ const StaffUtilization: React.FC = () => { }, }, dataLabels: { - enabled: true + enabled: true, }, xaxis: { - categories: teamTotalManhoursSpentPeriod + categories: teamTotalManhoursSpentPeriod, }, yaxis: [ - { title: { - text: 'Team Total Manhours Spent (Hour)' + text: "Team Total Manhours Spent (Hour)", }, min: 0, max: totalManHoursMaxValue, - tickAmount: 5 + tickAmount: 5, }, - ], + ], grid: { - borderColor: '#f1f1f1', + borderColor: "#f1f1f1", }, - annotations: { - }, - series:[ + annotations: {}, + series: [ { - name:"Planned", - type:"line", + name: "Planned", + type: "line", color: "#efbe7d", - data:teamTotalManhoursSpentPlanData + data: teamTotalManhoursSpentPlanData, }, { - name:"Actual", - type:"line", + name: "Actual", + type: "line", color: "#7cd3f2", - data:teamTotalManhoursSpentActualData - } - ] + data: teamTotalManhoursSpentActualData, + }, + ], }; const staffGradeOptions: ApexOptions = { chart: { height: 350, - type: 'line', + type: "line", }, stroke: { - width: [2, 2] + width: [2, 2], }, plotOptions: { bar: { @@ -273,7 +333,7 @@ const StaffUtilization: React.FC = () => { }, }, dataLabels: { - enabled: true + enabled: true, }, xaxis: { categories: [ @@ -281,48 +341,46 @@ const StaffUtilization: React.FC = () => { "Grade 2: QS", "Grade 3: Senior QS", "Grade 4: Manager", - "Grade 5: Director" - ] + "Grade 5: Director", + ], }, yaxis: [ - { title: { - text: 'Staff Grade' + text: "Staff Grade", }, min: 0, max: 60, - tickAmount: 5 + tickAmount: 5, }, - ], + ], grid: { - borderColor: '#f1f1f1', + borderColor: "#f1f1f1", }, - annotations: { - }, - series:[ + annotations: {}, + series: [ { - name:"Planned", - type:"bar", + name: "Planned", + type: "bar", color: "#efbe7d", - data:[35,45,35,20,10] + data: [35, 45, 35, 20, 10], }, { - name:"Actual", - type:"bar", + name: "Actual", + type: "bar", color: "#00acb1", - data:[25,26,33,20,11] - } - ] + data: [25, 26, 33, 20, 11], + }, + ], }; const individualStaffOptions: ApexOptions = { chart: { height: 350, - type: 'line', + type: "line", }, stroke: { - width: [1] + width: [1], }, plotOptions: { bar: { @@ -331,7 +389,7 @@ const StaffUtilization: React.FC = () => { }, }, dataLabels: { - enabled: true + enabled: true, }, xaxis: { categories: [ @@ -339,270 +397,313 @@ const StaffUtilization: React.FC = () => { "Consultancy Project 456 (CUST-001, Subsidiary A)", "Construction Project A (CUST-001, Subsidiary A)", "Construction Project B (CUST-001, Subsidiary A)", - "Construction Project C (CUST-001, Subsidiary A)" - ] + "Construction Project C (CUST-001, Subsidiary A)", + ], }, yaxis: [ - { title: { - text: 'Project' + text: "Project", }, min: 0, max: 12, - tickAmount: 5 + tickAmount: 5, }, - ], + ], grid: { - borderColor: '#f1f1f1', + borderColor: "#f1f1f1", }, - annotations: { - }, - series:[ + annotations: {}, + series: [ { - name:"Manhours(Hour)", - type:"bar", + name: "Manhours(Hour)", + type: "bar", color: "#00acb1", - data:[12,12,11,12,0] - } - ] + data: [12, 12, 11, 12, 0], + }, + ], }; - const teamTotalManhoursSpentOnClick = (r:any) => { - setTeamTotalManhoursSpentSelect(r) + const teamTotalManhoursSpentOnClick = (r: any) => { + setTeamTotalManhoursSpentSelect(r); if (r === "Weekly") { - setValue(dayjs(new Date)) - setTeamTotalManhoursSpentPeriod(weekDates) - setTeamTotalManhoursSpentPlanData([42,42,42,42,42,0,0]) - setTeamTotalManhoursSpentActualData([45,42,60,42,58,0,0]) - setTotalManHoursMaxValue(75) + setValue(dayjs(new Date())); + setTeamTotalManhoursSpentPeriod(weekDates); + setTeamTotalManhoursSpentPlanData([42, 42, 42, 42, 42, 0, 0]); + setTeamTotalManhoursSpentActualData([45, 42, 60, 42, 58, 0, 0]); + setTotalManHoursMaxValue(75); } else if (r === "Monthly") { - setTeamTotalManhoursSpentPeriod(monthDates) - setTeamTotalManhoursSpentPlanData([840,840,840,840,840,840]) - setTeamTotalManhoursSpentActualData([900,840,1200,840,1160,840]) - setTotalManHoursMaxValue(1250) + setTeamTotalManhoursSpentPeriod(monthDates); + setTeamTotalManhoursSpentPlanData([840, 840, 840, 840, 840, 840]); + setTeamTotalManhoursSpentActualData([900, 840, 1200, 840, 1160, 840]); + setTotalManHoursMaxValue(1250); } -}; + }; -const individualStaffManhoursSpentOnClick = (r:any) => { - setIndividualStaffManhoursSpentSelect(r) - // if (r === "Weekly") { - // setValue(dayjs(new Date)) - // setTeamTotalManhoursSpentPeriod(weekDates) - // setTeamTotalManhoursSpentPlanData([42,42,42,42,42,0,0]) - // setTeamTotalManhoursSpentActualData([45,42,60,42,58,0,0]) - // setTotalManHoursMaxValue(75) - // } else if (r === "Monthly") { - // setTeamTotalManhoursSpentPeriod(monthDates) - // setTeamTotalManhoursSpentPlanData([840,840,840,840,840,840]) - // setTeamTotalManhoursSpentActualData([900,840,1200,840,1160,840]) - // setTotalManHoursMaxValue(1250) - // } -}; + const individualStaffManhoursSpentOnClick = (r: any) => { + setIndividualStaffManhoursSpentSelect(r); + // if (r === "Weekly") { + // setValue(dayjs(new Date)) + // setTeamTotalManhoursSpentPeriod(weekDates) + // setTeamTotalManhoursSpentPlanData([42,42,42,42,42,0,0]) + // setTeamTotalManhoursSpentActualData([45,42,60,42,58,0,0]) + // setTotalManHoursMaxValue(75) + // } else if (r === "Monthly") { + // setTeamTotalManhoursSpentPeriod(monthDates) + // setTeamTotalManhoursSpentPlanData([840,840,840,840,840,840]) + // setTeamTotalManhoursSpentActualData([900,840,1200,840,1160,840]) + // setTotalManHoursMaxValue(1250) + // } + }; -const selectWeeklyPeriod = (r:any) => { - const selectDate = new Date(r); - const firstDayOfWeek = new Date; - firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); - const weekDates :any[] = []; - for (let i = 0; i < 7; i++) { - const currentDate = new Date(firstDayOfWeek); - currentDate.setDate(firstDayOfWeek.getDate() + i); - const formattedDate = dayjs(currentDate).format('DD MMM (ddd)'); - weekDates.push(formattedDate); - } - setTeamTotalManhoursSpentPeriod(weekDates) - setValue(dayjs(firstDayOfWeek)) -} + const selectWeeklyPeriod = (r: any) => { + const selectDate = new Date(r); + const firstDayOfWeek = new Date(); + firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); + const weekDates: any[] = []; + for (let i = 0; i < 7; i++) { + const currentDate = new Date(firstDayOfWeek); + currentDate.setDate(firstDayOfWeek.getDate() + i); + const formattedDate = dayjs(currentDate).format("DD MMM (ddd)"); + weekDates.push(formattedDate); + } + setTeamTotalManhoursSpentPeriod(weekDates); + setValue(dayjs(firstDayOfWeek)); + }; -const selectWeeklyPeriodByStaffGrade = (r:any) => { - const selectDate = new Date(r); - const firstDayOfWeek = new Date; - firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); - const weekDates :any[] = []; - for (let i = 0; i < 7; i++) { - const currentDate = new Date(firstDayOfWeek); - currentDate.setDate(firstDayOfWeek.getDate() + i); - const formattedDate = dayjs(currentDate).format('DD MMM (ddd)'); - weekDates.push(formattedDate); - } - setTeamTotalManhoursByStaffGrade(weekDates) - setWeeklyValueByStaffGrade(dayjs(firstDayOfWeek)) -} + const selectWeeklyPeriodByStaffGrade = (r: any) => { + const selectDate = new Date(r); + const firstDayOfWeek = new Date(); + firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); + const weekDates: any[] = []; + for (let i = 0; i < 7; i++) { + const currentDate = new Date(firstDayOfWeek); + currentDate.setDate(firstDayOfWeek.getDate() + i); + const formattedDate = dayjs(currentDate).format("DD MMM (ddd)"); + weekDates.push(formattedDate); + } + setTeamTotalManhoursByStaffGrade(weekDates); + setWeeklyValueByStaffGrade(dayjs(firstDayOfWeek)); + }; -const selectWeeklyPeriodIndividualStaff = (r:any) => { - const selectDate = new Date(r); - const firstDayOfWeek = new Date; - firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); - const weekDates :any[] = []; - for (let i = 0; i < 7; i++) { - const currentDate = new Date(firstDayOfWeek); - currentDate.setDate(firstDayOfWeek.getDate() + i); - const formattedDate = dayjs(currentDate).format('DD MMM (ddd)'); - weekDates.push(formattedDate); - } - setIndividualStaffManhoursSpentPeriod(weekDates) - setWeeklyValueByIndividualStaff(dayjs(firstDayOfWeek)) -} + const selectWeeklyPeriodIndividualStaff = (r: any) => { + const selectDate = new Date(r); + const firstDayOfWeek = new Date(); + firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); + const weekDates: any[] = []; + for (let i = 0; i < 7; i++) { + const currentDate = new Date(firstDayOfWeek); + currentDate.setDate(firstDayOfWeek.getDate() + i); + const formattedDate = dayjs(currentDate).format("DD MMM (ddd)"); + weekDates.push(formattedDate); + } + setIndividualStaffManhoursSpentPeriod(weekDates); + setWeeklyValueByIndividualStaff(dayjs(firstDayOfWeek)); + }; -const selectMonthlyPeriodFrom = (r:any) => { - const monthDates :any[] = []; - const monthPlanData :any[] = []; - const monthActualData :any[] = []; - const selectFromDate = dayjs(r); - for (let date = selectFromDate.clone(); date.isBefore(totalManHoursMonthlyToValue, 'month'); date = date.add(1, 'month')) { - monthDates.push(date.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - } - monthDates.push(totalManHoursMonthlyToValue.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - setTeamTotalManhoursSpentPlanData(monthPlanData) - setTeamTotalManhoursSpentActualData(monthActualData) - setTeamTotalManhoursSpentPeriod(monthDates) -} + const selectMonthlyPeriodFrom = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectFromDate = dayjs(r); + for ( + let date = selectFromDate.clone(); + date.isBefore(totalManHoursMonthlyToValue, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + setTeamTotalManhoursSpentPlanData(monthPlanData); + setTeamTotalManhoursSpentActualData(monthActualData); + setTeamTotalManhoursSpentPeriod(monthDates); + }; -const selectMonthlyPeriodTo = (r:any) => { - const monthDates :any[] = []; - const monthPlanData :any[] = []; - const monthActualData :any[] = []; - const selectToDate = dayjs(r); - for (let date = totalManHoursMonthlyFromValue.clone(); date.isBefore(selectToDate, 'month'); date = date.add(1, 'month')) { - monthDates.push(date.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - } - monthDates.push(selectToDate.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - setTeamTotalManhoursSpentPlanData(monthPlanData) - setTeamTotalManhoursSpentActualData(monthActualData) - setTeamTotalManhoursSpentPeriod(monthDates) -} + const selectMonthlyPeriodTo = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectToDate = dayjs(r); + for ( + let date = totalManHoursMonthlyFromValue.clone(); + date.isBefore(selectToDate, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(selectToDate.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + setTeamTotalManhoursSpentPlanData(monthPlanData); + setTeamTotalManhoursSpentActualData(monthActualData); + setTeamTotalManhoursSpentPeriod(monthDates); + }; -const selectStaffGradeMonthlyPeriodFrom = (r:any) => { - const monthDates :any[] = []; - const monthPlanData :any[] = []; - const monthActualData :any[] = []; - const selectFromDate = dayjs(r); - for (let date = selectFromDate.clone(); date.isBefore(totalManHoursMonthlyToValue, 'month'); date = date.add(1, 'month')) { - monthDates.push(date.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - } - monthDates.push(totalManHoursMonthlyToValue.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - // setTeamTotalManhoursSpentPlanData(monthPlanData) - // setTeamTotalManhoursSpentActualData(monthActualData) - setTeamTotalManhoursByStaffGrade(weekDates) -} + const selectStaffGradeMonthlyPeriodFrom = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectFromDate = dayjs(r); + for ( + let date = selectFromDate.clone(); + date.isBefore(totalManHoursMonthlyToValue, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + // setTeamTotalManhoursSpentPlanData(monthPlanData) + // setTeamTotalManhoursSpentActualData(monthActualData) + setTeamTotalManhoursByStaffGrade(weekDates); + }; -const selectStaffGradeMonthlyPeriodTo = (r:any) => { - const monthDates :any[] = []; - const monthPlanData :any[] = []; - const monthActualData :any[] = []; - const selectToDate = dayjs(r); - for (let date = totalManHoursMonthlyFromValue.clone(); date.isBefore(selectToDate, 'month'); date = date.add(1, 'month')) { - monthDates.push(date.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - } - monthDates.push(selectToDate.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - // setTeamTotalManhoursSpentPlanData(monthPlanData) - // setTeamTotalManhoursSpentActualData(monthActualData) - setTeamTotalManhoursByStaffGrade(weekDates) -} + const selectStaffGradeMonthlyPeriodTo = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectToDate = dayjs(r); + for ( + let date = totalManHoursMonthlyFromValue.clone(); + date.isBefore(selectToDate, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(selectToDate.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + // setTeamTotalManhoursSpentPlanData(monthPlanData) + // setTeamTotalManhoursSpentActualData(monthActualData) + setTeamTotalManhoursByStaffGrade(weekDates); + }; -const selectIndividualStaffMonthlyPeriodFrom = (r:any) => { - const monthDates :any[] = []; - const monthPlanData :any[] = []; - const monthActualData :any[] = []; - const selectFromDate = dayjs(r); - for (let date = selectFromDate.clone(); date.isBefore(totalManHoursMonthlyToValue, 'month'); date = date.add(1, 'month')) { - monthDates.push(date.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - } - monthDates.push(totalManHoursMonthlyToValue.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - // setTeamTotalManhoursSpentPlanData(monthPlanData) - // setTeamTotalManhoursSpentActualData(monthActualData) - setIndividualStaffManhoursSpentPeriod(weekDates) -} + const selectIndividualStaffMonthlyPeriodFrom = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectFromDate = dayjs(r); + for ( + let date = selectFromDate.clone(); + date.isBefore(totalManHoursMonthlyToValue, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + // setTeamTotalManhoursSpentPlanData(monthPlanData) + // setTeamTotalManhoursSpentActualData(monthActualData) + setIndividualStaffManhoursSpentPeriod(weekDates); + }; -const selectIndividualStaffMonthlyPeriodTo = (r:any) => { - const monthDates :any[] = []; - const monthPlanData :any[] = []; - const monthActualData :any[] = []; - const selectToDate = dayjs(r); - for (let date = totalManHoursMonthlyFromValue.clone(); date.isBefore(selectToDate, 'month'); date = date.add(1, 'month')) { - monthDates.push(date.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - } - monthDates.push(selectToDate.format('MM-YYYY')); - monthPlanData.push(840) - monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)) - // setTeamTotalManhoursSpentPlanData(monthPlanData) - // setTeamTotalManhoursSpentActualData(monthActualData) - setIndividualStaffManhoursSpentPeriod(weekDates) -} + const selectIndividualStaffMonthlyPeriodTo = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectToDate = dayjs(r); + for ( + let date = totalManHoursMonthlyFromValue.clone(); + date.isBefore(selectToDate, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(selectToDate.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + // setTeamTotalManhoursSpentPlanData(monthPlanData) + // setTeamTotalManhoursSpentActualData(monthActualData) + setIndividualStaffManhoursSpentPeriod(weekDates); + }; return ( <> - -
-
+ +
+
- -
-
- {teamTotalManhoursSpentSelect === "Weekly" && ( - <> - - - - )} - {teamTotalManhoursSpentSelect === "Monthly" && ( - <> - - - - )} - - + +
+
+ {teamTotalManhoursSpentSelect === "Weekly" && ( + <> + + + + )} + {teamTotalManhoursSpentSelect === "Monthly" && ( + <> + + + + )} +
+
+
+
-
-
- -
-
- +
+
+ {/* */} - {teamTotalManhoursSpentSelect === "Weekly" && ( - - + selectWeeklyPeriod(newValue)} + onChange={(newValue) => + selectWeeklyPeriod(newValue) + } showDaysOutsideCurrentMonth displayWeekNumber slots={{ day: Day }} @@ -611,64 +712,101 @@ const selectIndividualStaffMonthlyPeriodTo = (r:any) => { ({ selectedDay: value, hoveredDay, - onPointerEnter: () => setHoveredDay(ownerState.day), + onPointerEnter: () => + setHoveredDay(ownerState.day), onPointerLeave: () => setHoveredDay(null), - } as any), + }) as any, }} /> - - )} - {teamTotalManhoursSpentSelect === "Monthly" && ( - - selectMonthlyPeriodFrom(newValue)} defaultValue={totalManHoursMonthlyFromValue} label={'Form'} views={['month', 'year']} /> - selectMonthlyPeriodTo(newValue)} defaultValue={totalManHoursMonthlyToValue} label={'To'} views={['month', 'year']} /> - - )} - -
+ + )} + {teamTotalManhoursSpentSelect === "Monthly" && ( + + + selectMonthlyPeriodFrom(newValue) + } + defaultValue={totalManHoursMonthlyFromValue} + label={"Form"} + views={["month", "year"]} + /> + + selectMonthlyPeriodTo(newValue) + } + defaultValue={totalManHoursMonthlyToValue} + label={"To"} + views={["month", "year"]} + /> + + )}
- -
+ + +
-
-
+
+
- -
-
+ +
+
+ {staffGradeManhoursSpentSelect === "Weekly" && ( + <> + + + + )} + {staffGradeManhoursSpentSelect === "Monthly" && ( + <> + + + + )} +
+
+
{staffGradeManhoursSpentSelect === "Weekly" && ( - <> - - - - )} - {staffGradeManhoursSpentSelect === "Monthly" && ( - <> - - - - )} - - -
-
-
- {staffGradeManhoursSpentSelect === "Weekly" && ( - - + selectWeeklyPeriodByStaffGrade(newValue)} + onChange={(newValue) => + selectWeeklyPeriodByStaffGrade(newValue) + } showDaysOutsideCurrentMonth displayWeekNumber slots={{ day: Day }} @@ -677,20 +815,41 @@ const selectIndividualStaffMonthlyPeriodTo = (r:any) => { ({ selectedDay: value, hoveredDay, - onPointerEnter: () => setHoveredDay(ownerState.day), + onPointerEnter: () => + setHoveredDay(ownerState.day), onPointerLeave: () => setHoveredDay(null), - } as any), + }) as any, }} /> - - )} - {staffGradeManhoursSpentSelect === "Monthly" && ( - - selectStaffGradeMonthlyPeriodFrom(newValue)} defaultValue={totalManHoursByStaffGradeMonthlyFromValue} label={'Form'} views={['month', 'year']} /> - selectStaffGradeMonthlyPeriodTo(newValue)} defaultValue={totalManHoursByStaffGradeMonthlyToValue} label={'To'} views={['month', 'year']} /> - - )} - {/*
-
+ +
-
-
- +
+
+ + - - -
-
- {individualStaffManhoursSpentSelect === "Daily" && ( - <> - - - - - )} - {individualStaffManhoursSpentSelect === "Weekly" && ( - <> - - - - - )} - {individualStaffManhoursSpentSelect === "Monthly" && ( - <> - - - - - )} - - + +
+
+ {individualStaffManhoursSpentSelect === "Daily" && ( + <> + + + + + )} + {individualStaffManhoursSpentSelect === "Weekly" && ( + <> + + + + + )} + {individualStaffManhoursSpentSelect === "Monthly" && ( + <> + + + + + )} +
+
+
+
-
-
- -
-
- +
+
+ {/* */} - {individualStaffManhoursSpentSelect === "Daily" && ( - - selectIndividualStaffMonthlyPeriodFrom(newValue)} defaultValue={totalManHoursByIndividualStaffDailyFromValue} label={'Form'} views={['day','month', 'year']} /> - selectIndividualStaffMonthlyPeriodTo(newValue)} defaultValue={totalManHoursByIndividualStaffDailyToValue} label={'To'} views={['day','month', 'year']} /> - - )} - {individualStaffManhoursSpentSelect === "Weekly" && ( - - + + selectIndividualStaffMonthlyPeriodFrom(newValue) + } + defaultValue={ + totalManHoursByIndividualStaffDailyFromValue + } + label={"Form"} + views={["day", "month", "year"]} + /> + + selectIndividualStaffMonthlyPeriodTo(newValue) + } + defaultValue={ + totalManHoursByIndividualStaffDailyToValue + } + label={"To"} + views={["day", "month", "year"]} + /> + + )} + {individualStaffManhoursSpentSelect === "Weekly" && ( + + selectWeeklyPeriodIndividualStaff(newValue)} + onChange={(newValue) => + selectWeeklyPeriodIndividualStaff(newValue) + } showDaysOutsideCurrentMonth displayWeekNumber slots={{ day: Day }} @@ -783,57 +1020,119 @@ const selectIndividualStaffMonthlyPeriodTo = (r:any) => { ({ selectedDay: value, hoveredDay, - onPointerEnter: () => setHoveredDay(ownerState.day), + onPointerEnter: () => + setHoveredDay(ownerState.day), onPointerLeave: () => setHoveredDay(null), - } as any), + }) as any, }} /> - - )} - {individualStaffManhoursSpentSelect === "Monthly" && ( - - selectIndividualStaffMonthlyPeriodFrom(newValue)} defaultValue={totalManHoursByIndividualStaffMonthlyFromValue} label={'Form'} views={['month', 'year']} /> - selectIndividualStaffMonthlyPeriodTo(newValue)} defaultValue={totalManHoursByIndividualStaffMonthlyToValue} label={'To'} views={['month', 'year']} /> - - )} - -
+ + )} + {individualStaffManhoursSpentSelect === "Monthly" && ( + + + selectIndividualStaffMonthlyPeriodFrom(newValue) + } + defaultValue={ + totalManHoursByIndividualStaffMonthlyFromValue + } + label={"Form"} + views={["month", "year"]} + /> + + selectIndividualStaffMonthlyPeriodTo(newValue) + } + defaultValue={ + totalManHoursByIndividualStaffMonthlyToValue + } + label={"To"} + views={["month", "year"]} + /> + + )}
- - -
- -
-
- -
Total Normal Hours Spent
-
40.00
-
- -
Total Leave Hours
-
0.00
-
-
-
- -
Total Other Hours Spent
-
7.00
-
- -
Remaining Hours
-
0.00
-
+ +
- -
- +
+
+ +
+ Total Normal Hours Spent +
+
+ 40.00 +
+
+ +
+ Total Leave Hours +
+
+ 0.00 +
+
+
+
+ +
+ Total Other Hours Spent +
+
+ 7.00 +
+
+ +
+ Remaining Hours +
+
+ 0.00 +
+
+
+
+ + +
+ ); }; diff --git a/src/components/Swal/CustomAlerts.js b/src/components/Swal/CustomAlerts.js index d8d5cdd..62c853d 100644 --- a/src/components/Swal/CustomAlerts.js +++ b/src/components/Swal/CustomAlerts.js @@ -1,23 +1,22 @@ import Swal from "sweetalert2"; - export const msg = (text) => { - Swal.mixin({ - toast: true, - position: "bottom-end", - showConfirmButton: false, - timer: 3000, - timerProgressBar: true, - didOpen: (toast) => { - toast.onmouseenter = Swal.stopTimer; - toast.onmouseleave = Swal.resumeTimer; - } - }).fire({ - icon: "Success", - title: text - }); -} + Swal.mixin({ + toast: true, + position: "bottom-end", + showConfirmButton: false, + timer: 3000, + timerProgressBar: true, + didOpen: (toast) => { + toast.onmouseenter = Swal.stopTimer; + toast.onmouseleave = Swal.resumeTimer; + }, + }).fire({ + icon: "Success", + title: text, + }); +}; export const popup = (text) => { - Swal.fire(text); -} \ No newline at end of file + Swal.fire(text); +}; diff --git a/src/components/UserWorkspacePage/ProjectGrid.tsx b/src/components/UserWorkspacePage/ProjectGrid.tsx index c0b140f..8cc37d5 100644 --- a/src/components/UserWorkspacePage/ProjectGrid.tsx +++ b/src/components/UserWorkspacePage/ProjectGrid.tsx @@ -1,44 +1,78 @@ "use client"; import * as React from "react"; import Grid from "@mui/material/Grid"; -import { useEffect, useState } from 'react' -import { TFunction } from "i18next"; -import { useTranslation } from "react-i18next"; -import {Card,CardContent,CardHeader} from '@mui/material'; -import CustomCardGrid from '../CustomCardGrid/CustomCardGrid'; -import '../../app/global.css'; +import { useEffect } from "react"; +import { Card, CardContent, CardHeader } from "@mui/material"; +import CustomCardGrid from "../CustomCardGrid/CustomCardGrid"; +import "../../app/global.css"; import { PROJECT_CARD_STYLE } from "@/theme/colorConst"; interface ProjectGridProps { tab: number; } +const cards = [ + { + code: "M1001 (C)", + name: "Consultancy Project A", + hr_spent: 12.75, + hr_spent_normal: 0.0, + hr_alloc: 150.0, + hr_alloc_normal: 30.0, + }, + { + code: "M1301 (C)", + name: "Consultancy Project AAA", + hr_spent: 4.25, + hr_spent_normal: 0.25, + hr_alloc: 30.0, + hr_alloc_normal: 0.0, + }, + { + code: "M1354 (C)", + name: "Consultancy Project BBB", + hr_spent: 57.0, + hr_spent_normal: 6.5, + hr_alloc: 100.0, + hr_alloc_normal: 20.0, + }, + { + code: "M1973 (C)", + name: "Construction Project CCC", + hr_spent: 12.75, + hr_spent_normal: 0.0, + hr_alloc: 150.0, + hr_alloc_normal: 30.0, + }, + { + code: "M2014 (T)", + name: "Consultancy Project DDD", + hr_spent: 1.0, + hr_spent_normal: 0.0, + hr_alloc: 10.0, + hr_alloc_normal: 0.0, + }, +]; const ProjectGrid: React.FC = (props) => { - const [items, setItems] = React.useState([]) - + const [items, setItems] = React.useState([]); + useEffect(() => { if (props.tab == 0) { - setItems(cards) - } - else { - const filteredItems = cards;//cards.filter(item => (item.track == props.tab)); + setItems(cards); + } else { + const filteredItems = cards; //cards.filter(item => (item.track == props.tab)); setItems(filteredItems); } }, [props.tab]); - - const cards = [ - {code: 'M1001 (C)', name: 'Consultancy Project A', hr_spent: 12.75, hr_spent_normal: 0.00, hr_alloc: 150.00, hr_alloc_normal: 30.00}, - {code: 'M1301 (C)', name: 'Consultancy Project AAA', hr_spent: 4.25, hr_spent_normal: 0.25, hr_alloc: 30.00, hr_alloc_normal: 0.00}, - {code: 'M1354 (C)', name: 'Consultancy Project BBB', hr_spent: 57.00, hr_spent_normal: 6.50, hr_alloc: 100.00, hr_alloc_normal: 20.00}, - {code: 'M1973 (C)', name: 'Construction Project CCC', hr_spent: 12.75, hr_spent_normal: 0.00, hr_alloc: 150.00, hr_alloc_normal: 30.00}, - {code: 'M2014 (T)', name: 'Consultancy Project DDD', hr_spent: 1.00, hr_spent_normal: 0.00, hr_alloc: 10.00, hr_alloc_normal: 0.00}, - ]; - + const cardLayout = (item: Record) => { return ( - +

Hours Spent: {item.hr_spent}

Normal (Others): {item.hr_spent_normal}

@@ -47,15 +81,19 @@ const ProjectGrid: React.FC = (props) => {
); - } + }; // Apply the preset style to the cards in child, if not specified // return ( - {/* */} - {/* item count = {items?.length??"idk"} , track/tab = {props.tab} */} - - {/* */} - + {/* */} + {/* item count = {items?.length??"idk"} , track/tab = {props.tab} */} + + {/* */} + ); }; diff --git a/src/components/UserWorkspacePage/UserWorkspacePage.tsx b/src/components/UserWorkspacePage/UserWorkspacePage.tsx index 19cd266..e0f6072 100644 --- a/src/components/UserWorkspacePage/UserWorkspacePage.tsx +++ b/src/components/UserWorkspacePage/UserWorkspacePage.tsx @@ -8,9 +8,9 @@ import PageTitle from "../PageTitle/PageTitle"; import { Suspense } from "react"; import Button from "@mui/material/Button"; import Stack from "@mui/material/Stack"; -import { Add } from '@mui/icons-material'; +import { Add } from "@mui/icons-material"; import Link from "next/link"; -import { t } from 'i18next'; +import { t } from "i18next"; import { Modal } from "@mui/material"; import CustomModal from "../CustomModal/CustomModal"; import EnterTimesheetModal from "../EnterTimesheet/EnterTimesheetModal"; @@ -18,7 +18,6 @@ import EnterTimesheetModal from "../EnterTimesheet/EnterTimesheetModal"; const UserWorkspacePage: React.FC = () => { const [isModalVisible, setModalVisible] = useState(false); const { t } = useTranslation("home"); - const handleButtonClick = () => { setModalVisible(true); @@ -29,38 +28,36 @@ const UserWorkspacePage: React.FC = () => { }; return ( - + - -
- - - - {/*fallback={}>*/} - - -
- - + +
+ + + + + {/*fallback={}>*/} +
+ +
); diff --git a/src/theme.ts b/src/theme.ts index 90d1aa6..12ce360 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -1,12 +1,11 @@ -import { createTheme } from '@mui/material/styles'; +import { createTheme } from "@mui/material/styles"; const theme = createTheme({ palette: { background: { - default: '#fcfcfc' - } - } - + default: "#fcfcfc", + }, + }, }); -export default theme; \ No newline at end of file +export default theme; diff --git a/src/theme/colorConst.js b/src/theme/colorConst.js index 58802a0..0db2053 100644 --- a/src/theme/colorConst.js +++ b/src/theme/colorConst.js @@ -4,51 +4,85 @@ import { aborted } from "util"; // - - - - - - WORK IN PROGRESS - - - - - - // export const chartColor = [ - '#CB4047', '#ED3A41', '#F47B50', '#FBA647', - '#FDB64C', '#CCBB32', '#9ACC59', '#57B962', - '#1E83C5', '#7C4A9D' + "#CB4047", + "#ED3A41", + "#F47B50", + "#FBA647", + "#FDB64C", + "#CCBB32", + "#9ACC59", + "#57B962", + "#1E83C5", + "#7C4A9D", ]; export const chartSingleColor = [ - '#f2969a', '#fc9599', '#faa789', '#f7ae94', - '#ffd491', '#ede5a1', '#d1f5a2', '#9de0a4', - '#a2d4f5', '#b685d6' + "#f2969a", + "#fc9599", + "#faa789", + "#f7ae94", + "#ffd491", + "#ede5a1", + "#d1f5a2", + "#9de0a4", + "#a2d4f5", + "#b685d6", ]; export const rankColor = [ - '#FFD700', '#C0C0C0', '#CD853F', '#57B962', '#57B962', - '#57B962', '#57B962', '#57B962', '#57B962', '#57B962' + "#FFD700", + "#C0C0C0", + "#CD853F", + "#57B962", + "#57B962", + "#57B962", + "#57B962", + "#57B962", + "#57B962", + "#57B962", ]; export const piechartColor1 = [ - '#E84A3E', '#F2883C', '#FDCD4D', '#CE478A', '#B63D2A', - '#6A8B9E', '#60667E', '#58865F', '#2F763E', '#7D80B5', + "#E84A3E", + "#F2883C", + "#FDCD4D", + "#CE478A", + "#B63D2A", + "#6A8B9E", + "#60667E", + "#58865F", + "#2F763E", + "#7D80B5", ]; export const piechartColor2 = [ - '#6A8B9E', '#60667E', '#58865F', '#2F763E', '#7D80B5', - '#E84A3E', '#F2883C', '#FDCD4D', '#CE478A', '#B63D2A', + "#6A8B9E", + "#60667E", + "#58865F", + "#2F763E", + "#7D80B5", + "#E84A3E", + "#F2883C", + "#FDCD4D", + "#CE478A", + "#B63D2A", ]; -export const cardBorderColor = [ - '#efb142', '#4bb641', '#448df2', '#e03c04' -]; +export const cardBorderColor = ["#efb142", "#4bb641", "#448df2", "#e03c04"]; -export const chartLineColor = [ - '#FFFFFF', '#D9D9D9' -]; +export const chartLineColor = ["#FFFFFF", "#D9D9D9"]; -export const GENERAL_RED_COLOR = '#e03c04'; +export const GENERAL_RED_COLOR = "#e03c04"; export const TABLE_HEADER_TEXT_COLOR = "#3367D1"; -export const GENERAL_INFO_COLOR = '#448df2'; +export const GENERAL_INFO_COLOR = "#448df2"; -export const GENERAL_SETTING_COLOR = '#666666'; +export const GENERAL_SETTING_COLOR = "#666666"; -export const GENERAL_BORDER_COLOR = '#e6ebf1'; +export const GENERAL_BORDER_COLOR = "#e6ebf1"; -export const GENERAL_TEXT_COLOR = '#262626'; +export const GENERAL_TEXT_COLOR = "#262626"; export const FONT_SIZE_L = "1.875rem"; @@ -57,327 +91,327 @@ export const FONT_SIZE_M = "1.5rem"; export const FONT_SIZE_S = "1.25rem"; export const PROJECT_CARD_STYLE = { - borderRadius: '10px', - //border: '10px dotted #ccc', - width: '20rem', - margin: '20px', - //backgroundColor:"pink" + borderRadius: "10px", + //border: '10px dotted #ccc', + width: "20rem", + margin: "20px", + //backgroundColor:"pink" }; export const PROJECT_MODAL_STYLE = { - position: 'absolute', - width: '85%', - borderRadius: '10px', - height: '75%', - // top: '50%', - // left: '50%', - transform: 'translate(10%, 15%)', - backgroundColor: 'white', - padding: '20px', - display: 'flex', - flexDirection: 'column', - }; + position: "absolute", + width: "85%", + borderRadius: "10px", + height: "75%", + // top: '50%', + // left: '50%', + transform: "translate(10%, 15%)", + backgroundColor: "white", + padding: "20px", + display: "flex", + flexDirection: "column", +}; export const DATAGRID_STYLE = { - boxShadow: 2, - border: 2, - borderColor: 'primary.light', - '& .MuiDataGrid-cell:hover': { - color: 'primary.main' - }, - '& .MuiDataGrid-root': { - overflow: 'auto', - } + boxShadow: 2, + border: 2, + borderColor: "primary.light", + "& .MuiDataGrid-cell:hover": { + color: "primary.main", + }, + "& .MuiDataGrid-root": { + overflow: "auto", + }, }; export const TAB_THEME = { - components: { - MuiTab: { - styleOverrides: { - root: { - // fontSize: '1.0rem', - fontSize: '1.25rem'//'20px', - // height: '40px', - // width: '40vw', // Default width for xs screen sizes - // '@media (min-width: 600px)': { // sm breakpoint - // width: '20vw', - // }, - // '@media (min-width: 960px)': { // md breakpoint - // width: '15vw', - // }, - // '@media (min-width: 1280px)': { // lg breakpoint - // width: '7vw', - // }, - // textTransform: "none", - // alignItems: 'center' - }, - }, - }, - } - - }; + components: { + MuiTab: { + styleOverrides: { + root: { + // fontSize: '1.0rem', + fontSize: "1.25rem", //'20px', + // height: '40px', + // width: '40vw', // Default width for xs screen sizes + // '@media (min-width: 600px)': { // sm breakpoint + // width: '20vw', + // }, + // '@media (min-width: 960px)': { // md breakpoint + // width: '15vw', + // }, + // '@media (min-width: 1280px)': { // lg breakpoint + // width: '7vw', + // }, + // textTransform: "none", + // alignItems: 'center' + }, + }, + }, + }, +}; // copy from MTMS export const TSMS_BUTTON_THEME = createTheme({ - palette: { - primary: { - main: '#92C1E9', - contrastText: '#FFFFFF', - }, - secondary: { - main: '#898D8D', - contrastText: '#FFFFFF', - }, - success: { - main: '#ADCAB8', - contrastText: '#FFFFFF', - }, - danger: { - main: '#F890A5', - contrastText: '#FFFFFF', - }, - warning: { - main: '#EFBE7D', - contrastText: '#FFFFFF', - }, - disable: { - main: '#B2B4B2', - contrastText: '#FFFFFF', - }, - create: { - // main: '#57B962', - main: '#ADCAB8', - // light: will be calculated from palette.primary.main, - // dark: will be calculated from palette.primary.main, - // contrastText: will be calculated to contrast with palette.primary.main - contrastText: '#FFFFFF', - }, - delete: { - // main: '#E03C04', - main: '#F890A5', - contrastText: '#FFFFFF', - - }, - cancel: { - // main: '#999999', - main: '#F890A5', - contrastText: '#FFFFFF', - }, - back: { - // main: '#999999', - main: '#898D8D', - contrastText: '#FFFFFF', - }, - reset: { - main: '#EFBE7D', - contrastText: '#FFFFFF', - }, - save: { - // main: '#448DF2', - main: '#92C1E9', - contrastText: '#FFFFFF', - }, - export: { - main: '#8C52FF', - contrastText: '#FFFFFF', - }, - import: { - main: '#92C1E9', - contrastText: '#FFFFFF', - }, - saveAs: { - main: '#FFBD59', - contrastText: '#FFFFFF', - } - }, - components: { - MuiButton: { - styleOverrides: { - root: { - '& .MuiButtonBase-root-MuiButton-root': { - fontSize: FONT_SIZE_S - }, - } - } - }, - MuiButtonBase: { - styleOverrides: { - root: { - '&.MuiChip-root.Mui-disabled': { - opacity: 0.75, - }, - '&.MuiButton-root': { - fontSize: FONT_SIZE_S - }, - } - } - }, - } + palette: { + primary: { + main: "#92C1E9", + contrastText: "#FFFFFF", + }, + secondary: { + main: "#898D8D", + contrastText: "#FFFFFF", + }, + success: { + main: "#ADCAB8", + contrastText: "#FFFFFF", + }, + danger: { + main: "#F890A5", + contrastText: "#FFFFFF", + }, + warning: { + main: "#EFBE7D", + contrastText: "#FFFFFF", + }, + disable: { + main: "#B2B4B2", + contrastText: "#FFFFFF", + }, + create: { + // main: '#57B962', + main: "#ADCAB8", + // light: will be calculated from palette.primary.main, + // dark: will be calculated from palette.primary.main, + // contrastText: will be calculated to contrast with palette.primary.main + contrastText: "#FFFFFF", + }, + delete: { + // main: '#E03C04', + main: "#F890A5", + contrastText: "#FFFFFF", + }, + cancel: { + // main: '#999999', + main: "#F890A5", + contrastText: "#FFFFFF", + }, + back: { + // main: '#999999', + main: "#898D8D", + contrastText: "#FFFFFF", + }, + reset: { + main: "#EFBE7D", + contrastText: "#FFFFFF", + }, + save: { + // main: '#448DF2', + main: "#92C1E9", + contrastText: "#FFFFFF", + }, + export: { + main: "#8C52FF", + contrastText: "#FFFFFF", + }, + import: { + main: "#92C1E9", + contrastText: "#FFFFFF", + }, + saveAs: { + main: "#FFBD59", + contrastText: "#FFFFFF", + }, + }, + components: { + MuiButton: { + styleOverrides: { + root: { + "& .MuiButtonBase-root-MuiButton-root": { + fontSize: FONT_SIZE_S, + }, + }, + }, + }, + MuiButtonBase: { + styleOverrides: { + root: { + "&.MuiChip-root.Mui-disabled": { + opacity: 0.75, + }, + "&.MuiButton-root": { + fontSize: FONT_SIZE_S, + }, + }, + }, + }, + }, }); export const formTheme = createTheme({ - components: { - MuiFormLabel: { - root: { // Name of the rule - color: "rgba(0, 0, 0, 1)", - }, - styleOverrides: { - asterisk: { - color: "#db3131", - "&$error": { - color: "#db3131", - }, - }, - }, - }, + components: { + MuiFormLabel: { + root: { + // Name of the rule + color: "rgba(0, 0, 0, 1)", + }, + styleOverrides: { + asterisk: { + color: "#db3131", + "&$error": { + color: "#db3131", + }, + }, + }, }, + }, }); - export const ARS_BUTTON_THEME = createTheme({ - palette: { - create: { - main: '#57B962', - // light: will be calculated from palette.primary.main, - // dark: will be calculated from palette.primary.main, - // contrastText: will be calculated to contrast with palette.primary.main - contrastText: '#FFFFFF', - }, - delete: { - main: '#E03C04', - contrastText: '#FFFFFF', - - }, - cancel: { - main: '#999999', - contrastText: '#FFFFFF', - - }, - save: { - main: '#448DF2', - contrastText: '#FFFFFF', - }, - export: { - main: '#8C52FF', - contrastText: '#FFFFFF', - }, - saveAs: { - main: '#FFBD59', - contrastText: '#FFFFFF', - }, - edit: { - main: '#F3AF2B', - contrastText: '#FFFFFF', - }, - exportExcel: { - main: '#6A8B9E', - contrastText: '#FFFFFF', - } - }, - components: { - MuiDataGrid: { - styleOverrides: { - actionsCell: { - '& .MuiDataGrid-actionsContainer .MuiIconButton-root': { - fontSize: '80px', // Set the desired icon size here - }, - }, - }, - }, - MuiButton: { - styleOverrides: { - root: { - // fontSize: '1.0rem', - fontSize: '1.25rem', - height: '40px', - width: '40vw', // Default width for xs screen sizes - '@media (min-width: 600px)': { // sm breakpoint - width: '20vw', - }, - '@media (min-width: 960px)': { // md breakpoint - width: '15vw', - }, - '@media (min-width: 1280px)': { // lg breakpoint - width: '7vw', - }, - textTransform: "none", - alignItems: 'center' - }, - }, - }, - } + palette: { + create: { + main: "#57B962", + // light: will be calculated from palette.primary.main, + // dark: will be calculated from palette.primary.main, + // contrastText: will be calculated to contrast with palette.primary.main + contrastText: "#FFFFFF", + }, + delete: { + main: "#E03C04", + contrastText: "#FFFFFF", + }, + cancel: { + main: "#999999", + contrastText: "#FFFFFF", + }, + save: { + main: "#448DF2", + contrastText: "#FFFFFF", + }, + export: { + main: "#8C52FF", + contrastText: "#FFFFFF", + }, + saveAs: { + main: "#FFBD59", + contrastText: "#FFFFFF", + }, + edit: { + main: "#F3AF2B", + contrastText: "#FFFFFF", + }, + exportExcel: { + main: "#6A8B9E", + contrastText: "#FFFFFF", + }, + }, + components: { + MuiDataGrid: { + styleOverrides: { + actionsCell: { + "& .MuiDataGrid-actionsContainer .MuiIconButton-root": { + fontSize: "80px", // Set the desired icon size here + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + root: { + // fontSize: '1.0rem', + fontSize: "1.25rem", + height: "40px", + width: "40vw", // Default width for xs screen sizes + "@media (min-width: 600px)": { + // sm breakpoint + width: "20vw", + }, + "@media (min-width: 960px)": { + // md breakpoint + width: "15vw", + }, + "@media (min-width: 1280px)": { + // lg breakpoint + width: "7vw", + }, + textTransform: "none", + alignItems: "center", + }, + }, + }, + }, }); //from ARS export const TSMS_LONG_BUTTON_THEME = createTheme({ - palette: { - create: { - main: '#57B962', - // light: will be calculated from palette.primary.main, - // dark: will be calculated from palette.primary.main, - // contrastText: will be calculated to contrast with palette.primary.main - contrastText: '#FFFFFF', - }, - delete: { - main: '#E03C04', - contrastText: '#FFFFFF', - - }, - cancel: { - main: '#999999', - contrastText: '#FFFFFF', - - }, - save: { - main: '#448DF2', - contrastText: '#FFFFFF', - }, - export: { - main: '#8C52FF', - contrastText: '#FFFFFF', - }, - saveAs: { - main: '#FFBD59', - contrastText: '#FFFFFF', - }, - edit: { - main: '#F3AF2B', - contrastText: '#FFFFFF', - }, - exportExcel: { - main: '#60667E', - contrastText: '#FFFFFF', - } - }, - components: { - MuiDataGrid: { - styleOverrides: { - actionsCell: { - '& .MuiDataGrid-actionsContainer .MuiIconButton-root': { - fontSize: '80px', // Set the desired icon size here - }, - }, - }, - }, - MuiButton: { - styleOverrides: { - root: { - fontSize: '1.25rem', - height: '40px', - width: '40vw', // Default width for xs screen sizes - '@media (min-width: 600px)': { // sm breakpoint - width: '30vw', - }, - '@media (min-width: 960px)': { // md breakpoint - width: '25vw', - }, - '@media (min-width: 1280px)': { // lg breakpoint - width: '14vw', - }, - textTransform: "none", - alignItems: 'center' - }, - }, - }, - } -}); \ No newline at end of file + palette: { + create: { + main: "#57B962", + // light: will be calculated from palette.primary.main, + // dark: will be calculated from palette.primary.main, + // contrastText: will be calculated to contrast with palette.primary.main + contrastText: "#FFFFFF", + }, + delete: { + main: "#E03C04", + contrastText: "#FFFFFF", + }, + cancel: { + main: "#999999", + contrastText: "#FFFFFF", + }, + save: { + main: "#448DF2", + contrastText: "#FFFFFF", + }, + export: { + main: "#8C52FF", + contrastText: "#FFFFFF", + }, + saveAs: { + main: "#FFBD59", + contrastText: "#FFFFFF", + }, + edit: { + main: "#F3AF2B", + contrastText: "#FFFFFF", + }, + exportExcel: { + main: "#60667E", + contrastText: "#FFFFFF", + }, + }, + components: { + MuiDataGrid: { + styleOverrides: { + actionsCell: { + "& .MuiDataGrid-actionsContainer .MuiIconButton-root": { + fontSize: "80px", // Set the desired icon size here + }, + }, + }, + }, + MuiButton: { + styleOverrides: { + root: { + fontSize: "1.25rem", + height: "40px", + width: "40vw", // Default width for xs screen sizes + "@media (min-width: 600px)": { + // sm breakpoint + width: "30vw", + }, + "@media (min-width: 960px)": { + // md breakpoint + width: "25vw", + }, + "@media (min-width: 1280px)": { + // lg breakpoint + width: "14vw", + }, + textTransform: "none", + alignItems: "center", + }, + }, + }, + }, +});