MIF_E31222851/resources/views/admin/laporan/index.blade.php

558 lines
36 KiB
PHP

@extends('layouts.app')
@section('title', 'Laporan Antrian - Admin Dashboard')
@section('content')
<div class="min-h-screen bg-gray-50">
@include('admin.partials.top-nav')
<div class="flex">
@include('admin.partials.sidebar')
<!-- Main Content -->
<div class="flex-1 lg:ml-0">
<div class="px-4 sm:px-6 lg:px-8 py-6 md:py-8">
<!-- Header -->
<div class="mb-8 animate-fade-in">
<h1 class="text-3xl md:text-4xl font-bold text-gray-900 mb-2">Laporan Antrian</h1>
<p class="text-gray-600 text-lg">Kelola dan ekspor data antrian</p>
</div>
<!-- Export Buttons -->
<div class="flex flex-wrap gap-3 mb-8">
<a href="{{ route('admin.laporan.export-pdf', request()->query()) }}"
class="inline-flex items-center px-4 py-2 border border-red-300 rounded-md shadow-sm text-sm font-medium text-red-700 bg-white hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition duration-200">
<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd"
d="M6 2a2 2 0 00-2 2v12a2 2 0 002 2h8a2 2 0 002-2V7.414A2 2 0 0015.414 6L12 2.586A2 2 0 0010.586 2H6zm5 6a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V8z"
clip-rule="evenodd"></path>
</svg>
Export PDF
</a>
<a href="{{ route('admin.laporan.export-excel', request()->query()) }}"
class="inline-flex items-center px-4 py-2 border border-green-300 rounded-md shadow-sm text-sm font-medium text-green-700 bg-white hover:bg-green-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 transition duration-200">
<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd"
d="M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zM3 10a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H4a1 1 0 01-1-1v-6zM14 9a1 1 0 00-1 1v6a1 1 0 001 1h2a1 1 0 001-1v-6a1 1 0 00-1-1h-2z"
clip-rule="evenodd"></path>
</svg>
Export CSV
</a>
</div>
<!-- Filter Section -->
<div class="bg-white rounded-2xl shadow-xl border p-6 mb-8">
<h2 class="text-lg font-semibold text-gray-900 mb-4">Filter Laporan</h2>
<form method="GET" action="{{ route('admin.laporan.index') }}"
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<!-- Tanggal Mulai -->
<div>
<label for="tanggal_mulai" class="block text-sm font-medium text-gray-700 mb-1">Tanggal
Mulai</label>
<input type="date" id="tanggal_mulai" name="tanggal_mulai"
value="{{ request('tanggal_mulai') }}"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary">
</div>
<!-- Tanggal Akhir -->
<div>
<label for="tanggal_akhir" class="block text-sm font-medium text-gray-700 mb-1">Tanggal
Akhir</label>
<input type="date" id="tanggal_akhir" name="tanggal_akhir"
value="{{ request('tanggal_akhir') }}"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary">
</div>
<!-- Poli -->
<div>
<label for="poli_id" class="block text-sm font-medium text-gray-700 mb-1">Poli</label>
<select id="poli_id" name="poli_id"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary">
<option value="">Semua Poli</option>
@foreach ($polis as $poli)
<option value="{{ $poli->id }}"
{{ request('poli_id') == $poli->id ? 'selected' : '' }}>
{{ $poli->nama_poli }}
</option>
@endforeach
</select>
</div>
<!-- Status -->
<div>
<label for="status" class="block text-sm font-medium text-gray-700 mb-1">Status</label>
<select id="status" name="status"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary">
<option value="">Semua Status</option>
<option value="menunggu" {{ request('status') == 'menunggu' ? 'selected' : '' }}>
Menunggu
</option>
<option value="dipanggil" {{ request('status') == 'dipanggil' ? 'selected' : '' }}>
Dipanggil
</option>
<option value="sedang" {{ request('status') == 'sedang' ? 'selected' : '' }}>Sedang
</option>
<option value="selesai" {{ request('status') == 'selesai' ? 'selected' : '' }}>Selesai
</option>
<option value="batal" {{ request('status') == 'batal' ? 'selected' : '' }}>Batal
</option>
</select>
</div>
<!-- Jenis Kelamin -->
<div>
<label for="jenis_kelamin" class="block text-sm font-medium text-gray-700 mb-1">Jenis
Kelamin</label>
<select id="jenis_kelamin" name="jenis_kelamin"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary">
<option value="">Semua</option>
<option value="laki-laki"
{{ request('jenis_kelamin') == 'laki-laki' ? 'selected' : '' }}>
Laki-laki</option>
<option value="perempuan"
{{ request('jenis_kelamin') == 'perempuan' ? 'selected' : '' }}>
Perempuan</option>
</select>
</div>
<!-- Buttons -->
<div class="md:col-span-2 lg:col-span-4 flex space-x-3">
<button type="submit"
class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary transition duration-200">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
Filter
</button>
<a href="{{ route('admin.laporan.index') }}"
class="inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary transition duration-200">
Reset
</a>
</div>
</form>
</div>
<!-- Statistics Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-6 mb-8">
<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="M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2">
</path>
</svg>
</div>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Total Antrian</p>
<p class="text-2xl font-bold text-gray-900">{{ $totalAntrian }}</p>
</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-yellow-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-yellow-600" fill="none" stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Menunggu</p>
<p class="text-2xl font-bold text-gray-900">{{ $antrianMenunggu }}</p>
</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="flex items-center">
<div class="flex-shrink-0">
<div class="w-8 h-8 bg-green-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-green-600" fill="none" stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Selesai</p>
<p class="text-2xl font-bold text-gray-900">{{ $antrianSelesai }}</p>
</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-purple-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-purple-600" fill="none" stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
</div>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Sedang</p>
<p class="text-2xl font-bold text-gray-900">{{ $antrianSedang }}</p>
</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-red-100 rounded-lg flex items-center justify-center">
<svg class="w-5 h-5 text-red-600" fill="none" stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M6 18L18 6M6 6l12 12"></path>
</svg>
</div>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">Batal</p>
<p class="text-2xl font-bold text-gray-900">{{ $antrianBatal }}</p>
</div>
</div>
</div>
</div>
<!-- Data Table -->
<div class="bg-white rounded-2xl shadow-xl border">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-900">Data Antrian</h3>
</div>
<!-- Desktop Table -->
<div class="hidden lg:block overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
No Antrian</th>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Nama Pasien</th>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Poli</th>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Status</th>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Tanggal</th>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Waktu Daftar</th>
<th
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Waktu Panggil</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse($antrian as $item)
<tr class="hover:bg-gray-50 transition duration-200">
<td class="px-6 py-4 whitespace-nowrap">
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
{{ $item->no_antrian }}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div>
<div class="text-sm font-medium text-gray-900">{{ $item->user->nama }}
</div>
<div class="text-sm text-gray-500">{{ $item->user->no_ktp }}</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
{{ $item->poli->nama_poli }}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
@if ($item->status == 'menunggu')
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
Menunggu
</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_diperiksa')
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800">
Sedang
</span>
@elseif($item->status == 'selesai')
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
Selesai
</span>
@elseif($item->status == 'batal')
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
Batal
</span>
@endif
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{{ $item->created_at ? $item->created_at->format('d/m/Y') : '-' }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{{ $item->created_at ? $item->created_at->format('H:i') : '-' }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{{ $item->waktu_panggil ? $item->waktu_panggil->format('H:i') : '-' }}
</td>
</tr>
@empty
<tr>
<td colspan="7" class="px-6 py-4 text-center text-gray-500">
Tidak ada data antrian yang ditemukan
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<!-- Mobile Table -->
<div class="lg:hidden">
@forelse($antrian as $item)
<div class="border-b border-gray-200 p-4 hover:bg-gray-50">
<!-- 4 Kolom Penting untuk Mobile -->
<div class="grid grid-cols-2 gap-4 mb-3">
<div>
<p class="text-xs font-medium text-gray-500 uppercase tracking-wider">No
Antrian</p>
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
{{ $item->no_antrian }}
</span>
</div>
<div>
<p class="text-xs font-medium text-gray-500 uppercase tracking-wider">Nama
Pasien</p>
<div class="text-sm font-medium text-gray-900">{{ $item->user->nama }}</div>
</div>
<div>
<p class="text-xs font-medium text-gray-500 uppercase tracking-wider">Poli</p>
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
{{ $item->poli->nama_poli }}
</span>
</div>
<div>
<p class="text-xs font-medium text-gray-500 uppercase tracking-wider">Status
</p>
@if ($item->status == 'menunggu')
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
Menunggu
</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_diperiksa')
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800">
Sedang
</span>
@elseif($item->status == 'selesai')
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
Selesai
</span>
@elseif($item->status == 'batal')
<span
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
Batal
</span>
@endif
</div>
</div>
<!-- Button Selengkapnya untuk Mobile -->
<div class="border-t border-gray-100 pt-3">
<button onclick="toggleLaporanDetails({{ $item->id }})"
class="text-blue-600 hover:text-blue-800 text-sm font-medium flex items-center">
<span id="laporan-btn-text-{{ $item->id }}">Selengkapnya</span>
<svg id="laporan-icon-{{ $item->id }}"
class="w-4 h-4 ml-1 transform transition-transform" fill="none"
stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 9l-7 7-7-7"></path>
</svg>
</button>
<!-- Detail Tambahan (Hidden by default) -->
<div id="laporan-details-{{ $item->id }}" class="hidden mt-3 space-y-2">
<div class="grid grid-cols-1 gap-2 text-sm">
<div>
<span class="font-medium text-gray-700">No. KTP:</span>
<span class="text-gray-600">{{ $item->user->no_ktp }}</span>
</div>
<div>
<span class="font-medium text-gray-700">Tanggal:</span>
<span
class="text-gray-600">{{ $item->created_at ? $item->created_at->format('d/m/Y') : '-' }}</span>
</div>
<div>
<span class="font-medium text-gray-700">Waktu Daftar:</span>
<span
class="text-gray-600">{{ $item->created_at ? $item->created_at->format('H:i') : '-' }}</span>
</div>
<div>
<span class="font-medium text-gray-700">Waktu Panggil:</span>
<span
class="text-gray-600">{{ $item->waktu_panggil ? $item->waktu_panggil->format('H:i') : '-' }}</span>
</div>
</div>
</div>
</div>
</div>
@empty
<div class="p-8 text-center text-gray-500">
Tidak ada data antrian yang ditemukan
</div>
@endforelse
</div>
<!-- Pagination -->
<div class="mt-8">
{{ $antrian->withQueryString()->links() }}
</div>
</div>
</div>
</div>
</div>
</div>
@push('scripts')
<script>
// Sidebar toggle for mobile
document.getElementById('sidebar-toggle').addEventListener('click', function() {
document.getElementById('sidebar').classList.remove('-translate-x-full');
document.getElementById('sidebar-overlay').classList.remove('hidden');
});
document.getElementById('sidebar-close').addEventListener('click', function() {
document.getElementById('sidebar').classList.add('-translate-x-full');
document.getElementById('sidebar-overlay').classList.add('hidden');
});
document.getElementById('sidebar-overlay').addEventListener('click', function() {
document.getElementById('sidebar').classList.add('-translate-x-full');
document.getElementById('sidebar-overlay').classList.add('hidden');
});
// Function to confirm logout
function confirmLogout() {
Swal.fire({
title: 'Konfirmasi Logout',
text: 'Apakah Anda yakin ingin keluar dari sistem?',
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Ya, Logout',
cancelButtonText: 'Batal',
confirmButtonColor: '#EF4444',
cancelButtonColor: '#6B7280'
}).then((result) => {
if (result.isConfirmed) {
const form = document.createElement('form');
form.method = 'POST';
form.action = '{{ route('logout') }}';
const csrfToken = document.createElement('input');
csrfToken.type = 'hidden';
csrfToken.name = '_token';
csrfToken.value = '{{ csrf_token() }}';
form.appendChild(csrfToken);
document.body.appendChild(form);
form.submit();
}
});
}
// Show success message
@if (session('success'))
Swal.fire({
icon: 'success',
title: 'Berhasil!',
text: '{{ session('success') }}',
confirmButtonText: 'OK',
confirmButtonColor: '#10B981'
});
@endif
// Show error message
@if (session('error'))
Swal.fire({
icon: 'error',
title: 'Error!',
text: '{{ session('error') }}',
confirmButtonText: 'OK',
confirmButtonColor: '#EF4444'
});
@endif
// Function to toggle details visibility
function toggleLaporanDetails(id) {
const details = document.getElementById(`laporan-details-${id}`);
const buttonText = document.getElementById(`laporan-btn-text-${id}`);
const icon = document.getElementById(`laporan-icon-${id}`);
if (details.classList.contains('hidden')) {
details.classList.remove('hidden');
buttonText.textContent = 'Kurangi';
icon.classList.remove('transform', 'rotate-180');
} else {
details.classList.add('hidden');
buttonText.textContent = 'Selengkapnya';
icon.classList.add('transform', 'rotate-180');
}
}
</script>
@endpush
@include('admin.partials.sidebar-script')
@endsection