Commit the Projects/Tasks/Ideas/TaskComments feature
This was already implemented, migrated, and running live, but had never been committed. Bringing it into git: Project/Task/Idea/ TaskComment models, their JSON API (CRUD + status transitions, task comments, idea<->project linking), Livewire UI pages, and the nav/route wiring for them. All 42 of its own tests pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Projects;
|
||||
|
||||
use App\Models\Project;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Component;
|
||||
|
||||
#[Layout('components.layouts.app')]
|
||||
class Index extends Component
|
||||
{
|
||||
public bool $showForm = false;
|
||||
|
||||
public ?int $editingId = null;
|
||||
|
||||
public string $name = '';
|
||||
|
||||
public ?string $description = null;
|
||||
|
||||
public string $status = 'active';
|
||||
|
||||
public ?string $dueAt = null;
|
||||
|
||||
public string $search = '';
|
||||
|
||||
public string $statusFilter = '';
|
||||
|
||||
public function render()
|
||||
{
|
||||
$query = Project::query();
|
||||
|
||||
if ($this->search) {
|
||||
$query->where('name', 'like', '%' . $this->search . '%')
|
||||
->orWhere('description', 'like', '%' . $this->search . '%');
|
||||
}
|
||||
|
||||
if ($this->statusFilter) {
|
||||
$query->where('status', $this->statusFilter);
|
||||
}
|
||||
|
||||
$projects = $query->orderBy('name')->get();
|
||||
|
||||
return view('livewire.projects.index', [
|
||||
'projects' => $projects,
|
||||
'statuses' => Project::STATUSES,
|
||||
'totalProjects' => Project::count(),
|
||||
'activeProjects' => Project::active()->count(),
|
||||
'completedProjects' => Project::completed()->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(): void
|
||||
{
|
||||
$this->resetForm();
|
||||
$this->showForm = true;
|
||||
}
|
||||
|
||||
public function edit(int $id): void
|
||||
{
|
||||
$project = Project::findOrFail($id);
|
||||
$this->editingId = $project->id;
|
||||
$this->name = $project->name;
|
||||
$this->description = $project->description;
|
||||
$this->status = $project->status;
|
||||
$this->dueAt = $project->due_at?->format('Y-m-d\TH:i') ?? '';
|
||||
$this->showForm = true;
|
||||
}
|
||||
|
||||
public function save(): void
|
||||
{
|
||||
$validated = $this->validate([
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'description' => ['nullable', 'string'],
|
||||
'status' => ['required', 'string', 'in:' . implode(',', Project::STATUSES)],
|
||||
'dueAt' => ['nullable', 'date'],
|
||||
]);
|
||||
|
||||
Project::updateOrCreate(['id' => $this->editingId], [
|
||||
'name' => $validated['name'],
|
||||
'description' => $validated['description'],
|
||||
'status' => $validated['status'],
|
||||
'due_at' => $validated['dueAt'] ?: null,
|
||||
]);
|
||||
|
||||
$this->resetForm();
|
||||
$this->showForm = false;
|
||||
}
|
||||
|
||||
public function delete(int $id): void
|
||||
{
|
||||
Project::findOrFail($id)->delete();
|
||||
}
|
||||
|
||||
public function clearFilters(): void
|
||||
{
|
||||
$this->search = '';
|
||||
$this->statusFilter = '';
|
||||
}
|
||||
|
||||
public function resetForm(): void
|
||||
{
|
||||
$this->editingId = null;
|
||||
$this->name = '';
|
||||
$this->description = null;
|
||||
$this->status = 'active';
|
||||
$this->dueAt = null;
|
||||
$this->resetValidation();
|
||||
}
|
||||
|
||||
public function getTasksCount(int $projectId): int
|
||||
{
|
||||
return \App\Models\Task::where('project_id', $projectId)->count();
|
||||
}
|
||||
|
||||
public function getStatusColor(string $status): string
|
||||
{
|
||||
return match ($status) {
|
||||
'active' => 'bg-green-100 text-green-800',
|
||||
'completed' => 'bg-blue-100 text-blue-800',
|
||||
'archived' => 'bg-gray-100 text-gray-800',
|
||||
'on_hold' => 'bg-yellow-100 text-yellow-800',
|
||||
'planned' => 'bg-purple-100 text-purple-800',
|
||||
default => 'bg-gray-100 text-gray-800',
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user