diff --git a/src/components/LeaveModal/LeaveModal.tsx b/src/components/LeaveModal/LeaveModal.tsx index a6a551c..3889a4e 100644 --- a/src/components/LeaveModal/LeaveModal.tsx +++ b/src/components/LeaveModal/LeaveModal.tsx @@ -9,8 +9,6 @@ import { ModalProps, SxProps, Typography, - useMediaQuery, - useTheme, } from "@mui/material"; import { useTranslation } from "react-i18next"; import { Check, Close } from "@mui/icons-material"; @@ -26,6 +24,7 @@ import LeaveTable from "../LeaveTable"; import { LeaveType } from "@/app/api/timesheets"; import FullscreenModal from "../FullscreenModal"; import MobileLeaveTable from "../LeaveTable/MobileLeaveTable"; +import useIsMobile from "../utils/useIsMobile"; interface Props { isOpen: boolean; @@ -106,12 +105,11 @@ const LeaveModal: React.FC = ({ [onCancel], ); - const theme = useTheme(); - const matches = useMediaQuery(theme.breakpoints.up("sm")); + const matches = useIsMobile(); return ( - {matches ? ( + {!matches ? ( // Desktop version diff --git a/src/components/LeaveTable/LeaveEditModal.tsx b/src/components/LeaveTable/LeaveEditModal.tsx index 70eacaa..b708596 100644 --- a/src/components/LeaveTable/LeaveEditModal.tsx +++ b/src/components/LeaveTable/LeaveEditModal.tsx @@ -47,7 +47,11 @@ const LeaveEditModal: React.FC = ({ }) => { const { t } = useTranslation("home"); const { register, control, reset, getValues, trigger, formState } = - useForm(); + useForm({ + defaultValues: { + leaveTypeId: leaveTypes[0].id, + }, + }); useEffect(() => { reset(defaultValues ?? { leaveTypeId: leaveTypes[0].id, id: Date.now() }); @@ -57,14 +61,14 @@ const LeaveEditModal: React.FC = ({ const valid = await trigger(); if (valid) { onSave(getValues()); - reset(); + reset({ id: Date.now() }); } }, [getValues, onSave, reset, trigger]); const closeHandler = useCallback>( (...args) => { onClose?.(...args); - reset(); + reset({ id: Date.now() }); }, [onClose, reset], ); diff --git a/src/components/LeaveTable/LeaveEntryCard.tsx b/src/components/LeaveTable/LeaveEntryCard.tsx new file mode 100644 index 0000000..0c4912f --- /dev/null +++ b/src/components/LeaveTable/LeaveEntryCard.tsx @@ -0,0 +1,63 @@ +import { LeaveType } from "@/app/api/timesheets"; +import { LeaveEntry } from "@/app/api/timesheets/actions"; +import { manhourFormatter } from "@/app/utils/formatUtil"; +import { Edit } from "@mui/icons-material"; +import { Box, Card, CardContent, IconButton, Typography } from "@mui/material"; +import { useTranslation } from "react-i18next"; + +interface Props { + entry: LeaveEntry; + onEdit?: () => void; + leaveTypeMap: { + [id: number]: LeaveType; + }; +} + +const LeaveEntryCard: React.FC = ({ entry, onEdit, leaveTypeMap }) => { + const { t } = useTranslation("home"); + return ( + + + + + + {leaveTypeMap[entry.leaveTypeId].name} + + + {manhourFormatter.format(entry.inputHours)} + + + {onEdit && ( + + + + )} + + {entry.remark && ( + + + {t("Remark")} + + {entry.remark} + + )} + + + ); +}; + +export default LeaveEntryCard; diff --git a/src/components/LeaveTable/MobileLeaveEntry.tsx b/src/components/LeaveTable/MobileLeaveEntry.tsx index 5fca597..8d52fdb 100644 --- a/src/components/LeaveTable/MobileLeaveEntry.tsx +++ b/src/components/LeaveTable/MobileLeaveEntry.tsx @@ -15,6 +15,7 @@ import React, { useCallback, useMemo, useState } from "react"; import { useFormContext } from "react-hook-form"; import { useTranslation } from "react-i18next"; import LeaveEditModal, { Props as LeaveEditModalProps } from "./LeaveEditModal"; +import LeaveEntryCard from "./LeaveEntryCard"; interface Props { date: string; @@ -105,60 +106,12 @@ const MobileLeaveEntry: React.FC = ({ date, leaveTypes }) => { {currentEntries.length ? ( currentEntries.map((entry, index) => { return ( - - - - - - {leaveTypeMap[entry.leaveTypeId].name} - - - {manhourFormatter.format(entry.inputHours)} - - - - - - - {entry.remark && ( - - - {t("Remark")} - - {entry.remark} - - )} - - + entry={entry} + onEdit={openEditModal(entry)} + leaveTypeMap={leaveTypeMap} + /> ); }) ) : ( diff --git a/src/components/PastEntryCalendar/PastEntryCalendarModal.tsx b/src/components/PastEntryCalendar/PastEntryCalendarModal.tsx index 53fd8dc..e3b49fc 100644 --- a/src/components/PastEntryCalendar/PastEntryCalendarModal.tsx +++ b/src/components/PastEntryCalendar/PastEntryCalendarModal.tsx @@ -15,10 +15,17 @@ import PastEntryCalendar, { import { useCallback, useState } from "react"; import { useTranslation } from "react-i18next"; import { ArrowBack } from "@mui/icons-material"; +import PastEntryList from "./PastEntryList"; +import { ProjectWithTasks } from "@/app/api/projects"; +import { LeaveType } from "@/app/api/timesheets"; +import useIsMobile from "../utils/useIsMobile"; +import FullscreenModal from "../FullscreenModal"; interface Props extends Omit { open: boolean; handleClose: () => void; + leaveTypes: LeaveType[]; + allProjects: ProjectWithTasks[]; } const Indicator = styled(Box)(() => ({ @@ -32,6 +39,8 @@ const PastEntryCalendarModal: React.FC = ({ open, timesheet, leaves, + leaveTypes, + allProjects, }) => { const { t } = useTranslation("home"); @@ -45,42 +54,75 @@ const PastEntryCalendarModal: React.FC = ({ handleClose(); }, [handleClose]); - return ( + const content = selectedDate ? ( + <> + + + ) : ( + <> + + + + {t("Has timesheet entry")} + + + + {t("Has leave entry")} + + + + + {t("Has both timesheet and leave entry")} + + + + + + ); + + const isMobile = useIsMobile(); + + return isMobile ? ( + + + + {t("Past Entries")} + + + {content} + + + + + + + ) : ( {t("Past Entries")} - - {selectedDate ? ( - {selectedDate} - ) : ( - - - - - - {t("Has timesheet entry")} - - - - - - {t("Has leave entry")} - - - - - - {t("Has both timesheet and leave entry")} - - - - - - )} - + {content} {selectedDate && ( = ({ const valid = await trigger(); if (valid) { onSave(getValues()); - reset(); + reset({ id: Date.now() }); } }, [getValues, onSave, reset, trigger]); const closeHandler = useCallback>( (...args) => { onClose?.(...args); - reset(); + reset({ id: Date.now() }); }, [onClose, reset], ); diff --git a/src/components/TransferList/TransferListWrapper.tsx b/src/components/TransferList/TransferListWrapper.tsx index 4668c47..520280b 100644 --- a/src/components/TransferList/TransferListWrapper.tsx +++ b/src/components/TransferList/TransferListWrapper.tsx @@ -2,14 +2,17 @@ import React from "react"; import TransferList, { TransferListProps } from "./TransferList"; -import { useMediaQuery, useTheme } from "@mui/material"; import MultiSelectList from "./MultiSelectList"; +import useIsMobile from "../utils/useIsMobile"; const TransferListWrapper: React.FC = (props) => { - const theme = useTheme(); - const matches = useMediaQuery(theme.breakpoints.up("sm")); + const matches = useIsMobile(); - return matches ? : ; + return !matches ? ( + + ) : ( + + ); }; export default TransferListWrapper; diff --git a/src/components/UserWorkspacePage/UserWorkspacePage.tsx b/src/components/UserWorkspacePage/UserWorkspacePage.tsx index 0c8615f..c0e88ef 100644 --- a/src/components/UserWorkspacePage/UserWorkspacePage.tsx +++ b/src/components/UserWorkspacePage/UserWorkspacePage.tsx @@ -99,6 +99,8 @@ const UserWorkspacePage: React.FC = ({ handleClose={handlePastEventClose} timesheet={defaultTimesheets} leaves={defaultLeaveRecords} + allProjects={allProjects} + leaveTypes={leaveTypes} /> { + const theme = useTheme(); + const matches = useMediaQuery(theme.breakpoints.up(breakpoint)); + + return !matches; +}; + +export default useIsMobile;