diff --git a/src/app/utils/holidayUtils.ts b/src/app/utils/holidayUtils.ts index c0a14d1..bd403fe 100644 --- a/src/app/utils/holidayUtils.ts +++ b/src/app/utils/holidayUtils.ts @@ -14,7 +14,7 @@ export const getPublicHolidaysForNYears = (years: number = 1, currYr?: number) = .flatMap((_, index) => { const currentYear = currYr ?? new Date().getFullYear(); const holidays = hd.getHolidays(currentYear - index); - console.log(holidays) + // console.log(holidays) return holidays.map((ele) => { const tempDay = new Date(ele.date); const tempYear = tempDay.getFullYear(); diff --git a/src/components/PastEntryCalendar/MonthlySummary.tsx b/src/components/PastEntryCalendar/MonthlySummary.tsx index 797000a..8dd5256 100644 --- a/src/components/PastEntryCalendar/MonthlySummary.tsx +++ b/src/components/PastEntryCalendar/MonthlySummary.tsx @@ -11,9 +11,9 @@ import { Typography, } from "@mui/material"; import union from "lodash/union"; -import { useCallback, useMemo } from "react"; +import { useCallback, useEffect, useMemo } from "react"; import dayjs, { Dayjs } from "dayjs"; -import { getHolidayForDate } from "@/app/utils/holidayUtils"; +import { getHolidayForDate, getPublicHolidaysForNYears } from "@/app/utils/holidayUtils"; import { HolidaysResult } from "@/app/api/holidays"; import { manhourFormatter, shortDateFormatter } from "@/app/utils/formatUtil"; import { useTranslation } from "react-i18next"; @@ -39,6 +39,14 @@ const MonthlySummary: React.FC = ({ i18n: { language }, } = useTranslation("home"); + // calendar related + const holidays = useMemo(() => { + const holidays = getPublicHolidaysForNYears(1, currentMonth.year()).map(holiday => holiday.date) + return holidays.filter(date => { + return currentMonth.isSame(dayjs(date), "month") + }) + }, [currentMonth]); + const timesheetForCurrentMonth = useMemo(() => { return pickBy(timesheet, (_, date) => { return currentMonth.isSame(dayjs(date), "month"); @@ -55,8 +63,9 @@ const MonthlySummary: React.FC = ({ return union( Object.keys(timesheetForCurrentMonth), Object.keys(leavesForCurrentMonth), + holidays ); - }, [timesheetForCurrentMonth, leavesForCurrentMonth]).sort(); + }, [timesheetForCurrentMonth, leavesForCurrentMonth, holidays]).sort(); const makeSelectDate = useCallback( (date: string) => () => { @@ -65,6 +74,11 @@ const MonthlySummary: React.FC = ({ [onDateSelect], ); + useEffect(()=> { + console.log(holidays) + console.log(timesheetForCurrentMonth) + },[currentMonth, timesheetForCurrentMonth]) + return ( void; onMonthChange: (day: Dayjs) => void; } @@ -32,6 +33,7 @@ export interface Props { const getColor = ( hasTimeInput: boolean, hasLeave: boolean, + isPublicHoliday: boolean, ): string | undefined => { if (hasTimeInput && hasLeave) { return "success.light"; @@ -39,7 +41,9 @@ const getColor = ( return "info.light"; } else if (hasLeave) { return "warning.light"; - } else { + } else if (isPublicHoliday){ + return "error.light"; + }else { return undefined; } }; @@ -47,6 +51,7 @@ const getColor = ( const EntryDay: React.FC & Props> = ({ timesheet, leaves, + publicHolidays, ...pickerProps }) => { const timesheetDays = Object.keys(timesheet); @@ -60,11 +65,15 @@ const EntryDay: React.FC & Props> = ({ dayjs(day).isSame(pickerProps.day, "day"), ); + const isPublicHoliday = publicHolidays.some((day) => + dayjs(day).isSame(pickerProps.day, "day"), + ); + return ( ); }; @@ -72,6 +81,7 @@ const EntryDay: React.FC & Props> = ({ const PastEntryCalendar: React.FC = ({ timesheet, leaves, + publicHolidays, onDateSelect, onMonthChange, }) => { @@ -98,6 +108,7 @@ const PastEntryCalendar: React.FC = ({ day: { timesheet, leaves, + publicHolidays, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any, }} diff --git a/src/components/PastEntryCalendar/PastEntryCalendarModal.tsx b/src/components/PastEntryCalendar/PastEntryCalendarModal.tsx index c0522e1..5647380 100644 --- a/src/components/PastEntryCalendar/PastEntryCalendarModal.tsx +++ b/src/components/PastEntryCalendar/PastEntryCalendarModal.tsx @@ -12,7 +12,7 @@ import { import PastEntryCalendar, { Props as PastEntryCalendarProps, } from "./PastEntryCalendar"; -import { useCallback, useState } from "react"; +import { useCallback, useState, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { ArrowBack } from "@mui/icons-material"; import PastEntryList from "./PastEntryList"; @@ -23,9 +23,10 @@ import FullscreenModal from "../FullscreenModal"; import MonthlySummary from "./MonthlySummary"; import { HolidaysResult } from "@/app/api/holidays"; import dayjs from "dayjs"; +import { getPublicHolidaysForNYears } from "@/app/utils/holidayUtils"; interface Props - extends Omit { + extends Omit { open: boolean; handleClose: () => void; leaveTypes: LeaveType[]; @@ -60,6 +61,13 @@ const PastEntryCalendarModal: React.FC = ({ handleClose(); }, [handleClose]); + const publicHolidays = useMemo(() => { + const holidays = getPublicHolidaysForNYears(1, currentMonth.year()).map(holiday => holiday.date) + return holidays.filter(date => { + return currentMonth.isSame(dayjs(date), "month") + }) + }, [currentMonth]); + const content = ( @@ -80,10 +88,17 @@ const PastEntryCalendarModal: React.FC = ({ {t("Has both timesheet and leave entry")} + + + + {t("Public Holiday")} + + diff --git a/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx b/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx index ea42ddf..7523ed7 100644 --- a/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx +++ b/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx @@ -307,7 +307,7 @@ const ProjectFinancialCard: React.FC = ({ > {"(k) " + t("Projected Cost Performance Index") + " (CPI)"} - {Number(ProjectedCPI) < 1 && ( + {Number(ProjectedCPI) < 1.2 && ( <>
= ({
)} - {Number(ProjectedCPI) >= 1 && ( + {Number(ProjectedCPI) >= 1.2 && ( <>
= ({ // return list // }, []) - const comboList: string[] = useMemo(() => { - const list = ["All"]; - for (let i = 1; i < lengthOfCombo - 1; i++) { - const yearRange = `${currFinancialYear - i} - ${currFinancialYear - i + 1}`; - const label = i === 1 ? `${yearRange} ${t("(current year)")}` : yearRange; - list.push(label); - } - const oldestYear = currFinancialYear - (lengthOfCombo - 2); - list.push(`< ${oldestYear}`); - return list; + const comboList: InputDate[] = useMemo(() => { + const list = [{startDate: "", endDate: "", label: "All"}]; + const curMonth = new Date().getMonth() + 1 + // for (let i = 1; i < lengthOfCombo - 1; i++) { + // const yearRange = `${currFinancialYear - i} - ${currFinancialYear - i + 1}`; + // const label = i === 1 ? `${yearRange} ${t("(current year)")}` : yearRange; + // list.push(label); + // } + // const oldestYear = currFinancialYear - (lengthOfCombo - 2); + // list.push(`< ${oldestYear}`); + + // for (let j = 0; j < lengthOfCombo - 3; j++) { + // const yearRange = `${currFinancialYear + j} - ${currFinancialYear + j + 1}`; + // const label = yearRange; + // list.push(label); + // } + // const latestYear = currFinancialYear + (lengthOfCombo - 2); + // list.push(`< ${latestYear}`); + const tempList = generateYearRanges(3, curMonth) + const combinedList = [...list, ...tempList] + + return combinedList; }, [currFinancialYear, lengthOfCombo, t]); const futureList: string[] = useMemo(() => { @@ -165,21 +179,22 @@ const FinancialSummaryPage: React.FC = ({ }, []); const handleFilter = useCallback(async (value: number) => { - if (isFuture){ + // if (isFuture){ setPeriod(value) console.log(value) - var _startDate = dateMap[value as keyof DateParams].startDate - var _endDate = dateMap[value as keyof DateParams].endDate + var _startDate = comboList[value].startDate + var _endDate = comboList[value].endDate console.log(_startDate) console.log(_endDate) - }else{ - setPeriod(value) - console.log(value) - var _startDate = futureDateMap[value as keyof DateParams].startDate - var _endDate = futureDateMap[value as keyof DateParams].endDate - console.log(_startDate) - console.log(_endDate) - } + // } + // else{ + // setPeriod(value) + // console.log(value) + // var _startDate = futureDateMap[value as keyof DateParams].startDate + // var _endDate = futureDateMap[value as keyof DateParams].endDate + // console.log(_startDate) + // console.log(_endDate) + // } await fetchFinancialSummaryByProject(_endDate, _startDate) @@ -212,21 +227,21 @@ const FinancialSummaryPage: React.FC = ({ onChange={(e) => handleFilter(Number(e.target.value))} > { - isFuture - ? - comboList.map((str, i) => ( - {str} + // isFuture + // ? + comboList.map((item, i) => ( + {item.label} )) - : - Object.entries(futureDateMap).map(([year, dates], index) => { - const isLastItem = index === Object.keys(futureDateMap).length - 1; - const str = isLastItem ? `> ${dates.startDate.slice(0,4)}` : `${dates.startDate.slice(0,4)} - ${dates.endDate.slice(0,4)}`; - return {str}; - }) + // : + // Object.entries(futureDateMap).map(([year, dates], index) => { + // const isLastItem = index === Object.keys(futureDateMap).length - 1; + // const str = isLastItem ? `> ${dates.startDate.slice(0,4)}` : `${dates.startDate.slice(0,4)} - ${dates.endDate.slice(0,4)}`; + // return {str}; + // }) } - = ({ /> } label={isFuture ? t("Past Years") : t("Future Years")} - /> + /> */} diff --git a/src/components/ProjectFinancialSummaryV2/Util.tsx b/src/components/ProjectFinancialSummaryV2/Util.tsx new file mode 100644 index 0000000..96e3dcc --- /dev/null +++ b/src/components/ProjectFinancialSummaryV2/Util.tsx @@ -0,0 +1,71 @@ +type InputDate = { + startDate: string; + endDate: string; + label?: string; +} + +/** + * Generates a list of year ranges based on the number of past and future years specified. + * @param numberOfYears The number of past and future years to include separately. + * @returns An array of objects with start year, end year, and label. + */ +export function generateYearRanges(numberOfYears: number, month: number): InputDate[] { + const startDate = "10-01" //start date of each financial year + const endDate = "09-30" // end date of each financial year + + // Get the base year + const baseYear = new Date().getFullYear(); + + // Determine the current year based on the month + let currentYear: number; + if (month < 10) { // October is month 10 + currentYear = baseYear - 1; + } else { + currentYear = baseYear; + } + + + // Initialize the result array + const yearRanges: InputDate[] = []; + + // Add past years beyond numberOfYears as one group + if (numberOfYears > 0) { + yearRanges.push({ + startDate: "", + endDate: `${(currentYear - numberOfYears)}-${endDate}`, + label: `< ${currentYear - numberOfYears}` + }); + } + + // Add individual past years + for (let i = numberOfYears - 1; i >= 0; i--) { + const startYear = currentYear - i - 1; + const endYear = currentYear - i; + yearRanges.push({ startDate: `${startYear}-${startDate}`, endDate: `${endYear}-${endDate}`, label: `${startYear} - ${endYear}` }); + } + + // Add current year + yearRanges.push({ + startDate: `${currentYear}-${startDate}`, + endDate: `${(currentYear + 1)}-${endDate}`, + label: `${currentYear} - ${currentYear + 1} (current year)` + }); + + // Add individual future years + for (let i = 0; i < numberOfYears; i++) { + const startYear = currentYear + i + 1; + const endYear = currentYear + i + 2; + yearRanges.push({ startDate: `${startYear}-${startDate}`, endDate: `${endYear}-${endDate}`, label: `${startYear} - ${endYear}` }); + } + + // Add future years beyond numberOfYears as one group + if (numberOfYears > 0) { + yearRanges.push({ + startDate: `${(currentYear + numberOfYears + 1)}-${startDate}`, + endDate: "", + label: `> ${currentYear + numberOfYears + 1}` + }); + } + + return yearRanges; +} \ No newline at end of file