project = $project; } protected function rules(): array { return [ 'name' => 'required|string|max:255', 'description' => 'nullable|string', 'color' => 'required|string|max:7', 'order' => 'required|integer|min:0', 'progressPercent' => 'required|integer|min:0|max:100', 'plannedStart' => 'nullable|date', 'plannedEnd' => 'nullable|date|after_or_equal:plannedStart', 'actualStart' => 'nullable|date', 'actualEnd' => 'nullable|date|after_or_equal:actualStart', ]; } protected $validationAttributes = [ 'name' => 'nombre', 'color' => 'color', 'order' => 'orden', 'progressPercent' => 'progreso', 'plannedStart' => 'inicio previsto', 'plannedEnd' => 'fin previsto', 'actualStart' => 'inicio real', 'actualEnd' => 'fin real', ]; public function openForm($phaseId = null): void { abort_unless(Auth::user()->can('manage phases'), 403); $this->resetForm(); if ($phaseId) { $phase = $this->project->phases()->findOrFail($phaseId); $this->editingId = $phase->id; $this->name = $phase->name; $this->description = $phase->description ?? ''; $this->color = $phase->color ?? '#3b82f6'; $this->order = (int) $phase->order; $this->progressPercent = (int) $phase->progress_percent; $this->plannedStart = $phase->planned_start?->format('Y-m-d') ?? ''; $this->plannedEnd = $phase->planned_end?->format('Y-m-d') ?? ''; $this->actualStart = $phase->actual_start?->format('Y-m-d') ?? ''; $this->actualEnd = $phase->actual_end?->format('Y-m-d') ?? ''; } else { $this->order = (int) $this->project->phases()->max('order') + 1; $this->color = '#' . substr(md5((string) rand()), 0, 6); } $this->showForm = true; } /** Opened from the table's edit button. */ #[On('phase-edit')] public function editPhase($id): void { $this->openForm($id); } public function closeForm(): void { $this->showForm = false; $this->resetForm(); } private function resetForm(): void { $this->reset([ 'editingId', 'name', 'description', 'plannedStart', 'plannedEnd', 'actualStart', 'actualEnd', ]); $this->color = '#3b82f6'; $this->order = 1; $this->progressPercent = 0; $this->resetErrorBag(); } public function save(): void { abort_unless(Auth::user()->can('manage phases'), 403); $this->validate(); $data = [ 'name' => $this->name, 'description' => $this->description ?: null, 'color' => $this->color, 'order' => $this->order, 'progress_percent' => $this->progressPercent, 'planned_start' => $this->plannedStart ?: null, 'planned_end' => $this->plannedEnd ?: null, 'actual_start' => $this->actualStart ?: null, 'actual_end' => $this->actualEnd ?: null, ]; if ($this->editingId) { $this->project->phases()->findOrFail($this->editingId)->update($data); } else { $this->project->phases()->create($data); } $this->closeForm(); $this->dispatch('phases-changed'); $this->dispatch('notify', 'Fase guardada correctamente'); } public function render() { return view('livewire.phase-list'); } }