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 = ({ 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(); const currentEntries = watch(date); // Edit modal const [editModalProps, setEditModalProps] = useState< Partial >({}); 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 ( <> {shortDateFormatter(language).format(dayJsObj.toDate())} {holiday && ( {`(${holiday.title})`} )} {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 ( ); }) ) : ( {t("Add some time entries!")} )} ); }; export default MobileTimesheetEntry;