import { useState, useEffect } from "react"; import { format } from "date-fns"; import type { Task, Project, Tag } from "../types"; import { api } from "../api"; import Modal from "./Modal"; interface TaskModalProps { open: boolean; onClose: () => void; onSaved: () => void; task?: Task | null; projects: Project[]; tags: Tag[]; } const STATUS_OPTIONS = ["todo", "in_progress", "done"] as const; const PRIORITY_OPTIONS = ["low", "medium", "high", "critical"] as const; export default function TaskModal({ open, onClose, onSaved, task, projects, tags, }: TaskModalProps) { const isEdit = !!task; const [title, setTitle] = useState(""); const [description, setDescription] = useState(""); const [status, setStatus] = useState("todo"); const [priority, setPriority] = useState("medium"); const [dueDate, setDueDate] = useState(""); const [projectId, setProjectId] = useState(""); const [saving, setSaving] = useState(false); const [error, setError] = useState(""); const [showDelete, setShowDelete] = useState(false); useEffect(() => { if (!open) return; setError(""); setShowDelete(false); if (task) { setTitle(task.title); setDescription(task.description || ""); setStatus(task.status); setPriority(task.priority); setDueDate(task.due_date ? format(new Date(task.due_date), "yyyy-MM-dd") : ""); setProjectId(task.project_id || ""); } else { setTitle(""); setDescription(""); setStatus("todo"); setPriority("medium"); setDueDate(""); setProjectId(""); } }, [open, task]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!title.trim()) return; setSaving(true); setError(""); try { if (isEdit) { await api.updateTask(task!.id, { title: title.trim(), description: description || undefined, status, priority, due_date: dueDate || undefined, project_id: projectId || undefined, }); } else { await api.createTask({ title: title.trim(), description: description || undefined, status, priority, due_date: dueDate || undefined, project_id: projectId || undefined, }); } onSaved(); onClose(); } catch (err: unknown) { setError((err as { error?: string })?.error || "Failed to save task"); } finally { setSaving(false); } }; const handleDelete = async () => { if (!task) return; setSaving(true); try { await api.deleteTask(task.id); onSaved(); onClose(); } catch { setError("Failed to delete task"); } finally { setSaving(false); } }; return (
{error && (
{error}
)}
setTitle(e.target.value)} className="w-full px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100" placeholder="Task title" required />