Merge branch 'feature/tasks' into 'dev'

Feature/tasks

See merge request sae-but2/2025-26/gestion-benevoles-association/backend!5
This commit is contained in:
T'JAMPENS QUENTIN p2406187
2025-11-21 23:39:59 +00:00
25 changed files with 689 additions and 37 deletions
+53
View File
@@ -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);
}
}
}
+151
View File
@@ -0,0 +1,151 @@
<?php
namespace App\Http\Controllers;
use App\Models\Events;
use App\Models\Task;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class TasksController extends Controller
{
public function isAdmin(int $role) {
if($role != 1) return false;
return true;
}
public function create(Request $request): JsonResponse {
if(!$this->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);
}
}
}
+30
View File
@@ -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);
}
}
}
+4
View File
@@ -12,4 +12,8 @@ class Events extends Model
"name",
"description",
];
public function tasks() {
return $this->hasMany(Task::class);
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
/** @use HasFactory<\Database\Factories\TaskFactory> */
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);
}
}
+4 -4
View File
@@ -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');
}
}
+4 -1
View File
@@ -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'));
}
}
@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tasks', function (Blueprint $table) {
$table->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');
}
};
@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('task_user', function (Blueprint $table) {
$table->id();
$table->foreignId('task_id')->constrained()->onDelete('cascade');
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};
-32
View File
@@ -1,9 +1,5 @@
<?php
use App\Http\Controllers\AuthController;
use App\Http\Controllers\UserController;
use App\Http\Controllers\EventsController;
use App\Http\Controllers\NotificationsController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
@@ -11,31 +7,3 @@ Route::get("/hello", function (Request $request) {
return "Hello";
});
Route::middleware(['web', 'auth'])->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"]);
+12
View File
@@ -0,0 +1,12 @@
<?php
use App\Http\Controllers\AuthController;
use App\Http\Controllers\UserController;
use Illuminate\Support\Facades\Route;
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']);
+25
View File
@@ -0,0 +1,25 @@
<?php
use App\Http\Controllers\EventsController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TasksController;
Route::middleware(['web', 'auth:sanctum'])->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"]);
+43
View File
@@ -0,0 +1,43 @@
<?php
use App\Http\Controllers\AuthController;
use App\Http\Controllers\UserController;
use App\Http\Controllers\EventsController;
use App\Http\Controllers\NotificationsController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TasksController;
Route::middleware(['web', 'auth:sanctum'])->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');
+20
View File
@@ -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
}
+15
View File
@@ -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
}
+20
View File
@@ -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
}
+29
View File
@@ -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
}
@@ -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
}
+26
View File
@@ -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
}
+20
View File
@@ -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
}
+37
View File
@@ -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
}
+28
View File
@@ -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
}
+8
View File
@@ -0,0 +1,8 @@
meta {
name: tasks
seq: 2
}
auth {
mode: inherit
}
+20
View File
@@ -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
}
+16
View File
@@ -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
}