diff --git a/app/Events/EventParticipationCancelled.php b/app/Events/EventParticipationCancelled.php index 679fe7e..015ba90 100644 --- a/app/Events/EventParticipationCancelled.php +++ b/app/Events/EventParticipationCancelled.php @@ -2,12 +2,10 @@ namespace App\Events; -use App\Models\Events; +use App\Models\Event; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\PrivateChannel; -use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; @@ -18,14 +16,16 @@ class EventParticipationCancelled implements ShouldBroadcastNow public $userId; public $event; + public $notificationId; /** * Create a new event instance. */ - public function __construct($userId, Events $event) + public function __construct($userId, Event $event, $notificationId) { $this->userId = $userId; $this->event = $event; + $this->notificationId = $notificationId; } /** diff --git a/app/Events/TaskDateUpdated.php b/app/Events/TaskDateUpdated.php new file mode 100644 index 0000000..dcf7fa1 --- /dev/null +++ b/app/Events/TaskDateUpdated.php @@ -0,0 +1,53 @@ +userId = $userId; + $this->task = $task; + $this->event = $event; + $this->start = $start; + $this->end = $end; + $this->notificationId = $notificationId; + } + + /** + * Get the channels the event should broadcast on. + * + * @return array + */ + public function broadcastOn(): array + { + return [ + new PrivateChannel('user.' . $this->userId), + ]; + } + + public function broadcastAs() + { + return 'task.date.updated'; + } +} diff --git a/app/Events/TaskParticipationCancelled.php b/app/Events/TaskParticipationCancelled.php index 2a45dd3..698a10e 100644 --- a/app/Events/TaskParticipationCancelled.php +++ b/app/Events/TaskParticipationCancelled.php @@ -2,13 +2,10 @@ namespace App\Events; -use App\Models\Events; +use App\Models\Event; use App\Models\Task; -use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\PrivateChannel; -use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; @@ -20,15 +17,17 @@ class TaskParticipationCancelled implements ShouldBroadcastNow public $userId; public $task; public $event; + public $notificationId; /** * Create a new event instance. */ - public function __construct($userId, Task $task, Events $event) + public function __construct($userId, Task $task, Event $event, $notificationId) { $this->userId = $userId; $this->task = $task; $this->event = $event; + $this->notificationId = $notificationId; } /** diff --git a/app/Events/UserCreated.php b/app/Events/UserCreated.php index c5274eb..a27ee47 100644 --- a/app/Events/UserCreated.php +++ b/app/Events/UserCreated.php @@ -15,13 +15,15 @@ class UserCreated implements ShouldBroadcastNow public $user; + public $notificationId; /** * Create a new event instance. */ - public function __construct(User $user) + public function __construct(User $user, $notificationId) { $this->user = $user; + $this->notificationId = $notificationId; } /** @@ -32,7 +34,7 @@ class UserCreated implements ShouldBroadcastNow public function broadcastOn(): array { return [ - new privateChannel('users.registration'), + new privateChannel('users.admin'), ]; } diff --git a/app/Events/VolunteerAssignedToTask.php b/app/Events/VolunteerAssignedToTask.php index 959dc0c..0b96aaf 100644 --- a/app/Events/VolunteerAssignedToTask.php +++ b/app/Events/VolunteerAssignedToTask.php @@ -2,13 +2,10 @@ namespace App\Events; -use App\Models\Events; +use App\Models\Event; use App\Models\Task; -use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\PrivateChannel; -use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; @@ -19,16 +16,18 @@ class VolunteerAssignedToTask implements ShouldBroadcastNow public $task; public $event; + public $notificationId; protected $userId; /** * Create a new event instance. */ - public function __construct($userId, Task $task, Events $event) + public function __construct($userId, Task $task, Event $event, $notificationId) { $this->userId = $userId; $this->task = $task; $this->event = $event; + $this->notificationId = $notificationId; } /** diff --git a/app/Events/VolunteerRoleUpdated.php b/app/Events/VolunteerRoleUpdated.php new file mode 100644 index 0000000..690d114 --- /dev/null +++ b/app/Events/VolunteerRoleUpdated.php @@ -0,0 +1,47 @@ +userId = $userId; + $this->role = $role; + $this->notificationId = $notificationId; + } + + /** + * Get the channels the event should broadcast on. + * + * @return array + */ + public function broadcastOn(): array + { + return [ + new PrivateChannel('user.' . $this->userId), + ]; + } + + public function broadcastAs() + { + return 'volunteer.role.updated'; + } +} diff --git a/app/Events/VolunteerUnassignedFromTask.php b/app/Events/VolunteerUnassignedFromTask.php index 5ff4e43..14f370b 100644 --- a/app/Events/VolunteerUnassignedFromTask.php +++ b/app/Events/VolunteerUnassignedFromTask.php @@ -2,13 +2,10 @@ namespace App\Events; -use App\Models\Events; +use App\Models\Event; use App\Models\Task; -use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; -use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\PrivateChannel; -use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; @@ -20,15 +17,17 @@ class VolunteerUnassignedFromTask implements ShouldBroadcastNow public $userId; public $task; public $event; + public $notificationId; /** * Create a new event instance. */ - public function __construct($userId, Task $task, Events $event) + public function __construct($userId, Task $task, Event $event, $notificationId) { $this->userId = $userId; $this->task = $task; $this->event = $event; + $this->notificationId = $notificationId; } /** diff --git a/app/Http/Controllers/EventsController.php b/app/Http/Controllers/EventsController.php index a44d71b..4ac3e5a 100644 --- a/app/Http/Controllers/EventsController.php +++ b/app/Http/Controllers/EventsController.php @@ -3,12 +3,16 @@ namespace App\Http\Controllers; use App\Events\EventParticipationCancelled; -use App\Models\Events; +use App\Models\Event; +use App\Models\Notification; +use App\Mail\EventParticipationCancelledMail; use App\Models\Task; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Mail; +use Carbon\Carbon; class EventsController extends Controller @@ -17,13 +21,13 @@ class EventsController extends Controller { - if (Gate::denies('create', Events::class)) { + if (Gate::denies('create', Event::class)) { return response()->json(['message' => 'Forbidden'], 403); } try { - Events::create([ + Event::create([ "name" => $request['name'], "description" => $request['description'], "start" => $request['start'], @@ -41,13 +45,13 @@ class EventsController extends Controller public function update(Request $request, int $id): JsonResponse { - if (Gate::denies('update', Events::class)) { + if (Gate::denies('update', Event::class)) { return response()->json(['message' => 'Forbidden'], 403); } try { - $event = Events::find($id); + $event = Event::find($id); $event->name = $request['name']; $event->description = $request['description']; @@ -64,10 +68,8 @@ class EventsController extends Controller } public function getEvents(Request $request): JsonResponse { - try { - - $events = Events::with('tasks')->get(); + $events = Event::with('tasks')->get(); return response()->json(['data' => $events]); @@ -80,12 +82,12 @@ class EventsController extends Controller public function delete(Request $request, int $id): JsonResponse { - if (Gate::denies('delete', Events::class)) { + if (Gate::denies('delete', Event::class)) { return response()->json(['message' => 'Forbidden'], 403); } try { - $event = Events::with('tasks.users')->find($id); + $event = Event::with('tasks.users')->find($id); if (!$event) { return response()->json(['message' => 'Event not found'], 404); @@ -95,17 +97,40 @@ class EventsController extends Controller return $task->users; })->unique('id'); - foreach ($participants as $user) { - broadcast(new EventParticipationCancelled( - $user->id, - $event - )); + if (Carbon::now()->lessThanOrEqualTo($event->end)) { + $webParticipants = $participants->filter(fn($user) => $user->web_notifications); + + if ($webParticipants->isNotEmpty()) { + $notification = Notification::create([ + 'content' => "L'événement {$event->name} a été supprimé. Vous n'y participez donc plus." + ]); + $notification->users()->attach($webParticipants->pluck('id')); + + foreach ($webParticipants as $user) { + broadcast(new EventParticipationCancelled( + $user->id, + $event, + $notification->id, + )); + } + } + + foreach ($participants as $user) { + if ($user->email_notifications) { + $data = [ + 'name' => $user->name, + 'lastname' => $user->lastname, + 'eventName' => $event->name, + 'start' => $event->start, + 'end' => $event->end, + ]; + Mail::to($user->email)->send(new EventParticipationCancelledMail($data)); + } + } } $event->delete(); - return response()->json(["message" => "Event deleted and participants notified"]); - } catch (\Exception $e) { Log::error("Event delete error: " . $e->getMessage()); return response()->json(['message' => "Server error"], 500); @@ -113,12 +138,9 @@ class EventsController extends Controller } public function getEvent(Request $request, int $id): JsonResponse { - try { - $event = Events::with(['tasks' => function ($query) { - $query->withCount('users'); - }])->find($id); + $event = Event::find($id); return response()->json([ "id" => $event->id, "name" => $event->name, diff --git a/app/Http/Controllers/TasksController.php b/app/Http/Controllers/TasksController.php index 55111b8..9c655c4 100644 --- a/app/Http/Controllers/TasksController.php +++ b/app/Http/Controllers/TasksController.php @@ -2,16 +2,25 @@ namespace App\Http\Controllers; +use App\Events\TaskDateUpdated; use App\Events\TaskParticipationCancelled; use App\Events\VolunteerAssignedToTask; use App\Events\VolunteerUnassignedFromTask; -use App\Models\Events; +use App\Mail\TaskDateUpdateMail; +use App\Models\Event; +use App\Models\Notification; +use App\Mail\VolunteerAssignToTaskMail; +use App\Mail\VolunteerUnassignToTaskMail; use App\Models\Task; use App\Models\User; +use Carbon\Carbon; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Mail; +use App\Mail\TaskParticipationCancelledMail; +use App\Services\FormatDate; class TasksController extends Controller { @@ -23,18 +32,17 @@ class TasksController extends Controller try { - $event = Events::find($request["event_id"]); + $event = Event::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"], + "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) { @@ -73,8 +81,8 @@ class TasksController extends Controller } try { - - $task = Task::with('event')->find($request["task_id"]); + $task = Task::find($request["task_id"]); + $event = Event::find($task->events_id); if ($task->users()->where('user_id', $id)->exists()) { return response()->json(["message" => "User already assigned to this task"], 400); @@ -85,14 +93,35 @@ class TasksController extends Controller } $user = User::find($id); + $task->users()->attach($id); - if($user) { - $task->users()->attach($id); - broadcast(new VolunteerAssignedToTask( - $user->id, - $task, - $task->event - )); + if($user && Carbon::now()->lessThanOrEqualTo($task->end)) { + + if ($user->web_notifications) { + $notification = Notification::create([ + 'content' => "Vous avez été assigné à la tâche {$task->name} de l'événement {$event->name}." + ]); + $notification->users()->attach($user->id); + + broadcast(new VolunteerAssignedToTask( + $user->id, + $task, + $event, + $notification->id, + )); + } + + if ($user->email_notifications) { + $data = [ + 'name' => $user->name, + 'lastname' => $user->lastname, + 'taskName' => $task->name, + 'start' => $task->start, + 'end' => $task->end, + 'eventName' => $event->name, + ]; + Mail::to($user->email)->send(new VolunteerAssignToTaskMail($data)); + } } return response()->json(['message' => "Task assigned"], 200); @@ -107,7 +136,7 @@ class TasksController extends Controller try { - $event = Events::find($id); + $event = Event::find($id); return response()->json(['data' => $event->tasks()->get()]); @@ -115,7 +144,6 @@ class TasksController extends Controller Log::info($e->getMessage()); return response()->json(['message' => "Server error"], 500); } - } public function deleteTask(Request $request, int $id): JsonResponse { @@ -124,7 +152,8 @@ class TasksController extends Controller } try { - $task = Task::with(['users', 'event'])->find($id); + $task = Task::with(['users'])->find($id); + $event = Event::find($task->events_id); if (!$task) { return response()->json(["message" => "Task not found"], 404); @@ -132,12 +161,40 @@ class TasksController extends Controller $participants = $task->users; - foreach ($participants as $user) { - broadcast(new TaskParticipationCancelled( - $user->id, - $task, - $task->event - )); + if (Carbon::now()->lessThanOrEqualTo($task->end)) { + if ($participants->isNotEmpty()) { + $webParticipants = $participants->filter(fn($user) => $user->web_notifications); + + if ($webParticipants->isNotEmpty()) { + $notification = Notification::create([ + 'content' => "La tâche {$task->name} pour l'événement {$event->name} a été supprimée. Vous n'y participez donc plus." + ]); + $notification->users()->attach($webParticipants->pluck('id')); + + foreach ($webParticipants as $user) { + broadcast(new TaskParticipationCancelled( + $user->id, + $task, + $event, + $notification->id, + )); + } + } + + foreach ($participants as $user) { + if ($user->email_notifications) { + $data = [ + 'name' => $user->name, + 'lastname' => $user->lastname, + 'taskName' => $task->name, + 'start' => $event->start, + 'end' => $task->end, + 'eventName' => $event->name, + ]; + Mail::to($user->email)->send(new TaskParticipationCancelledMail($data)); + } + } + } } $task->delete(); @@ -157,8 +214,50 @@ class TasksController extends Controller } try { - $task = Task::find($id); + if(( + $task->start !== $request["start"] || $task->end !== $request["end"] + ) && + Carbon::now()->lessThanOrEqualTo($task->end) + ){ + $participants = $task->users; + $formatedTaskStart = FormatDate::formatDate($task->start); + $formatedTaskEnd = FormatDate::formatDate($task->end); + $event = Event::find($task->events_id); + + foreach ($participants as $user) { + if ($user->web_notifications) { + $notification = Notification::create([ + 'content' => "La date de la tâche {$task->name} de l'événement {$event->name} à été mis à jour. Cette tâche aura maintenant lieu du {$formatedTaskStart} au {$formatedTaskEnd}." + ]); + $notification->users()->attach($user->id); + + broadcast(new TaskDateUpdated( + $user->id, + $task, + $event, + FormatDate::formatDate($request["start"]), + FormatDate::formatDate($request["end"]), + $notification->id, + )); + } + + if ($user->email_notifications) { + $data = [ + 'name' => $user->name, + 'lastname' => $user->lastname, + 'taskName' => $task->name, + 'oldStart' => $formatedTaskStart, + 'oldEnd' => $formatedTaskEnd, + 'newStart' => $request["start"], + 'newEnd' => $request["end"], + 'eventName' => $event->name, + ]; + Mail::to($user->email)->send(new TaskDateUpdateMail($data)); + } + } + } + $task->name = $request["name"]; $task->description = $request["description"]; $task->start = $request["start"]; @@ -175,10 +274,6 @@ class TasksController extends Controller } } - - - - public function unassignSelf(Request $request): JsonResponse { try { $task = Task::find($request["task_id"]); @@ -198,8 +293,6 @@ class TasksController extends Controller } } - - public function unassignUser(Request $request, int $id): JsonResponse { if(Gate::denies('unassignOther', Task::class)) { @@ -207,7 +300,8 @@ class TasksController extends Controller } try { - $task = Task::with('event')->find($request["task_id"]); + $task = Task::find($request["task_id"]); + $event = Event::find($task->events_id); if (!$task) { return response()->json(["message" => "Task not found"], 404); @@ -219,15 +313,34 @@ class TasksController extends Controller } $user = User::find($id); + $task->users()->detach($id); - if ($user) { - $task->users()->detach($id); + if ($user && Carbon::now()->lessThanOrEqualTo($task->end)) { + if ($user->web_notifications) { + $notification = Notification::create([ + 'content' => "Vous avez été désassigné de la tâche {$task->name} de l'événement {$event->name}." + ]); + $notification->users()->attach($user->id); - broadcast(new VolunteerUnassignedFromTask( - $user->id, - $task, - $task->event - )); + broadcast(new VolunteerUnassignedFromTask( + $user->id, + $task, + $event, + $notification->id, + )); + } + + if ($user->email_notifications) { + $data = [ + 'name' => $user->name, + 'lastname' => $user->lastname, + 'taskName' => $task->name, + 'start' => $task->start, + 'end' => $task->end, + 'eventName' => $event->name, + ]; + Mail::to($user->email)->send(new VolunteerUnassignToTaskMail($data)); + } } return response()->json(['message' => "User unassigned successfully"], 200); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 1eb2f3e..d19db18 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -3,8 +3,16 @@ namespace App\Http\Controllers; use App\Events\UserCreated; +use App\Events\VolunteerRoleUpdated; +use App\Mail\CreateUserByAdminMail; +use App\Mail\DeactivateAccountMail; +use App\Mail\DeleteAccountMail; +use App\Mail\RegisterMail; +use App\Mail\UpdateRoleMail; +use App\Mail\ValidateMail; use App\Models\Notification; use App\Models\User; +use App\Services\GetRole; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -12,6 +20,7 @@ use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Log; use App\Services\UserService; +use Illuminate\Support\Facades\Mail; use Pest\Support\Str; use Propaganistas\LaravelPhone\PhoneNumber; @@ -42,18 +51,34 @@ class UserController extends Controller "lastname" => $request["lastname"], "validate" => 0, "phone" => $phone->formatInternational(), + "web_notifications" => 1, + "email_notifications" => 1, ]); - $notification = Notification::create([ - 'content' => "Nouvelle demande d'inscription : {$user->name} {$user->lastname}", + 'content' => "Nouvelle demande d'inscription : {$user->name} {$user->lastname}" ]); $admins = User::whereIn('role', [1, 2])->get(); - $notification->users()->attach( - $admins->pluck('id')->toArray() - ); - broadcast(new UserCreated($user)); + $webAdmins = $admins->filter(fn($admin) => $admin->web_notifications); + $notification->users()->attach($webAdmins->pluck('id')->toArray()); + + broadcast(new UserCreated( + $user, + $notification->id, + )); + + foreach ($admins as $admin) { + if ($admin->email_notifications) { + $data = [ + 'adminName' => $admin->name, + 'adminLastname' => $admin->lastname, + 'userName' => $user->name, + 'userLastname' => $user->lastname, + ]; + Mail::to($admin->email)->send(new RegisterMail($data)); + } + } return response()->json(['message' => 'User created successfully']); } @@ -81,8 +106,18 @@ class UserController extends Controller "validate" => 1, "role" => 3, "phone" => $phone->formatInternational(), + "web_notifications" => 1, + "email_notifications" => 1, ]); + if ($user->email_notifications) { + $data = [ + 'name' => $user->name, + 'lastname' => $user->lastname, + ]; + Mail::to($user->email)->send(new CreateUserByAdminMail($data)); + } + return response()->json([ 'message' => 'User created successfully', "password" => $password, @@ -92,6 +127,15 @@ class UserController extends Controller public function delete(Request $request): JsonResponse { try { $user = User::find($request->user()->id); + + if ($user->email_notifications) { + $data = [ + 'name' => $user->name, + 'lastname' => $user->lastname, + ]; + Mail::to($user->email)->send(new DeleteAccountMail($data)); + } + $user->delete(); return response()->json(['message' => 'User deleted successfully']); } catch(\Exception $e) { @@ -101,7 +145,6 @@ class UserController extends Controller } public function getUser(Request $request, int $id): JsonResponse { - try { return response()->json(UserService::getData($id)); } catch (ModelNotFoundException $e) { @@ -110,7 +153,6 @@ class UserController extends Controller Log::info($e->getMessage()); return response()->json(['message' => "Server error"], 500); } - } public function deleteById(Request $request, int $id): JsonResponse { @@ -122,6 +164,14 @@ class UserController extends Controller try { $user = User::find($id); + if ($user->email_notifications) { + $data = [ + 'name' => $user->name, + 'lastname' => $user->lastname, + ]; + Mail::to($user->email)->send(new DeleteAccountMail($data)); + } + $user->delete(); return response()->json(['message' => 'User deleted successfully']); } catch(\Exception $e) { @@ -140,6 +190,14 @@ class UserController extends Controller try { $userToDeactivate->update(['validate' => 0]); + if ($userToDeactivate->email_notifications) { + $data = [ + 'name' => $userToDeactivate->name, + 'lastname' => $userToDeactivate->lastname, + ]; + Mail::to($userToDeactivate->email)->send(new DeactivateAccountMail($data)); + } + return response()->json(['message' => 'User deactivated successfully']); } catch (ModelNotFoundException $e) { return response()->json(['message' => 'Utilisateur non trouvé'], 404); @@ -147,13 +205,10 @@ class UserController extends Controller Log::info($e->getMessage()); return response()->json(['message' => "Server error"], 500); } - } public function update(Request $request): JsonResponse { - try { - $phone = new PhoneNumber($request["phone"], 'FR'); $user = User::find($request->user()->id); @@ -163,12 +218,10 @@ class UserController extends Controller $user->save(); return response()->json(['message' => 'User updated successfully']); - } catch(\Exception $e) { Log::info($e->getMessage()); return response()->json(['message' => "Server error"], 500); } - } public function validate(Request $request, int $id): JsonResponse { @@ -179,22 +232,21 @@ class UserController extends Controller try { $user = User::find($id); - $content = "Nouvelle demande d'inscription : {$user->name} {$user->lastname}"; - //$notification = Notification::where('user_id', $user->id) - $notification = Notification::where('content', $content)->first(); - - if ($notification) { - $notification->users()->detach(); - $notification->delete(); - } $user->validate = 1; $user->role = 3; $user->verified_at = now(); $user->save(); - return response()->json(['message' => 'User validated successfully']); + if ($user->email_notifications) { + $data = [ + 'name' => $user->name, + 'lastname' => $user->lastname, + ]; + Mail::to($user->email)->send(new ValidateMail($data)); + } + return response()->json(['message' => 'User validated successfully']); } catch(\Exception $e) { Log::info($e->getMessage()); return response()->json(['message' => "Server error"], 500); @@ -212,11 +264,29 @@ class UserController extends Controller $user->role = $request['role']; $user->save(); - $role = \App\Services\GetRole::getRole($request['role']); - $notification = Notification::create([ - 'content' => "Votre rôle à changé pour {$role} !", - ]); - $notification->users()->attach($user->id); + $role = GetRole::getRole($request['role']); + + if ($user->web_notifications) { + $notification = Notification::create([ + 'content' => "Votre rôle à changé pour : {$role}", + ]); + $notification->users()->attach($user->id); + + broadcast(new VolunteerRoleUpdated( + $user->id, + $role, + $notification->id, + )); + } + + if ($user->email_notifications) { + $data = [ + 'name' => $user->name, + 'lastname' => $user->lastname, + 'role' => $role, + ]; + Mail::to($user->email)->send(new UpdateRoleMail($data)); + } return response()->json(['message' => 'User role added successfully']); } catch(\Exception $e) { @@ -226,16 +296,12 @@ class UserController extends Controller } public function getUsers(Request $request): JsonResponse { - try { - $users = User::where('validate', 1) ->orderBy('verified_at', 'desc') ->pluck('id'); return response()->json($users); - - } catch(\Exception $e) { Log::info($e->getMessage()); return response()->json(['message' => "Server error"], 500); @@ -243,7 +309,6 @@ class UserController extends Controller } public function getUserTasks(Request $request): JsonResponse { - try { return response()->json(['data' => $request->user()->tasks]); } catch (\Exception $e) { @@ -253,7 +318,6 @@ class UserController extends Controller } public function getUserByIdTasks(Request $request, int $id): JsonResponse { - try { return response()->json(['data' => User::find($id)->tasks]); } catch (\Exception $e) { @@ -263,7 +327,6 @@ class UserController extends Controller } public function getUserTaskById(Request $request, int $idTask): JsonResponse { - try { return response()->json(['data' => $request->user()->tasks->find($idTask)]); } catch (\Exception $e) { @@ -278,14 +341,38 @@ class UserController extends Controller } try { - $users = User::where('validate', 0)->pluck('id'); return response()->json($users); - } catch (\Exception $e) { Log::info($e->getMessage()); return response()->json(['message' => "Server error"], 500); } } + + public function toggleEmailNotifications(Request $request, int $id): JsonResponse { + try { + $user = User::findOrFail($id); + $user->email_notifications = $user->email_notifications ? 0 : 1; + $user->save(); + + return response()->json($user); + } catch(\Exception $e){ + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } + + public function toggleWebNotifications(Request $request, int $id): JsonResponse { + try { + $user = User::findOrFail($id); + $user->web_notifications = $user->web_notifications ? 0 : 1; + $user->save(); + + return response()->json($user); + } catch(\Exception $e){ + Log::info($e->getMessage()); + return response()->json(['message' => "Server error"], 500); + } + } } diff --git a/app/Mail/CreateUserByAdminMail.php b/app/Mail/CreateUserByAdminMail.php new file mode 100644 index 0000000..1a9d6ff --- /dev/null +++ b/app/Mail/CreateUserByAdminMail.php @@ -0,0 +1,58 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Compte créé - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.createUserByAdmin', + with: [ + 'name' => $this->data['name'], + 'lastname' => $this->data['lastname'], + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/DeactivateAccountMail.php b/app/Mail/DeactivateAccountMail.php new file mode 100644 index 0000000..1ce8ff9 --- /dev/null +++ b/app/Mail/DeactivateAccountMail.php @@ -0,0 +1,58 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Compte désactivé - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.deactivateAccount', + with: [ + 'name' => $this->data['name'], + 'lastname' => $this->data['lastname'], + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/DeleteAccountMail.php b/app/Mail/DeleteAccountMail.php new file mode 100644 index 0000000..2b5571d --- /dev/null +++ b/app/Mail/DeleteAccountMail.php @@ -0,0 +1,58 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Compte supprimé - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.deleteAccount', + with: [ + 'name' => $this->data['name'], + 'lastname' => $this->data['lastname'], + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/EventParticipationCancelledMail.php b/app/Mail/EventParticipationCancelledMail.php new file mode 100644 index 0000000..bcb8e7a --- /dev/null +++ b/app/Mail/EventParticipationCancelledMail.php @@ -0,0 +1,62 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Evénement supprimé - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.eventParticipationCancelled', + with: [ + 'name' => $this->data['name'], + 'lastname' => $this->data['lastname'], + 'eventName' => $this->data['eventName'], + 'start' => FormatDate::formatDate($this->data['start']), + 'end' => FormatDate::formatDate($this->data['end']), + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/RegisterMail.php b/app/Mail/RegisterMail.php new file mode 100644 index 0000000..d572676 --- /dev/null +++ b/app/Mail/RegisterMail.php @@ -0,0 +1,60 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Nouvelle demande de validation - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.register', + with: [ + 'adminName' => $this->data['adminName'], + 'adminLastname' => $this->data['adminLastname'], + 'userName' => $this->data['userName'], + 'userLastname' => $this->data['userLastname'], + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/TaskDateUpdateMail.php b/app/Mail/TaskDateUpdateMail.php new file mode 100644 index 0000000..6405074 --- /dev/null +++ b/app/Mail/TaskDateUpdateMail.php @@ -0,0 +1,64 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Date de tâche modifiée - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.updateRole', + with: [ + 'name' => $this->data['name'], + 'lastname' => $this->data['lastname'], + 'taskName' => $this->data['taskName'], + 'oldStart' => $this->data['oldStart'], + 'oldEnd' => $this->data['oldEnd'], + 'newStart' => $this->data['newStart'], + 'newEnd' => $this->data['newEnd'], + 'eventName' => $this->data['eventName'], + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/TaskParticipationCancelledMail.php b/app/Mail/TaskParticipationCancelledMail.php new file mode 100644 index 0000000..b5a390d --- /dev/null +++ b/app/Mail/TaskParticipationCancelledMail.php @@ -0,0 +1,63 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Tâche supprimée - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.taskParticipationCancelled', + with: [ + 'name' => $this->data['name'], + 'lastname' => $this->data['lastname'], + 'taskName' => $this->data['taskName'], + 'end' => FormatDate::formatDate($this->data['end']), + 'start' => FormatDate::formatDate($this->data['start']), + 'eventName' => $this->data['eventName'], + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/UpdateRoleMail.php b/app/Mail/UpdateRoleMail.php new file mode 100644 index 0000000..64eb863 --- /dev/null +++ b/app/Mail/UpdateRoleMail.php @@ -0,0 +1,59 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Rôle mis à jour - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.updateRole', + with: [ + 'name' => $this->data['name'], + 'lastname' => $this->data['lastname'], + 'role' => $this->data['role'], + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/ValidateMail.php b/app/Mail/ValidateMail.php new file mode 100644 index 0000000..9002787 --- /dev/null +++ b/app/Mail/ValidateMail.php @@ -0,0 +1,58 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Compte validé - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.validate', + with: [ + 'name' => $this->data['name'], + 'lastname' => $this->data['lastname'], + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/VolunteerAssignToTaskMail.php b/app/Mail/VolunteerAssignToTaskMail.php new file mode 100644 index 0000000..9fa1681 --- /dev/null +++ b/app/Mail/VolunteerAssignToTaskMail.php @@ -0,0 +1,63 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Assignation - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.volunteerAssignToTask', + with: [ + 'name' => $this->data['name'], + 'lastname' => $this->data['lastname'], + 'taskName' => $this->data['taskName'], + 'start' => FormatDate::formatDate($this->data['start']), + 'end' => FormatDate::formatDate($this->data['end']), + 'eventName' => $this->data['eventName'], + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/VolunteerUnassignToTaskMail.php b/app/Mail/VolunteerUnassignToTaskMail.php new file mode 100644 index 0000000..b4c5305 --- /dev/null +++ b/app/Mail/VolunteerUnassignToTaskMail.php @@ -0,0 +1,63 @@ +data = $data; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + return new Envelope( + subject: 'Désassignation - Comité des fêtes de Beaupont', + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + view: 'mails.volunteerUnassignToTask', + with: [ + 'name' => $this->data['name'], + 'lastname' => $this->data['lastname'], + 'taskName' => $this->data['taskName'], + 'start' => FormatDate::formatDate($this->data['start']), + 'end' => FormatDate::formatDate($this->data['end']), + 'eventName' => $this->data['eventName'], + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Models/Events.php b/app/Models/Event.php similarity index 77% rename from app/Models/Events.php rename to app/Models/Event.php index 94ce833..b4feeef 100644 --- a/app/Models/Events.php +++ b/app/Models/Event.php @@ -5,7 +5,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -class Events extends Model +class Event extends Model { use HasFactory; protected $fillable = [ @@ -16,6 +16,6 @@ class Events extends Model ]; public function tasks() { - return $this->hasMany(Task::class); + return $this->hasMany(Task::class, 'events_id'); } } diff --git a/app/Models/Notification.php b/app/Models/Notification.php index 24237b3..e3bfe5b 100644 --- a/app/Models/Notification.php +++ b/app/Models/Notification.php @@ -8,6 +8,7 @@ class Notification extends Model { protected $fillable = [ 'content', + 'user_id', ]; public function users(): \Illuminate\Database\Eloquent\Relations\BelongsToMany @@ -16,7 +17,6 @@ class Notification extends Model User::class, 'notification_user', 'notification_id', - 'user_id' ) ->withPivot('unread') ->withTimestamps(); diff --git a/app/Models/Task.php b/app/Models/Task.php index c569495..e0dd0b7 100644 --- a/app/Models/Task.php +++ b/app/Models/Task.php @@ -2,13 +2,10 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -class Task extends Model +class Task extends Model { - use HasFactory; - protected $fillable = [ 'name', 'start', @@ -19,7 +16,7 @@ class Task extends Model ]; public function event() { - return $this->belongsTo(Events::class); + return $this->belongsTo(Event::class); } public function users() { diff --git a/app/Models/User.php b/app/Models/User.php index cbbb472..0df9fd2 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -26,7 +26,9 @@ class User extends Authenticatable 'validate', 'role', 'verified_at', - 'profile_photo_path' + 'profile_photo_path', + 'email_notifications', + 'web_notifications' ]; /** diff --git a/app/Observers/EventObserver.php b/app/Observers/EventObserver.php index 6991bb4..2c13028 100644 --- a/app/Observers/EventObserver.php +++ b/app/Observers/EventObserver.php @@ -2,22 +2,22 @@ namespace App\Observers; -use App\Models\Events; +use App\Models\Event; use App\Services\TypesenseService; class EventObserver { - public function created(Events $event) + public function created(Event $event) { app(TypesenseService::class)->upsertEvent($event); } - public function updated(Events $event) + public function updated(Event $event) { app(TypesenseService::class)->upsertEvent($event); } - public function deleted(Events $event) + public function deleted(Event $event) { app(TypesenseService::class)->deleteEvent($event->id); } diff --git a/app/Policies/EventsPolicy.php b/app/Policies/EventsPolicy.php index a888718..abbed2f 100644 --- a/app/Policies/EventsPolicy.php +++ b/app/Policies/EventsPolicy.php @@ -2,7 +2,7 @@ namespace App\Policies; -use App\Models\Events; +use App\Models\Event; use App\Models\User; use Illuminate\Auth\Access\Response; diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 1cbe384..ba8c9ac 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,7 +2,7 @@ namespace App\Providers; -use App\Models\Events; +use App\Models\Event; use App\Models\User; use App\Observers\EventObserver; use App\Observers\UserObserver; @@ -30,6 +30,6 @@ class AppServiceProvider extends ServiceProvider Route::middleware('web')->prefix('api')->group(base_path('routes/notifications.php')); Route::middleware('web')->prefix('api')->group(base_path('routes/channels.php')); User::observe(UserObserver::class); - Events::observe(EventObserver::class); + Event::observe(EventObserver::class); } } diff --git a/app/Providers/GateServiceProvider.php b/app/Providers/GateServiceProvider.php index 6e7d69c..094ec54 100644 --- a/app/Providers/GateServiceProvider.php +++ b/app/Providers/GateServiceProvider.php @@ -2,7 +2,7 @@ namespace App\Providers; -use App\Models\Events; +use App\Models\Event; use App\Models\Task; use App\Models\User; use App\Policies\EventsPolicy; @@ -27,7 +27,7 @@ class GateServiceProvider extends ServiceProvider public function boot(): void { Gate::policy(User::class, UsersPolicy::class); - Gate::policy(Events::class, EventsPolicy::class); + Gate::policy(Event::class, EventsPolicy::class); Gate::policy(Task::class, TasksPolicy::class); } } diff --git a/app/Services/FormatDate.php b/app/Services/FormatDate.php new file mode 100644 index 0000000..aece902 --- /dev/null +++ b/app/Services/FormatDate.php @@ -0,0 +1,13 @@ +format('d/m/Y, H:i'); + } + +} diff --git a/app/Services/GetRole.php b/app/Services/GetRole.php index d1ae26e..d752d7d 100644 --- a/app/Services/GetRole.php +++ b/app/Services/GetRole.php @@ -6,6 +6,7 @@ class GetRole { public static function getRole($role) { + $role = (int)$role; return match ($role) { 1 => "Président", 2 => "Gérant", diff --git a/app/Services/TypesenseService.php b/app/Services/TypesenseService.php index adfe500..c00153c 100644 --- a/app/Services/TypesenseService.php +++ b/app/Services/TypesenseService.php @@ -3,7 +3,7 @@ namespace App\Services; use App\Models\User; -use App\Models\Events; +use App\Models\Event; use Illuminate\Support\Facades\Cache; use Typesense\Client; @@ -65,7 +65,7 @@ class TypesenseService } } - public function upsertEvent(Events $event): void + public function upsertEvent(Event $event): void { $this->ensureCollectionsExist(); diff --git a/app/Services/UserService.php b/app/Services/UserService.php index f95070c..2942786 100644 --- a/app/Services/UserService.php +++ b/app/Services/UserService.php @@ -2,6 +2,7 @@ namespace App\Services; use App\Models\User; +use Illuminate\Support\Facades\Log; class UserService { @@ -23,6 +24,8 @@ class UserService "validate" => $user->validate, "tasks" => $user->tasks, "profile_photo_path" => $user->profile_photo_path, + "email_notifications" => $user->email_notifications, + "web_notifications" => $user->web_notifications, ]; } } diff --git a/config/cors.php b/config/cors.php index b8a7871..19f2551 100644 --- a/config/cors.php +++ b/config/cors.php @@ -15,11 +15,14 @@ return [ | */ - 'paths' => ['api/*', 'sanctum/csrf-cookie', 'broadcasting/auth'], + + 'paths' => explode(',', env('CORS_PATHS', 'api/*')), 'allowed_methods' => ['*'], - 'allowed_origins' => ['*'], + 'allowed_origins' => env('DEV', 0) == 1 + ? explode(',', env('DEV_CORS_ALLOWED_ORIGINS')) + : explode(',', env('PROD_CORS_ALLOWED_ORIGINS')), 'allowed_origins_patterns' => [], diff --git a/database/factories/EventsFactory.php b/database/factories/EventFactory.php similarity index 89% rename from database/factories/EventsFactory.php rename to database/factories/EventFactory.php index 17d97d4..22651e6 100644 --- a/database/factories/EventsFactory.php +++ b/database/factories/EventFactory.php @@ -5,9 +5,9 @@ namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; /** - * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Events> + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Event> */ -class EventsFactory extends Factory +class EventFactory extends Factory { /** * Define the model's default state. diff --git a/database/migrations/2025_10_13_215246_create_users_table.php b/database/migrations/2025_10_13_215246_create_users_table.php index 509e0ae..b989881 100644 --- a/database/migrations/2025_10_13_215246_create_users_table.php +++ b/database/migrations/2025_10_13_215246_create_users_table.php @@ -21,6 +21,8 @@ return new class extends Migration $table->integer('validate'); $table->integer('role')->nullable(); $table->dateTime('verified_at')->nullable(); + $table->integer('email_notifications')->default(1); + $table->integer('web_notifications')->default(1); $table->timestamps(); }); } diff --git a/database/seeders/DevSeeder.php b/database/seeders/DevSeeder.php index c743000..0be9f81 100644 --- a/database/seeders/DevSeeder.php +++ b/database/seeders/DevSeeder.php @@ -2,7 +2,7 @@ namespace Database\Seeders; -use App\Models\Events; +use App\Models\Event; use App\Models\User; use App\Services\TypesenseService; use Illuminate\Database\Console\Seeds\WithoutModelEvents; @@ -25,7 +25,9 @@ class DevSeeder extends Seeder 'password' => bcrypt(config('app.admin_password')), 'phone' => config('app.admin_phone'), 'role' => 1, - 'validate' => 1 + 'validate' => 1, + 'web_notifications' => 1, + 'email_notifications' => 1, ] ); @@ -33,7 +35,7 @@ class DevSeeder extends Seeder User::factory()->count(10)->create(); - Events::factory()->count(10)->create(); + Event::factory()->count(10)->create(); } } diff --git a/database/seeders/ProdSeeder.php b/database/seeders/ProdSeeder.php index 99e55ae..5ee8d00 100644 --- a/database/seeders/ProdSeeder.php +++ b/database/seeders/ProdSeeder.php @@ -23,7 +23,9 @@ class ProdSeeder extends Seeder 'password' => bcrypt(config('app.admin_password')), 'phone' => config('app.admin_phone'), 'role' => 1, - 'validate' => 1 + 'validate' => 1, + 'web_notifications' => 1, + 'email_notifications' => 1, ] ); diff --git a/resources/views/mails/createUserByAdmin.blade.php b/resources/views/mails/createUserByAdmin.blade.php new file mode 100644 index 0000000..82b23f8 --- /dev/null +++ b/resources/views/mails/createUserByAdmin.blade.php @@ -0,0 +1,48 @@ + + + + + + Compte créé + + +
+

Bonjour {{ $name }} {{ $lastname }},

+ +

+ Un compte a été créé pour vous par un administrateur sur le site de gestion des bénévoles + du Comité des fêtes de Beaupont. +

+ +

+ Vous pouvez dès à présent vous connecter et accéder à votre espace personnel afin de participer + aux activités proposées. +

+ +

+ Veuillez vous renseigner auprès d'un administrateur pour récupérer vos identifiants. +

+ +

+ + Se connecter + +

+ +

+ Si vous n’êtes pas à l’origine de cette création de compte ou si vous avez des questions, + merci de contacter rapidement l’équipe organisatrice. +

+ +

+ À très bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/resources/views/mails/deactivateAccount.blade.php b/resources/views/mails/deactivateAccount.blade.php new file mode 100644 index 0000000..b1010f5 --- /dev/null +++ b/resources/views/mails/deactivateAccount.blade.php @@ -0,0 +1,40 @@ + + + + + + Compte désactivé + + +
+

Bonjour {{ $name }} {{ $lastname }},

+ +

+ Nous vous informons que votre compte sur le site de gestion des bénévoles + du Comité des fêtes de Beaupont a été désactivé par un administrateur. +

+ +

+ Vous ne pouvez désormais plus accéder à votre espace personnel ni participer aux activités proposées. +

+ +

+ Si vous pensez qu’il s’agit d’une erreur ou si vous souhaitez obtenir plus d’informations, + nous vous invitons à contacter l’équipe organisatrice. +

+ +

+ Votre compte pourra être réactivé ultérieurement si nécessaire. +

+ +

+ À bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/resources/views/mails/deleteAccount.blade.php b/resources/views/mails/deleteAccount.blade.php new file mode 100644 index 0000000..f9c616e --- /dev/null +++ b/resources/views/mails/deleteAccount.blade.php @@ -0,0 +1,39 @@ + + + + + + Compte supprimé + + +
+

Bonjour {{ $name }} {{ $lastname }},

+ +

+ Nous vous informons que votre compte sur le site de gestion des bénévoles + du Comité des fêtes de Beaupont a été supprimé. +

+ +

+ Vous n’avez désormais plus accès à votre espace personnel ni aux services associés. +

+ +

+ Si vous n’êtes pas à l’origine de cette action, merci de nous contacter rapidement. +

+ +

+ Si vous souhaitez à nouveau participer aux activités, vous pouvez effectuer une nouvelle inscription à tout moment. +

+ +

+ À bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/resources/views/mails/eventParticipationCancelled.blade.php b/resources/views/mails/eventParticipationCancelled.blade.php new file mode 100644 index 0000000..9d2a4c2 --- /dev/null +++ b/resources/views/mails/eventParticipationCancelled.blade.php @@ -0,0 +1,32 @@ + + + + + + Événement supprimé + + +
+

Bonjour {{ $name }} {{ $lastname }},

+ +

+ L’événement {{ $eventName }} a été supprimé par un administrateur. + Vous n’y participez donc plus. Cet événement avait lieu du {{ $start }} au {{ $end }}. +

+ +

+ Si vous pensez qu’il s’agit d’une erreur ou si vous souhaitez plus d’informations, + merci de contacter l’équipe du Comité des fêtes de Beaupont. +

+ +

+ À très bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/resources/views/mails/register.blade.php b/resources/views/mails/register.blade.php new file mode 100644 index 0000000..1f6626c --- /dev/null +++ b/resources/views/mails/register.blade.php @@ -0,0 +1,38 @@ + + + + + + Nouvelle demande de validation + + +
+

Bonjour {{ $adminName }} {{ $adminLastname }},

+ +

+ L’utilisateur {{ $userName }} {{ $userLastname }} a créé un compte + qui est maintenant en attente de validation sur le site du Comité des fêtes de Beaupont. +

+ +

+ + Valider ce compte + +

+ +

+ Vous pouvez cliquer sur le bouton ci-dessus pour vous rendre sur la page permettant de valider le compte. +

+ +

+ À très bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/resources/views/mails/taskDateUpdate.blade.php b/resources/views/mails/taskDateUpdate.blade.php new file mode 100644 index 0000000..2f48e99 --- /dev/null +++ b/resources/views/mails/taskDateUpdate.blade.php @@ -0,0 +1,32 @@ + + + + + + Date de tâche modifiée + + +
+

Bonjour {{ $name }} {{ $lastname }},

+ +

+ La date de la tâche {{ $taskName }} de l'événement {{ $eventName }} a été modifié par un administrateur. + Cette tâche avait lieu du {{ $oldStart }} au {{ $oldEnd }}. Et aura maintenant lieu du {{ $newStart }} au {{ $newEnd }}. +

+ +

+ Si vous pensez qu’il s’agit d’une erreur ou si vous souhaitez plus d’informations, + merci de contacter l’équipe du Comité des fêtes de Beaupont. +

+ +

+ À très bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/resources/views/mails/taskParticipationCancelled.blade.php b/resources/views/mails/taskParticipationCancelled.blade.php new file mode 100644 index 0000000..922b087 --- /dev/null +++ b/resources/views/mails/taskParticipationCancelled.blade.php @@ -0,0 +1,32 @@ + + + + + + Tâche supprimée + + +
+

Bonjour {{ $name }} {{ $lastname }},

+ +

+ La tâche {{ $taskName }} de l'événement {{ $eventName }} a été supprimé par un administrateur. + Vous n’y participez donc plus. Cette tâche avait lieu du {{ $start }} au {{ $end }}. +

+ +

+ Si vous pensez qu’il s’agit d’une erreur ou si vous souhaitez plus d’informations, + merci de contacter l’équipe du Comité des fêtes de Beaupont. +

+ +

+ À très bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/resources/views/mails/updateRole.blade.php b/resources/views/mails/updateRole.blade.php new file mode 100644 index 0000000..4b5d00a --- /dev/null +++ b/resources/views/mails/updateRole.blade.php @@ -0,0 +1,35 @@ + + + + + + Rôle mis à jour + + +
+

Bonjour {{ $name }} {{ $lastname }},

+ +

+ Votre rôle sur le site de gestion des bénévoles du Comité des fêtes de Beaupont + a été mis à jour par un administrateur. +

+ +

+ Vous êtes désormais : {{ $role }} +

+ +

+ Si vous avez des questions concernant ce changement, n’hésitez pas à contacter l’équipe organisatrice. +

+ +

+ À très bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/resources/views/mails/validate.blade.php b/resources/views/mails/validate.blade.php new file mode 100644 index 0000000..9c07457 --- /dev/null +++ b/resources/views/mails/validate.blade.php @@ -0,0 +1,47 @@ + + + + + + Compte validé + + + + +
+

🎉 Compte validé !

+
+ +
+

Bonjour {{ $name }} {{ $lastname }},

+ +

+ Nous avons le plaisir de vous informer que votre compte sur le site de gestion des bénévoles du Comité des fêtes de Beaupont a été validé avec succès. +

+ +

+ Vous pouvez dès à présent accéder à votre espace personnel et participer aux différentes activités proposées. +

+ + + +

+ Si vous avez la moindre question ou besoin d’assistance, n’hésitez pas à nous contacter. +

+ +

+ À très bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/resources/views/mails/volunteerAssignToTask.blade.php b/resources/views/mails/volunteerAssignToTask.blade.php new file mode 100644 index 0000000..e084dc7 --- /dev/null +++ b/resources/views/mails/volunteerAssignToTask.blade.php @@ -0,0 +1,32 @@ + + + + + + Assignation + + +
+

Bonjour {{ $name }} {{ $lastname }},

+ +

+ Vous avez été assigné à la tâche {{ $taskName }} de l'événément {{ $eventName }} par un administrateur. + Cette tâche aura lieu du {{ $start }} au {{ $end }}. +

+ +

+ Si vous pensez qu’il s’agit d’une erreur ou si vous souhaitez plus d’informations, + merci de contacter l’équipe du Comité des fêtes de Beaupont. +

+ +

+ À très bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/resources/views/mails/volunteerUnassignToTask.blade.php b/resources/views/mails/volunteerUnassignToTask.blade.php new file mode 100644 index 0000000..d97dce0 --- /dev/null +++ b/resources/views/mails/volunteerUnassignToTask.blade.php @@ -0,0 +1,32 @@ + + + + + + Désassignation + + +
+

Bonjour {{ $name }} {{ $lastname }},

+ +

+ Vous avez été désassigné de la tâche {{ $taskName }} de l'événement {{ $eventName }} par un administrateur. + Vous n'y participez donc plus. Cette tâche avait lieu du {{ $start }} au {{ $end }}. +

+ +

+ Si vous pensez qu’il s’agit d’une erreur ou si vous souhaitez plus d’informations, + merci de contacter l’équipe du Comité des fêtes de Beaupont. +

+ +

+ À très bientôt,
+ L’équipe du Comité des fêtes de Beaupont +

+
+ +

+ Cet email a été envoyé automatiquement, merci de ne pas y répondre. +

+ + diff --git a/routes/channels.php b/routes/channels.php index e819e24..57bc353 100644 --- a/routes/channels.php +++ b/routes/channels.php @@ -3,7 +3,7 @@ use Illuminate\Support\Facades\Broadcast; -Broadcast::channel('users.registration', function ($user) { +Broadcast::channel('users.admin', function ($user) { return in_array($user->role, [1, 2]); }); diff --git a/routes/users.php b/routes/users.php index eeb2ac0..261389a 100644 --- a/routes/users.php +++ b/routes/users.php @@ -38,3 +38,10 @@ Route::middleware(['web', 'auth:sanctum'])->get('/users/search', [SearchControll Route::middleware(['web', 'auth:sanctum'])->get('/users/invalid', [UserController::class, "getInvalidUsers"]); +Route::middleware(['web', 'auth:sanctum'])->patch('/users/{id}/email-notifications', [UserController::class, "toggleEmailNotifications"]) + ->whereNumber('id'); + +Route::middleware(['web', 'auth:sanctum'])->patch('/users/{id}/web-notifications', [UserController::class, "toggleWebNotifications"]) + ->whereNumber('id'); + + diff --git a/tests/collection.bru b/tests/collection.bru index f18ae36..b0aa5f7 100644 --- a/tests/collection.bru +++ b/tests/collection.bru @@ -1,4 +1,4 @@ headers { Accept: application/json - X-XSRF-TOKEN: + X-XSRF-TOKEN: eyJpdiI6ImVGRmdjSGtkUUtUT2E3TVE0RVM3c0E9PSIsInZhbHVlIjoiTkNldWpJb0I3T1dQMVJmTm43ekRPa2ZocFRZc25jYVlyZ0RBVDV3UjJVVDdpQkI1MUtkNWZROS9xbHdPUElHNTlrcjh2TUIxaTNtL20wYXZpdnltRGhNTGpsSGZETFV3VUtNd200OWcwUXFiYU9Eamd1VmFxRzVBNVNZVHBxMEEiLCJtYWMiOiJiMTM1OGVhOGRjM2VjMTg5ZDk4MzMwMjBmNjBkZjQ4OGIzODcwZjMzYzZkOTQxY2E5YjYyMDUxNGY5MzFjNjA1IiwidGFnIjoiIn0= }