diff --git a/src/admin/components/PlanCellModal.tsx b/src/admin/components/PlanCellModal.tsx new file mode 100644 index 0000000..618b96d --- /dev/null +++ b/src/admin/components/PlanCellModal.tsx @@ -0,0 +1,390 @@ +import { useState } from "react"; +import FormModal from "./FormModal"; +import FormField from "./FormField"; +import AdminDatePicker from "./AdminDatePicker"; +import ConfirmModal from "./ConfirmModal"; +import { ResolvedCell } from "../lib/queries/plan"; + +interface Project { + id: number; + name: string; +} + +export type PlanCellModalMode = + | { kind: "closed" } + | { kind: "create"; userId: number; date: string } + | { + kind: "edit-range"; + entryId: number; + userId: number; + date: string; + range: { + date_from: string; + date_to: string; + project_id: number | null; + category: string; + note: string; + }; + } + | { + kind: "edit-override"; + overrideId: number; + userId: number; + date: string; + cell: ResolvedCell; + } + | { + kind: "day-in-range"; + entryId: number; + userId: number; + date: string; + range: { + date_from: string; + date_to: string; + project_id: number | null; + category: string; + note: string; + }; + } + | { kind: "view"; userId: number; date: string; cell: ResolvedCell }; + +interface Props { + open: boolean; + mode: PlanCellModalMode; + projects: Project[]; + onClose: () => void; + onSaveEntry: (body: any) => Promise; + onUpdateEntry: (id: number, body: any) => Promise; + onDeleteEntry: (id: number) => Promise; + onSaveOverride: (body: any) => Promise; + onUpdateOverride: (id: number, body: any) => Promise; + onDeleteOverride: (id: number) => Promise; + onCreateOverrideFromRange: ( + entryId: number, + userId: number, + date: string, + ) => Promise; +} + +const CATEGORIES = [ + { value: "work", label: "Práce" }, + { value: "preparation", label: "Příprava" }, + { value: "travel", label: "Cesta / Montáž" }, + { value: "leave", label: "Dovolená" }, + { value: "sick", label: "Nemoc" }, + { value: "training", label: "Školení" }, + { value: "other", label: "Jiné" }, +]; + +export default function PlanCellModal(props: Props) { + const { open, mode, onClose } = props; + if (!open || mode.kind === "closed") return null; + if (mode.kind === "view") return ; + if (mode.kind === "day-in-range") + return ; + return ; +} + +function EditForm(props: Props) { + const { + mode, + onClose, + onSaveEntry, + onUpdateEntry, + onDeleteEntry, + onSaveOverride, + onUpdateOverride, + onDeleteOverride, + projects, + } = props; + const [submitting, setSubmitting] = useState(false); + const [confirmDelete, setConfirmDelete] = useState(false); + + const isOverride = mode.kind === "edit-override"; + + const initial = (() => { + if (mode.kind === "create") { + return { + date_from: mode.date, + date_to: mode.date, + is_range: false, + project_id: null as number | null, + category: "work", + note: "", + }; + } + if (mode.kind === "edit-range") { + return { + date_from: mode.range.date_from, + date_to: mode.range.date_to, + is_range: mode.range.date_from !== mode.range.date_to, + project_id: mode.range.project_id, + category: mode.range.category, + note: mode.range.note, + }; + } + return { + date_from: mode.date, + date_to: mode.date, + is_range: false, + project_id: mode.cell.project_id, + category: mode.cell.category, + note: mode.cell.note, + }; + })(); + + const [dateFrom, setDateFrom] = useState(initial.date_from); + const [dateTo, setDateTo] = useState(initial.date_to); + const [isRange, setIsRange] = useState(initial.is_range); + const [projectId, setProjectId] = useState(initial.project_id); + const [category, setCategory] = useState(initial.category); + const [note, setNote] = useState(initial.note); + + const title = + mode.kind === "create" + ? "Nový záznam plánu" + : mode.kind === "edit-range" + ? "Upravit rozsah" + : "Upravit přepsání dne"; + + const handleSubmit = async () => { + setSubmitting(true); + try { + if (mode.kind === "create") { + const userId = mode.userId; + await onSaveEntry({ + user_id: userId, + date_from: dateFrom, + date_to: isRange ? dateTo : dateFrom, + project_id: projectId, + category, + note, + }); + } else if (mode.kind === "edit-range") { + await onUpdateEntry(mode.entryId, { + date_from: dateFrom, + date_to: isRange ? dateTo : dateFrom, + project_id: projectId, + category, + note, + }); + } else { + await onUpdateOverride(mode.overrideId, { + project_id: projectId, + category, + note, + }); + } + onClose(); + } finally { + setSubmitting(false); + } + }; + + const handleDelete = async () => { + setSubmitting(true); + try { + if (mode.kind === "edit-range") { + await onDeleteEntry(mode.entryId); + } else if (mode.kind === "edit-override") { + await onDeleteOverride(mode.overrideId); + } + onClose(); + } finally { + setSubmitting(false); + } + }; + + return ( + <> + + {mode.kind !== "create" && ( +
+ +
+ )} + + + + {!isOverride && ( + + + + )} + {!isOverride && isRange && ( + + + + )} + + + + + + + +