import React, { useState, useEffect } from 'react'; import { useMutation, useQuery } from '@tanstack/react-query'; import { X } from 'lucide-react'; import api from '../../utils/api'; import toast from 'react-hot-toast'; import '../../components/ui/components.css'; import styles from './TaskModal.module.css'; export default function TaskModal({ task, defaultStatus = 'todo', onClose, onSuccess }) { const isEdit = !!task; const [form, setForm] = useState({ title: task?.title || '', description: task?.description || '', status: task?.status || defaultStatus, priority: task?.priority || 'medium', assignee_id: task?.assignee_id || '', due_date: task?.due_date ? task.due_date.slice(0, 10) : '', }); const [errors, setErrors] = useState({}); const { data: orgUsers = [] } = useQuery({ queryKey: ['org-users'], queryFn: () => api.get('/admin/users/org').then(r => r.data), }); const set = k => e => setForm(f => ({ ...f, [k]: e.target.value })); const validate = () => { const e = {}; if (!form.title.trim()) e.title = 'Title is required.'; setErrors(e); return !Object.keys(e).length; }; const mutation = useMutation({ mutationFn: payload => isEdit ? api.patch(`/tasks/${task.id}`, payload).then(r => r.data) : api.post('/tasks', payload).then(r => r.data), onSuccess: () => { toast.success(isEdit ? 'Task updated.' : 'Task created.'); onSuccess(); }, onError: err => { const d = err.response?.data; if (d?.details) { const fe = {}; d.details.forEach(({ field, message }) => { fe[field] = message; }); setErrors(fe); } else toast.error(d?.error || 'Something went wrong.'); }, }); const handleSubmit = ev => { ev.preventDefault(); if (!validate()) return; mutation.mutate({ ...form, assignee_id: form.assignee_id || null, due_date: form.due_date || null }); }; useEffect(() => { const h = e => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', h); return () => window.removeEventListener('keydown', h); }, [onClose]); return (
{ if (e.target === e.currentTarget) onClose(); }}>

{isEdit ? 'Edit Task' : 'New Task'}

{errors.title && {errors.title}}