From 5aed126889757dfc7536841a06f78145f4ebca71 Mon Sep 17 00:00:00 2001 From: Dwi Swandhana Date: Tue, 10 Mar 2026 13:53:06 +0700 Subject: [PATCH] update --- .../app/Http/Controllers/DokterController.php | 68 ++++++++++++++++-- .../app/Http/Controllers/ListController.php | 9 ++- ...ical_value_samples_add_followup_fields.php | 41 +++++++++++ .../base/partials/header-plain.blade.php | 71 ++++++++++++------- .../notifications/critical-values.blade.php | 27 +++++++ .../partials/critical-bell.blade.php | 25 +++++++ .../views/penerimaansample.blade.php | 8 +++ htdocs/routes/web.php | 1 + 8 files changed, 217 insertions(+), 33 deletions(-) create mode 100644 htdocs/database/migrations/2026_03_10_000009_alter_critical_value_samples_add_followup_fields.php create mode 100644 htdocs/resources/views/notifications/partials/critical-bell.blade.php diff --git a/htdocs/app/Http/Controllers/DokterController.php b/htdocs/app/Http/Controllers/DokterController.php index c846efd2..9fb83546 100644 --- a/htdocs/app/Http/Controllers/DokterController.php +++ b/htdocs/app/Http/Controllers/DokterController.php @@ -726,6 +726,7 @@ class DokterController extends Controller $criticalSample = CriticalValueSample::firstOrNew(['periksa_id' => $periksa->id]); $criticalSample->nofoto = $periksa->nofoto; $criticalSample->noregister = $periksa->noregister; + $criticalSample->asalpasien = $periksa->asalpasien; $criticalSample->nmpasien = $periksa->nmpasien; $criticalSample->nm_spesimen = $periksa->nm_spesimen; @@ -766,19 +767,74 @@ class DokterController extends Controller 'highlightId' => $highlightId, ]); } + public function criticalValueNotificationSummary() + { + if (Session::get('id') === null) { + return response()->json([ + 'count' => 0, + 'menu_html' => view('notifications.partials.critical-bell', [ + 'count' => 0, + 'items' => collect(), + ])->render(), + ]); + } + + $count = CriticalValueSample::whereNull('followed_up_at')->count(); + $items = CriticalValueSample::whereNull('followed_up_at') + ->orderBy('critical_set_at', 'asc') + ->limit(8) + ->get(); + + return response()->json([ + 'count' => (int) $count, + 'menu_html' => view('notifications.partials.critical-bell', [ + 'count' => (int) $count, + 'items' => $items, + ])->render(), + ]); + } public function criticalValueNotificationOpen($id) { - $criticalSample = CriticalValueSample::findOrFail($id); - $this->markCriticalValueAsRead($criticalSample); - return redirect() - ->route('criticalValueNotifications', ['highlight' => $criticalSample->id]) - ->with('success', 'Sample nilai kritis sudah ditandai sudah ditindaklanjuti.'); + ->route('criticalValueNotifications', ['highlight' => $id]); } public function criticalValueNotificationMarkRead($id) { $criticalSample = CriticalValueSample::findOrFail($id); - $this->markCriticalValueAsRead($criticalSample); + if (!empty($criticalSample->followed_up_at)) { + return redirect() + ->route('criticalValueNotifications', ['highlight' => $criticalSample->id]) + ->with('success', 'Sample nilai kritis ini sudah ditindaklanjuti sebelumnya.'); + } + + $followUpMethod = trim((string) request('caratindaklanjut', '')); + $followUpRecipient = trim((string) request('penerima_laporan', '')); + $followUpReason = trim((string) request('alasan_belum_laporkan', '')); + + // If method is empty -> not reported, reason is required. + // If method is filled -> reported, recipient is required. + if ($followUpMethod === '') { + if ($followUpReason === '') { + return back()->with('error', 'Alasan belum dilaporkan wajib diisi jika belum dilaporkan.'); + } + } else { + $allowed = ['Telpon', 'Whatshap', 'Email', 'Ketemu di Jalan']; + if (!in_array($followUpMethod, $allowed, true)) { + return back()->with('error', 'Cara tindak lanjut tidak valid.'); + } + if ($followUpRecipient === '') { + return back()->with('error', 'Penerima laporan wajib diisi jika sudah dilaporkan.'); + } + } + + $criticalSample->followed_up_at = Carbon::now(); + $criticalSample->followed_up_by_user_id = Session('id'); + $criticalSample->followed_up_by_name = Session('nama'); + $criticalSample->follow_up_status = $followUpMethod === '' ? 'not_reported' : 'reported'; + $criticalSample->follow_up_method = $followUpMethod !== '' ? $followUpMethod : null; + $criticalSample->follow_up_recipient = $followUpRecipient !== '' ? $followUpRecipient : null; + $criticalSample->follow_up_reason = $followUpReason !== '' ? $followUpReason : null; + $criticalSample->save(); return redirect() ->route('criticalValueNotifications', ['highlight' => $criticalSample->id]) diff --git a/htdocs/app/Http/Controllers/ListController.php b/htdocs/app/Http/Controllers/ListController.php index 82a783f3..39236e9e 100644 --- a/htdocs/app/Http/Controllers/ListController.php +++ b/htdocs/app/Http/Controllers/ListController.php @@ -28,7 +28,6 @@ class ListController extends Controller } else { return redirect('/pendaftaran'); } - } public function getList(Request $request) { $jenis = $request->input('jenis'); @@ -737,7 +736,13 @@ class ListController extends Controller '; }) - ->rawColumns(['aksi', 'tlsstatus', 'tlsnofoto', 'tlsnoregister', 'tlsnama', 'tlsreques']) + ->addColumn('batalaksi', function ($row) { + return ' + '; + }) + ->rawColumns(['aksi', 'tlsstatus', 'tlsnofoto', 'tlsnoregister', 'tlsnama', 'tlsreques', 'batalaksi']) ->make(true); } diff --git a/htdocs/database/migrations/2026_03_10_000009_alter_critical_value_samples_add_followup_fields.php b/htdocs/database/migrations/2026_03_10_000009_alter_critical_value_samples_add_followup_fields.php new file mode 100644 index 00000000..92faccc9 --- /dev/null +++ b/htdocs/database/migrations/2026_03_10_000009_alter_critical_value_samples_add_followup_fields.php @@ -0,0 +1,41 @@ +string('asalpasien', 250)->nullable()->after('noregister'); + + // Follow-up details recorded when marking as read. + $table->string('follow_up_status', 25)->nullable()->after('followed_up_by_name'); // reported|not_reported + $table->string('follow_up_method', 50)->nullable()->after('follow_up_status'); + $table->string('follow_up_recipient', 250)->nullable()->after('follow_up_method'); + $table->string('follow_up_reason', 250)->nullable()->after('follow_up_recipient'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('critical_value_samples', function (Blueprint $table) { + $table->dropColumn([ + 'asalpasien', + 'follow_up_status', + 'follow_up_method', + 'follow_up_recipient', + 'follow_up_reason', + ]); + }); + } +}; diff --git a/htdocs/resources/views/base/partials/header-plain.blade.php b/htdocs/resources/views/base/partials/header-plain.blade.php index a37508b7..56ad0038 100644 --- a/htdocs/resources/views/base/partials/header-plain.blade.php +++ b/htdocs/resources/views/base/partials/header-plain.blade.php @@ -37,31 +37,7 @@ {{ $criticalNotificationCount }} @if(Session::get('id') !== null) @@ -272,3 +248,48 @@ + +@if(Session::get('id') !== null) + @push('script') + + @endpush +@endif diff --git a/htdocs/resources/views/notifications/critical-values.blade.php b/htdocs/resources/views/notifications/critical-values.blade.php index 3c53996b..eb1fa641 100644 --- a/htdocs/resources/views/notifications/critical-values.blade.php +++ b/htdocs/resources/views/notifications/critical-values.blade.php @@ -18,6 +18,13 @@ @endif + @if (session('error')) +
+
+
{{ session('error') }}
+
+
+ @endif
@@ -36,6 +43,7 @@ No Foto No Register Pasien + Asal Pasien Spesimen Waktu Set Nilai Kritis Waktu Ditindaklanjuti @@ -49,6 +57,7 @@ {{ $item->nofoto ?? '-' }} {{ $item->noregister ?? '-' }} {{ $item->nmpasien ?? '-' }} + {{ $item->asalpasien ?? '-' }} {{ $item->nm_spesimen ?? '-' }} {{ $item->critical_set_at ? \Carbon\Carbon::parse($item->critical_set_at)->format('d-m-Y H:i:s') : '-' }} @@ -60,6 +69,24 @@
@csrf +
+ + +
+
+ + +
+
+ + +
diff --git a/htdocs/resources/views/notifications/partials/critical-bell.blade.php b/htdocs/resources/views/notifications/partials/critical-bell.blade.php new file mode 100644 index 00000000..d1bc3616 --- /dev/null +++ b/htdocs/resources/views/notifications/partials/critical-bell.blade.php @@ -0,0 +1,25 @@ + +
+ @if(($items ?? collect())->isEmpty()) + + @else + @foreach($items as $criticalItem) + +
+

+ {{ $criticalItem->nofoto ?? '-' }} - {{ $criticalItem->nmpasien ?? 'Tanpa Nama' }} + + Set: {{ $criticalItem->critical_set_at ? \Carbon\Carbon::parse($criticalItem->critical_set_at)->format('d-m-Y H:i:s') : '-' }} + +

+
+ @endforeach + @endif +
diff --git a/htdocs/resources/views/penerimaansample.blade.php b/htdocs/resources/views/penerimaansample.blade.php index af5ca7d7..8c18e95a 100644 --- a/htdocs/resources/views/penerimaansample.blade.php +++ b/htdocs/resources/views/penerimaansample.blade.php @@ -58,6 +58,7 @@ Kode Spesimen Status + Batal Aksi @@ -130,6 +131,11 @@ $('#gridkiriman').DataTable().ajax.reload(); }); } + function btnBatal(id){ + $.post('{{ route("batalPeriksa") }}', { id: id, _token: '{{ csrf_token() }}'},function(data){ + $('#gridkiriman').DataTable().ajax.reload(); + }); + } $(document).ready(function () { $("#tglreport").datepicker({format: 'yyyy-mm-dd'}); $("#mulai").datepicker({format: 'yyyy-mm-dd'}); @@ -213,6 +219,8 @@ { data: 'kd_spesimen', name: 'kd_spesimen' }, { data: 'nm_spesimen', name: 'nm_spesimen' }, { data: 'tlsstatus', name: 'status' }, + { data: 'batalaksi', name: 'batalaksi', orderable: false, searchable: false }, + ], language: { lengthMenu : "Tampilkan _MENU_ data per halaman", diff --git a/htdocs/routes/web.php b/htdocs/routes/web.php index 04a5778a..1c447e3a 100644 --- a/htdocs/routes/web.php +++ b/htdocs/routes/web.php @@ -112,6 +112,7 @@ Route::group(['middleware' => 'project.ipg'], function() { Route::post('dokter/getListadendum', [DokterController::class, 'getListadendum'])->name('getListadendum'); Route::post('dokter/exprinttandaterima', [DokterController::class, 'exTandaTerima'])->name('exTandaTerima'); Route::get('notifikasi/nilai-kritis', [DokterController::class, 'criticalValueNotifications'])->name('criticalValueNotifications'); + Route::get('notifikasi/nilai-kritis/summary', [DokterController::class, 'criticalValueNotificationSummary'])->name('criticalValueNotificationSummary'); Route::get('notifikasi/nilai-kritis/{id}', [DokterController::class, 'criticalValueNotificationOpen'])->name('criticalValueNotificationOpen'); Route::post('notifikasi/nilai-kritis/{id}/mark-read', [DokterController::class, 'criticalValueNotificationMarkRead'])->name('criticalValueNotificationMarkRead');