Skip to content

Commit c4c89c9

Browse files
committed
Implementación del módulo de gestión de tareas. Se han creado los controladores TodoController y TodoListController, junto con los modelos Todo y TodoList, y las migraciones correspondientes para las tablas de tareas y listas de tareas. Además, se ha añadido la lógica para manejar la creación, actualización y eliminación de tareas y listas, mejorando la funcionalidad de gestión de tareas en la aplicación.
1 parent 631dfed commit c4c89c9

File tree

10 files changed

+631
-3
lines changed

10 files changed

+631
-3
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Http\Controllers;
6+
7+
use App\Models\Todo;
8+
use App\Models\TodoList;
9+
use Illuminate\Http\Request;
10+
use Illuminate\Http\RedirectResponse;
11+
12+
final class TodoController extends Controller
13+
{
14+
private function ensureAjaxOrJson(Request $request): void
15+
{
16+
if (!($request->wantsJson() || $request->ajax())) {
17+
abort(404);
18+
}
19+
}
20+
21+
public function index(Request $request, TodoList $todoList)
22+
{
23+
$this->ensureAjaxOrJson($request);
24+
$todos = $todoList->todos()->orderBy('created_at')->get();
25+
return response()->json(['todos' => $todos]);
26+
}
27+
28+
public function store(Request $request, TodoList $todoList)
29+
{
30+
$this->ensureAjaxOrJson($request);
31+
$validated = $request->validate([
32+
'title' => 'required|string|max:255',
33+
]);
34+
$todoList->todos()->create([
35+
'title' => $validated['title'],
36+
'is_completed' => false,
37+
]);
38+
$todos = $todoList->todos()->orderBy('created_at')->get();
39+
return response()->json(['todos' => $todos]);
40+
}
41+
42+
public function update(Request $request, TodoList $todoList, Todo $todo)
43+
{
44+
$this->ensureAjaxOrJson($request);
45+
$validated = $request->validate([
46+
'title' => 'required|string|max:255',
47+
'is_completed' => 'required|boolean',
48+
]);
49+
$todo->update($validated);
50+
$todos = $todoList->todos()->orderBy('created_at')->get();
51+
return response()->json(['todos' => $todos]);
52+
}
53+
54+
public function destroy(Request $request, TodoList $todoList, Todo $todo)
55+
{
56+
$this->ensureAjaxOrJson($request);
57+
$todo->delete();
58+
$todos = $todoList->todos()->orderBy('created_at')->get();
59+
return response()->json(['todos' => $todos]);
60+
}
61+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Http\Controllers;
6+
7+
use App\Models\TodoList;
8+
use Illuminate\Http\Request;
9+
use Illuminate\Support\Facades\Auth;
10+
use Illuminate\Http\RedirectResponse;
11+
use Inertia\Inertia;
12+
use Inertia\Response;
13+
14+
final class TodoListController extends Controller
15+
{
16+
private function ensureAjaxOrJson(Request $request): void
17+
{
18+
if (!($request->wantsJson() || $request->ajax())) {
19+
abort(404);
20+
}
21+
}
22+
23+
public function index(Request $request)
24+
{
25+
$this->ensureAjaxOrJson($request);
26+
$lists = TodoList::where('user_id', Auth::id())
27+
->withCount('todos')
28+
->orderBy('created_at', 'desc')
29+
->get();
30+
return response()->json(['lists' => $lists]);
31+
}
32+
33+
public function store(Request $request)
34+
{
35+
$this->ensureAjaxOrJson($request);
36+
$validated = $request->validate([
37+
'name' => 'required|string|max:255|unique:todo_lists,name',
38+
]);
39+
TodoList::create([
40+
'user_id' => Auth::id(),
41+
'name' => $validated['name'],
42+
]);
43+
$lists = TodoList::where('user_id', Auth::id())
44+
->withCount('todos')
45+
->orderBy('created_at', 'desc')
46+
->get();
47+
return response()->json(['lists' => $lists]);
48+
}
49+
50+
public function update(Request $request, TodoList $todoList)
51+
{
52+
$this->ensureAjaxOrJson($request);
53+
$validated = $request->validate([
54+
'name' => 'required|string|max:255|unique:todo_lists,name,' . $todoList->id,
55+
]);
56+
$todoList->update($validated);
57+
$lists = TodoList::where('user_id', Auth::id())
58+
->withCount('todos')
59+
->orderBy('created_at', 'desc')
60+
->get();
61+
return response()->json(['lists' => $lists]);
62+
}
63+
64+
public function destroy(Request $request, TodoList $todoList)
65+
{
66+
$this->ensureAjaxOrJson($request);
67+
$todoList->delete();
68+
$lists = TodoList::where('user_id', Auth::id())
69+
->withCount('todos')
70+
->orderBy('created_at', 'desc')
71+
->get();
72+
return response()->json(['lists' => $lists]);
73+
}
74+
}

app/Models/Todo.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Models;
6+
7+
use Illuminate\Database\Eloquent\Factories\HasFactory;
8+
use Illuminate\Database\Eloquent\Model;
9+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
10+
11+
final class Todo extends Model
12+
{
13+
use HasFactory;
14+
15+
protected $fillable = [
16+
'todo_list_id',
17+
'title',
18+
'is_completed',
19+
];
20+
21+
protected $casts = [
22+
'is_completed' => 'boolean',
23+
];
24+
25+
public function todoList(): BelongsTo
26+
{
27+
return $this->belongsTo(TodoList::class);
28+
}
29+
}

app/Models/TodoList.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Models;
6+
7+
use Illuminate\Database\Eloquent\Factories\HasFactory;
8+
use Illuminate\Database\Eloquent\Model;
9+
use Illuminate\Database\Eloquent\Relations\HasMany;
10+
use Illuminate\Database\Eloquent\Relations\BelongsTo;
11+
12+
final class TodoList extends Model
13+
{
14+
use HasFactory;
15+
16+
protected $fillable = [
17+
'user_id',
18+
'name',
19+
];
20+
21+
public function todos(): HasMany
22+
{
23+
return $this->hasMany(Todo::class);
24+
}
25+
26+
public function user(): BelongsTo
27+
{
28+
return $this->belongsTo(User::class);
29+
}
30+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration {
8+
public function up(): void
9+
{
10+
Schema::create('todo_lists', function (Blueprint $table) {
11+
$table->id();
12+
$table->unsignedBigInteger('user_id')->index();
13+
$table->string('name')->unique();
14+
$table->timestamps();
15+
16+
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
17+
});
18+
}
19+
20+
public function down(): void
21+
{
22+
Schema::dropIfExists('todo_lists');
23+
}
24+
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration {
8+
public function up(): void
9+
{
10+
Schema::create('todos', function (Blueprint $table) {
11+
$table->id();
12+
$table->unsignedBigInteger('todo_list_id');
13+
$table->string('title');
14+
$table->boolean('is_completed')->default(false);
15+
$table->timestamps();
16+
17+
$table->foreign('todo_list_id')->references('id')->on('todo_lists')->onDelete('cascade');
18+
});
19+
}
20+
21+
public function down(): void
22+
{
23+
Schema::dropIfExists('todos');
24+
}
25+
};

resources/js/components/ui/TodoFloatingPanel.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import React from 'react';
22
import { X } from 'lucide-react';
3+
import { TodoPanelContent } from './TodoPanelContent';
34

45
interface TodoFloatingPanelProps {
56
open: boolean;
67
onClose: () => void;
78
title?: string;
8-
children: React.ReactNode;
99
}
1010

11-
export const TodoFloatingPanel: React.FC<TodoFloatingPanelProps> = ({ open, onClose, title = 'Lista de Tareas', children }) => {
11+
export const TodoFloatingPanel: React.FC<TodoFloatingPanelProps> = ({ open, onClose, title = 'Lista de Tareas' }) => {
1212
if (!open) return null;
1313
return (
1414
<>
@@ -35,7 +35,7 @@ export const TodoFloatingPanel: React.FC<TodoFloatingPanelProps> = ({ open, onCl
3535
</button>
3636
</div>
3737
<div className="flex-1 overflow-y-auto p-4">
38-
{children}
38+
<TodoPanelContent />
3939
</div>
4040
</aside>
4141
</>

0 commit comments

Comments
 (0)