import { useMutation } from "@tanstack/react-query"; import { addWeeks, format } from "date-fns"; import { useEffect, useState } from "react"; import { createAllocation, deleteAllocation, updateAllocation } from "../../api/allocations"; import { formatHoursPerDay } from "../../planner/allocationTimeline"; import { Modal } from "../ui/Modal"; import { toastFromError, useToast } from "../ui/Toast"; import type { Allocation, Person, Project } from "../../types"; interface AddProjectMemberModalProps { open: boolean; project: Project | null; people: Person[]; allocation: Allocation | null; assignedPersonIds: number[]; onClose: () => void; onSaved: () => void; } export function AddProjectMemberModal({ open, project, people, allocation, assignedPersonIds, onClose, onSaved, }: AddProjectMemberModalProps) { const { push } = useToast(); const [personId, setPersonId] = useState(""); const [startDate, setStartDate] = useState(""); const [endDate, setEndDate] = useState(""); const [allocationPct, setAllocationPct] = useState(50); useEffect(() => { if (!open || !project) return; if (allocation) { setPersonId(allocation.person_id); setStartDate(allocation.start_date); setEndDate(allocation.end_date); setAllocationPct(allocation.allocation_pct); return; } const available = people.find((person) => !assignedPersonIds.includes(person.id)); setPersonId(available?.id ?? ""); setStartDate(format(new Date(), "yyyy-MM-dd")); setEndDate(format(addWeeks(new Date(), 1), "yyyy-MM-dd")); setAllocationPct(50); }, [open, project, allocation, people, assignedPersonIds]); const createMutation = useMutation({ mutationFn: createAllocation, onSuccess: () => { push("Developer added to project", "success"); onSaved(); onClose(); }, onError: (error) => push(toastFromError(error, "Could not add developer"), "error"), }); const updateMutation = useMutation({ mutationFn: ({ id, input }: { id: number; input: { start_date: string; end_date: string; allocation_pct: number } }) => updateAllocation(id, input), onSuccess: () => { push("Allocation updated", "success"); onSaved(); onClose(); }, onError: (error) => push(toastFromError(error, "Could not update allocation"), "error"), }); const deleteMutation = useMutation({ mutationFn: deleteAllocation, onSuccess: () => { push("Developer removed from project", "success"); onSaved(); onClose(); }, onError: (error) => push(toastFromError(error, "Could not remove developer"), "error"), }); const isSaving = createMutation.isPending || updateMutation.isPending || deleteMutation.isPending; const availablePeople = allocation ? people.filter((person) => person.id === allocation.person_id) : people.filter((person) => !assignedPersonIds.includes(person.id)); const handleSave = () => { if (!project || personId === "") return; if (allocation) { updateMutation.mutate({ id: allocation.id, input: { start_date: startDate, end_date: endDate, allocation_pct: allocationPct }, }); return; } createMutation.mutate({ person_id: Number(personId), project_id: project.id, start_date: startDate, end_date: endDate, allocation_pct: allocationPct, }); }; return ( {allocation ? ( ) : null} } > {!project ? null : (
)}
); }