Files
silaras-rssa/app/Views/pasien_aktif.php
T

582 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pasien Aktif Ambulans</title>
<meta http-equiv="refresh" content="5">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
:root{
--primary: #2563eb;
--primary-soft: #dbeafe;
--success: #16a34a;
--success-soft: #dcfce7;
--warning: #d97706;
--warning-soft: #fef3c7;
--danger: #dc2626;
--danger-soft: #fee2e2;
--secondary: #64748b;
--secondary-soft: #f1f5f9;
--surface: rgba(255,255,255,.92);
--shadow: 0 10px 35px rgba(15,23,42,.08);
--radius: 24px;
}
body{
background:
radial-gradient(circle at top right, #dbeafe 0%, transparent 35%),
radial-gradient(circle at bottom left, #dcfce7 0%, transparent 35%),
linear-gradient(180deg, #f8fafc 0%, #eef4ff 100%);
font-family: 'Segoe UI', sans-serif;
color: #0f172a;
min-height: 100vh;
}
.header-title{
font-size: 2rem;
font-weight: 800;
letter-spacing: -.5px;
color: #0f172a;
}
/* CARD */
.card{
border: none;
border-radius: var(--radius);
background: var(--surface);
backdrop-filter: blur(18px);
box-shadow: var(--shadow);
transition: all .3s ease;
overflow: hidden;
}
.card:hover{
transform: translateY(-5px);
box-shadow: 0 18px 45px rgba(15,23,42,.14);
}
/* MENU */
.menu-row{
display:flex;
gap:12px;
margin-bottom:18px;
}
.menu-row .menu-card{
flex:1;
}
/* MENU CARD - CLEAN VERSION */
.menu-card{
background: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 16px;
padding: 14px 10px;
text-align: center;
cursor: pointer;
transition: all .2s ease;
box-shadow: 0 4px 12px rgba(0,0,0,.04);
color: #0f172a;
}
/* hover */
.menu-card:hover{
transform: translateY(-2px);
border-color: #cbd5e1;
box-shadow: 0 8px 18px rgba(0,0,0,.06);
}
/* ICON */
.menu-icon{
font-size: 1.6rem;
margin-bottom: 6px;
opacity: .9;
}
/* TEXT */
.menu-card h6{
font-size: .85rem;
font-weight: 600;
margin: 0;
color: #334155;
}
/* BACK BUTTON STYLE */
.menu-card.back{
background: #f1f5f9;
}
/* SUMMARY */
.summary-card{
background: rgba(255,255,255,.95);
backdrop-filter: blur(18px);
border-radius: 28px;
padding: 28px;
box-shadow: var(--shadow);
margin-bottom: 30px;
border: 1px solid rgba(255,255,255,.7);
}
.summary-header{
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 28px;
}
.summary-header h5{
font-size: 1.6rem;
font-weight: 800;
margin: 0;
color: #0f172a;
}
.summary-header small{
color: #64748b;
font-size: .95rem;
}
.summary-stats{
display: grid;
grid-template-columns: repeat(auto-fit,minmax(150px,1fr));
gap: 18px;
}
.stat-item{
border-radius: 22px;
padding: 24px 18px;
text-align: center;
transition: all .3s ease;
}
.stat-item:hover{
transform: translateY(-5px);
}
.stat-number{
font-size: 2.2rem;
font-weight: 800;
line-height: 1;
margin-bottom: 8px;
}
.stat-label{
font-size: .95rem;
font-weight: 600;
opacity: .9;
}
.stat-item.emergency{
background: var(--danger-soft);
color: var(--danger);
}
.stat-item.non{
background: var(--warning-soft);
color: var(--warning);
}
.stat-item.pending{
background: var(--success-soft);
color: var(--success);
}
/* ACCORDION */
.accordion-item{
border: none !important;
background: transparent;
}
.accordion-button{
background: transparent;
border: none;
padding: 1.4rem;
box-shadow: none !important;
}
.accordion-button:not(.collapsed){
background: #f8fafc;
color: inherit;
}
.accordion-button::after{
transition: .3s;
}
/* PHASE */
.fase-box{
padding: 14px 18px;
border-radius: 18px;
margin-bottom: 12px;
font-size: .95rem;
transition: .25s;
}
.fase-box:hover{
transform: translateX(4px);
}
.done{
background: var(--success-soft);
border-left: 6px solid var(--success);
}
.active{
background: var(--warning-soft);
border-left: 6px solid var(--warning);
}
.locked{
background: var(--secondary-soft);
border-left: 6px solid #cbd5e1;
color: #94a3b8;
}
/* BADGES */
.badge{
padding: .65rem 1rem;
border-radius: 999px;
font-size: .8rem;
font-weight: 700;
letter-spacing: .3px;
}
.badge-emergency{
background: linear-gradient(135deg,#ef4444,#dc2626);
color: white;
box-shadow: 0 6px 18px rgba(220,38,38,.30);
}
.badge-non{
background: linear-gradient(135deg,#facc15,#eab308);
color: #713f12;
}
.badge-pending{
background: linear-gradient(135deg,#22c55e,#16a34a);
color: white;
}
/* BUTTON */
.btn-sm{
border-radius: 999px;
padding: .45rem 1rem;
font-size: .82rem;
font-weight: 600;
box-shadow: 0 4px 12px rgba(0,0,0,.12);
}
/* EMPTY */
.empty-state{
margin-top: 100px;
padding: 50px 20px;
text-align: center;
opacity: .75;
}
.empty-state h1{
font-size: 5rem;
margin-bottom: 15px;
}
/* SCROLLBAR */
::-webkit-scrollbar{
width: 10px;
}
::-webkit-scrollbar-thumb{
background: #cbd5e1;
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover{
background: #94a3b8;
}
.top-bar{
display:flex;
justify-content:space-between;
align-items:center;
padding:14px 18px;
background:rgba(255,255,255,.8);
border-radius:18px;
box-shadow:0 6px 18px rgba(0,0,0,.06);
backdrop-filter: blur(10px);
}
.top-bar .title{
font-weight:800;
font-size:1.1rem;
color:#0f172a;
}
.time-box{
text-align:right;
font-weight:600;
color:#334155;
}
#clock{
font-size:1rem;
font-weight:700;
}
#date{
font-size:.8rem;
color:#64748b;
}
#autoPanel.minimized{
opacity: .55;
transform: scale(.98);
filter: blur(.2px);
transition: all .4s ease;
}
/* supaya masih enak dibaca */
#autoPanel.minimized .card{
box-shadow: 0 2px 8px rgba(0,0,0,.05);
}
</style>
</head>
<body>
<div class="container py-4">
<?php
$totalPasien = count($pasien);
$totalEmergency = 0;
$totalNon = 0;
$totalPending = 0;
foreach ($pasien as $p) {
switch ($p['order_type'] ?? '') {
case 'True Emergency':
$totalEmergency++;
break;
case 'Non Emergency':
$totalNon++;
break;
default:
$totalPending++;
break;
}
}
?>
<!-- ================= SUMMARY ================= -->
<div class="summary-card mb-4">
<div class="summary-header">
<div>
<h5 class="mb-1">🚑 Pasien Aktif</h5>
<small>Monitoring Pasien Ambulans 119 Saat Ini Berjumlah <?= $totalPasien ?> Pasien</small>
</div>
<div class="time-box">
<div id="clock">--:--:--</div>
<div id="date">-</div>
</div>
</div>
<div class="summary-stats">
<div class="stat-item emergency">
<div class="stat-number"><?= $totalEmergency ?></div>
<div class="stat-label">True Emergency</div>
</div>
<div class="stat-item non">
<div class="stat-number"><?= $totalNon ?></div>
<div class="stat-label">Non Emergency</div>
</div>
<div class="stat-item pending">
<div class="stat-number"><?= $totalPending ?></div>
<div class="stat-label">Pending Order</div>
</div>
</div>
</div>
<div class="menu-row">
<div class="menu-card" onclick="window.location.href='../pasien/input'">
<div class="menu-icon"></div>
<h6 class="mt-2 mb-0">Tambah Pasien Baru</h6>
</div>
<div class="menu-card back" onclick="window.location.href='/silaras119/public/dashboard'">
<div class="menu-icon">🏠</div>
<h6 class="mt-2 mb-0">Kembali ke Dashboard Utama Silaras 119</h6>
</div>
</div>
<div id="autoPanel">
<?php if (!empty($pasien)): ?>
<div class="accordion" id="accordionPasien">
<?php foreach($pasien as $index => $p): ?>
<?php
$fase = $p['fase'] ?? 1;
$orderType = $p['order_type'] ?? 'Pending Order';
switch ($orderType) {
case 'True Emergency':
$badgeClass = 'badge-emergency';
break;
case 'Non Emergency':
$badgeClass = 'badge-non';
break;
default:
$badgeClass = 'badge-pending';
break;
}
$steps = [
1 => "Pre Dispatch",
2 => "Dispatch",
3 => "En Route",
4 => "On Scene",
5 => "Transport",
6 => "Selesai"
];
?>
<div class="card mb-3 shadow-sm">
<div class="accordion-item border-0 rounded-4">
<h2 class="accordion-header">
<button class="accordion-button collapsed rounded-4"
type="button"
data-bs-toggle="collapse"
data-bs-target="#collapse<?= $p['id'] ?>">
<div class="w-100">
<div class="d-flex justify-content-between align-items-center">
<h6 class="mb-1">👤 <?= esc($p['nama']) ?></h6>
<span class="badge <?= $badgeClass ?>">
<?= esc($orderType) ?>
</span>
</div>
<small class="text-muted">
<?= esc($p['alamat'] ?? '-') ?>
</small>
</div>
</button>
</h2>
<div id="collapse<?= $p['id'] ?>"
class="accordion-collapse collapse"
data-bs-parent="#accordionPasien">
<div class="accordion-body">
<?php foreach($steps as $key => $label): ?>
<?php
$class =
$fase > $key ? 'done' :
($fase == $key ? 'active' : 'locked');
?>
<div class="fase-box <?= $class ?>">
<div class="d-flex justify-content-between align-items-center">
<?php if($key == 1): ?>
<a href="../pasien/predispatch/<?= $p['id'] ?>"
class="text-decoration-none text-dark">
<b><?= $label ?></b>
</a>
<?php else: ?>
<b><?= $label ?></b>
<?php endif; ?>
<?php if($fase == $key && $fase < 6): ?>
<a href="../pasien/next/<?= $p['id'] ?>"
class="btn btn-sm btn-warning">
➡️ Lanjut
</a>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="text-center empty-state">
<h1>🚑</h1>
<p>Tidak ada pasien aktif</p>
</div>
<?php endif; ?>
</div>
</div>
<script>
function updateTime(){
const now = new Date();
const time = now.toLocaleTimeString('id-ID', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
const date = now.toLocaleDateString('id-ID', {
weekday: 'long',
day: '2-digit',
month: 'long',
year: 'numeric'
});
document.getElementById('clock').innerText = time;
document.getElementById('date').innerText = date;
}
setInterval(updateTime, 1000);
updateTime();
let idleTime = 0;
let panel = document.getElementById("autoPanel");
// reset kalau user aktif
function resetIdle(){
idleTime = 0;
panel.classList.remove("minimized");
}
// event user aktif
document.addEventListener("mousemove", resetIdle);
document.addEventListener("click", resetIdle);
document.addEventListener("keydown", resetIdle);
document.addEventListener("scroll", resetIdle);
// timer idle
setInterval(() => {
idleTime++;
// 10 detik tidak aktif → minimize
if(idleTime >= 10){
panel.classList.add("minimized");
}
}, 1000);
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>