diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php index 9c88150..186e171 100644 --- a/app/Http/Controllers/AdminController.php +++ b/app/Http/Controllers/AdminController.php @@ -49,7 +49,7 @@ public function dashboard() // Get recent antrian $antrianTerbaru = Antrian::with(['user', 'poli']) ->orderBy('created_at', 'desc') - ->limit(10) + ->limit(3) ->get(); return view('admin.dashboard', compact( @@ -65,6 +65,56 @@ public function dashboard() )); } + public function dashboardApi() + { + // Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit + $this->autoBatalkanAntrianLama(); + + // Get counts for each poli + $poliUmumCount = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'umum'); + })->where('status', 'menunggu')->count(); + + $poliGigiCount = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'gigi'); + })->where('status', 'menunggu')->count(); + + $poliJiwaCount = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan jiwa'); + })->where('status', 'menunggu')->count(); + + $poliTradisionalCount = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan tradisional'); + })->where('status', 'menunggu')->count(); + + // Get recent antrian + $antrianTerbaru = Antrian::with(['user', 'poli']) + ->orderBy('created_at', 'desc') + ->limit(3) + ->get(); + + return response()->json([ + 'success' => true, + 'data' => [ + 'poliUmumCount' => $poliUmumCount, + 'poliGigiCount' => $poliGigiCount, + 'poliJiwaCount' => $poliJiwaCount, + 'poliTradisionalCount' => $poliTradisionalCount, + 'antrianTerbaru' => $antrianTerbaru->map(function ($antrian) { + return [ + 'id' => $antrian->id, + 'no_antrian' => $antrian->no_antrian, + 'status' => $antrian->status, + 'poli_name' => $antrian->poli->nama_poli, + 'user_name' => $antrian->user->nama, + 'created_at' => $antrian->created_at->diffForHumans(), + 'updated_at' => $antrian->updated_at->diffForHumans(), + ]; + }) + ] + ]); + } + public function manageUsers(Request $request) { // Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit @@ -91,10 +141,39 @@ public function manageUsers(Request $request) public function showUser(User $user) { - $user->load(['antrians.poli']); + // Load user with antrians ordered by created_at desc to get the latest first + $user->load([ + 'antrians' => function ($query) { + $query->with('poli')->orderBy('created_at', 'desc'); + } + ]); + return view('admin.users.show', compact('user')); } + public function getUserAntrianTerbaru(User $user) + { + // Get latest 5 antrians for the user + $antrians = $user->antrians() + ->with('poli') + ->orderBy('created_at', 'desc') + ->take(5) + ->get(); + + return response()->json([ + 'success' => true, + 'antrians' => $antrians->map(function ($antrian) { + return [ + 'id' => $antrian->id, + 'no_antrian' => $antrian->no_antrian, + 'poli_name' => $antrian->poli->nama_poli ?? 'N/A', + 'status' => $antrian->status, + 'created_at' => $antrian->created_at ? $antrian->created_at->format('d/m/Y H:i') : 'N/A' + ]; + }) + ]); + } + public function createUser() { return view('admin.users.create'); @@ -213,7 +292,12 @@ public function laporan(Request $request) // Filter berdasarkan status if ($request->filled('status')) { - $query->where('status', $request->status); + $status = $request->status; + // Convert 'sedang' to 'sedang_diperiksa' for database compatibility + if ($status === 'sedang') { + $status = 'sedang_diperiksa'; + } + $query->where('status', $status); } // Filter berdasarkan jenis kelamin @@ -223,17 +307,23 @@ public function laporan(Request $request) }); } - $antrian = $query->orderBy('created_at', 'desc')->get(); + // Clone query for statistics before pagination + $statisticQuery = clone $query; + $allData = $statisticQuery->get(); + + // Paginate the results + $antrian = $query->orderBy('created_at', 'desc')->paginate(10); $polis = Poli::all(); - // Statistik - $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(); + // Statistik dari semua data (tidak hanya yang dipaginate) + $totalAntrian = $allData->count(); + $antrianSelesai = $allData->where('status', 'selesai')->count(); + $antrianMenunggu = $allData->where('status', 'menunggu')->count(); + $antrianDipanggil = $allData->where('status', 'dipanggil')->count(); + $antrianSedang = $allData->where('status', 'sedang_diperiksa')->count(); + $antrianBatal = $allData->where('status', 'batal')->count(); - return view('admin.laporan.index', compact('antrian', 'polis', 'totalAntrian', 'antrianSelesai', 'antrianMenunggu', 'antrianDipanggil', 'antrianSedang')); + return view('admin.laporan.index', compact('antrian', 'polis', 'totalAntrian', 'antrianSelesai', 'antrianMenunggu', 'antrianDipanggil', 'antrianSedang', 'antrianBatal')); } public function exportPDF(Request $request) @@ -256,7 +346,11 @@ public function exportPDF(Request $request) // Filter berdasarkan status if ($request->filled('status')) { - $query->where('status', $request->status); + $status = $request->status; + if ($status === 'sedang') { + $status = 'sedang_diperiksa'; + } + $query->where('status', $status); } // Filter berdasarkan jenis kelamin @@ -273,7 +367,7 @@ public function exportPDF(Request $request) $antrianSelesai = $antrian->where('status', 'selesai')->count(); $antrianMenunggu = $antrian->where('status', 'menunggu')->count(); $antrianDipanggil = $antrian->where('status', 'dipanggil')->count(); - $antrianSedang = $antrian->where('status', 'sedang')->count(); + $antrianSedang = $antrian->where('status', 'sedang_diperiksa')->count(); $pdf = Pdf::loadView('admin.laporan.pdf', compact('antrian', 'totalAntrian', 'antrianSelesai', 'antrianMenunggu', 'antrianDipanggil', 'antrianSedang')); return $pdf->download('laporan-antrian-' . date('Y-m-d') . '.pdf'); @@ -299,7 +393,11 @@ public function exportExcel(Request $request) // Filter berdasarkan status if ($request->filled('status')) { - $query->where('status', $request->status); + $status = $request->status; + if ($status === 'sedang') { + $status = 'sedang_diperiksa'; + } + $query->where('status', $status); } // Filter berdasarkan jenis kelamin @@ -316,7 +414,7 @@ public function exportExcel(Request $request) $antrianSelesai = $antrian->where('status', 'selesai')->count(); $antrianMenunggu = $antrian->where('status', 'menunggu')->count(); $antrianDipanggil = $antrian->where('status', 'dipanggil')->count(); - $antrianSedang = $antrian->where('status', 'sedang')->count(); + $antrianSedang = $antrian->where('status', 'sedang_diperiksa')->count(); $filename = 'laporan-antrian-' . date('Y-m-d') . '.csv'; @@ -339,21 +437,21 @@ public function exportExcel(Request $request) 'Tanggal Daftar', 'Waktu Daftar', 'Waktu Panggil' - ]); + ], ';'); // Data CSV foreach ($antrian as $item) { fputcsv($file, [ $item->no_antrian, $item->user->nama, - $item->user->no_ktp, + "'" . $item->user->no_ktp, $item->user->jenis_kelamin, $item->poli->nama_poli, ucfirst($item->status), $item->created_at ? $item->created_at->format('d/m/Y') : '-', $item->created_at ? $item->created_at->format('H:i') : '-', $item->waktu_panggil ? $item->waktu_panggil->format('H:i') : '-' - ]); + ], ';'); } fclose($file); @@ -362,7 +460,7 @@ public function exportExcel(Request $request) return response()->stream($callback, 200, $headers); } - public function poliUmum() + public function poliUmum(Request $request) { // Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit $this->autoBatalkanAntrianLama(); @@ -372,13 +470,13 @@ public function poliUmum() $query->where('nama_poli', 'umum'); }) ->orderBy('created_at', 'asc') - ->get(); + ->paginate(10); $title = 'Poli Umum'; return view('admin.poli.index', compact('antrians', 'title')); } - public function poliGigi() + public function poliGigi(Request $request) { // Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit $this->autoBatalkanAntrianLama(); @@ -388,13 +486,13 @@ public function poliGigi() $query->where('nama_poli', 'gigi'); }) ->orderBy('created_at', 'asc') - ->get(); + ->paginate(10); $title = 'Poli Gigi'; return view('admin.poli.index', compact('antrians', 'title')); } - public function poliJiwa() + public function poliJiwa(Request $request) { // Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit $this->autoBatalkanAntrianLama(); @@ -404,13 +502,13 @@ public function poliJiwa() $query->where('nama_poli', 'kesehatan jiwa'); }) ->orderBy('created_at', 'asc') - ->get(); + ->paginate(10); $title = 'Poli Jiwa'; return view('admin.poli.index', compact('antrians', 'title')); } - public function poliTradisional() + public function poliTradisional(Request $request) { // Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit $this->autoBatalkanAntrianLama(); @@ -420,7 +518,7 @@ public function poliTradisional() $query->where('nama_poli', 'kesehatan tradisional'); }) ->orderBy('created_at', 'asc') - ->get(); + ->paginate(10); $title = 'Poli Tradisional'; return view('admin.poli.index', compact('antrians', 'title')); @@ -513,10 +611,10 @@ public function selesaiAntrian(Request $request) $antrian = Antrian::findOrFail($request->antrian_id); - if ($antrian->status !== 'dipanggil') { + if (!in_array($antrian->status, ['dipanggil', 'sedang_diperiksa'])) { return response()->json([ 'success' => false, - 'message' => 'Antrian ini tidak dalam status dipanggil' + 'message' => 'Antrian ini tidak dalam status dipanggil atau sedang diperiksa' ]); } @@ -535,6 +633,71 @@ public function selesaiAntrian(Request $request) } } + public function konfirmasiKehadiran(Request $request) + { + try { + $request->validate([ + 'antrian_id' => 'required|exists:antrians,id' + ]); + + $antrian = Antrian::findOrFail($request->antrian_id); + + if ($antrian->status !== 'dipanggil') { + return response()->json([ + 'success' => false, + 'message' => 'Antrian ini tidak dalam status dipanggil' + ]); + } + + // Update waktu hadir + $antrian->update(['waktu_hadir' => now()]); + + return response()->json([ + 'success' => true, + 'message' => 'Kehadiran pasien ' . $antrian->no_antrian . ' telah dikonfirmasi' + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } + + public function mulaiPemeriksaan(Request $request) + { + try { + $request->validate([ + 'antrian_id' => 'required|exists:antrians,id' + ]); + + $antrian = Antrian::findOrFail($request->antrian_id); + + if ($antrian->status !== 'dipanggil' || !$antrian->waktu_hadir) { + return response()->json([ + 'success' => false, + 'message' => 'Pasien harus dikonfirmasi hadir terlebih dahulu' + ]); + } + + // Update status dan waktu mulai pemeriksaan + $antrian->update([ + 'status' => 'sedang_diperiksa', + 'waktu_mulai_periksa' => now() + ]); + + return response()->json([ + 'success' => true, + 'message' => 'Pemeriksaan pasien ' . $antrian->no_antrian . ' dimulai' + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } + public function batalAntrian(Request $request) { try { @@ -607,13 +770,30 @@ public function storeAntrianAdmin(Request $request) $existingQueue = Antrian::where('user_id', $request->user_id) ->where('poli_id', $request->poli_id) ->whereDate('created_at', today()) - ->whereIn('status', ['menunggu', 'dipanggil']) + ->whereIn('status', ['menunggu', 'dipanggil', 'sedang_diperiksa']) ->first(); if ($existingQueue) { + $statusMessage = ''; + switch ($existingQueue->status) { + case 'menunggu': + $statusMessage = 'User ini masih memiliki antrian yang menunggu di ' . $poli->nama_poli . '.'; + break; + case 'dipanggil': + $statusMessage = 'User ini memiliki antrian yang sudah dipanggil di ' . $poli->nama_poli . '.'; + break; + case 'sedang_diperiksa': + $statusMessage = 'User ini sedang dalam proses pemeriksaan di ' . $poli->nama_poli . '. Tidak dapat membuat antrian baru.'; + break; + } + return response()->json([ 'success' => false, - 'message' => 'User ini sudah memiliki antrian aktif di ' . $poli->nama_poli . ' hari ini.' + 'message' => $statusMessage, + 'existing_queue' => [ + 'no_antrian' => $existingQueue->no_antrian, + 'status' => $existingQueue->status + ] ]); } @@ -681,14 +861,15 @@ private function getPoliPrefix($namaPoli) /** * Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit - * tanpa dikonfirmasi selesai oleh admin + * tetapi belum dikonfirmasi kehadirannya (belum ada waktu_hadir) */ private function autoBatalkanAntrianLama() { try { - // Cari antrian yang sudah dipanggil lebih dari 5 menit + // Cari antrian yang sudah dipanggil lebih dari 5 menit tapi belum konfirmasi hadir $antrianLama = Antrian::where('status', 'dipanggil') ->where('waktu_panggil', '<=', now()->subMinutes(5)) + ->whereNull('waktu_hadir') // Hanya yang belum konfirmasi hadir ->get(); $count = 0; @@ -698,16 +879,16 @@ private function autoBatalkanAntrianLama() $count++; // Log untuk tracking - \Log::info("Antrian {$antrian->no_antrian} otomatis dibatalkan karena lewat 5 menit sejak dipanggil"); + Log::info("Antrian {$antrian->no_antrian} otomatis dibatalkan karena lewat 5 menit sejak dipanggil tanpa konfirmasi kehadiran"); } // Jika ada antrian yang dibatalkan, log jumlahnya if ($count > 0) { - \Log::info("Total {$count} antrian otomatis dibatalkan karena timeout"); + Log::info("Total {$count} antrian otomatis dibatalkan karena timeout tanpa konfirmasi kehadiran"); } } catch (\Exception $e) { // Log error jika terjadi masalah - \Log::error("Error saat auto-batalkan antrian: " . $e->getMessage()); + Log::error("Error saat auto-batalkan antrian: " . $e->getMessage()); } } @@ -737,7 +918,7 @@ public function playQueueCallAudio(Request $request) ]); $poliName = $request->input('poli_name'); - + // Get audio sequence from AudioService $audioService = app(AudioService::class); $result = $audioService->getQueueCallAudio($poliName); @@ -765,9 +946,9 @@ public function panggilSelanjutnya(Request $request) $poliName = $request->input('poli_name'); // Cari antrian berikutnya yang status 'menunggu' - $antrianSelanjutnya = Antrian::whereHas('poli', function($query) use ($poliName) { - $query->where('nama_poli', $poliName); - }) + $antrianSelanjutnya = Antrian::whereHas('poli', function ($query) use ($poliName) { + $query->where('nama_poli', $poliName); + }) ->where('status', 'menunggu') ->whereDate('created_at', today()) ->orderBy('created_at', 'asc') @@ -790,7 +971,7 @@ public function panggilSelanjutnya(Request $request) \App\Models\RiwayatPanggilan::create([ 'antrian_id' => $antrianSelanjutnya->id, 'waktu_panggilan' => now(), - 'admin_id' => auth()->id() + 'admin_id' => Auth::id() ]); // Get audio sequence diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index a2725af..83049d8 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -43,20 +43,34 @@ public function addQueue(Request $request) $poli = Poli::find($request->poli_id); $poliName = $poli->nama_poli; - // Check if user already has a queue today for the same poli + // Check if user already has an active queue today for the same poli $existingQueue = Antrian::where('user_id', $user->id) ->where('poli_id', $request->poli_id) ->whereDate('created_at', today()) - ->whereIn('status', ['menunggu', 'dipanggil']) + ->whereIn('status', ['menunggu', 'dipanggil', 'sedang_diperiksa']) ->first(); if ($existingQueue) { + // Determine the appropriate message based on status + $statusMessage = ''; + switch ($existingQueue->status) { + case 'menunggu': + $statusMessage = 'Anda masih memiliki antrian yang menunggu di ' . $poliName . '.'; + break; + case 'dipanggil': + $statusMessage = 'Anda memiliki antrian yang sudah dipanggil di ' . $poliName . '. Silakan datang ke poli.'; + break; + case 'sedang_diperiksa': + $statusMessage = 'Anda sedang dalam proses pemeriksaan di ' . $poliName . '. Tidak dapat mengambil antrian baru di poli yang sama.'; + break; + } + // Check if request wants JSON response if ($request->expectsJson()) { return response()->json([ 'success' => false, 'type' => 'existing_queue', - 'message' => 'Anda sudah memiliki antrian di ' . $poliName . ' hari ini.', + 'message' => $statusMessage, 'existing_queue' => [ 'id' => $existingQueue->id, 'no_antrian' => $existingQueue->no_antrian, @@ -68,7 +82,7 @@ public function addQueue(Request $request) } // Fallback to redirect for non-AJAX requests - return redirect()->back()->with('error', 'Anda sudah memiliki antrian di ' . $poliName . ' hari ini.'); + return redirect()->back()->with('error', $statusMessage); } // Note: User CAN have multiple queues in different polis @@ -91,14 +105,14 @@ public function addQueue(Request $request) $lastNumber = (int) preg_replace('/^[A-Z]+/', '', $lastQueue->no_antrian); // Debug log - \Log::info("Last queue: {$lastQueue->no_antrian}, Extracted number: {$lastNumber}"); + Log::info("Last queue: {$lastQueue->no_antrian}, Extracted number: {$lastNumber}"); } $nextNumber = $lastNumber + 1; $nextQueueNumber = $prefix . $nextNumber; // Debug log - \Log::info("Generated next queue number: {$nextQueueNumber} for poli: {$poliName}"); + Log::info("Generated next queue number: {$nextQueueNumber} for poli: {$poliName}"); // Create new queue using current user's data $antrian = Antrian::create([ @@ -152,6 +166,7 @@ public function updateProfile(Request $request) ]); try { + /** @var \App\Models\User $user */ $user = Auth::user(); // Check if KTP number is already used by another user @@ -205,14 +220,15 @@ private function getPoliPrefix($namaPoli) /** * Auto-batalkan antrian yang sudah dipanggil lebih dari 5 menit - * tanpa dikonfirmasi selesai oleh admin + * tetapi belum dikonfirmasi kehadirannya (belum ada waktu_hadir) */ private function autoBatalkanAntrianLama() { try { - // Cari antrian yang sudah dipanggil lebih dari 5 menit + // Cari antrian yang sudah dipanggil lebih dari 5 menit tapi belum konfirmasi hadir $antrianLama = Antrian::where('status', 'dipanggil') ->where('waktu_panggil', '<=', now()->subMinutes(5)) + ->whereNull('waktu_hadir') // Hanya yang belum konfirmasi hadir ->get(); foreach ($antrianLama as $antrian) { @@ -220,16 +236,61 @@ private function autoBatalkanAntrianLama() $antrian->update(['status' => 'batal']); // Log untuk tracking (optional) - \Log::info("Antrian {$antrian->no_antrian} otomatis dibatalkan karena lewat 5 menit sejak dipanggil"); + Log::info("Antrian {$antrian->no_antrian} otomatis dibatalkan karena lewat 5 menit sejak dipanggil tanpa konfirmasi kehadiran"); } // Jika ada antrian yang dibatalkan, log jumlahnya if ($antrianLama->count() > 0) { - \Log::info("Total {$antrianLama->count()} antrian otomatis dibatalkan karena timeout"); + Log::info("Total {$antrianLama->count()} antrian otomatis dibatalkan karena timeout tanpa konfirmasi kehadiran"); } } catch (\Exception $e) { // Log error jika terjadi masalah - \Log::error("Error saat auto-batalkan antrian: " . $e->getMessage()); + Log::error("Error saat auto-batalkan antrian: " . $e->getMessage()); + } + } + + /** + * Check if user has active queue in specific poli today + * @param int $userId + * @param int $poliId + * @return array|null + */ + private function checkActiveQueue($userId, $poliId) + { + $activeQueue = Antrian::where('user_id', $userId) + ->where('poli_id', $poliId) + ->whereDate('created_at', today()) + ->whereIn('status', ['menunggu', 'dipanggil', 'sedang_diperiksa']) + ->first(); + + if ($activeQueue) { + return [ + 'exists' => true, + 'queue' => $activeQueue, + 'message' => $this->getStatusMessage($activeQueue->status, $activeQueue->poli->nama_poli) + ]; + } + + return ['exists' => false]; + } + + /** + * Get appropriate message based on queue status + * @param string $status + * @param string $poliName + * @return string + */ + private function getStatusMessage($status, $poliName) + { + switch ($status) { + case 'menunggu': + return "Anda masih memiliki antrian yang menunggu di {$poliName}."; + case 'dipanggil': + return "Anda memiliki antrian yang sudah dipanggil di {$poliName}. Silakan datang ke poli."; + case 'sedang_diperiksa': + return "Anda sedang dalam proses pemeriksaan di {$poliName}. Tidak dapat mengambil antrian baru di poli yang sama."; + default: + return "Anda sudah memiliki antrian aktif di {$poliName}."; } } diff --git a/app/Http/Controllers/DisplayController.php b/app/Http/Controllers/DisplayController.php index 170ed08..61a3452 100644 --- a/app/Http/Controllers/DisplayController.php +++ b/app/Http/Controllers/DisplayController.php @@ -12,71 +12,71 @@ public function index() { // Get all available polis $polis = Poli::all(); - + // Current: sedang dipanggil per poli - $poliUmumCurrent = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'umum'); - }) - ->where('status', 'dipanggil') + $poliUmumCurrent = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'umum'); + }) + ->whereIn('status', ['dipanggil', 'sedang_diperiksa']) ->whereDate('created_at', today()) ->orderByDesc('updated_at') ->first(); - $poliGigiCurrent = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'gigi'); - }) - ->where('status', 'dipanggil') + $poliGigiCurrent = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'gigi'); + }) + ->whereIn('status', ['dipanggil', 'sedang_diperiksa']) ->whereDate('created_at', today()) ->orderByDesc('updated_at') ->first(); - $poliJiwaCurrent = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'kesehatan jiwa'); - }) - ->where('status', 'dipanggil') + $poliJiwaCurrent = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan jiwa'); + }) + ->whereIn('status', ['dipanggil', 'sedang_diperiksa']) ->whereDate('created_at', today()) ->orderByDesc('updated_at') ->first(); - $poliTradisionalCurrent = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'kesehatan tradisional'); - }) - ->where('status', 'dipanggil') + $poliTradisionalCurrent = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan tradisional'); + }) + ->whereIn('status', ['dipanggil', 'sedang_diperiksa']) ->whereDate('created_at', today()) ->orderByDesc('updated_at') ->first(); // Next: menunggu per poli (maks 3) - $poliUmumNext = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'umum'); - }) + $poliUmumNext = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'umum'); + }) ->where('status', 'menunggu') ->whereDate('created_at', today()) ->orderBy('created_at', 'asc') ->take(3) ->get(); - $poliGigiNext = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'gigi'); - }) + $poliGigiNext = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'gigi'); + }) ->where('status', 'menunggu') ->whereDate('created_at', today()) ->orderBy('created_at', 'asc') ->take(3) ->get(); - $poliJiwaNext = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'kesehatan jiwa'); - }) + $poliJiwaNext = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan jiwa'); + }) ->where('status', 'menunggu') ->whereDate('created_at', today()) ->orderBy('created_at', 'asc') ->take(3) ->get(); - $poliTradisionalNext = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'kesehatan tradisional'); - }) + $poliTradisionalNext = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan tradisional'); + }) ->where('status', 'menunggu') ->whereDate('created_at', today()) ->orderBy('created_at', 'asc') @@ -126,57 +126,57 @@ public function checkNewCalls(Request $request) public function getDisplayData() { // Current: sedang dipanggil per poli - $poliUmumCurrent = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'umum'); - }) - ->where('status', 'dipanggil') + $poliUmumCurrent = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'umum'); + }) + ->whereIn('status', ['dipanggil', 'sedang_diperiksa']) ->whereDate('created_at', today()) ->orderByDesc('updated_at') ->first(); - $poliGigiCurrent = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'gigi'); - }) - ->where('status', 'dipanggil') + $poliGigiCurrent = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'gigi'); + }) + ->whereIn('status', ['dipanggil', 'sedang_diperiksa']) ->whereDate('created_at', today()) ->orderByDesc('updated_at') ->first(); - $poliJiwaCurrent = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'kesehatan jiwa'); - }) - ->where('status', 'dipanggil') + $poliJiwaCurrent = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan jiwa'); + }) + ->whereIn('status', ['dipanggil', 'sedang_diperiksa']) ->whereDate('created_at', today()) ->orderByDesc('updated_at') ->first(); $poliTradisionalCurrent = Antrian::where('poli_id', 4) - ->where('status', 'dipanggil') + ->whereIn('status', ['dipanggil', 'sedang_diperiksa']) ->whereDate('created_at', today()) ->orderByDesc('updated_at') ->first(); // Next: menunggu per poli (maks 3) - $poliUmumNext = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'umum'); - }) + $poliUmumNext = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'umum'); + }) ->where('status', 'menunggu') ->whereDate('created_at', today()) ->orderBy('created_at', 'asc') ->take(3) ->get(); - $poliGigiNext = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'gigi'); - }) + $poliGigiNext = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'gigi'); + }) ->where('status', 'menunggu') ->whereDate('created_at', today()) ->orderBy('created_at', 'asc') ->get(); - $poliJiwaNext = Antrian::whereHas('poli', function($query) { - $query->where('nama_poli', 'kesehatan jiwa'); - }) + $poliJiwaNext = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan jiwa'); + }) ->where('status', 'menunggu') ->whereDate('created_at', today()) ->orderBy('created_at', 'asc') diff --git a/app/Models/Antrian.php b/app/Models/Antrian.php index 3861e7f..d8da537 100644 --- a/app/Models/Antrian.php +++ b/app/Models/Antrian.php @@ -18,12 +18,15 @@ class Antrian extends Model 'is_call', 'status', 'waktu_panggil', - 'loket_id' + 'waktu_hadir', + 'waktu_mulai_periksa' ]; protected $casts = [ 'tanggal_antrian' => 'date', 'waktu_panggil' => 'datetime', + 'waktu_hadir' => 'datetime', + 'waktu_mulai_periksa' => 'datetime', 'is_call' => 'boolean', ]; @@ -37,11 +40,6 @@ public function poli() return $this->belongsTo(Poli::class); } - public function loket() - { - return $this->belongsTo(Loket::class); - } - public function riwayatPanggilan() { return $this->hasMany(RiwayatPanggilan::class); diff --git a/app/Models/Loket.php b/app/Models/Loket.php deleted file mode 100644 index 4a5733c..0000000 --- a/app/Models/Loket.php +++ /dev/null @@ -1,19 +0,0 @@ -hasMany(Antrian::class); - } -} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index cdf5020..246b608 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -19,7 +19,8 @@ public function register(): void */ public function boot(): void { - // Set pagination to use Tailwind CSS styling - \Illuminate\Pagination\Paginator::useTailwind(); + // Set pagination to use custom view + \Illuminate\Pagination\Paginator::defaultView('custom.pagination'); + \Illuminate\Pagination\Paginator::defaultSimpleView('custom.pagination-simple'); } } diff --git a/composer.json b/composer.json index 281564c..0c1c1b0 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,6 @@ "php": "^8.2", "barryvdh/laravel-dompdf": "^3.1", "laravel/framework": "^12.0", - "laravel/sanctum": "^4.2", "laravel/tinker": "^2.10.1", "pusher/pusher-php-server": "^7.2" }, diff --git a/composer.lock b/composer.lock index 6a7614e..5a8dce3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6a7319662ab12a24a54850a3e8a7b468", + "content-hash": "74ecb2b28b89ed06697fc02c059657d8", "packages": [ { "name": "barryvdh/laravel-dompdf", @@ -1559,70 +1559,6 @@ }, "time": "2025-07-07T14:17:42+00:00" }, - { - "name": "laravel/sanctum", - "version": "v4.2.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/sanctum.git", - "reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/sanctum/zipball/fd6df4f79f48a72992e8d29a9c0ee25422a0d677", - "reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677", - "shasum": "" - }, - "require": { - "ext-json": "*", - "illuminate/console": "^11.0|^12.0", - "illuminate/contracts": "^11.0|^12.0", - "illuminate/database": "^11.0|^12.0", - "illuminate/support": "^11.0|^12.0", - "php": "^8.2", - "symfony/console": "^7.0" - }, - "require-dev": { - "mockery/mockery": "^1.6", - "orchestra/testbench": "^9.0|^10.0", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^11.3" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Sanctum\\SanctumServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Laravel\\Sanctum\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", - "keywords": [ - "auth", - "laravel", - "sanctum" - ], - "support": { - "issues": "https://github.com/laravel/sanctum/issues", - "source": "https://github.com/laravel/sanctum" - }, - "time": "2025-07-09T19:45:24+00:00" - }, { "name": "laravel/serializable-closure", "version": "v2.0.4", @@ -8747,12 +8683,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.2" }, - "platform-dev": {}, + "platform-dev": [], "plugin-api-version": "2.6.0" } diff --git a/config/auth.php b/config/auth.php index fc8b76c..c9138a1 100644 --- a/config/auth.php +++ b/config/auth.php @@ -93,14 +93,25 @@ | */ - 'passwords' => [ - 'users' => [ - 'provider' => 'users', - 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), - 'expire' => 60, - 'throttle' => 60, - ], - ], + /* + |-------------------------------------------------------------------------- + | Password Reset Settings (DISABLED) + |-------------------------------------------------------------------------- + | + | Password reset settings are disabled because this application uses + | session-based password reset instead of Laravel's built-in token-based + | password reset functionality. + | + */ + + // 'passwords' => [ + // 'users' => [ + // 'provider' => 'users', + // 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), + // 'expire' => 60, + // 'throttle' => 60, + // ], + // ], /* |-------------------------------------------------------------------------- diff --git a/config/sanctum.php b/config/sanctum.php deleted file mode 100644 index 44527d6..0000000 --- a/config/sanctum.php +++ /dev/null @@ -1,84 +0,0 @@ - explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( - '%s%s', - 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', - Sanctum::currentApplicationUrlWithPort(), - // Sanctum::currentRequestHost(), - ))), - - /* - |-------------------------------------------------------------------------- - | Sanctum Guards - |-------------------------------------------------------------------------- - | - | This array contains the authentication guards that will be checked when - | Sanctum is trying to authenticate a request. If none of these guards - | are able to authenticate the request, Sanctum will use the bearer - | token that's present on an incoming request for authentication. - | - */ - - 'guard' => ['web'], - - /* - |-------------------------------------------------------------------------- - | Expiration Minutes - |-------------------------------------------------------------------------- - | - | This value controls the number of minutes until an issued token will be - | considered expired. This will override any values set in the token's - | "expires_at" attribute, but first-party sessions are not affected. - | - */ - - 'expiration' => null, - - /* - |-------------------------------------------------------------------------- - | Token Prefix - |-------------------------------------------------------------------------- - | - | Sanctum can prefix new tokens in order to take advantage of numerous - | security scanning initiatives maintained by open source platforms - | that notify developers if they commit tokens into repositories. - | - | See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning - | - */ - - 'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''), - - /* - |-------------------------------------------------------------------------- - | Sanctum Middleware - |-------------------------------------------------------------------------- - | - | When authenticating your first-party SPA with Sanctum you may need to - | customize some of the middleware Sanctum uses while processing the - | request. You may change the middleware listed below as required. - | - */ - - 'middleware' => [ - 'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class, - 'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class, - 'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, - ], - -]; diff --git a/database/migrations/2024_01_01_000003_create_lokets_table.php b/database/migrations/2024_01_01_000003_create_lokets_table.php deleted file mode 100644 index 29da2f8..0000000 --- a/database/migrations/2024_01_01_000003_create_lokets_table.php +++ /dev/null @@ -1,27 +0,0 @@ -id(); - $table->string('nama_loket', 100); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('lokets'); - } -}; diff --git a/database/migrations/2025_08_08_092603_create_personal_access_tokens_table.php b/database/migrations/2025_08_08_092603_create_personal_access_tokens_table.php deleted file mode 100644 index 4279a2e..0000000 --- a/database/migrations/2025_08_08_092603_create_personal_access_tokens_table.php +++ /dev/null @@ -1,32 +0,0 @@ -id(); - $table->morphs('tokenable'); - $table->text('name'); - $table->string('token', 64)->unique(); - $table->text('abilities')->nullable(); - $table->timestamp('last_used_at')->nullable(); - $table->timestamp('expires_at')->nullable()->index(); - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('personal_access_tokens'); - } -}; diff --git a/database/migrations/2025_08_10_160027_create_jobs_table.php b/database/migrations/2025_08_10_160027_create_jobs_table.php deleted file mode 100644 index 6098d9b..0000000 --- a/database/migrations/2025_08_10_160027_create_jobs_table.php +++ /dev/null @@ -1,32 +0,0 @@ -bigIncrements('id'); - $table->string('queue')->index(); - $table->longText('payload'); - $table->unsignedTinyInteger('attempts'); - $table->unsignedInteger('reserved_at')->nullable(); - $table->unsignedInteger('available_at'); - $table->unsignedInteger('created_at'); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('jobs'); - } -}; diff --git a/database/migrations/2025_08_14_004750_add_sedang_diperiksa_status_to_antrians_table.php b/database/migrations/2025_08_14_004750_add_sedang_diperiksa_status_to_antrians_table.php new file mode 100644 index 0000000..30b4039 --- /dev/null +++ b/database/migrations/2025_08_14_004750_add_sedang_diperiksa_status_to_antrians_table.php @@ -0,0 +1,42 @@ +enum('status', ['menunggu', 'dipanggil', 'sedang_diperiksa', 'selesai', 'batal']) + ->default('menunggu') + ->change(); + + // Tambah field waktu konfirmasi kehadiran + $table->timestamp('waktu_hadir')->nullable()->after('waktu_panggil'); + + // Tambah field waktu mulai pemeriksaan + $table->timestamp('waktu_mulai_periksa')->nullable()->after('waktu_hadir'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('antrians', function (Blueprint $table) { + // Kembalikan enum status ke yang lama + $table->enum('status', ['menunggu', 'dipanggil', 'selesai', 'batal']) + ->default('menunggu') + ->change(); + + // Hapus field yang ditambahkan + $table->dropColumn(['waktu_hadir', 'waktu_mulai_periksa']); + }); + } +}; diff --git a/database/migrations/2025_08_14_014038_cleanup_unused_database_tables.php b/database/migrations/2025_08_14_014038_cleanup_unused_database_tables.php new file mode 100644 index 0000000..2c9cd8c --- /dev/null +++ b/database/migrations/2025_08_14_014038_cleanup_unused_database_tables.php @@ -0,0 +1,92 @@ +dropForeign(['loket_id']); + $table->dropColumn('loket_id'); + }); + + // 2. Drop unused tables + Schema::dropIfExists('lokets'); + Schema::dropIfExists('personal_access_tokens'); + Schema::dropIfExists('jobs'); + + // 3. Drop failed_jobs table if exists (related to jobs) + Schema::dropIfExists('failed_jobs'); + Schema::dropIfExists('job_batches'); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // Recreate jobs related tables + Schema::create('jobs', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->string('queue')->index(); + $table->longText('payload'); + $table->unsignedTinyInteger('attempts'); + $table->unsignedInteger('reserved_at')->nullable(); + $table->unsignedInteger('available_at'); + $table->unsignedInteger('created_at'); + }); + + Schema::create('failed_jobs', function (Blueprint $table) { + $table->id(); + $table->string('uuid')->unique(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + + Schema::create('job_batches', function (Blueprint $table) { + $table->string('id')->primary(); + $table->string('name'); + $table->integer('total_jobs'); + $table->integer('pending_jobs'); + $table->integer('failed_jobs'); + $table->longText('failed_job_ids'); + $table->mediumText('options')->nullable(); + $table->integer('cancelled_at')->nullable(); + $table->integer('created_at'); + $table->integer('finished_at')->nullable(); + }); + + // Recreate personal_access_tokens table + Schema::create('personal_access_tokens', function (Blueprint $table) { + $table->id(); + $table->morphs('tokenable'); + $table->text('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamp('expires_at')->nullable()->index(); + $table->timestamps(); + }); + + // Recreate lokets table + Schema::create('lokets', function (Blueprint $table) { + $table->id(); + $table->string('nama_loket', 100); + $table->timestamps(); + }); + + // Add back loket_id to antrians table + Schema::table('antrians', function (Blueprint $table) { + $table->foreignId('loket_id')->nullable()->constrained('lokets')->onDelete('set null'); + }); + } +}; diff --git a/database/migrations/2025_08_14_015356_drop_password_reset_tokens_table.php b/database/migrations/2025_08_14_015356_drop_password_reset_tokens_table.php new file mode 100644 index 0000000..d7ab0cb --- /dev/null +++ b/database/migrations/2025_08_14_015356_drop_password_reset_tokens_table.php @@ -0,0 +1,30 @@ +string('email')->primary(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + } +}; diff --git a/database/seeders/AntrianPuskesmasSeeder.php b/database/seeders/AntrianPuskesmasSeeder.php index 42407ab..6c60d9a 100644 --- a/database/seeders/AntrianPuskesmasSeeder.php +++ b/database/seeders/AntrianPuskesmasSeeder.php @@ -30,18 +30,6 @@ public function run(): void ); } - // Seed lokets table with upsert - $lokets = [ - ['id' => 1, 'nama_loket' => 'Loket 1'], - ['id' => 2, 'nama_loket' => 'Loket 2'], - ]; - foreach ($lokets as $loket) { - DB::table('lokets')->updateOrInsert( - ['id' => $loket['id']], - ['nama_loket' => $loket['nama_loket'], 'updated_at' => now()] - ); - } - // Seed users table with upsert DB::table('users')->updateOrInsert( ['id' => 1], @@ -57,7 +45,7 @@ public function run(): void ] ); - // Seed antrians table with upsert + // Seed antrians table with upsert (removed loket_id reference) DB::table('antrians')->updateOrInsert( ['id' => 1], [ @@ -68,12 +56,13 @@ public function run(): void 'is_call' => 0, 'status' => 'menunggu', 'waktu_panggil' => null, - 'loket_id' => 1, + 'waktu_hadir' => null, + 'waktu_mulai_periksa' => null, 'updated_at' => now(), ] ); - // Add more antrian data for testing + // Add more antrian data for testing - Poli Gigi DB::table('antrians')->updateOrInsert( ['id' => 2], [ @@ -84,11 +73,13 @@ public function run(): void 'is_call' => 0, 'status' => 'menunggu', 'waktu_panggil' => null, - 'loket_id' => 1, + 'waktu_hadir' => null, + 'waktu_mulai_periksa' => null, 'updated_at' => now(), ] ); + // Poli Jiwa - Status dipanggil untuk testing DB::table('antrians')->updateOrInsert( ['id' => 3], [ @@ -96,14 +87,16 @@ public function run(): void 'poli_id' => 3, 'no_antrian' => 'J1', 'tanggal_antrian' => now()->toDateString(), - 'is_call' => 0, + 'is_call' => 1, 'status' => 'dipanggil', 'waktu_panggil' => now(), - 'loket_id' => 1, + 'waktu_hadir' => null, + 'waktu_mulai_periksa' => null, 'updated_at' => now(), ] ); + // Poli Tradisional - Status sedang diperiksa untuk testing DB::table('antrians')->updateOrInsert( ['id' => 4], [ @@ -111,10 +104,79 @@ public function run(): void 'poli_id' => 4, 'no_antrian' => 'T1', 'tanggal_antrian' => now()->toDateString(), + 'is_call' => 1, + 'status' => 'sedang_diperiksa', + 'waktu_panggil' => now()->subMinutes(10), + 'waktu_hadir' => now()->subMinutes(8), + 'waktu_mulai_periksa' => now()->subMinutes(5), + 'updated_at' => now(), + ] + ); + + // Tambah satu lagi data sedang diperiksa untuk testing filter + DB::table('antrians')->updateOrInsert( + ['id' => 5], + [ + 'user_id' => 1, + 'poli_id' => 1, + 'no_antrian' => 'U2', + 'tanggal_antrian' => now()->toDateString(), + 'is_call' => 1, + 'status' => 'sedang_diperiksa', + 'waktu_panggil' => now()->subMinutes(15), + 'waktu_hadir' => now()->subMinutes(12), + 'waktu_mulai_periksa' => now()->subMinutes(8), + 'updated_at' => now(), + ] + ); + + // Tambah data dengan status batal untuk testing filter + DB::table('antrians')->updateOrInsert( + ['id' => 6], + [ + 'user_id' => 1, + 'poli_id' => 2, + 'no_antrian' => 'G2', + 'tanggal_antrian' => now()->toDateString(), 'is_call' => 0, - 'status' => 'menunggu', + 'status' => 'batal', 'waktu_panggil' => null, - 'loket_id' => 1, + 'waktu_hadir' => null, + 'waktu_mulai_periksa' => null, + 'updated_at' => now(), + ] + ); + + // Tambah satu lagi data batal untuk testing filter + DB::table('antrians')->updateOrInsert( + ['id' => 7], + [ + 'user_id' => 1, + 'poli_id' => 3, + 'no_antrian' => 'J2', + 'tanggal_antrian' => now()->toDateString(), + 'is_call' => 0, + 'status' => 'batal', + 'waktu_panggil' => null, + 'waktu_hadir' => null, + 'waktu_mulai_periksa' => null, + 'updated_at' => now(), + ] + ); + + // Tambah data dengan status selesai untuk testing filter + DB::table('antrians')->updateOrInsert( + ['id' => 8], + [ + 'user_id' => 1, + 'poli_id' => 4, + 'no_antrian' => 'T2', + 'tanggal_antrian' => now()->toDateString(), + 'is_call' => 1, + 'status' => 'selesai', + 'waktu_panggil' => now()->subMinutes(30), + 'waktu_hadir' => now()->subMinutes(25), + 'waktu_mulai_periksa' => now()->subMinutes(20), 'updated_at' => now(), ] ); diff --git a/database/seeders/LoketSeeder.php b/database/seeders/LoketSeeder.php deleted file mode 100644 index defc0fc..0000000 --- a/database/seeders/LoketSeeder.php +++ /dev/null @@ -1,22 +0,0 @@ - 'Loket 1'], - ['nama_loket' => 'Loket 2'], - ['nama_loket' => 'Loket 3'], - ]; - - foreach ($lokets as $loket) { - Loket::create($loket); - } - } -} diff --git a/resources/views/admin/antrian/tambah.blade.php b/resources/views/admin/antrian/tambah.blade.php index 28fad1c..d746191 100644 --- a/resources/views/admin/antrian/tambah.blade.php +++ b/resources/views/admin/antrian/tambah.blade.php @@ -1,143 +1,151 @@ @extends('layouts.app') @section('content') -
Bantu pasien yang tidak bisa antri online dengan membuat antrian manual
-Bantu pasien yang tidak bisa antri online dengan membuat antrian manual
+${data.message}
+No. Antrian: ${data.existing_queue.no_antrian}
+Status: ${statusText}
+⚠️ User tidak dapat mengambil antrian baru di poli yang sama selama masih dalam proses pemeriksaan.
' + : 'Silakan tunggu hingga antrian selesai atau dibatalkan terlebih dahulu.
' + } +Poli Umum
-{{ $poliUmumCount ?? 0 }}
-Antrian menunggu
-Poli Umum
+{{ $poliUmumCount ?? 0 }}
+Antrian menunggu
Poli Gigi
-{{ $poliGigiCount ?? 0 }}
-Antrian menunggu
-Poli Gigi
+{{ $poliGigiCount ?? 0 }}
+Antrian menunggu
Poli Jiwa
-{{ $poliJiwaCount ?? 0 }}
-Antrian menunggu
-Poli Jiwa
+{{ $poliJiwaCount ?? 0 }}
+Antrian menunggu
Poli Tradisional
-{{ $poliTradisionalCount ?? 0 }}
-Antrian menunggu
-Poli Tradisional
+{{ $poliTradisionalCount ?? 0 }}
+Antrian menunggu
Antrian baru ditambahkan
+{{ $antrian->poli->nama_poli }} - + {{ $antrian->created_at->diffForHumans() }}
+Antrian dipanggil
+{{ $antrian->poli->nama_poli }} - + {{ $antrian->updated_at->diffForHumans() }}
+Antrian selesai
+{{ $antrian->poli->nama_poli }} - + {{ $antrian->updated_at->diffForHumans() }}
+Sedang diperiksa
+{{ $antrian->poli->nama_poli }} - + {{ $antrian->updated_at->diffForHumans() }}
+Antrian dibatalkan
+{{ $antrian->poli->nama_poli }} - + {{ $antrian->updated_at->diffForHumans() }}
+Status tidak dikenal
+{{ $antrian->poli->nama_poli }} - + {{ $antrian->updated_at->diffForHumans() }}
+Belum ada aktivitas hari ini
+Antrian baru ditambahkan
-Poli Umum - 2 menit yang lalu
-Antrian selesai
-Poli Gigi - 5 menit yang lalu
-Antrian dipanggil
-Poli Jiwa - 8 menit yang lalu
-Batal
+{{ $antrianBatal }}
+Belum ada antrian
+User ini belum pernah mengambil antrian +
+Belum ada antrian
+User ini belum pernah mengambil antrian
+