update lagi

This commit is contained in:
Endyfadlullah 2025-08-11 03:23:58 +07:00
parent a2f7caf21f
commit 5f97cb9bff
3 changed files with 112 additions and 10 deletions

View File

@ -6,6 +6,7 @@
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Models\User; use App\Models\User;
use App\Models\Admin; use App\Models\Admin;
use App\Models\Antrian; use App\Models\Antrian;
@ -19,6 +20,9 @@ class AdminController extends Controller
{ {
public function dashboard() public function dashboard()
{ {
// Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit
$this->autoBatalkanAntrianLama();
$totalUsers = User::count(); $totalUsers = User::count();
$totalAntrian = Antrian::count(); $totalAntrian = Antrian::count();
$antrianHariIni = Antrian::whereDate('created_at', today())->count(); $antrianHariIni = Antrian::whereDate('created_at', today())->count();
@ -62,6 +66,9 @@ public function dashboard()
public function manageUsers(Request $request) public function manageUsers(Request $request)
{ {
// Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit
$this->autoBatalkanAntrianLama();
$query = User::with(['antrians.poli']); $query = User::with(['antrians.poli']);
// Search functionality // Search functionality
@ -184,6 +191,9 @@ public function resetUserPassword(Request $request, User $user)
public function laporan(Request $request) public function laporan(Request $request)
{ {
// Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit
$this->autoBatalkanAntrianLama();
$query = Antrian::with(['user', 'poli']); $query = Antrian::with(['user', 'poli']);
// Filter berdasarkan tanggal // Filter berdasarkan tanggal
@ -219,9 +229,10 @@ public function laporan(Request $request)
$totalAntrian = $antrian->count(); $totalAntrian = $antrian->count();
$antrianSelesai = $antrian->where('status', 'selesai')->count(); $antrianSelesai = $antrian->where('status', 'selesai')->count();
$antrianMenunggu = $antrian->where('status', 'menunggu')->count(); $antrianMenunggu = $antrian->where('status', 'menunggu')->count();
$antrianDipanggil = $antrian->where('status', 'dipanggil')->count();
$antrianSedang = $antrian->where('status', 'sedang')->count(); $antrianSedang = $antrian->where('status', 'sedang')->count();
return view('admin.laporan.index', compact('antrian', 'polis', 'totalAntrian', 'antrianSelesai', 'antrianMenunggu', 'antrianSedang')); return view('admin.laporan.index', compact('antrian', 'polis', 'totalAntrian', 'antrianSelesai', 'antrianMenunggu', 'antrianDipanggil', 'antrianSedang'));
} }
public function exportPDF(Request $request) public function exportPDF(Request $request)
@ -256,7 +267,14 @@ public function exportPDF(Request $request)
$antrian = $query->orderBy('created_at', 'desc')->get(); $antrian = $query->orderBy('created_at', 'desc')->get();
$pdf = Pdf::loadView('admin.laporan.pdf', compact('antrian')); // Statistik untuk PDF
$totalAntrian = $antrian->count();
$antrianSelesai = $antrian->where('status', 'selesai')->count();
$antrianMenunggu = $antrian->where('status', 'menunggu')->count();
$antrianDipanggil = $antrian->where('status', 'dipanggil')->count();
$antrianSedang = $antrian->where('status', 'sedang')->count();
$pdf = Pdf::loadView('admin.laporan.pdf', compact('antrian', 'totalAntrian', 'antrianSelesai', 'antrianMenunggu', 'antrianDipanggil', 'antrianSedang'));
return $pdf->download('laporan-antrian-' . date('Y-m-d') . '.pdf'); return $pdf->download('laporan-antrian-' . date('Y-m-d') . '.pdf');
} }
@ -292,6 +310,13 @@ public function exportExcel(Request $request)
$antrian = $query->orderBy('created_at', 'desc')->get(); $antrian = $query->orderBy('created_at', 'desc')->get();
// Statistik untuk Excel
$totalAntrian = $antrian->count();
$antrianSelesai = $antrian->where('status', 'selesai')->count();
$antrianMenunggu = $antrian->where('status', 'menunggu')->count();
$antrianDipanggil = $antrian->where('status', 'dipanggil')->count();
$antrianSedang = $antrian->where('status', 'sedang')->count();
$filename = 'laporan-antrian-' . date('Y-m-d') . '.csv'; $filename = 'laporan-antrian-' . date('Y-m-d') . '.csv';
$headers = [ $headers = [
@ -338,6 +363,9 @@ public function exportExcel(Request $request)
public function poliUmum() public function poliUmum()
{ {
// Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit
$this->autoBatalkanAntrianLama();
$antrians = Antrian::with(['user', 'poli']) $antrians = Antrian::with(['user', 'poli'])
->whereHas('poli', function ($query) { ->whereHas('poli', function ($query) {
$query->where('nama_poli', 'umum'); $query->where('nama_poli', 'umum');
@ -351,6 +379,9 @@ public function poliUmum()
public function poliGigi() public function poliGigi()
{ {
// Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit
$this->autoBatalkanAntrianLama();
$antrians = Antrian::with(['user', 'poli']) $antrians = Antrian::with(['user', 'poli'])
->whereHas('poli', function ($query) { ->whereHas('poli', function ($query) {
$query->where('nama_poli', 'gigi'); $query->where('nama_poli', 'gigi');
@ -364,6 +395,9 @@ public function poliGigi()
public function poliJiwa() public function poliJiwa()
{ {
// Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit
$this->autoBatalkanAntrianLama();
$antrians = Antrian::with(['user', 'poli']) $antrians = Antrian::with(['user', 'poli'])
->whereHas('poli', function ($query) { ->whereHas('poli', function ($query) {
$query->where('nama_poli', 'kesehatan jiwa'); $query->where('nama_poli', 'kesehatan jiwa');
@ -377,6 +411,9 @@ public function poliJiwa()
public function poliTradisional() public function poliTradisional()
{ {
// Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit
$this->autoBatalkanAntrianLama();
$antrians = Antrian::with(['user', 'poli']) $antrians = Antrian::with(['user', 'poli'])
->whereHas('poli', function ($query) { ->whereHas('poli', function ($query) {
$query->where('nama_poli', 'kesehatan tradisional'); $query->where('nama_poli', 'kesehatan tradisional');
@ -641,6 +678,38 @@ private function getPoliPrefix($namaPoli)
return $prefixMap[strtolower($namaPoli)] ?? 'A'; return $prefixMap[strtolower($namaPoli)] ?? 'A';
} }
/**
* Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit
* tanpa dikonfirmasi selesai oleh admin
*/
private function autoBatalkanAntrianLama()
{
try {
// Cari antrian yang sudah dipanggil lebih dari 5 menit
$antrianLama = Antrian::where('status', 'dipanggil')
->where('waktu_panggil', '<=', now()->subMinutes(5))
->get();
$count = 0;
foreach ($antrianLama as $antrian) {
// Update status menjadi 'batal'
$antrian->update(['status' => 'batal']);
$count++;
// Log untuk tracking
\Log::info("Antrian {$antrian->no_antrian} otomatis dibatalkan karena lewat 5 menit sejak dipanggil");
}
// Jika ada antrian yang dibatalkan, log jumlahnya
if ($count > 0) {
\Log::info("Total {$count} antrian otomatis dibatalkan karena timeout");
}
} catch (\Exception $e) {
// Log error jika terjadi masalah
\Log::error("Error saat auto-batalkan antrian: " . $e->getMessage());
}
}
public function cetakAntrian(Antrian $antrian) public function cetakAntrian(Antrian $antrian)
{ {
try { try {

View File

@ -20,7 +20,7 @@
</div> </div>
</div> </div>
<div class="hidden md:flex items-center space-x-4"> <div class="hidden md:flex items-center space-x-4">
<span class="text-gray-700">Selamat datang, Admin</span> <span class="text-gray-700">Selamat datang, Admin</span>
<button onclick="confirmLogout()" <button onclick="confirmLogout()"
class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-200"> class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-200">
@ -219,6 +219,9 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none foc
<option value="menunggu" {{ request('status') == 'menunggu' ? 'selected' : '' }}> <option value="menunggu" {{ request('status') == 'menunggu' ? 'selected' : '' }}>
Menunggu Menunggu
</option> </option>
<option value="dipanggil" {{ request('status') == 'dipanggil' ? 'selected' : '' }}>
Dipanggil
</option>
<option value="sedang" {{ request('status') == 'sedang' ? 'selected' : '' }}>Sedang <option value="sedang" {{ request('status') == 'sedang' ? 'selected' : '' }}>Sedang
</option> </option>
<option value="selesai" {{ request('status') == 'selesai' ? 'selected' : '' }}>Selesai <option value="selesai" {{ request('status') == 'selesai' ? 'selected' : '' }}>Selesai
@ -263,7 +266,7 @@ class="inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shad
</div> </div>
<!-- Statistics Cards --> <!-- Statistics Cards -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8"> <div class="grid grid-cols-1 md:grid-cols-5 gap-6 mb-8">
<div class="bg-white rounded-2xl shadow-xl border p-6"> <div class="bg-white rounded-2xl shadow-xl border p-6">
<div class="flex items-center"> <div class="flex items-center">
<div class="flex-shrink-0"> <div class="flex-shrink-0">
@ -301,6 +304,25 @@ class="inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shad
</div> </div>
</div> </div>
<div class="bg-white rounded-2xl shadow-xl border p-6">
<div class="flex items-center">
<div class="flex-shrink-0">
<div class="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-blue-600" fill="none" stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z">
</path>
</svg>
</div>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Dipanggil</p>
<p class="text-2xl font-bold text-gray-900">{{ $antrianDipanggil }}</p>
</div>
</div>
</div>
<div class="bg-white rounded-2xl shadow-xl border p-6"> <div class="bg-white rounded-2xl shadow-xl border p-6">
<div class="flex items-center"> <div class="flex items-center">
<div class="flex-shrink-0"> <div class="flex-shrink-0">
@ -400,6 +422,11 @@ class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium b
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800"> class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
Menunggu Menunggu
</span> </span>
@elseif($item->status == 'dipanggil')
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
Dipanggil
</span>
@elseif($item->status == 'sedang') @elseif($item->status == 'sedang')
<span <span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800"> class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800">
@ -410,7 +437,7 @@ class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium b
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800"> class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
Selesai Selesai
</span> </span>
@else @elseif($item->status == 'batal')
<span <span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800"> class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
Batal Batal
@ -472,6 +499,11 @@ class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium b
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800"> class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
Menunggu Menunggu
</span> </span>
@elseif($item->status == 'dipanggil')
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
Dipanggil
</span>
@elseif($item->status == 'sedang') @elseif($item->status == 'sedang')
<span <span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800"> class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800">
@ -482,7 +514,7 @@ class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium b
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800"> class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
Selesai Selesai
</span> </span>
@else @elseif($item->status == 'batal')
<span <span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800"> class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
Batal Batal

View File

@ -132,10 +132,11 @@
<div class="summary"> <div class="summary">
<h3>Ringkasan Statistik:</h3> <h3>Ringkasan Statistik:</h3>
<p><strong>Total Antrian:</strong> {{ $antrian->count() }}</p> <p><strong>Total Antrian:</strong> {{ $totalAntrian }}</p>
<p><strong>Menunggu:</strong> {{ $antrian->where('status', 'menunggu')->count() }}</p> <p><strong>Menunggu:</strong> {{ $antrianMenunggu }}</p>
<p><strong>Sedang:</strong> {{ $antrian->where('status', 'sedang')->count() }}</p> <p><strong>Dipanggil:</strong> {{ $antrianDipanggil }}</p>
<p><strong>Selesai:</strong> {{ $antrian->where('status', 'selesai')->count() }}</p> <p><strong>Sedang:</strong> {{ $antrianSedang }}</p>
<p><strong>Selesai:</strong> {{ $antrianSelesai }}</p>
<p><strong>Batal:</strong> {{ $antrian->where('status', 'batal')->count() }}</p> <p><strong>Batal:</strong> {{ $antrian->where('status', 'batal')->count() }}</p>
</div> </div>
</body> </body>