'openModal']; public function mount(?Project $project = null, ?Task $task = null): void { $this->project = $project; $this->task = $task; if ($task) { $this->mode = 'edit'; $this->fillFromTask($task); abort_unless(Auth::user()->can('update', $task), 403); } else { $this->mode = 'create'; abort_unless(Auth::user()->can('create tasks', $project), 403); // Auto-open modal when accessed via route (create page) $this->showModal = true; } } public function openModal(array $params = []): void { $this->resetForm(); $this->mode = $params['mode'] ?? 'create'; $this->project = $params['project'] ?? $this->project; $this->task = $params['task'] ?? null; if ($this->task) { $this->fillFromTask($this->task); } else { $this->status = 'pending'; $this->priority = 'medium'; $this->order = 0; } $this->showModal = true; } private function fillFromTask(Task $task): void { $this->title = $task->title; $this->description = $task->description; $this->phase_id = $task->phase_id ?? ''; $this->status = $task->status; $this->priority = $task->priority; $this->assigned_to = $task->assigned_to ?? ''; $this->due_date = $task->due_date?->format('Y-m-d') ?? ''; $this->start_date = $task->start_date?->format('Y-m-d') ?? ''; $this->estimated_hours = $task->estimated_hours ?? ''; $this->actual_hours = $task->actual_hours ?? ''; $this->order = $task->order ?? 0; $this->parent_task_id = $task->parent_task_id ?? ''; } private function resetForm(): void { $this->reset(['title', 'description', 'phase_id', 'status', 'priority', 'assigned_to', 'due_date', 'start_date', 'estimated_hours', 'actual_hours', 'order', 'parent_task_id']); $this->resetValidation(); } public function save(): void { $validated = $this->validate(); $data = [ 'title' => $validated['title'], 'description' => $validated['description'] ?? null, 'phase_id' => $validated['phase_id'] ?? null, 'status' => $validated['status'], 'priority' => $validated['priority'], 'assigned_to' => $validated['assigned_to'] ?? null, 'due_date' => $validated['due_date'] ?? null, 'start_date' => $validated['start_date'] ?? null, 'estimated_hours' => $validated['estimated_hours'] ?? null, 'actual_hours' => $validated['actual_hours'] ?? null, 'order' => $validated['order'], 'parent_task_id' => $validated['parent_task_id'] ?? null, 'project_id' => $this->project?->id, 'created_by' => Auth::id(), ]; // Handle status transitions if ($this->mode === 'edit' && $this->task) { $oldStatus = $this->task->status; $newStatus = $data['status']; if ($oldStatus !== 'completed' && $newStatus === 'completed') { $data['completed_at'] = now(); $data['completed_by'] = Auth::id(); } elseif ($oldStatus === 'completed' && $newStatus !== 'completed') { $data['completed_at'] = null; $data['completed_by'] = null; } $this->task->update($data); $task = $this->task; session()->flash('message', 'Tarea actualizada correctamente'); } else { $data['uuid'] = Str::uuid(); $task = Task::create($data); session()->flash('message', 'Tarea creada correctamente'); } $this->dispatch('tasksChanged'); $this->dispatch('taskSaved', taskId: $task->id); $this->closeModal(); } #[On('close-modal')] public function closeModal(): void { $this->showModal = false; $this->resetForm(); $this->mode = 'create'; $this->task = null; } public function render() { $assignees = User::whereHas('assignedTasks', function ($q) { if ($this->project) { $q->where('project_id', $this->project->id); } })->get(['id', 'name']); $phases = $this->project ? $this->project->phases->pluck('name', 'id') : collect(); // For parent task selector (only sibling tasks in same project) $parentTasks = $this->project ? Task::where('project_id', $this->project->id) ->whereNull('parent_task_id') ->when($this->task, fn ($q) => $q->where('id', '!=', $this->task->id)) ->get(['id', 'title']) : collect(); return view('livewire.tasks.task-form', [ 'assignees' => $assignees, 'phases' => $phases, 'parentTasks' => $parentTasks, 'statusOptions' => Task::statusOptions(), 'priorityOptions' => Task::priorityOptions(), ]); } }