From 3d551315cadb38283b5aa90e48277090d64dbedb Mon Sep 17 00:00:00 2001 From: Wayne Date: Sun, 21 Jul 2024 17:39:59 +0900 Subject: [PATCH] Remove unused code --- src/app/api/timesheets/utils.ts | 88 +-- src/components/EnterLeave/EnterLeaveModal.tsx | 109 ---- src/components/EnterLeave/LeaveInputGrid.tsx | 548 ------------------ src/components/EnterLeave/index.ts | 1 - .../EnterTimesheet/EnterTimesheetModal.tsx | 109 ---- .../EnterTimesheet/TimesheetInputGrid.tsx | 548 ------------------ src/components/EnterTimesheet/index.ts | 1 - .../TimesheetModal/TimesheetModal.tsx | 223 ------- src/components/TimesheetModal/index.ts | 1 - .../TimesheetTable/FastTimeEntryModal.tsx | 1 + 10 files changed, 4 insertions(+), 1625 deletions(-) delete mode 100644 src/components/EnterLeave/EnterLeaveModal.tsx delete mode 100644 src/components/EnterLeave/LeaveInputGrid.tsx delete mode 100644 src/components/EnterLeave/index.ts delete mode 100644 src/components/EnterTimesheet/EnterTimesheetModal.tsx delete mode 100644 src/components/EnterTimesheet/TimesheetInputGrid.tsx delete mode 100644 src/components/EnterTimesheet/index.ts delete mode 100644 src/components/TimesheetModal/TimesheetModal.tsx delete mode 100644 src/components/TimesheetModal/index.ts diff --git a/src/app/api/timesheets/utils.ts b/src/app/api/timesheets/utils.ts index 714b1c8..81d798d 100644 --- a/src/app/api/timesheets/utils.ts +++ b/src/app/api/timesheets/utils.ts @@ -1,12 +1,6 @@ import { getPublicHolidaysForNYears } from "@/app/utils/holidayUtils"; import { HolidaysResult } from "../holidays"; -import { - LeaveEntry, - RecordLeaveInput, - RecordTimeLeaveInput, - RecordTimesheetInput, - TimeEntry, -} from "./actions"; +import { LeaveEntry, RecordTimeLeaveInput, TimeEntry } from "./actions"; import { convertDateArrayToString } from "@/app/utils/formatUtil"; import compact from "lodash/compact"; @@ -83,82 +77,6 @@ export const validateLeaveEntry = ( return Object.keys(error).length > 0 ? error : undefined; }; -export const validateTimesheet = ( - timesheet: RecordTimesheetInput, - leaveRecords: RecordLeaveInput, - companyHolidays: HolidaysResult[], -): { [date: string]: string } | undefined => { - const errors: { [date: string]: string } = {}; - - const holidays = new Set( - compact([ - ...getPublicHolidaysForNYears(2).map((h) => h.date), - ...companyHolidays.map((h) => convertDateArrayToString(h.date)), - ]), - ); - - Object.keys(timesheet).forEach((date) => { - const timeEntries = timesheet[date]; - - // Check each entry - for (const entry of timeEntries) { - const entryErrors = validateTimeEntry(entry, holidays.has(date)); - - if (entryErrors) { - errors[date] = "There are errors in the entries"; - return; - } - } - - // Check total hours - const leaves = leaveRecords[date] || []; - const totalHourError = checkTotalHours(timeEntries, leaves); - if (totalHourError) { - errors[date] = totalHourError; - } - }); - - return Object.keys(errors).length > 0 ? errors : undefined; -}; - -export const validateLeaveRecord = ( - leaveRecords: RecordLeaveInput, - timesheet: RecordTimesheetInput, - companyHolidays: HolidaysResult[], -): { [date: string]: string } | undefined => { - const errors: { [date: string]: string } = {}; - - const holidays = new Set( - compact([ - ...getPublicHolidaysForNYears(2).map((h) => h.date), - ...companyHolidays.map((h) => convertDateArrayToString(h.date)), - ]), - ); - - Object.keys(leaveRecords).forEach((date) => { - const leaves = leaveRecords[date]; - - // Check each leave entry - for (const entry of leaves) { - const entryError = validateLeaveEntry(entry, holidays.has(date)); - if (entryError) { - errors[date] = "There are errors in the entries"; - return; - } - } - - // Check total hours - const timeEntries = timesheet[date] || []; - - const totalHourError = checkTotalHours(timeEntries, leaves); - if (totalHourError) { - errors[date] = totalHourError; - } - }); - - return Object.keys(errors).length > 0 ? errors : undefined; -}; - export const validateTimeLeaveRecord = ( records: RecordTimeLeaveInput, companyHolidays: HolidaysResult[], @@ -191,8 +109,8 @@ export const validateTimeLeaveRecord = ( // Check total hours const totalHourError = checkTotalHours( - entries.filter((e) => e.type === "timeEntry"), - entries.filter((e) => e.type === "leaveEntry"), + entries.filter((e) => e.type === "timeEntry") as TimeEntry[], + entries.filter((e) => e.type === "leaveEntry") as LeaveEntry[], ); if (totalHourError) { diff --git a/src/components/EnterLeave/EnterLeaveModal.tsx b/src/components/EnterLeave/EnterLeaveModal.tsx deleted file mode 100644 index 97f0d3c..0000000 --- a/src/components/EnterLeave/EnterLeaveModal.tsx +++ /dev/null @@ -1,109 +0,0 @@ -"use client"; - -import { useState } from "react"; -import Button from "@mui/material/Button"; -import { Card, Modal } from "@mui/material"; -import TimesheetInputGrid from "./LeaveInputGrid"; - -// import { fetchLeaves } from "@/app/api/leave"; - -interface EnterTimesheetModalProps { - isOpen: boolean; - onClose: () => void; - modalStyle?: any; -} - -const EnterTimesheetModal: React.FC = ({ - ...props -}) => { - const [lockConfirm, setLockConfirm] = useState(false); - const columns = [ - { - id: "projectCode", - field: "projectCode", - headerName: "Project Code and Name", - flex: 1, - }, - { - id: "task", - field: "task", - headerName: "Task", - flex: 1, - }, - ]; - - const rows = [ - { - id: 1, - projectCode: "M1001", - task: "1.2", - }, - { - id: 2, - projectCode: "M1301", - task: "1.1", - }, - ]; - - const fetchTimesheet = async () => { - // fetchLeaves(); - // const res = await fetch(`http://localhost:8090/api/timesheets`, { - // // const res = await fetch(`${BASE_API_URL}/timesheets`, { - // method: "GET", - // mode: 'no-cors', - // }); - - // console.log(res.json); - }; - - return ( - -
- {/* -
- Record Leave -
-
*/} - - - -
- - -
-
-
-
- ); -}; - -export default EnterTimesheetModal; diff --git a/src/components/EnterLeave/LeaveInputGrid.tsx b/src/components/EnterLeave/LeaveInputGrid.tsx deleted file mode 100644 index 03eeaab..0000000 --- a/src/components/EnterLeave/LeaveInputGrid.tsx +++ /dev/null @@ -1,548 +0,0 @@ -"use client"; -import Grid from "@mui/material/Grid"; -import Paper from "@mui/material/Paper"; -import { useState, useEffect } from "react"; -import { useTranslation } from "react-i18next"; -import PageTitle from "../PageTitle/PageTitle"; -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 Swal from "sweetalert2"; -import { msg } from "../Swal/CustomAlerts"; -import React from "react"; -import { DatePicker } from "@mui/x-date-pickers/DatePicker"; -import { - GridRowsProp, - GridRowModesModel, - GridRowModes, - DataGrid, - GridColDef, - GridToolbarContainer, - GridFooterContainer, - GridActionsCellItem, - GridEventListener, - GridRowId, - GridRowModel, - GridRowEditStopReasons, - GridEditInputCell, - GridValueSetterParams, -} 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"]; - -interface BottomBarProps { - getHoursTotal: (column: string) => number; - setLockConfirm: (newLock: (oldLock: boolean) => boolean) => void; - setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; - setRowModesModel: ( - newModel: (oldModel: GridRowModesModel) => GridRowModesModel, - ) => void; -} - -interface EditToolbarProps { - // setDay: (newDay : dayjs.Dayjs) => void; - setDay: (newDay: (oldDay: dayjs.Dayjs) => dayjs.Dayjs) => void; - setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; - setRowModesModel: ( - newModel: (oldModel: GridRowModesModel) => GridRowModesModel, - ) => void; -} - -interface EditFooterProps { - setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; - setRowModesModel: ( - newModel: (oldModel: GridRowModesModel) => GridRowModesModel, - ) => void; -} - -const EditToolbar = (props: EditToolbarProps) => { - const { setDay } = props; - const [selectedDate, setSelectedDate] = useState(dayjs()); - - const handleClickLeft = () => { - if (selectedDate) { - const newDate = selectedDate.add(-7, "day"); - setSelectedDate(newDate); - } - }; - const handleClickRight = () => { - if (selectedDate) { - const newDate = - selectedDate.add(7, "day") > dayjs() - ? dayjs() - : selectedDate.add(7, "day"); - setSelectedDate(newDate); - } - }; - - const handleDateChange = (date: dayjs.Dayjs | Date | null) => { - const newDate = dayjs(date); - setSelectedDate(newDate); - }; - - useEffect(() => { - setDay((oldDay) => selectedDate); - }, [selectedDate]); - - return ( - -
- - Record Leave - - - - -
-
- ); -}; - -const BottomBar = (props: BottomBarProps) => { - const { setRows, setRowModesModel, getHoursTotal, setLockConfirm } = props; - // const getHoursTotal = props.getHoursTotal; - const [newId, setNewId] = useState(-1); - const [invalidDays, setInvalidDays] = useState(0); - - const handleAddClick = () => { - const id = newId; - setNewId(newId - 1); - setRows((oldRows) => [ - ...oldRows, - { id, projectCode: "", task: "", isNew: true }, - ]); - setRowModesModel((oldModel) => ({ - ...oldModel, - [id]: { mode: GridRowModes.Edit, fieldToFocus: "projectCode" }, - })); - }; - - const totalColDef = { - flex: 1, - // style: {color:getHoursTotal('mon')>24?"red":"black"} - }; - - const TotalCell = ({ value }: Props) => { - const [invalid, setInvalid] = useState(false); - - useEffect(() => { - const newInvalid = (value ?? 0) > 24; - setInvalid(newInvalid); - }, [value]); - - return ( - - {value} - - ); - }; - - const checkUnlockConfirmBtn = () => { - // setLockConfirm((oldLock)=> valid); - 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; - onClose?: () => void; -} - -const initialRows: GridRowsProp = [ - { - id: 1, - projectCode: "M1001", - task: "1.2", - mon: 2.5, - }, - { - id: 2, - projectCode: "M1002", - task: "1.3", - mon: 3.25, - }, -]; - -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", -]; - -const getDateForHeader = (date: dayjs.Dayjs, weekday: number) => { - if (date.day() == 0) { - return date.add(weekday - date.day() - 7, "day").format("DD MMM"); - } else { - return date.add(weekday - date.day(), "day").format("DD MMM"); - } -}; - -const TimesheetInputGrid: React.FC = ({ - ...props -}) => { - const [rows, setRows] = useState(initialRows); - const [day, setDay] = useState(dayjs()); - const [rowModesModel, setRowModesModel] = React.useState( - {}, - ); - const { setLockConfirm } = props; - - const handleRowEditStop: GridEventListener<"rowEditStop"> = ( - params, - event, - ) => { - if (params.reason === GridRowEditStopReasons.rowFocusOut) { - event.defaultMuiPrevented = true; - } - }; - - const handleEditClick = (id: GridRowId) => () => { - setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } }); - }; - - const handleSaveClick = (id: GridRowId) => () => { - setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } }); - }; - - const handleDeleteClick = (id: GridRowId) => () => { - setRows(rows.filter((row) => row.id !== id)); - }; - - const handleCancelClick = (id: GridRowId) => () => { - setRowModesModel({ - ...rowModesModel, - [id]: { mode: GridRowModes.View, ignoreModifications: true }, - }); - - const editedRow = rows.find((row) => row.id === id); - if (editedRow!.isNew) { - setRows(rows.filter((row) => row.id !== id)); - } - }; - - const processRowUpdate = (newRow: GridRowModel) => { - const updatedRow = { ...newRow, isNew: false }; - setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row))); - return updatedRow; - }; - - const handleRowModesModelChange = (newRowModesModel: GridRowModesModel) => { - setRowModesModel(newRowModesModel); - }; - - const getHoursTotal = (column: any) => { - let sum = 0; - rows.forEach((row) => { - sum += row[column] ?? 0; - }); - return sum; - }; - - const weekdayColConfig: any = { - type: "number", - // sortable: false, - //width: 100, - flex: 1, - align: "left", - headerAlign: "left", - editable: true, - renderEditCell: (value: any) => ( - - ), - }; - - const columns: GridColDef[] = [ - { - field: "actions", - type: "actions", - headerName: "Actions", - width: 100, - cellClassName: "actions", - getActions: ({ id }) => { - const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; - - if (isInEditMode) { - return [ - } - title="Save" - label="Save" - sx={{ - color: "primary.main", - }} - onClick={handleSaveClick(id)} - />, - } - title="Cancel" - label="Cancel" - className="textPrimary" - onClick={handleCancelClick(id)} - color="inherit" - />, - ]; - } - - return [ - } - title="Edit" - label="Edit" - className="textPrimary" - onClick={handleEditClick(id)} - color="inherit" - />, - } - onClick={handleDeleteClick(id)} - sx={{ color: "red" }} - />, - ]; - }, - }, - { - field: "projectCode", - headerName: "Project Code", - // width: 220, - flex: 2, - editable: true, - type: "singleSelect", - valueOptions: options, - }, - { - field: "task", - headerName: "Task", - // width: 220, - flex: 3, - editable: true, - type: "singleSelect", - valueOptions: options2, - }, - { - // Mon - field: "mon", - ...weekdayColConfig, - renderHeader: () => { - return
Mon - {getDateForHeader(day, 1)}
; - }, - }, - { - // Tue - field: "tue", - ...weekdayColConfig, - renderHeader: () => { - return
Tue - {getDateForHeader(day, 2)}
; - }, - }, - { - // Wed - field: "wed", - ...weekdayColConfig, - renderHeader: () => { - return
Wed - {getDateForHeader(day, 3)}
; - }, - }, - { - // Thu - field: "thu", - ...weekdayColConfig, - renderHeader: () => { - return
Thu - {getDateForHeader(day, 4)}
; - }, - }, - { - // Fri - field: "fri", - ...weekdayColConfig, - renderHeader: () => { - return
Fri - {getDateForHeader(day, 5)}
; - }, - }, - { - // Sat - field: "sat", - ...weekdayColConfig, - renderHeader: () => { - return
Sat - {getDateForHeader(day, 6)}
; - }, - }, - { - // Sun - field: "sun", - ...weekdayColConfig, - renderHeader: () => { - return ( -
Sun - {getDateForHeader(day, 7)}
- ); - }, - }, - // { - // field: 'joinDate', - // headerName: 'Join date', - // type: 'date', - // width: 180, - // editable: true, - // }, - ]; - - return ( - - - - - - ); -}; - -export default TimesheetInputGrid; diff --git a/src/components/EnterLeave/index.ts b/src/components/EnterLeave/index.ts deleted file mode 100644 index 33541f2..0000000 --- a/src/components/EnterLeave/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./EnterLeaveModal"; diff --git a/src/components/EnterTimesheet/EnterTimesheetModal.tsx b/src/components/EnterTimesheet/EnterTimesheetModal.tsx deleted file mode 100644 index d8854a1..0000000 --- a/src/components/EnterTimesheet/EnterTimesheetModal.tsx +++ /dev/null @@ -1,109 +0,0 @@ -"use client"; - -import { useState } from "react"; -import Button from "@mui/material/Button"; -import { Card, Modal } from "@mui/material"; -import TimesheetInputGrid from "./TimesheetInputGrid"; - -// import { fetchTimesheets } from "@/app/api/timesheets"; - -interface EnterTimesheetModalProps { - isOpen: boolean; - onClose: () => void; - modalStyle?: any; -} - -const EnterTimesheetModal: React.FC = ({ - ...props -}) => { - const [lockConfirm, setLockConfirm] = useState(false); - const columns = [ - { - id: "projectCode", - field: "projectCode", - headerName: "Project Code and Name", - flex: 1, - }, - { - id: "task", - field: "task", - headerName: "Task", - flex: 1, - }, - ]; - - const rows = [ - { - id: 1, - projectCode: "M1001", - task: "1.2", - }, - { - id: 2, - projectCode: "M1301", - task: "1.1", - }, - ]; - - const fetchTimesheet = async () => { - // fetchTimesheets(); - // const res = await fetch(`http://localhost:8090/api/timesheets`, { - // // const res = await fetch(`${BASE_API_URL}/timesheets`, { - // method: "GET", - // mode: 'no-cors', - // }); - - // console.log(res.json); - }; - - return ( - -
- {/* -
- Timesheet Input -
-
*/} - - - -
- - -
-
-
-
- ); -}; - -export default EnterTimesheetModal; diff --git a/src/components/EnterTimesheet/TimesheetInputGrid.tsx b/src/components/EnterTimesheet/TimesheetInputGrid.tsx deleted file mode 100644 index bc64c50..0000000 --- a/src/components/EnterTimesheet/TimesheetInputGrid.tsx +++ /dev/null @@ -1,548 +0,0 @@ -"use client"; -import Grid from "@mui/material/Grid"; -import Paper from "@mui/material/Paper"; -import { useState, useEffect } from "react"; -import { useTranslation } from "react-i18next"; -import PageTitle from "../PageTitle/PageTitle"; -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 Swal from "sweetalert2"; -import { msg } from "../Swal/CustomAlerts"; -import React from "react"; -import { DatePicker } from "@mui/x-date-pickers/DatePicker"; -import { - GridRowsProp, - GridRowModesModel, - GridRowModes, - DataGrid, - GridColDef, - GridToolbarContainer, - GridFooterContainer, - GridActionsCellItem, - GridEventListener, - GridRowId, - GridRowModel, - GridRowEditStopReasons, - GridEditInputCell, - GridValueSetterParams, -} 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"]; - -interface BottomBarProps { - getHoursTotal: (column: string) => number; - setLockConfirm: (newLock: (oldLock: boolean) => boolean) => void; - setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; - setRowModesModel: ( - newModel: (oldModel: GridRowModesModel) => GridRowModesModel, - ) => void; -} - -interface EditToolbarProps { - // setDay: (newDay : dayjs.Dayjs) => void; - setDay: (newDay: (oldDay: dayjs.Dayjs) => dayjs.Dayjs) => void; - setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; - setRowModesModel: ( - newModel: (oldModel: GridRowModesModel) => GridRowModesModel, - ) => void; -} - -interface EditFooterProps { - setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; - setRowModesModel: ( - newModel: (oldModel: GridRowModesModel) => GridRowModesModel, - ) => void; -} - -const EditToolbar = (props: EditToolbarProps) => { - const { setDay } = props; - const [selectedDate, setSelectedDate] = useState(dayjs()); - - const handleClickLeft = () => { - if (selectedDate) { - const newDate = selectedDate.add(-7, "day"); - setSelectedDate(newDate); - } - }; - const handleClickRight = () => { - if (selectedDate) { - const newDate = - selectedDate.add(7, "day") > dayjs() - ? dayjs() - : selectedDate.add(7, "day"); - setSelectedDate(newDate); - } - }; - - const handleDateChange = (date: dayjs.Dayjs | Date | null) => { - const newDate = dayjs(date); - setSelectedDate(newDate); - }; - - useEffect(() => { - setDay((oldDay) => selectedDate); - }, [selectedDate]); - - return ( - -
- - Timesheet Input - - - - -
-
- ); -}; - -const BottomBar = (props: BottomBarProps) => { - const { setRows, setRowModesModel, getHoursTotal, setLockConfirm } = props; - // const getHoursTotal = props.getHoursTotal; - const [newId, setNewId] = useState(-1); - const [invalidDays, setInvalidDays] = useState(0); - - const handleAddClick = () => { - const id = newId; - setNewId(newId - 1); - setRows((oldRows) => [ - ...oldRows, - { id, projectCode: "", task: "", isNew: true }, - ]); - setRowModesModel((oldModel) => ({ - ...oldModel, - [id]: { mode: GridRowModes.Edit, fieldToFocus: "projectCode" }, - })); - }; - - const totalColDef = { - flex: 1, - // style: {color:getHoursTotal('mon')>24?"red":"black"} - }; - - const TotalCell = ({ value }: Props) => { - const [invalid, setInvalid] = useState(false); - - useEffect(() => { - const newInvalid = (value ?? 0) > 24; - setInvalid(newInvalid); - }, [value]); - - return ( - - {value} - - ); - }; - - const checkUnlockConfirmBtn = () => { - // setLockConfirm((oldLock)=> valid); - 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; - onClose?: () => void; -} - -const initialRows: GridRowsProp = [ - { - id: 1, - projectCode: "M1001", - task: "1.2", - mon: 2.5, - }, - { - id: 2, - projectCode: "M1002", - task: "1.3", - mon: 3.25, - }, -]; - -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", -]; - -const getDateForHeader = (date: dayjs.Dayjs, weekday: number) => { - if (date.day() == 0) { - return date.add(weekday - date.day() - 7, "day").format("DD MMM"); - } else { - return date.add(weekday - date.day(), "day").format("DD MMM"); - } -}; - -const TimesheetInputGrid: React.FC = ({ - ...props -}) => { - const [rows, setRows] = useState(initialRows); - const [day, setDay] = useState(dayjs()); - const [rowModesModel, setRowModesModel] = React.useState( - {}, - ); - const { setLockConfirm } = props; - - const handleRowEditStop: GridEventListener<"rowEditStop"> = ( - params, - event, - ) => { - if (params.reason === GridRowEditStopReasons.rowFocusOut) { - event.defaultMuiPrevented = true; - } - }; - - const handleEditClick = (id: GridRowId) => () => { - setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } }); - }; - - const handleSaveClick = (id: GridRowId) => () => { - setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } }); - }; - - const handleDeleteClick = (id: GridRowId) => () => { - setRows(rows.filter((row) => row.id !== id)); - }; - - const handleCancelClick = (id: GridRowId) => () => { - setRowModesModel({ - ...rowModesModel, - [id]: { mode: GridRowModes.View, ignoreModifications: true }, - }); - - const editedRow = rows.find((row) => row.id === id); - if (editedRow!.isNew) { - setRows(rows.filter((row) => row.id !== id)); - } - }; - - const processRowUpdate = (newRow: GridRowModel) => { - const updatedRow = { ...newRow, isNew: false }; - setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row))); - return updatedRow; - }; - - const handleRowModesModelChange = (newRowModesModel: GridRowModesModel) => { - setRowModesModel(newRowModesModel); - }; - - const getHoursTotal = (column: any) => { - let sum = 0; - rows.forEach((row) => { - sum += row[column] ?? 0; - }); - return sum; - }; - - const weekdayColConfig: any = { - type: "number", - // sortable: false, - //width: 100, - flex: 1, - align: "left", - headerAlign: "left", - editable: true, - renderEditCell: (value: any) => ( - - ), - }; - - const columns: GridColDef[] = [ - { - field: "actions", - type: "actions", - headerName: "Actions", - width: 100, - cellClassName: "actions", - getActions: ({ id }) => { - const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; - - if (isInEditMode) { - return [ - } - title="Save" - label="Save" - sx={{ - color: "primary.main", - }} - onClick={handleSaveClick(id)} - />, - } - title="Cancel" - label="Cancel" - className="textPrimary" - onClick={handleCancelClick(id)} - color="inherit" - />, - ]; - } - - return [ - } - title="Edit" - label="Edit" - className="textPrimary" - onClick={handleEditClick(id)} - color="inherit" - />, - } - onClick={handleDeleteClick(id)} - sx={{ color: "red" }} - />, - ]; - }, - }, - { - field: "projectCode", - headerName: "Project Code", - // width: 220, - flex: 2, - editable: true, - type: "singleSelect", - valueOptions: options, - }, - { - field: "task", - headerName: "Task", - // width: 220, - flex: 3, - editable: true, - type: "singleSelect", - valueOptions: options2, - }, - { - // Mon - field: "mon", - ...weekdayColConfig, - renderHeader: () => { - return
Mon - {getDateForHeader(day, 1)}
; - }, - }, - { - // Tue - field: "tue", - ...weekdayColConfig, - renderHeader: () => { - return
Tue - {getDateForHeader(day, 2)}
; - }, - }, - { - // Wed - field: "wed", - ...weekdayColConfig, - renderHeader: () => { - return
Wed - {getDateForHeader(day, 3)}
; - }, - }, - { - // Thu - field: "thu", - ...weekdayColConfig, - renderHeader: () => { - return
Thu - {getDateForHeader(day, 4)}
; - }, - }, - { - // Fri - field: "fri", - ...weekdayColConfig, - renderHeader: () => { - return
Fri - {getDateForHeader(day, 5)}
; - }, - }, - { - // Sat - field: "sat", - ...weekdayColConfig, - renderHeader: () => { - return
Sat - {getDateForHeader(day, 6)}
; - }, - }, - { - // Sun - field: "sun", - ...weekdayColConfig, - renderHeader: () => { - return ( -
Sun - {getDateForHeader(day, 7)}
- ); - }, - }, - // { - // field: 'joinDate', - // headerName: 'Join date', - // type: 'date', - // width: 180, - // editable: true, - // }, - ]; - - return ( - - - - - - ); -}; - -export default TimesheetInputGrid; diff --git a/src/components/EnterTimesheet/index.ts b/src/components/EnterTimesheet/index.ts deleted file mode 100644 index e070291..0000000 --- a/src/components/EnterTimesheet/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./EnterTimesheetModal"; diff --git a/src/components/TimesheetModal/TimesheetModal.tsx b/src/components/TimesheetModal/TimesheetModal.tsx deleted file mode 100644 index c6746d6..0000000 --- a/src/components/TimesheetModal/TimesheetModal.tsx +++ /dev/null @@ -1,223 +0,0 @@ -import React, { useCallback, useEffect, useMemo } from "react"; -import { - Box, - Button, - Card, - CardActions, - CardContent, - Modal, - ModalProps, - SxProps, - Typography, -} from "@mui/material"; -import TimesheetTable from "../TimesheetTable"; -import { useTranslation } from "react-i18next"; -import { Check, Close } from "@mui/icons-material"; -import { FormProvider, SubmitHandler, useForm } from "react-hook-form"; -import { - RecordLeaveInput, - RecordTimesheetInput, - saveTimesheet, -} from "@/app/api/timesheets/actions"; -import dayjs from "dayjs"; -import { INPUT_DATE_FORMAT } from "@/app/utils/formatUtil"; -import { AssignedProject, ProjectWithTasks } from "@/app/api/projects"; -import FullscreenModal from "../FullscreenModal"; -import MobileTimesheetTable from "../TimesheetTable/MobileTimesheetTable"; -import useIsMobile from "@/app/utils/useIsMobile"; -import { HolidaysResult } from "@/app/api/holidays"; -import { - DAILY_NORMAL_MAX_HOURS, - TIMESHEET_DAILY_MAX_HOURS, - validateTimesheet, -} from "@/app/api/timesheets/utils"; -import ErrorAlert from "../ErrorAlert"; - -interface Props { - isOpen: boolean; - onClose: () => void; - allProjects: ProjectWithTasks[]; - assignedProjects: AssignedProject[]; - defaultTimesheets?: RecordTimesheetInput; - leaveRecords: RecordLeaveInput; - companyHolidays: HolidaysResult[]; - fastEntryEnabled?: boolean; -} - -const modalSx: SxProps = { - position: "absolute", - top: "50%", - left: "50%", - transform: "translate(-50%, -50%)", - width: { xs: "calc(100% - 2rem)", sm: "90%" }, - maxHeight: "90%", - maxWidth: 1400, -}; - -const TimesheetModal: React.FC = ({ - isOpen, - onClose, - allProjects, - assignedProjects, - defaultTimesheets, - leaveRecords, - companyHolidays, - fastEntryEnabled, -}) => { - const { t } = useTranslation("home"); - - const defaultValues = useMemo(() => { - const today = dayjs(); - return Array(7) - .fill(undefined) - .reduce((acc, _, index) => { - const date = today.subtract(index, "day").format(INPUT_DATE_FORMAT); - return { - ...acc, - [date]: defaultTimesheets?.[date] ?? [], - }; - }, {}); - }, [defaultTimesheets]); - - const formProps = useForm({ defaultValues }); - useEffect(() => { - formProps.reset(defaultValues); - }, [defaultValues, formProps]); - - const onSubmit = useCallback>( - async (data) => { - const errors = validateTimesheet(data, leaveRecords, companyHolidays); - if (errors) { - Object.keys(errors).forEach((date) => - formProps.setError(date, { - message: errors[date], - }), - ); - return; - } - const savedRecords = await saveTimesheet(data); - - const today = dayjs(); - const newFormValues = Array(7) - .fill(undefined) - .reduce((acc, _, index) => { - const date = today.subtract(index, "day").format(INPUT_DATE_FORMAT); - return { - ...acc, - [date]: savedRecords[date] ?? [], - }; - }, {}); - - formProps.reset(newFormValues); - onClose(); - }, - [companyHolidays, formProps, leaveRecords, onClose], - ); - - const onCancel = useCallback(() => { - formProps.reset(defaultValues); - onClose(); - }, [defaultValues, formProps, onClose]); - - const onModalClose = useCallback>( - (_, reason) => { - if (reason !== "backdropClick") { - onClose(); - } - }, - [onClose], - ); - - const errorComponent = ( - { - const error = formProps.formState.errors[date]?.message; - return error - ? `${date}: ${t(error, { - TIMESHEET_DAILY_MAX_HOURS, - DAILY_NORMAL_MAX_HOURS, - })}` - : undefined; - })} - /> - ); - - const matches = useIsMobile(); - - return ( - - {!matches ? ( - // Desktop version - - - - - {t("Timesheet Input")} - - - - - {errorComponent} - - - - - - - - ) : ( - // Mobile version - - - - {t("Timesheet Input")} - - - - - )} - - ); -}; - -export default TimesheetModal; diff --git a/src/components/TimesheetModal/index.ts b/src/components/TimesheetModal/index.ts deleted file mode 100644 index c5197a7..0000000 --- a/src/components/TimesheetModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./TimesheetModal"; diff --git a/src/components/TimesheetTable/FastTimeEntryModal.tsx b/src/components/TimesheetTable/FastTimeEntryModal.tsx index 6181c49..c025b16 100644 --- a/src/components/TimesheetTable/FastTimeEntryModal.tsx +++ b/src/components/TimesheetTable/FastTimeEntryModal.tsx @@ -174,6 +174,7 @@ const FastTimeEntryModal: React.FC = ({ name="projectIds" render={({ field }) => (