diff --git a/app/Http/Controllers/EventsController.php b/app/Http/Controllers/EventsController.php index e9dfe70..332d49b 100644 --- a/app/Http/Controllers/EventsController.php +++ b/app/Http/Controllers/EventsController.php @@ -3,9 +3,11 @@ namespace App\Http\Controllers; use App\Models\Events; +use http\Env\Response; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Log; +use PHPUnit\Event\Event; class EventsController extends Controller { @@ -30,4 +32,55 @@ class EventsController extends Controller } } + + public function update(Request $request, int $id): JsonResponse { + + if ($request->user()->role != 1) { + return response()->json(['message' => 'Forbidden'], 403); + } + + try { + + $event = Events::find($id); + + $event->name = $request['name']; + $event->description = $request['description']; + $event->save(); + + return response()->json(["message" => "Event updated"]); + + } catch (\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } + + public function getEvents(Request $request): JsonResponse { + + try { + + return response()->json(['data' => Events::all()]); + + } catch (\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } + + public function delete(Request $request, int $id): JsonResponse { + + if ($request->user()->role != 1) { + return response()->json(['message' => 'Forbidden'], 403); + } + + try { + + $event = Events::find($id); + $event->delete(); + return response()->json(["message" => "Event deleted"]); + } catch (\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } } diff --git a/app/Http/Controllers/TasksController.php b/app/Http/Controllers/TasksController.php new file mode 100644 index 0000000..1de2456 --- /dev/null +++ b/app/Http/Controllers/TasksController.php @@ -0,0 +1,151 @@ +isAdmin($request->user()->role)){ + return response()->json(["message" => "Can't create task"], 403); + } + + try { + + $event = Events::find($request["event_id"]); + + $event->tasks()->create([ + "name" => $request["name"], + "description" => $request["description"], + "start" => $request["start"], + "end" => $request["end"], + "location" => $request["location"], + "max_participants" => $request["max_participants"], + ]); + + + return response()->json(['message' => "Task created"], 200); + + } catch(\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } + + public function assignSelf(Request $request): JsonResponse { + + try { + + $task = Task::find($request["task_id"]); + + if($task->max_participants = $task->users()->count()) { + return response()->json(["message" => "Max participants reached"], 403); + } + + $task->users()->attach($request->user()->id); + return response()->json(['message' => "Task assigned"], 200); + + } catch (\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } + + public function assignUser(request $request, int $id): JsonResponse { + + if(!$this->isAdmin($request->user()->role)){ + return response()->json(["message" => "Can't create task"], 403); + } + + try { + + $task = Task::find($request["task_id"]); + + if($task->max_participants === $task->users()->count()) { + return response()->json(["message" => "Max participants reached"], 403); + } + + $user = User::find($id); + + if($user) $task->users()->attach($id); + + return response()->json(['message' => "Task assigned"], 200); + + } catch(\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } + + public function getEventTasks(Request $request, int $id): JsonResponse { + + try { + + $event = Events::find($id); + + return response()->json(['data' => $event->tasks()->get()]); + + } catch(\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + + } + + public function deleteTask(Request $request, int $id): JsonResponse { + + if(!$this->isAdmin($request->user()->role)){ + return response()->json(["message" => "Can't delete task"], 403); + } + + try { + + $task = Task::find($id); + $task->delete(); + return response()->json(['message' => "Task deleted"], 200); + + } catch(\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } + + public function update(Request $request, int $id): JsonResponse { + + if(!$this->isAdmin($request->user()->role)){ + return response()->json(["message" => "Forbidden"], 403); + } + + try { + + $task = Task::find($id); + $task->name = $request["name"]; + $task->description = $request["description"]; + $task->start = $request["start"]; + $task->end = $request["end"]; + $task->location = $request["location"]; + $task->max_participants = $request["max_participants"]; + $task->save(); + + return response()->json(['message' => "Task updated"], 200); + + } catch (\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } +} diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 0c97cb4..37b0e05 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -151,4 +151,34 @@ class UserController extends Controller return response()->json(['message' => "Server error"], 500); } } + + public function getUserTasks(Request $request): JsonResponse { + + try { + return response()->json(['data' => $request->user()->tasks]); + } catch (\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } + + public function getUserByIdTasks(Request $request, int $id): JsonResponse { + + try { + return response()->json(['data' => User::find($id)->tasks]); + } catch (\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } + + public function getUserTaskById(Request $request, int $idTask): JsonResponse { + + try { + return response()->json(['data' => $request->user()->tasks->find($idTask)]); + } catch (\Exception $e) { + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } } diff --git a/app/Models/Events.php b/app/Models/Events.php index 4a589cc..ba500fe 100644 --- a/app/Models/Events.php +++ b/app/Models/Events.php @@ -12,4 +12,8 @@ class Events extends Model "name", "description", ]; + + public function tasks() { + return $this->hasMany(Task::class); + } } diff --git a/app/Models/Task.php b/app/Models/Task.php new file mode 100644 index 0000000..353ea54 --- /dev/null +++ b/app/Models/Task.php @@ -0,0 +1,30 @@ + */ + use HasFactory; + + protected $fillable = [ + 'name', + 'start', + 'end', + 'location', + 'description', + 'max_participants', + ]; + + public function event() { + return $this->belongsTo(Events::class); + } + + public function users() { + return $this->belongsToMany(User::class); + } + +} diff --git a/app/Models/User.php b/app/Models/User.php index 29c2ddc..8bb91b0 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -51,12 +51,12 @@ class User extends Authenticatable ]; } + public function tasks() { + return $this->belongsToMany(Task::class); + } + public function notifications(): \Illuminate\Database\Eloquent\Relations\BelongsToMany { return $this->belongsToMany(Notification::class, 'user_notification', 'user_id', 'notification_id'); } } - - - - diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 452e6b6..1187d01 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -3,6 +3,7 @@ namespace App\Providers; use Illuminate\Support\ServiceProvider; +use Illuminate\Support\Facades\Route; class AppServiceProvider extends ServiceProvider { @@ -19,6 +20,8 @@ class AppServiceProvider extends ServiceProvider */ public function boot(): void { - // + Route::middleware('api')->prefix('api')->group(base_path('routes/users.php')); + Route::middleware('api')->prefix('api')->group(base_path('routes/auth.php')); + Route::middleware('api')->prefix('api')->group(base_path('routes/events.php')); } } diff --git a/database/migrations/2025_11_09_144248_create_tasks_table.php b/database/migrations/2025_11_09_144248_create_tasks_table.php new file mode 100644 index 0000000..e6ce615 --- /dev/null +++ b/database/migrations/2025_11_09_144248_create_tasks_table.php @@ -0,0 +1,37 @@ +id(); + + $table->string('name'); + $table->string('description'); + $table->string('location'); + $table->dateTime("start"); + $table->dateTime("end"); + $table->integer('max_participants'); + + $table->foreignId("events_id")->constrained("events")->onDelete("cascade"); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('tasks'); + } +}; diff --git a/database/migrations/2025_11_14_081656_task_user.php b/database/migrations/2025_11_14_081656_task_user.php new file mode 100644 index 0000000..0403a79 --- /dev/null +++ b/database/migrations/2025_11_14_081656_task_user.php @@ -0,0 +1,30 @@ +id(); + $table->foreignId('task_id')->constrained()->onDelete('cascade'); + $table->foreignId('user_id')->constrained()->onDelete('cascade'); + $table->timestamps(); + }); + + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + } +}; diff --git a/routes/api.php b/routes/api.php index 33ef2ea..295aea6 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,9 +1,5 @@ get('/me', fn (Request $r) => $r->user()); - -Route::post("/users/register", [UserController::class, "create"]); - -Route::middleware('web')->post('/users/login', [AuthController::class, 'login']); - -Route::middleware(['web', 'auth:sanctum'])->post('/users/logout', [AuthController::class, 'logout']); - -Route::middleware(['web', 'auth:sanctum'])->delete('/users', [UserController::class, "delete"]); - -Route::middleware(['web', 'auth:sanctum'])->delete('/users/{id}', [UserController::class, "deleteById"]); - -Route::middleware(['web', 'auth:sanctum'])->get('/users/{id}', [UserController::class, "getUser"]); - -Route::middleware(['web', 'auth:sanctum'])->post('/users/update', [UserController::class, "update"]); - -Route::middleware(['web', 'auth:sanctum'])->post('/users/{id}/validate', [UserController::class, "validate"]); - -Route::middleware(['web', 'auth:sanctum'])->post('/users/{id}/role', [UserController::class, "addRole"]); - -Route::middleware(['web', 'auth:sanctum'])->get('/users', [UserController::class, "getUsers"]); - -Route::middleware(['web', 'auth:sanctum'])->post('/events/create', [EventsController::class, "create"]); - -Route::post("/users/{id}/create/notification", [NotificationsController::class, "create"]); - -Route::middleware(['web', 'auth:sanctum'])->get('/users/{id}/notifications', [NotificationsController::class, "getNotifications"]); - diff --git a/routes/auth.php b/routes/auth.php new file mode 100644 index 0000000..e033c23 --- /dev/null +++ b/routes/auth.php @@ -0,0 +1,12 @@ +post('/users/login', [AuthController::class, 'login']); + +Route::middleware(['web', 'auth:sanctum'])->post('/users/logout', [AuthController::class, 'logout']); diff --git a/routes/events.php b/routes/events.php new file mode 100644 index 0000000..a503abd --- /dev/null +++ b/routes/events.php @@ -0,0 +1,25 @@ +post('/events/create', [EventsController::class, "create"]); + +Route::middleware(['web', 'auth:sanctum'])->post('/events/task', [TasksController::class, "create"]); + +Route::middleware(['web', 'auth:sanctum'])->post('/events/task/assign', [TasksController::class, "assignSelf"]); + +Route::middleware(['web', 'auth:sanctum'])->post('/events/task/assign/{id}', [TasksController::class, "assignUser"])->whereNumber('id'); + +Route::middleware(['web', 'auth:sanctum'])->get('/events/{id}/tasks', [TasksController::class, "getEventTasks"]); + +Route::middleware(['web', 'auth:sanctum'])->delete('/events/tasks/{id}', [TasksController::class, "deleteTask"]); + +Route::middleware(['web', 'auth:sanctum'])->post('/events/{id}/update', [EventsController::class, "update"]); + +Route::middleware(['web', 'auth:sanctum'])->post('/events/tasks/{id}/update', [TasksController::class, "update"]); + +Route::middleware(['web', 'auth:sanctum'])->get('/events', [EventsController::class, "getEvents"]); + +Route::middleware(['web', 'auth:sanctum'])->delete('/events/{id}', [EventsController::class, "delete"]); diff --git a/routes/users.php b/routes/users.php new file mode 100644 index 0000000..031caf8 --- /dev/null +++ b/routes/users.php @@ -0,0 +1,43 @@ +get('/users/me', function (Request $request) { + return $request->user(); +}); + +Route::middleware(['web', 'auth:sanctum'])->delete('/users', [UserController::class, "delete"]); + +Route::middleware(['web', 'auth:sanctum'])->delete('/users/{id}', [UserController::class, "deleteById"]) + ->whereNumber('id'); + +Route::middleware(['web', 'auth:sanctum'])->get('/users/{id}', [UserController::class, "getUser"]) + ->whereNumber('id'); + +Route::middleware(['web', 'auth:sanctum'])->post('/users/update', [UserController::class, "update"]); + +Route::middleware(['web', 'auth:sanctum'])->post('/users/{id}/validate', [UserController::class, "validate"]) + ->whereNumber('id'); + +Route::middleware(['web', 'auth:sanctum'])->post('/users/{id}/role', [UserController::class, "addRole"]) + ->whereNumber('id'); + +Route::middleware(['web', 'auth:sanctum'])->get('/users', [UserController::class, "getUsers"]); + +Route::middleware(['web', 'auth:sanctum'])->get('/users/tasks', [UserController::class, "getUserTasks"]); + +Route::middleware(['web', 'auth:sanctum'])->get('/users/{id}/tasks', [UserController::class, "getUserByIdTasks"]); + +Route::middleware(['web', 'auth:sanctum'])->get('/users/tasks/{idTask}', [UserController::class, "getUserTaskById"]); + +Route::middleware(['web', 'auth:sanctum'])->get('/users/{id}/notifications', [NotificationsController::class, "getNotifications"])->whereNumber('id'); + +Route::post("/users/{id}/create/notification", [NotificationsController::class, "create"])->whereNumber('id'); diff --git a/tests/Events/Delete event.bru b/tests/Events/Delete event.bru new file mode 100644 index 0000000..1cfedb3 --- /dev/null +++ b/tests/Events/Delete event.bru @@ -0,0 +1,20 @@ +meta { + name: Delete event + type: http + seq: 6 +} + +delete { + url: {{url}}/api/events/{{id}} + body: none + auth: inherit +} + +vars:pre-request { + id: +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/tests/Events/Get all events.bru b/tests/Events/Get all events.bru new file mode 100644 index 0000000..c7267c8 --- /dev/null +++ b/tests/Events/Get all events.bru @@ -0,0 +1,15 @@ +meta { + name: Get all events + type: http + seq: 5 +} + +get { + url: {{url}}/api/events + body: none + auth: inherit +} + +settings { + encodeUrl: true +} diff --git a/tests/Events/Get event tasks.bru b/tests/Events/Get event tasks.bru new file mode 100644 index 0000000..4df5473 --- /dev/null +++ b/tests/Events/Get event tasks.bru @@ -0,0 +1,20 @@ +meta { + name: Get event tasks + type: http + seq: 3 +} + +get { + url: {{url}}/api/events/{{id}}/tasks + body: none + auth: inherit +} + +vars:pre-request { + id: +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/tests/Events/Update event.bru b/tests/Events/Update event.bru new file mode 100644 index 0000000..dc5b573 --- /dev/null +++ b/tests/Events/Update event.bru @@ -0,0 +1,29 @@ +meta { + name: Update event + type: http + seq: 4 +} + +post { + url: {{url}}/api/events/{{id}}/update + body: json + auth: inherit +} + +body:json { + { + "name": "{{name}}", + "description": "{{description}}" + } +} + +vars:pre-request { + id: 1 + name: BLAAHHHH + description: DADADADADDA +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/tests/Events/tasks/Assign task to user.bru b/tests/Events/tasks/Assign task to user.bru new file mode 100644 index 0000000..15cf31b --- /dev/null +++ b/tests/Events/tasks/Assign task to user.bru @@ -0,0 +1,27 @@ +meta { + name: Assign task to user + type: http + seq: 3 +} + +post { + url: {{url}}/api/events/task/assign/{{id}} + body: json + auth: inherit +} + +body:json { + { + "task_id": "{{task_id}}" + } +} + +vars:pre-request { + id: 1 + task_id: 3 +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/tests/Events/tasks/Assign task.bru b/tests/Events/tasks/Assign task.bru new file mode 100644 index 0000000..74cda3e --- /dev/null +++ b/tests/Events/tasks/Assign task.bru @@ -0,0 +1,26 @@ +meta { + name: Assign task + type: http + seq: 2 +} + +post { + url: {{url}}/api/events/task/assign + body: json + auth: inherit +} + +body:json { + { + "task_id": "{{taskId}}" + } +} + +vars:pre-request { + taskId: 1 +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/tests/Events/tasks/Delete task.bru b/tests/Events/tasks/Delete task.bru new file mode 100644 index 0000000..fac39b0 --- /dev/null +++ b/tests/Events/tasks/Delete task.bru @@ -0,0 +1,20 @@ +meta { + name: Delete task + type: http + seq: 1 +} + +delete { + url: {{url}}/api/events/tasks/{{id}} + body: none + auth: inherit +} + +vars:pre-request { + id: +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/tests/Events/tasks/Update Task.bru b/tests/Events/tasks/Update Task.bru new file mode 100644 index 0000000..ef57d9a --- /dev/null +++ b/tests/Events/tasks/Update Task.bru @@ -0,0 +1,37 @@ +meta { + name: Update Task + type: http + seq: 5 +} + +post { + url: {{url}}/api/events/tasks/{{id}}/update + body: json + auth: inherit +} + +body:json { + { + "name": "{{name}}", + "description": "{{description}}", + "location": "{{location}}", + "start": "{{start}}", + "end": "{{end}}", + "max_participants": "{{max_participants}}" + } +} + +vars:pre-request { + id: + name: + description: + location: + start: + end: + max_participants: +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/tests/Events/tasks/create event task.bru b/tests/Events/tasks/create event task.bru new file mode 100644 index 0000000..4f00dd7 --- /dev/null +++ b/tests/Events/tasks/create event task.bru @@ -0,0 +1,28 @@ +meta { + name: create event task + type: http + seq: 1 +} + +post { + url: {{url}}/api/events/task + body: json + auth: inherit +} + +body:json { + { + "event_id": 1, + "name": "test12", + "location": "blahhhhh", + "description": "blouuuuuuuuuuh", + "start": "2025-11-09 15:30:00", + "end": "2025-11-09 15:30:00", + "max_participants": 10 + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/tests/Events/tasks/folder.bru b/tests/Events/tasks/folder.bru new file mode 100644 index 0000000..7e05219 --- /dev/null +++ b/tests/Events/tasks/folder.bru @@ -0,0 +1,8 @@ +meta { + name: tasks + seq: 2 +} + +auth { + mode: inherit +} diff --git a/tests/Users/Get user tasks by id.bru b/tests/Users/Get user tasks by id.bru new file mode 100644 index 0000000..95f990e --- /dev/null +++ b/tests/Users/Get user tasks by id.bru @@ -0,0 +1,20 @@ +meta { + name: Get user tasks by id + type: http + seq: 10 +} + +get { + url: {{url}}/api/users/tasks/{{id}} + body: none + auth: inherit +} + +vars:pre-request { + id: +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/tests/Users/Get user tasks.bru b/tests/Users/Get user tasks.bru new file mode 100644 index 0000000..0b7f05e --- /dev/null +++ b/tests/Users/Get user tasks.bru @@ -0,0 +1,16 @@ +meta { + name: Get user tasks + type: http + seq: 9 +} + +get { + url: {{url}}/api/users/tasks + body: none + auth: inherit +} + +settings { + encodeUrl: true + timeout: 0 +}