|
- import { TimeEntry, RecordTimesheetInput } from "@/app/api/timesheets/actions";
- import { manhourFormatter, shortDateFormatter } from "@/app/utils/formatUtil";
- import { Add, Edit } from "@mui/icons-material";
- import {
- Box,
- Button,
- Card,
- CardContent,
- IconButton,
- Typography,
- } from "@mui/material";
- import dayjs from "dayjs";
- import React, { useCallback, useMemo, useState } from "react";
- import { useFormContext } from "react-hook-form";
- import { useTranslation } from "react-i18next";
- import { AssignedProject, ProjectWithTasks } from "@/app/api/projects";
- import TimesheetEditModal, {
- Props as TimesheetEditModalProps,
- } from "./TimesheetEditModal";
- import TimeEntryCard from "./TimeEntryCard";
- import { HolidaysResult } from "@/app/api/holidays";
- import { getHolidayForDate } from "@/app/utils/holidayUtils";
-
- interface Props {
- date: string;
- allProjects: ProjectWithTasks[];
- assignedProjects: AssignedProject[];
- companyHolidays: HolidaysResult[];
- }
-
- const MobileTimesheetEntry: React.FC<Props> = ({
- date,
- allProjects,
- assignedProjects,
- companyHolidays,
- }) => {
- const {
- t,
- i18n: { language },
- } = useTranslation("home");
-
- const projectMap = useMemo(() => {
- return allProjects.reduce<{
- [id: ProjectWithTasks["id"]]: ProjectWithTasks;
- }>((acc, project) => {
- return { ...acc, [project.id]: project };
- }, {});
- }, [allProjects]);
-
- const dayJsObj = dayjs(date);
- const holiday = getHolidayForDate(date, companyHolidays);
- const isHoliday = holiday || dayJsObj.day() === 0 || dayJsObj.day() === 6;
-
- const { watch, setValue, clearErrors } = useFormContext<RecordTimesheetInput>();
- const currentEntries = watch(date);
-
- // Edit modal
- const [editModalProps, setEditModalProps] = useState<
- Partial<TimesheetEditModalProps>
- >({});
- const [editModalOpen, setEditModalOpen] = useState(false);
-
- const openEditModal = useCallback(
- (defaultValues?: TimeEntry) => () => {
- setEditModalProps({
- defaultValues,
- onDelete: defaultValues
- ? () => {
- setValue(
- date,
- currentEntries.filter((entry) => entry.id !== defaultValues.id),
- );
- clearErrors(date);
- setEditModalOpen(false);
- }
- : undefined,
- });
- setEditModalOpen(true);
- },
- [clearErrors, currentEntries, date, setValue],
- );
-
- const closeEditModal = useCallback(() => {
- setEditModalOpen(false);
- }, []);
-
- const onSaveEntry = useCallback(
- async (entry: TimeEntry) => {
- const existingEntry = currentEntries.find((e) => e.id === entry.id);
- if (existingEntry) {
- setValue(
- date,
- currentEntries.map((e) => ({
- ...(e.id === existingEntry.id ? entry : e),
- })),
- );
- clearErrors(date);
- } else {
- setValue(date, [...currentEntries, entry]);
- }
- setEditModalOpen(false);
- },
- [clearErrors, currentEntries, date, setValue],
- );
-
- return (
- <>
- <Typography
- paddingInline={2}
- variant="overline"
- color={isHoliday ? "error.main" : undefined}
- >
- {shortDateFormatter(language).format(dayJsObj.toDate())}
- {holiday && (
- <Typography
- marginInlineStart={1}
- variant="caption"
- >{`(${holiday.title})`}</Typography>
- )}
- </Typography>
- <Box
- paddingInline={2}
- flex={1}
- display="flex"
- flexDirection="column"
- gap={2}
- overflow="scroll"
- >
- {currentEntries.length ? (
- currentEntries.map((entry, index) => {
- const project = entry.projectId
- ? projectMap[entry.projectId]
- : undefined;
-
- const task = project?.tasks.find((t) => t.id === entry.taskId);
-
- return (
- <TimeEntryCard
- key={`${entry.id}-${index}`}
- project={project}
- task={task}
- entry={entry}
- onEdit={openEditModal(entry)}
- />
- );
- })
- ) : (
- <Typography variant="body2" display="block">
- {t("Add some time entries!")}
- </Typography>
- )}
- <Box>
- <Button startIcon={<Add />} onClick={openEditModal()}>
- {t("Record time")}
- </Button>
- </Box>
- <TimesheetEditModal
- allProjects={allProjects}
- assignedProjects={assignedProjects}
- open={editModalOpen}
- onClose={closeEditModal}
- onSave={onSaveEntry}
- isHoliday={Boolean(isHoliday)}
- {...editModalProps}
- />
- </Box>
- </>
- );
- };
-
- export default MobileTimesheetEntry;
|