2026-05-07 23:31:33 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Livewire;
|
|
|
|
|
|
|
|
|
|
use App\Models\Phase;
|
2026-06-18 13:56:05 +02:00
|
|
|
use App\Models\Project;
|
|
|
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
|
use Livewire\Attributes\On;
|
|
|
|
|
use Livewire\Component;
|
2026-05-07 23:31:33 +02:00
|
|
|
|
|
|
|
|
class PhaseList extends Component
|
|
|
|
|
{
|
|
|
|
|
public Project $project;
|
2026-06-18 13:56:05 +02:00
|
|
|
|
|
|
|
|
// Modal state
|
|
|
|
|
public bool $showForm = false;
|
|
|
|
|
public $editingId = null;
|
|
|
|
|
|
|
|
|
|
// Form fields
|
|
|
|
|
public string $name = '';
|
|
|
|
|
public string $description = '';
|
|
|
|
|
public string $color = '#3b82f6';
|
|
|
|
|
public int $order = 1;
|
|
|
|
|
public int $progressPercent = 0;
|
|
|
|
|
public string $plannedStart = '';
|
|
|
|
|
public string $plannedEnd = '';
|
|
|
|
|
public string $actualStart = '';
|
|
|
|
|
public string $actualEnd = '';
|
2026-05-07 23:31:33 +02:00
|
|
|
|
|
|
|
|
public function mount(Project $project)
|
|
|
|
|
{
|
|
|
|
|
$this->project = $project;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-18 13:56:05 +02:00
|
|
|
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
|
2026-05-07 23:31:33 +02:00
|
|
|
{
|
2026-06-18 13:56:05 +02:00
|
|
|
$this->showForm = false;
|
|
|
|
|
$this->resetForm();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function resetForm(): void
|
|
|
|
|
{
|
|
|
|
|
$this->reset([
|
|
|
|
|
'editingId', 'name', 'description', 'plannedStart', 'plannedEnd', 'actualStart', 'actualEnd',
|
2026-05-07 23:31:33 +02:00
|
|
|
]);
|
2026-06-18 13:56:05 +02:00
|
|
|
$this->color = '#3b82f6';
|
|
|
|
|
$this->order = 1;
|
|
|
|
|
$this->progressPercent = 0;
|
|
|
|
|
$this->resetErrorBag();
|
2026-05-07 23:31:33 +02:00
|
|
|
}
|
|
|
|
|
|
2026-06-18 13:56:05 +02:00
|
|
|
public function save(): void
|
2026-05-07 23:31:33 +02:00
|
|
|
{
|
2026-06-18 13:56:05 +02:00
|
|
|
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');
|
2026-05-07 23:31:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function render()
|
|
|
|
|
{
|
|
|
|
|
return view('livewire.phase-list');
|
|
|
|
|
}
|
2026-06-18 13:56:05 +02:00
|
|
|
}
|