import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import { useMutation, useQueryClient, useQuery } from '@tanstack/react-query'; import { tasksApi, type CreateTaskData } from '@/services/tasks.api'; import { projectsApi } from '@/services/projects.api'; import { settingsApi } from '@/services/settings.api'; // Pre statusy a priority import type { Task } from '@/types'; import { Button, Input, Textarea, Select, ModalFooter, UserSelect } from '@/components/ui'; import toast from 'react-hot-toast'; const taskSchema = z.object({ title: z.string().min(1, 'Názov je povinný'), description: z.string().optional(), projectId: z.string().optional(), statusId: z.string().optional(), priorityId: z.string().optional(), deadline: z.string().optional(), }); type TaskFormData = z.infer; interface TaskFormProps { task: Task | null; onClose: () => void; } export function TaskForm({ task, onClose }: TaskFormProps) { const queryClient = useQueryClient(); const isEditing = !!task; // State pre vybraných používateľov const [selectedAssignees, setSelectedAssignees] = useState( task?.assignees?.map((a) => a.userId) || [] ); const { data: projectsData } = useQuery({ queryKey: ['projects-select'], queryFn: () => projectsApi.getAll({ limit: 1000 }), }); const { data: statusesData } = useQuery({ queryKey: ['task-statuses'], queryFn: () => settingsApi.getTaskStatuses(), }); const { data: prioritiesData } = useQuery({ queryKey: ['priorities'], queryFn: () => settingsApi.getPriorities(), }); const { register, handleSubmit, formState: { errors }, } = useForm({ resolver: zodResolver(taskSchema), defaultValues: task ? { title: task.title, description: task.description || '', projectId: task.projectId || '', statusId: task.statusId, priorityId: task.priorityId, deadline: task.deadline?.split('T')[0] || '', } : { title: '', description: '', projectId: '', statusId: '', priorityId: '', deadline: '', }, }); const createMutation = useMutation({ mutationFn: (data: CreateTaskData) => tasksApi.create(data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['tasks'] }); toast.success('Úloha bola vytvorená'); onClose(); }, onError: (error: unknown) => { console.error('Create task error:', error); const axiosError = error as { response?: { data?: { message?: string } } }; const message = axiosError.response?.data?.message || 'Chyba pri vytváraní úlohy'; toast.error(message); }, }); const updateMutation = useMutation({ mutationFn: (data: CreateTaskData) => tasksApi.update(task!.id, data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['tasks'] }); toast.success('Úloha bola aktualizovaná'); onClose(); }, onError: (error: unknown) => { console.error('Update task error:', error); const axiosError = error as { response?: { data?: { message?: string } } }; const message = axiosError.response?.data?.message || 'Chyba pri aktualizácii úlohy'; toast.error(message); }, }); const onSubmit = (data: TaskFormData) => { const cleanData = { ...data, projectId: data.projectId || undefined, statusId: data.statusId || undefined, priorityId: data.priorityId || undefined, deadline: data.deadline || undefined, // Pre create: undefined ak prázdne (backend priradí default) // Pre update: vždy poslať pole (aj prázdne) aby sa aktualizovali assignees assigneeIds: isEditing ? selectedAssignees : (selectedAssignees.length > 0 ? selectedAssignees : undefined), }; console.log('Submitting task data:', cleanData); if (isEditing) { updateMutation.mutate(cleanData); } else { createMutation.mutate(cleanData); } }; const isPending = createMutation.isPending || updateMutation.isPending; const projectOptions = projectsData?.data.map((p) => ({ value: p.id, label: p.name })) || []; const statusOptions = statusesData?.data.map((s) => ({ value: s.id, label: s.name })) || []; const priorityOptions = prioritiesData?.data.map((p) => ({ value: p.id, label: p.name })) || []; // Pripraviť počiatočných používateľov pre editáciu (už priradení) const initialAssignees = task?.assignees?.map((a) => ({ id: a.userId, name: a.user?.name || '', email: a.user?.email || '', })) || []; return (