From aaa50582490dfc536be4cef06258a92abd7e4c58 Mon Sep 17 00:00:00 2001 From: Developer Date: Tue, 7 Jul 2026 10:32:38 +0800 Subject: [PATCH] feat: update barangay management and dashboard roles - Created dashboard-router to separate LGU and Super Admin landing pages - Added Barangays and LGUs statistical cards to Super Admin dashboard - Moved LGU Management to Areas group in sidebar and added API Docs link - Removed geofence spatial validation (ST_Contains) for Barangay creation in both LGU and Super Admin controllers to allow flexible boundaries --- .../Api/V1/Admin/AdminBarangayController.php | 30 +------------- .../SuperAdminBarangayController.php | 38 +----------------- commit_message.txt | Bin 186 -> 413 bytes .../views/admin/dashboard-router.blade.php | 19 +++++++++ resources/views/admin/dashboard.blade.php | 8 ++++ .../views/admin/partials/sidebar.blade.php | 11 ++++- routes/web.php | 4 +- 7 files changed, 43 insertions(+), 67 deletions(-) create mode 100644 resources/views/admin/dashboard-router.blade.php diff --git a/app/Http/Controllers/Api/V1/Admin/AdminBarangayController.php b/app/Http/Controllers/Api/V1/Admin/AdminBarangayController.php index fae5ba2..3bf02b7 100644 --- a/app/Http/Controllers/Api/V1/Admin/AdminBarangayController.php +++ b/app/Http/Controllers/Api/V1/Admin/AdminBarangayController.php @@ -55,20 +55,7 @@ class AdminBarangayController extends ApiController $boundary = $this->buildPolygon($data['boundary']); $centroid = $this->calculateCentroid($boundary); - if ($tenant->boundary_polygon) { - $isContained = DB::selectOne( - 'SELECT ST_Contains(boundary_polygon, ST_GeomFromText(?, 4326, \'axis-order=long-lat\')) as contained FROM tenants WHERE id = ?', - [$boundary->toWkt(), $tenant->id] - ); - - if (! $isContained || ! $isContained->contained) { - return $this->fail( - 'The drawn Barangay boundary must lie completely within your LGU boundary.', - ['boundary' => ['The Barangay boundary is outside your LGU border.']], - 422 - ); - } - } + // Spatial validation check removed as per user request // Code auto-generation if empty $city = CityMunicipality::findOrFail($cityId); @@ -130,20 +117,7 @@ class AdminBarangayController extends ApiController $boundary = $this->buildPolygon($data['boundary']); $centroid = $this->calculateCentroid($boundary); - if ($tenant->boundary_polygon) { - $isContained = DB::selectOne( - 'SELECT ST_Contains(boundary_polygon, ST_GeomFromText(?, 4326, \'axis-order=long-lat\')) as contained FROM tenants WHERE id = ?', - [$boundary->toWkt(), $tenant->id] - ); - - if (! $isContained || ! $isContained->contained) { - return $this->fail( - 'The drawn Barangay boundary must lie completely within your LGU boundary.', - ['boundary' => ['The Barangay boundary is outside your LGU border.']], - 422 - ); - } - } + // Spatial validation check removed as per user request // Code auto-generation if empty $city = CityMunicipality::findOrFail($cityId); diff --git a/app/Http/Controllers/Api/V1/SuperAdmin/SuperAdminBarangayController.php b/app/Http/Controllers/Api/V1/SuperAdmin/SuperAdminBarangayController.php index 7a75627..4deaa77 100644 --- a/app/Http/Controllers/Api/V1/SuperAdmin/SuperAdminBarangayController.php +++ b/app/Http/Controllers/Api/V1/SuperAdmin/SuperAdminBarangayController.php @@ -52,24 +52,7 @@ class SuperAdminBarangayController extends ApiController $boundary = $this->buildPolygon($data['boundary']); $centroid = $this->calculateCentroid($boundary); - // Spatial validation check - $cityId = $data['city_municipality_id']; - $tenant = Tenant::where('city_municipality_id', $cityId)->first(); - - if ($tenant && $tenant->boundary_polygon) { - $isContained = DB::selectOne( - 'SELECT ST_Contains(boundary_polygon, ST_GeomFromText(?, 4326, \'axis-order=long-lat\')) as contained FROM tenants WHERE id = ?', - [$boundary->toWkt(), $tenant->id] - ); - - if (! $isContained || ! $isContained->contained) { - return $this->fail( - 'The drawn Barangay boundary must lie completely within the LGU/Municipality boundary.', - ['boundary' => ['The Barangay boundary is outside the LGU border.']], - 422 - ); - } - } + // Spatial validation check removed as per user request // Code auto-generation if empty $city = CityMunicipality::findOrFail($cityId); @@ -120,24 +103,7 @@ class SuperAdminBarangayController extends ApiController $boundary = $this->buildPolygon($data['boundary']); $centroid = $this->calculateCentroid($boundary); - // Spatial validation check - $cityId = $data['city_municipality_id']; - $tenant = Tenant::where('city_municipality_id', $cityId)->first(); - - if ($tenant && $tenant->boundary_polygon) { - $isContained = DB::selectOne( - 'SELECT ST_Contains(boundary_polygon, ST_GeomFromText(?, 4326, \'axis-order=long-lat\')) as contained FROM tenants WHERE id = ?', - [$boundary->toWkt(), $tenant->id] - ); - - if (! $isContained || ! $isContained->contained) { - return $this->fail( - 'The drawn Barangay boundary must lie completely within the LGU/Municipality boundary.', - ['boundary' => ['The Barangay boundary is outside the LGU border.']], - 422 - ); - } - } + // Spatial validation check removed as per user request // Code auto-generation if empty $city = CityMunicipality::findOrFail($cityId); diff --git a/commit_message.txt b/commit_message.txt index 2129799768e35a368a1fb3f5f13389bba2189ce8..8cc7562a4f73f00936d2d58eb6c74051e0f4e879 100644 GIT binary patch literal 413 zcmZvZK~4iP3`O@ng_p4C1=tNmLP%6XEv%7e;+aNd>?qC@xIKR&RJveo`@Nr^QMlgG zk^@(vo(t>5-!!xGB(rEG)O>g=2dE1HnEPL|w|(3>dF2|t#(@(JaQlkBCS6j2vbQrRt8f1o9s3<( zI!(xy3387?@W>|NChlII=)nf36!in3gUk&ziH)LzkY~g|gfpjzlAQsE4wO&br8a zkIXlYD=+JbZ}0`D>4jn_l`W}(Blv^5GDn+%M&I4l4r_D-ave5#zJaUXn3p 'Loading Dashboard...']) + +@section('page') +
+ + + + +
Routing to your dashboard...
+
+ +@endsection diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index c70ab97..a54e1cb 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -15,6 +15,8 @@ ['key' => 'pending_households', 'label' => 'Pending households', 'href' => '/admin/households'], ['key' => 'verified_households', 'label' => 'Verified households', 'href' => '/admin/households'], ['key' => 'service_areas', 'label' => 'Service areas', 'href' => '/admin/service-areas'], + ['key' => 'barangays', 'label' => 'Barangays', 'href' => '/admin/barangays'], + ['key' => 'lgus', 'label' => 'LGUs', 'href' => '/admin/lgus'], ['key' => 'drop_off_points', 'label' => 'Drop-off points', 'href' => '/admin/drop-off-points'], ['key' => 'dumpsites', 'label' => 'Dumpsites', 'href' => '/admin/dumpsites'], ['key' => 'qr_batches', 'label' => 'QR batches', 'href' => '/admin/qr-batches'], @@ -81,6 +83,12 @@ const sa = await window.Verde.apiFetch('/api/v1/service-areas'); if (sa.ok) setStat('service_areas', (sa.body.data ?? []).length); + const ba = await window.Verde.apiFetch('/api/v1/super-admin/barangays?per_page=1'); + if (ba.ok) setStat('barangays', ba.body.meta?.total ?? 0); + + const lgus = await window.Verde.apiFetch('/api/v1/super-admin/tenants?per_page=1'); + if (lgus.ok) setStat('lgus', lgus.body.meta?.total ?? 0); + const dop = await window.Verde.apiFetch('/api/v1/admin/drop-off-points?per_page=1'); if (dop.ok) setStat('drop_off_points', dop.body.meta?.total ?? 0); diff --git a/resources/views/admin/partials/sidebar.blade.php b/resources/views/admin/partials/sidebar.blade.php index 6c557cb..f4ac27a 100644 --- a/resources/views/admin/partials/sidebar.blade.php +++ b/resources/views/admin/partials/sidebar.blade.php @@ -27,6 +27,7 @@ 'Areas' => [ ['href' => '/admin/service-areas', 'label' => 'Service Areas', 'icon' => 'globe'], ['href' => '/admin/barangays', 'label' => 'Barangays', 'icon' => 'pin'], + ['href' => '/admin/lgus', 'label' => 'LGU Management', 'icon' => 'globe', 'super_admin_only' => true], ], 'Finance' => [ ['href' => '/admin/finance', 'label' => 'Payments', 'icon' => 'cash'], @@ -38,8 +39,8 @@ ['href' => '/admin/settings', 'label' => 'System Config', 'icon' => 'cog'], ], 'System Admin' => [ - ['href' => '/admin/lgus', 'label' => 'LGU Management', 'icon' => 'globe'], ['href' => '/admin/system-users', 'label' => 'User Accounts', 'icon' => 'users'], + ['href' => '/docs/api', 'label' => 'API Docs', 'icon' => 'route', 'external' => true], ], ]; @@ -89,11 +90,16 @@ $disabled = ! empty($item['disabled']); $href = $disabled ? '#' : $item['href']; $active = ! $disabled && $isActive(ltrim($item['href'], '/')); + $superAdminOnly = ! empty($item['super_admin_only']); + $classes = 'nav-link ' . ($active ? 'is-active ' : '') . ($disabled ? 'is-disabled ' : ''); + if ($superAdminOnly) { + $classes .= ' hidden super-admin-item'; + } @endphp + class="{{ trim($classes) }}"> {!! $renderIcon($item['icon']) !!} {{ $item['label'] }} @if ($disabled) @@ -111,6 +117,7 @@ // Show System Admin group only for super_admin if (user.role === 'super_admin') { document.getElementById('nav-group-superadmin')?.classList.remove('hidden'); + document.querySelectorAll('.super-admin-item').forEach(el => el.classList.remove('hidden')); } // Update role badge diff --git a/routes/web.php b/routes/web.php index eadf330..c3807cf 100644 --- a/routes/web.php +++ b/routes/web.php @@ -14,7 +14,9 @@ Route::get('/qr/{serial}', function ($serial) { })->name('qr.verify'); Route::prefix('admin')->group(function () { - Route::view('/dashboard', 'admin.lgu-dashboard')->name('admin.dashboard'); + Route::view('/dashboard', 'admin.dashboard-router')->name('admin.dashboard'); + Route::view('/lgu-dashboard', 'admin.lgu-dashboard')->name('admin.lgu-dashboard'); + Route::view('/superadmin-dashboard', 'admin.dashboard')->name('admin.superadmin-dashboard'); Route::view('/households', 'admin.households')->name('admin.households'); Route::view('/service-areas', 'admin.service-areas')->name('admin.service-areas'); Route::view('/qr-batches', 'admin.qr-batches')->name('admin.qr-batches');