From 9ac2ea7bdaa1486f803fe508b8f7d744aa9ae8aa Mon Sep 17 00:00:00 2001 From: ramram1515 Date: Mon, 29 Jun 2026 13:53:07 +0800 Subject: [PATCH] chore: apply code review checklist and web design guidelines fixes --- .../Api/V1/Admin/AdminUserController.php | 22 +++++++++++++-- app/Http/Resources/DumpsiteResource.php | 1 + database/seeders/SuperAdminSeeder.php | 4 +-- resources/views/admin/dumpsites.blade.php | 28 ++++++++++++++++--- resources/views/admin/routes.blade.php | 4 +-- resources/views/auth/login.blade.php | 3 +- 6 files changed, 51 insertions(+), 11 deletions(-) diff --git a/app/Http/Controllers/Api/V1/Admin/AdminUserController.php b/app/Http/Controllers/Api/V1/Admin/AdminUserController.php index f1be851..4935d1f 100644 --- a/app/Http/Controllers/Api/V1/Admin/AdminUserController.php +++ b/app/Http/Controllers/Api/V1/Admin/AdminUserController.php @@ -9,14 +9,32 @@ use App\Http\Resources\UserDetailResource; use App\Models\User; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Illuminate\Validation\Rule; class AdminUserController extends ApiController { public function index(Request $request): JsonResponse { $request->validate([ - 'role' => ['nullable', 'in:admin,resident,driver,helper,scanner,store_partner'], - 'status' => ['nullable', 'in:active,suspended,pending'], + 'role' => [ + 'nullable', + Rule::in([ + User::ROLE_ADMIN, + User::ROLE_RESIDENT, + User::ROLE_DRIVER, + User::ROLE_HELPER, + User::ROLE_SCANNER, + User::ROLE_STORE_PARTNER, + ]) + ], + 'status' => [ + 'nullable', + Rule::in([ + User::STATUS_ACTIVE, + User::STATUS_SUSPENDED, + User::STATUS_PENDING, + ]) + ], 'verification_status' => ['nullable', 'in:pending,approved,rejected'], 'q' => ['nullable', 'string', 'max:100'], 'per_page' => ['nullable', 'integer', 'min:1', 'max:500'], diff --git a/app/Http/Resources/DumpsiteResource.php b/app/Http/Resources/DumpsiteResource.php index 9115b4d..60b52b3 100644 --- a/app/Http/Resources/DumpsiteResource.php +++ b/app/Http/Resources/DumpsiteResource.php @@ -22,6 +22,7 @@ class DumpsiteResource extends JsonResource return [ 'id' => $this->uuid, + 'db_id' => $this->id, 'name' => $this->name, 'code' => $this->code, 'address_line' => $this->address_line, diff --git a/database/seeders/SuperAdminSeeder.php b/database/seeders/SuperAdminSeeder.php index dee539e..d085fa2 100644 --- a/database/seeders/SuperAdminSeeder.php +++ b/database/seeders/SuperAdminSeeder.php @@ -15,7 +15,7 @@ class SuperAdminSeeder extends Seeder ['email' => 'super@verde.local'], [ 'phone' => '+639000000099', - 'password' => Hash::make('password'), + 'password' => Hash::make(env('SUPER_ADMIN_PASSWORD', 'password')), 'first_name' => 'Verde', 'last_name' => 'Super Admin', 'role' => User::ROLE_SUPER_ADMIN, @@ -30,6 +30,6 @@ class SuperAdminSeeder extends Seeder $user->syncRoles([User::ROLE_SUPER_ADMIN]); NotificationPreference::firstOrCreate(['user_id' => $user->id]); - $this->command->info("Super admin: {$user->email} (password: password)"); + $this->command->info("Super admin: {$user->email} (password: ".env('SUPER_ADMIN_PASSWORD', 'password').")"); } } diff --git a/resources/views/admin/dumpsites.blade.php b/resources/views/admin/dumpsites.blade.php index 532bb7c..e1c7970 100644 --- a/resources/views/admin/dumpsites.blade.php +++ b/resources/views/admin/dumpsites.blade.php @@ -37,11 +37,11 @@

New dumpsite

-
-
+
@@ -83,7 +83,13 @@
- +
@@ -125,7 +131,7 @@ div.innerHTML = ` - + `; div.querySelector('.remove-point').addEventListener('click', () => div.remove()); pointsEl.appendChild(div); @@ -285,6 +291,15 @@ document.getElementById('create-form').addEventListener('submit', async (e) => { e.preventDefault(); + + const submitBtn = document.getElementById('submit-btn'); + const btnLabel = submitBtn.querySelector('.btn-label'); + const btnSpinner = submitBtn.querySelector('.btn-spinner'); + + submitBtn.disabled = true; + btnLabel.textContent = 'Creating…'; + btnSpinner.classList.remove('hidden'); + const fd = new FormData(e.target); const payload = Object.fromEntries(fd.entries()); payload.lat = parseFloat(payload.lat); @@ -299,6 +314,11 @@ method: 'POST', body: JSON.stringify(payload), }); + + submitBtn.disabled = false; + btnLabel.textContent = 'Create'; + btnSpinner.classList.add('hidden'); + if (res.ok) { window.Verde.toast('Dumpsite created', 'success'); modal.classList.add('hidden'); e.target.reset(); load(); } else window.Verde.toast(res.body?.message ?? 'Create failed', 'error'); }); diff --git a/resources/views/admin/routes.blade.php b/resources/views/admin/routes.blade.php index b0cc3f0..cd98605 100644 --- a/resources/views/admin/routes.blade.php +++ b/resources/views/admin/routes.blade.php @@ -99,7 +99,7 @@ if (!res.ok) return; (res.body.data ?? []).forEach(d => { const opt = document.createElement('option'); - opt.value = d.id; + opt.value = d.db_id; opt.textContent = d.name; dumpsiteSelect.appendChild(opt); }); @@ -115,7 +115,7 @@ function renderPicker() { if (allDops.length === 0) { stopsPicker.innerHTML = '
No active DOPs found.
'; return; } stopsPicker.innerHTML = allDops.map(d => ` -