diff --git a/app/Http/Controllers/Admin/SettingsController.php b/app/Http/Controllers/Admin/SettingsController.php index 8829ecf271ec3f55a2789d4bf3bec3ac54f256e0..065a1bf7454f7033f122b739127b9c9266f80138 100644 --- a/app/Http/Controllers/Admin/SettingsController.php +++ b/app/Http/Controllers/Admin/SettingsController.php @@ -4,6 +4,7 @@ use App\Http\Controllers\Controller; use App\Mail\AdminInvitationMail; +use App\Models\DbConfig; use App\Models\User; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; @@ -22,16 +23,30 @@ class SettingsController extends Controller 'label' => 'Général', 'icon' => 'circle-user', ], - [ - 'route' => 'admin.settings.users', - 'label' => 'Utilisateurs', - 'icon' => 'users', - ], ]; + protected bool $isSuperAdmin; + + public function __construct() + { + $this->isSuperAdmin = Auth::user()->email === config('app.protected_account_email'); + + if ($this->isSuperAdmin) { + $this->headerRoutes[] = [ + 'route' => 'admin.settings.users', + 'label' => 'Utilisateurs', + 'icon' => 'users', + ]; + $this->headerRoutes[] = [ + 'route' => 'admin.settings.website-config', + 'label' => 'Configuration du site', + 'icon' => 'gear', + ]; + } + } + public function userListPage(): View { - $isSuperAdmin = auth()->user()->email === config('app.protected_account_email'); $users = User::all(); foreach ($users as $user) { @@ -41,7 +56,7 @@ public function userListPage(): View return view('admin.settings.users', [ 'headerRoutes' => $this->headerRoutes, 'users' => $users, - 'isSuperAdmin' => $isSuperAdmin, + 'isSuperAdmin' => $this->isSuperAdmin, ]); } @@ -52,9 +67,7 @@ public function createUser(Request $request): RedirectResponse 'email' => 'required|string|email|max:255|unique:users', ]); - $isSuperAdmin = Auth::user()->email === config('app.protected_account_email'); - - if (! $isSuperAdmin) { + if (! $this->isSuperAdmin) { return redirect()->route('admin.settings.users') ->with('error', 'Vous n\'avez pas les droits pour effectuer cette action.'); } @@ -73,9 +86,7 @@ public function createUser(Request $request): RedirectResponse public function deleteUser(int $id): RedirectResponse { - $isSuperAdmin = auth()->user()->email === config('app.protected_account_email'); - - if (! $isSuperAdmin) { + if (! $this->isSuperAdmin) { return redirect()->route('admin.settings.users') ->with('error', 'Vous n\'avez pas les droits pour effectuer cette action.'); } @@ -140,4 +151,39 @@ public function updateUserInfos(Request $request): RedirectResponse return redirect()->route('admin.settings.general')->with('success', 'Informations mises à jour.'); } + + public function websiteConfigPage(): RedirectResponse|View + { + if (! $this->isSuperAdmin) { + return redirect()->route('admin.settings.general') + ->with('error', 'Vous n\'avez pas les droits pour effectuer cette action.'); + } + + return view('admin.settings.website-config', [ + 'headerRoutes' => $this->headerRoutes, + ]); + } + + public function updateWebsiteConfig(Request $request): RedirectResponse + { + $request->validate([ + 'maintenance_mode' => 'sometimes|nullable|string|in:true,false', + 'website_name' => 'sometimes|nullable|string|max:255', + ]); + + if (! $this->isSuperAdmin) { + return redirect()->route('admin.settings.general') + ->with('error', 'Vous n\'avez pas les droits pour effectuer cette action.'); + } + + if ($request->filled('maintenance_mode')) { + DbConfig::set('maintenance_mode', $request->maintenance_mode); + } + + if ($request->filled('website_name')) { + DbConfig::set('website_name', $request->website_name); + } + + return redirect()->route('admin.settings.website-config')->with('success', 'Configuration mise à jour.'); + } } diff --git a/app/Models/DbConfig.php b/app/Models/DbConfig.php new file mode 100644 index 0000000000000000000000000000000000000000..3bd061f190e1a32415b7ae1cecb884fe7c794d13 --- /dev/null +++ b/app/Models/DbConfig.php @@ -0,0 +1,91 @@ +<?php + +namespace App\Models; + +use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Cache; + +class DbConfig extends Model +{ + use HasFactory; + + public $timestamps = false; + + protected $fillable = [ + 'key', + 'value', + ]; + + /** + * Get a configuration value by its key. + * Value types casts: + * - 'true' => true + * - 'false' => false + * - integers => int + * - floats => float + * - strings => string + * + * @param string $key The key of the configuration value. Example: 'app.name' + * @param float|bool|int|string|null $default The default value to return if the configuration does not exist. + * @return float|bool|int|string|null The value of the configuration. + */ + public static function get(string $key, float|bool|int|string|null $default = null): float|bool|int|string|null + { + $config = Cache::rememberForever('config_'.$key, function () use ($key) { + return self::where('key', $key)->first(); + }); + + if (empty($config) || ! $config->exists || $config->value === null) { + return $default; + } + + // Cast to boolean if the value is a boolean + if ($config->value === 'true') { + return true; + } elseif ($config->value === 'false') { + return false; + } + + // Cast to integer if the value is an integer + if (is_numeric($config->value)) { + if (is_float($config->value)) { + return (float) $config->value; + } else { + return (int) $config->value; + } + } + + return $config->value; + } + + /** + * Set a configuration value by its key. + * + * @param string $key The key of the configuration value. Example: 'app.name' + * @param string|int|float|bool $value The value of the configuration. + */ + public static function set(string $key, float|bool|int|string $value): void + { + if (Cache::has('config_'.$key)) { + Cache::forget('config_'.$key); + } + + $config = self::where('key', $key)->first(); + + if ($config === null) { + self::create([ + 'key' => $key, + 'value' => $value, + ]); + } else { + $config->update([ + 'value' => $value, + ]); + } + + Cache::rememberForever('config_'.$key, function () use ($key) { + return self::where('key', $key)->first(); + }); + } +} diff --git a/database/factories/DbConfigFactory.php b/database/factories/DbConfigFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..d1d7eae53fa035167c8d93a7e65764f08269fb1b --- /dev/null +++ b/database/factories/DbConfigFactory.php @@ -0,0 +1,19 @@ +<?php + +namespace Database\Factories; + +use App\Models\DbConfig; +use Illuminate\Database\Eloquent\Factories\Factory; + +class DbConfigFactory extends Factory +{ + protected $model = DbConfig::class; + + public function definition(): array + { + return [ + 'key' => $this->faker->word(), + 'value' => $this->faker->word(), + ]; + } +} diff --git a/database/migrations/2025_02_23_145044_create_db_configs_table.php b/database/migrations/2025_02_23_145044_create_db_configs_table.php new file mode 100644 index 0000000000000000000000000000000000000000..09506350a1f0e6c5e8025e55bdc84ad74a00902f --- /dev/null +++ b/database/migrations/2025_02_23_145044_create_db_configs_table.php @@ -0,0 +1,22 @@ +<?php + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + public function up(): void + { + Schema::create('db_configs', function (Blueprint $table) { + $table->id(); + $table->string('key')->unique(); + $table->string('value'); + }); + } + + public function down(): void + { + Schema::dropIfExists('db_configs'); + } +}; diff --git a/resources/views/admin/settings/general.blade.php b/resources/views/admin/settings/general.blade.php index ef891f725d4090d82f6aad10f774fe5fc8668061..6ea34cd993b44b73a28a9be5dd5f29bb6afbe364 100644 --- a/resources/views/admin/settings/general.blade.php +++ b/resources/views/admin/settings/general.blade.php @@ -3,10 +3,32 @@ @section('content') <div class="grid"> <div class="g-col-12 g-col-md-6"> + @if (!empty($errors) && $errors->any()) + <x-bs.alert type="danger" class="mt-3"> + <ul> + @foreach ($errors->all() as $error) + <li>{{ $error }}</li> + @endforeach + </ul> + </x-bs.alert> + @endif + + @if (session('success')) + <x-bs.alert type="success" class="mt-3"> + {{ session('success') }} + </x-bs.alert> + @endif + + @if (session('error')) + <x-bs.alert type="danger" class="mt-3"> + {{ session('error') }} + </x-bs.alert> + @endif + <h5>Information</h5> <p>Ne remplissez que les champs que vous souhaitez mettre à jour.</p> <form action="{{ route('admin.settings.update-user-infos') }}" - method="post"> + method="post"> @csrf @method('PUT') @@ -48,22 +70,6 @@ class="mb-3" <x-bs.button type="submit">Enregistrer</x-bs.button> </form> - - @if (!empty($errors) && $errors->any()) - <x-bs.alert type="danger" class="mt-3"> - <ul> - @foreach ($errors->all() as $error) - <li>{{ $error }}</li> - @endforeach - </ul> - </x-bs.alert> - @endif - - @if (session('success')) - <x-bs.alert type="success" class="mt-3"> - {{ session('success') }} - </x-bs.alert> - @endif </div> </div> @endsection diff --git a/resources/views/admin/settings/users.blade.php b/resources/views/admin/settings/users.blade.php index 57713da07d490c06ac3a5e2197c6641d2ebdc6de..a3bc900930e1c70365180da2a6845f843087cc05 100644 --- a/resources/views/admin/settings/users.blade.php +++ b/resources/views/admin/settings/users.blade.php @@ -7,7 +7,8 @@ par email.</p> <p><span class="fw-bold text-danger">Attention !</span> Pour des raisons de simplicité, ces personnes auront les - mêmes droits que vous (sauf toutes les actions liées à cette page, y compris son accès). + mêmes droits que vous (sauf toutes les actions liées à cette page et à la configuration du site, y compris + leur accès). <strong>Soyez bien certains d'avoir confiance en elles !</strong></p> <x-bs.button data-bs-toggle="modal" data-bs-target="#addUserModal" size="sm" variant="primary"> diff --git a/resources/views/admin/settings/website-config.blade.php b/resources/views/admin/settings/website-config.blade.php new file mode 100644 index 0000000000000000000000000000000000000000..9199ffbb15f46f92524c891921929aae4fb2010e --- /dev/null +++ b/resources/views/admin/settings/website-config.blade.php @@ -0,0 +1,48 @@ +@extends('layouts.admin', ['title' => 'Configuration', 'headerRoutes' => $headerRoutes]) + +@section('content') + <div class="grid"> + <div class="g-col-12 g-col-md-6"> + @if (!empty($errors) && $errors->any()) + <x-bs.alert type="danger" class="mt-3"> + <ul> + @foreach ($errors->all() as $error) + <li>{{ $error }}</li> + @endforeach + </ul> + </x-bs.alert> + @endif + + @if (session('success')) + <x-bs.alert type="success" class="mt-3"> + {{ session('success') }} + </x-bs.alert> + @endif + + <h5>Configuration</h5> + <p>Modifiez les paramètres du site internet.</p> + <form action="{{ route('admin.settings.update-website-config') }}" + method="post"> + @csrf + @method('PUT') + + <x-bs.select label="Statut du mode maintenance" + name="maintenance_mode" + class="mb-3" + :options="['false' => 'Désactivé', 'true' => 'Activé']" + :selected="old('maintenance_mode', \App\Models\DbConfig::get('maintenance_mode', 'false'))" + data-form-type="other" + /> + + <x-bs.input label="Nom du site internet" + name="website_name" + class="mb-3" + :value="old('website_name', \App\Models\DbConfig::get('website_name', config('app.name')))" + data-form-type="other" + /> + + <x-bs.button type="submit">Enregistrer</x-bs.button> + </form> + </div> + </div> +@endsection diff --git a/routes/web.php b/routes/web.php index d006a190a22dd7a0926f7202c57c29cd08fbcdd9..3049d6c2b25ac7f4dede3368ce149133bca9d192 100644 --- a/routes/web.php +++ b/routes/web.php @@ -113,6 +113,8 @@ Route::match(['GET', 'DELETE'], '/users/{id}/delete', [SettingsController::class, 'deleteUser'])->name('delete-user'); Route::get('/general', [SettingsController::class, 'generalPage'])->name('general'); Route::put('/general', [SettingsController::class, 'updateUserInfos'])->name('update-user-infos'); + Route::get('/website-configuration', [SettingsController::class, 'websiteConfigPage'])->name('website-config'); + Route::put('/website-configuration', [SettingsController::class, 'updateWebsiteConfig'])->name('update-website-config'); }); Route::prefix('prestations')->name('prestations.')->group(function () {