diff --git a/app/Http/Controllers/QuickSearchController.php b/app/Http/Controllers/QuickSearchController.php index acebfdc..a9f8e7a 100644 --- a/app/Http/Controllers/QuickSearchController.php +++ b/app/Http/Controllers/QuickSearchController.php @@ -4,9 +4,10 @@ namespace App\Http\Controllers; use App\Enums\PbgTaskApplicationTypes; use App\Enums\PbgTaskStatus; +use App\Http\Resources\TaskAssignmentsResource; use App\Models\PbgTask; +use App\Models\TaskAssignment; use Illuminate\Http\Request; -use function Illuminate\Log\log; class QuickSearchController extends Controller { @@ -66,4 +67,21 @@ class QuickSearchController extends Controller return response()->view('pages.404', [], 500); // Optional: create `resources/views/errors/500.blade.php` } } + + public function task_assignments(Request $request, $uuid){ + try{ + $query = TaskAssignment::query() + ->where('pbg_task_uid', $uuid) + ->orderBy('id', 'desc'); + + if ($request->filled('search')) { + $query->where('name', 'like', "%{$request->get('search')}%") + ->orWhere('email', 'like', "%{$request->get('search')}%"); + } + + return TaskAssignmentsResource::collection($query->paginate(config('app.paginate_per_page', 50))); + }catch(\Exception $exception){ + return response()->json(['message' => $exception->getMessage()], 500); + } + } } diff --git a/resources/js/quick-search/detail.js b/resources/js/quick-search/detail.js index e69de29..55ad8a8 100644 --- a/resources/js/quick-search/detail.js +++ b/resources/js/quick-search/detail.js @@ -0,0 +1,70 @@ +import { Grid } from "gridjs"; +class QuickSearchDetail { + init() { + this.initTablePbgTaskAssignments(); + } + + initTablePbgTaskAssignments() { + let tableContainer = document.getElementById( + "table-pbg-task-assignments" + ); + + let url_task_assignments = document.getElementById( + "url_task_assignments" + ).value; + + new Grid({ + columns: [ + "ID", + "Nama", + "Email", + "Nomor Telepon", + "Keahlian", + "Status", + ], + search: { + server: { + url: (prev, keyword) => `${prev}?search=${keyword}`, + }, + debounceTimeout: 1000, + }, + pagination: { + limit: 15, + server: { + url: (prev, page) => + `${prev}${prev.includes("?") ? "&" : "?"}page=${ + page + 1 + }`, + }, + }, + sort: true, + server: { + url: `${url_task_assignments}`, + then: (data) => { + return data.data.map((item) => { + const expertiseArray = + typeof item.expertise === "string" + ? JSON.parse(item.expertise) + : item.expertise; + + return [ + item.id, + item.name, + item.email, + item.phone_number, + Array.isArray(expertiseArray) + ? expertiseArray.map((e) => e.name).join(", ") + : "-", + item.status_name, + ]; + }); + }, + total: (data) => data.meta.total, + }, + }).render(tableContainer); + } +} + +document.addEventListener("DOMContentLoaded", function (e) { + new QuickSearchDetail().init(); +}); diff --git a/resources/js/quick-search/result.js b/resources/js/quick-search/result.js index 7b824e7..8c291bf 100644 --- a/resources/js/quick-search/result.js +++ b/resources/js/quick-search/result.js @@ -4,13 +4,56 @@ class QuickSearchResult { constructor() { this.table = null; const baseInput = document.getElementById("base_url_datatable"); - this.datatableUrl = baseInput ? baseInput.value : ""; + this.baseUrl = baseInput ? baseInput.value.split("?")[0] : ""; + this.keywordInput = document.getElementById("search_input"); + this.searchButton = document.getElementById("search_button"); + + this.datatableUrl = this.buildUrl(this.keywordInput.value); } init() { + this.bindSearchButton(); this.initDatatable(); } + bindSearchButton() { + const handleSearch = () => { + const newKeyword = this.keywordInput.value.trim(); + if (newKeyword !== "") { + // 1. Update datatable URL and reload + this.datatableUrl = this.buildUrl(newKeyword); + this.initDatatable(); + + // 2. Update URL query string (without reloading the page) + const newUrl = `${ + window.location.pathname + }?keyword=${encodeURIComponent(newKeyword)}`; + window.history.pushState({ path: newUrl }, "", newUrl); + + // 3. Update visible keyword text in {{ $keyword }}> + const keywordDisplay = document.querySelector(".qs-header em"); + if (keywordDisplay) { + keywordDisplay.textContent = newKeyword; + } + } + }; + + this.searchButton.addEventListener("click", handleSearch); + + this.keywordInput.addEventListener("keydown", (event) => { + if (event.key === "Enter") { + event.preventDefault(); + handleSearch(); + } + }); + } + + buildUrl(keyword) { + const url = new URL(this.baseUrl, window.location.origin); + url.searchParams.set("search", keyword); + return url.toString(); + } + initDatatable() { const tableContainer = document.getElementById( "datatable-quick-search-result" @@ -73,7 +116,12 @@ class QuickSearchResult { }; if (this.table) { - this.table = this.table.updateConfig(config).forceRender(); + this.table + .updateConfig({ + ...config, + server: { ...config.server, url: this.datatableUrl }, + }) + .forceRender(); } else { tableContainer.innerHTML = ""; this.table = new Grid(config).render(tableContainer); diff --git a/resources/scss/pages/quick-search/detail.scss b/resources/scss/pages/quick-search/detail.scss new file mode 100644 index 0000000..0b3c2eb --- /dev/null +++ b/resources/scss/pages/quick-search/detail.scss @@ -0,0 +1,73 @@ +.qs-detail-container { + color: #000; // black text + font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; + + .card { + background-color: #fff; + + .card-header { + background-color: #f5f5f5; + font-weight: bold; + color: #000; + } + + .card-body { + dt { + font-weight: 600; + color: #000; + } + + dd { + margin-bottom: 10px; + color: #000; + } + + .nav-tabs { + border-bottom: 1px solid #000; + + .nav-link { + color: #000; + border: 1px solid transparent; + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + font-weight: 500; + + &.active { + background-color: #e0e0e0; + border-color: #000 #000 #fff; + } + + &:hover { + color: #000; + } + } + } + + .tab-content { + padding: 1rem; + } + + .mb-3 { + dt { + font-weight: bold; + } + + dd { + margin-left: 0; + } + } + + .border { + border-color: #000 !important; + } + + .shadow-sm { + box-shadow: none !important; + } + + .rounded { + border-radius: 4px !important; + } + } + } +} diff --git a/resources/scss/pages/quick-search/result.scss b/resources/scss/pages/quick-search/result.scss index 7578421..4eea864 100644 --- a/resources/scss/pages/quick-search/result.scss +++ b/resources/scss/pages/quick-search/result.scss @@ -1,11 +1,52 @@ .qs-wrapper { - padding: 30px 15px; - max-width: 1200px; + width: 100%; margin: 0 auto; font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; color: #2c3e50; } +.qs-toolbar { + border-bottom: 1px solid #e0e0e0; + margin-bottom: 1.5rem; +} + +.qs-search-form { + width: 100%; + .gsp-input { + width: 100%; + height: 44px; + font-size: 16px; + padding: 0 20px; + border-radius: 24px; + border: 1px solid #dfe1e5; + background-color: #fff; + box-shadow: none; + transition: box-shadow 0.2s ease-in-out, border-color 0.2s; + + &:focus { + border-color: transparent; + box-shadow: 0 1px 6px rgba(32, 33, 36, 0.28); + outline: none; + } + } + + .gsp-btn { + height: 44px; + padding: 0 24px; + font-size: 16px; + border: none; + border-radius: 24px; + background-color: #1a73e8; + color: white; + cursor: pointer; + transition: background-color 0.2s ease-in-out; + + &:hover { + background-color: #1558d6; + } + } +} + .qs-header { margin-bottom: 30px; text-align: center; @@ -30,7 +71,6 @@ .qs-table-wrapper { background-color: #fff; border-radius: 10px; - padding: 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); overflow-x: auto; // allow horizontal scroll on small screens } diff --git a/resources/views/auth/signin.blade.php b/resources/views/auth/signin.blade.php index 35ce76a..5475ea7 100755 --- a/resources/views/auth/signin.blade.php +++ b/resources/views/auth/signin.blade.php @@ -21,8 +21,8 @@ class="authentication-bg" logo light -

Welcome Back!

-

Sign in to your account to continue

+

Selamat Datang!

+

Masuk kedalam akun untuk melihat lebih lanjut

@@ -35,7 +35,7 @@ class="authentication-bg" @endif
- +
@@ -45,6 +45,11 @@ class="authentication-bg"
+
diff --git a/resources/views/quick-search/detail.blade.php b/resources/views/quick-search/detail.blade.php index 66f08ed..0520fda 100644 --- a/resources/views/quick-search/detail.blade.php +++ b/resources/views/quick-search/detail.blade.php @@ -1,258 +1,229 @@ @extends('layouts.base', ['subtitle' => 'Quick Search']) @section('css') +@vite(['resources/scss/pages/quick-search/detail.scss']) +@vite(['node_modules/gridjs/dist/theme/mermaid.min.css']) @endsection @section('content') -
-
-
-
-
Detail Informasi Permohonan PBG
-
-
-
-
-
-
Nama Pemohon
-
{{ $data->name }}
+
+
+
+
+
+
Detail Informasi Permohonan PBG
+ Back +
+
+
+
+
+
Nama Pemohon
+
{{ $data->name }}
-
Nama Pemilik
-
{{ $data->owner_name }}
+
Nama Pemilik
+
{{ $data->owner_name }}
-
Jenis Permohonan
-
{{ $applicationTypes[$data->application_type] ?? '-' }}
+
Jenis Permohonan
+
{{ isset($data->application_type) ? $applicationTypes[$data->application_type] : '-' }}
-
Kondisi
-
{{ $data->condition }}
+
Kondisi
+
{{ $data->condition }}
-
Nomor Registrasi
-
{{ $data->registration_number }}
+
Nomor Registrasi
+
{{ $data->registration_number }}
-
Nomor Dokumen
-
{{ $data->document_number }}
+
Nomor Dokumen
+
{{ $data->document_number }}
-
Status
-
{{ $statusOptions[$data->status] ?? '-' }}
-
-
+
Status
+
{{ isset($data->status) ? $statusOptions[$data->status] : '-' }}
+
+
+
+
+
Alamat
+
{{ $data->address }}
-
-
-
Alamat
-
{{ $data->address }}
+
Status SLF
+
{{ $data->slf_status_name }}
-
Status SLF
-
{{ $data->slf_status_name }}
+
Fungsi Bangunan
+
{{ $data->function_type }}
-
Fungsi Bangunan
-
{{ $data->function_type }}
+
Jenis Konsultasi
+
{{ $data->consultation_type }}
-
Jenis Konsultasi
-
{{ $data->consultation_type }}
- -
Jatuh Tempo
-
{{ \Carbon\Carbon::parse($data->due_date)->format('d M Y') }}
- -
Tanggal Dibuat
-
{{ \Carbon\Carbon::parse($data->task_created_at)->format('d M Y H:i') }}
-
-
+
Jatuh Tempo
+
{{ \Carbon\Carbon::parse($data->due_date)->format('d M Y') }}
+
Tanggal Dibuat
+
{{ \Carbon\Carbon::parse($data->task_created_at)->format('d M Y H:i') }}
+
+
+
+
+
-
- - -
-
- -
-
-
- @if ($data->pbg_task_retributions) -
-
-
-
Luas Bangunan
-
{{$data->pbg_task_retributions->luas_bangunan}}
-
-
-
Indeks Lokalitas
-
{{$data->pbg_task_retributions->indeks_lokalitas}}
-
-
-
Wilayah SHST
-
{{$data->pbg_task_retributions->wilayah_shst}}
-
-
-
Kegiatan Name
-
{{$data->pbg_task_retributions->kegiatan_name}}
-
-
-
Nilai SHST
-
{{$data->pbg_task_retributions->nilai_shst}}
-
-
-
Indeks Integrasi
-
{{$data->pbg_task_retributions->indeks_terintegrasi}}
-
-
-
Indeks Bg Terbangun
-
{{$data->pbg_task_retributions->indeks_bg_terbangun}}
-
-
-
-
-
Nilai Retribusi Bangunan
-
{{$data->pbg_task_retributions->nilai_retribusi_bangunan}}
-
-
-
Nilai Prasarana
-
{{$data->pbg_task_retributions->nilai_prasarana}}
-
-
-
PBG Dokumen
-
{{$data->pbg_task_retributions->pbg_document}}
-
-
-
Underpayment
-
{{$data->pbg_task_retributions->underpayment}}
-
-
-
SKRD Amount
-
{{$data->pbg_task_retributions->skrd_amount}}
-
-
-
- @else -
-
- Data Not Available -
-
- @endif -
-
- @if ($data->pbg_task_index_integrations) -
-
-
-
Indeks Fungsi Bangunan
-
{{$data->pbg_task_index_integrations->indeks_fungsi_bangunan}}
-
-
-
Indeks Parameter Kompleksitas
-
{{$data->pbg_task_index_integrations->indeks_parameter_kompleksitas}}
-
-
-
Indeks Parameter Permanensi
-
{{$data->pbg_task_index_integrations->indeks_parameter_permanensi}}
-
-
-
Indeks Paramter Ketinggian
-
{{$data->pbg_task_index_integrations->indeks_parameter_ketinggian}}
-
-
-
Faktor Kepemilikan
-
{{$data->pbg_task_index_integrations->faktor_kepemilikan}}
-
-
-
Indeks Terintegrasi
-
{{$data->pbg_task_index_integrations->indeks_terintegrasi}}
-
-
-
Total
-
{{$data->pbg_task_index_integrations->total}}
-
-
-
- @else -
-
- Data Not Available -
-
- @endif -
-
-
- @if ($data->pbg_task_retributions && $data->pbg_task_retributions->pbg_task_prasarana) - @foreach ($data->pbg_task_retributions->pbg_task_prasarana as $prasarana) -
-
-
Prasarana Type
-
{{$prasarana->prasarana_type}}
-
-
-
Building Type
-
{{$prasarana->building_type}}
-
-
-
Total
-
{{$prasarana->total}}
-
-
-
Quantity
-
{{$prasarana->quantity}}
-
-
-
Unit
-
{{$prasarana->unit}}
-
-
-
Index Prasarana
-
{{$prasarana->index_prasarana}}
-
-
-
Created At
-
{{$prasarana->created_at}}
-
-
- @endforeach - @else -
-
- Data Not Available -
-
- @endif -
-
-
- -
-
-
-
-
-
- +
+
+ +
+
+
+ @if ($data->pbg_task_retributions) +
+
+
+
Luas Bangunan
+
{{$data->pbg_task_retributions->luas_bangunan}}
+ +
Indeks Lokalitas
+
{{$data->pbg_task_retributions->indeks_lokalitas}}
+ +
Wilayah SHST
+
{{$data->pbg_task_retributions->wilayah_shst}}
+ +
Nama Kegiatan
+
{{isset($data->pbg_task_retributions->kegiatan_name) ? $data->pbg_task_retributions->kegiatan_name : '-'}}
+ +
Nilai SHST
+
{{$data->pbg_task_retributions->nilai_shst}}
+ +
Indeks Integrasi
+
{{$data->pbg_task_retributions->indeks_terintegrasi}}
+ +
Indeks Bg Terbangun
+
{{$data->pbg_task_retributions->indeks_bg_terbangun}}
+
+
+
+
+
Nilai Retribusi Bangunan
+
{{$data->pbg_task_retributions->nilai_retribusi_bangunan}}
+
Nilai Prasarana
+
{{ isset($data->pbg_task_retributions->nilai_prasarana) ? $data->pbg_task_retributions->nilai_prasarana : '-'}}
+ +
PBG Dokumen
+
{{$data->pbg_task_retributions->pbg_document}}
+ +
Underpayment
+
{{$data->pbg_task_retributions->underpayment}}
+ +
SKRD Amount
+
{{$data->pbg_task_retributions->skrd_amount}}
+
+
+
+ @else + + @endif +
+
+ @if ($data->pbg_task_index_integrations) +
+
Indeks Fungsi Bangunan
+
{{$data->pbg_task_index_integrations->indeks_fungsi_bangunan}}
+ +
Indeks Parameter Kompleksitas
+
{{$data->pbg_task_index_integrations->indeks_parameter_kompleksitas}}
+ +
Indeks Parameter Permanensi
+
{{$data->pbg_task_index_integrations->indeks_parameter_permanensi}}
+ +
Indeks Parameter Ketinggian
+
{{$data->pbg_task_index_integrations->indeks_parameter_ketinggian}}
+ +
Faktor Kepemilikan
+
{{$data->pbg_task_index_integrations->faktor_kepemilikan}}
+ +
Indeks Terintegrasi
+
{{$data->pbg_task_index_integrations->indeks_terintegrasi}}
+ +
Total
+
{{$data->pbg_task_index_integrations->total}}
+
+ @else + + @endif +
+
+
+ @if ($data->pbg_task_retributions && $data->pbg_task_retributions->pbg_task_prasarana) + @foreach ($data->pbg_task_retributions->pbg_task_prasarana as $prasarana) +
+
+
Prasarana Type
+
{{$prasarana->prasarana_type}}
+ +
Building Type
+
{{$prasarana->building_type}}
+ +
Total
+
{{$prasarana->total}}
+ +
Quantity
+
{{$prasarana->quantity}}
+ +
Unit
+
{{$prasarana->unit}}
+ +
Index Prasarana
+
{{$prasarana->index_prasarana}}
+ +
Created At
+
{{\Carbon\Carbon::parse($prasarana->created_at)->format('d M Y')}}
+
+
+ @endforeach + @else + + @endif +
+
+
+ +
+
+
+
+
+
+ + @endsection @section('scripts') +@vite(['resources/js/quick-search/detail.js']) @endsection \ No newline at end of file diff --git a/resources/views/quick-search/index.blade.php b/resources/views/quick-search/index.blade.php index fbcec76..b38cb0b 100644 --- a/resources/views/quick-search/index.blade.php +++ b/resources/views/quick-search/index.blade.php @@ -9,6 +9,11 @@ class="gsp-body" @endsection @section('content') +
+ + Login + +
diff --git a/resources/views/quick-search/result.blade.php b/resources/views/quick-search/result.blade.php index de6b61e..07efcd2 100644 --- a/resources/views/quick-search/result.blade.php +++ b/resources/views/quick-search/result.blade.php @@ -6,19 +6,39 @@ @endsection @section('content') - -
-
+ +
+
+ + + Kembali + + +
+ + +
+
+ +

Hasil Pencarian: {{ $keyword }}

Berikut adalah data hasil pencarian berdasarkan kata kunci yang Anda masukkan.

+
-
+
@endsection @section('scripts') @vite(['resources/js/quick-search/result.js']) -@endsection \ No newline at end of file +@endsection diff --git a/routes/web.php b/routes/web.php index 82521e1..941d73b 100755 --- a/routes/web.php +++ b/routes/web.php @@ -39,6 +39,7 @@ Route::get('/search', [QuickSearchController::class, 'index'])->name('search'); Route::get('/search-result', [QuickSearchController::class, 'search_result'])->name('search-result'); Route::get('/quick-search-datatable', [QuickSearchController::class, 'quick_search_datatable'])->name('quick-search-datatable'); Route::get('/quick-search/{id}', [QuickSearchController::class, 'show'])->name('quick-search.detail'); +Route::get('/quick-search/{uuid}/task-assignments', [QuickSearchController::class, 'task_assignments'])->name('api.quick-search-task-assignments'); // auth Route::group(['middleware' => 'auth'], function(){ diff --git a/vite.config.js b/vite.config.js index 8b1d2e9..20531b8 100755 --- a/vite.config.js +++ b/vite.config.js @@ -20,6 +20,9 @@ export default defineConfig({ "resources/scss/components/_custom_circle.scss", "resources/scss/dashboards/potentials/_inside_system.scss", "resources/scss/dashboards/potentials/_outside_system.scss", + "resources/scss/pages/quick-search/detail.scss", + "resources/scss/pages/quick-search/index.scss", + "resources/scss/pages/quick-search/result.scss", "node_modules/quill/dist/quill.snow.css", "node_modules/quill/dist/quill.bubble.css", @@ -109,6 +112,10 @@ export default defineConfig({ "resources/js/pbg-task/create.js", // google-sheets "resources/js/data/google-sheet/index.js", + // quick-search + "resources/js/quick-search/index.js", + "resources/js/quick-search/result.js", + "resources/js/quick-search/detail.js", // dummy "resources/js/approval/index.js", "resources/js/invitations/index.js",