|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>SuperAdmin Console | MedMIS</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<script src="https://unpkg.com/feather-icons"></script> |
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> |
|
|
<script src="https://cdn.jsdelivr.net/npm/heatmap.js@2.0.5/build/heatmap.min.js"></script> |
|
|
<style> |
|
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); |
|
|
body { |
|
|
font-family: 'Inter', sans-serif; |
|
|
} |
|
|
.heatmap-container { |
|
|
width: 100%; |
|
|
height: 300px; |
|
|
position: relative; |
|
|
} |
|
|
.status-dot { |
|
|
width: 10px; |
|
|
height: 10px; |
|
|
border-radius: 50%; |
|
|
display: inline-block; |
|
|
} |
|
|
.status-online { |
|
|
background-color: #10b981; |
|
|
} |
|
|
.status-offline { |
|
|
background-color: #ef4444; |
|
|
} |
|
|
.status-busy { |
|
|
background-color: #f59e0b; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="bg-gray-900 text-white min-h-screen"> |
|
|
<div class="container mx-auto px-4 py-8"> |
|
|
<header class="mb-8"> |
|
|
<div class="flex items-center mb-4"> |
|
|
<button onclick="history.back()" class="mr-4 p-2 rounded-lg bg-gray-700 hover:bg-gray-600 transition"> |
|
|
<i data-feather="arrow-left" class="w-5 h-5"></i> |
|
|
</button> |
|
|
<div> |
|
|
<h1 class="text-3xl font-bold" data-i18n="superAdmin.title">SuperAdmin Console</h1> |
|
|
<p class="text-gray-300" data-i18n="superAdmin.subtitle">Global system management and monitoring</p> |
|
|
</div> |
|
|
</div> |
|
|
</header> |
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8"> |
|
|
<div class="bg-blue-900 rounded-xl p-4"> |
|
|
<div class="flex justify-between"> |
|
|
<div> |
|
|
<h3 class="text-sm text-gray-300">Active Clinics</h3> |
|
|
<p class="text-2xl font-bold">24</p> |
|
|
</div> |
|
|
<i data-feather="home" class="w-8 h-8 text-blue-300"></i> |
|
|
</div> |
|
|
<p class="text-sm text-blue-200 mt-2">+3 this month</p> |
|
|
</div> |
|
|
<div class="bg-purple-900 rounded-xl p-4"> |
|
|
<div class="flex justify-between"> |
|
|
<div> |
|
|
<h3 class="text-sm text-gray-300">Active Doctors</h3> |
|
|
<p class="text-2xl font-bold">187</p> |
|
|
</div> |
|
|
<i data-feather="users" class="w-8 h-8 text-purple-300"></i> |
|
|
</div> |
|
|
<p class="text-sm text-purple-200 mt-2">89% online</p> |
|
|
</div> |
|
|
<div class="bg-green-900 rounded-xl p-4"> |
|
|
<div class="flex justify-between"> |
|
|
<div> |
|
|
<h3 class="text-sm text-gray-300">SLA Compliance</h3> |
|
|
<p class="text-2xl font-bold">91%</p> |
|
|
</div> |
|
|
<i data-feather="clock" class="w-8 h-8 text-green-300"></i> |
|
|
</div> |
|
|
<p class="text-sm text-green-200 mt-2">+5% from last week</p> |
|
|
</div> |
|
|
<div class="bg-red-900 rounded-xl p-4"> |
|
|
<div class="flex justify-between"> |
|
|
<div> |
|
|
<h3 class="text-sm text-gray-300">Overdue Cases</h3> |
|
|
<p class="text-2xl font-bold">12</p> |
|
|
</div> |
|
|
<i data-feather="alert-circle" class="w-8 h-8 text-red-300"></i> |
|
|
</div> |
|
|
<p class="text-sm text-red-200 mt-2">-3 from yesterday</p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8"> |
|
|
|
|
|
<div class="bg-gray-800 rounded-xl p-6 lg:col-span-2"> |
|
|
<h2 class="text-xl font-semibold mb-4 flex items-center"> |
|
|
<i data-feather="activity" class="w-5 h-5 mr-2"></i> |
|
|
Clinics Overview |
|
|
</h2> |
|
|
<canvas id="clinicsChart" height="250"></canvas> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-gray-800 rounded-xl p-6"> |
|
|
<h2 class="text-xl font-semibold mb-4 flex items-center"> |
|
|
<i data-feather="user-check" class="w-5 h-5 mr-2"></i> |
|
|
Doctor Status |
|
|
</h2> |
|
|
<div class="space-y-4"> |
|
|
<div class="flex justify-between items-center"> |
|
|
<span>Group A (Radiologists)</span> |
|
|
<div class="flex items-center"> |
|
|
<span class="status-dot status-online mr-1"></span> |
|
|
<span>24/30</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex justify-between items-center"> |
|
|
<span>Group B (Technicians)</span> |
|
|
<div class="flex items-center"> |
|
|
<span class="status-dot status-online mr-1"></span> |
|
|
<span>18/22</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex justify-between items-center"> |
|
|
<span>Group C (Referrers)</span> |
|
|
<div class="flex items-center"> |
|
|
<span class="status-dot status-online mr-1"></span> |
|
|
<span>45/55</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="pt-4"> |
|
|
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg transition"> |
|
|
<i data-feather="refresh-cw" class="w-4 h-4 mr-2"></i> |
|
|
Reassign Groups |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-gray-800 rounded-xl p-6 mb-8"> |
|
|
<div class="flex justify-between items-center mb-4"> |
|
|
<h2 class="text-xl font-semibold flex items-center"> |
|
|
<i data-feather="list" class="w-5 h-5 mr-2"></i> |
|
|
Active Queues |
|
|
</h2> |
|
|
<div class="flex space-x-2"> |
|
|
<button class="bg-gray-700 hover:bg-gray-600 text-white py-2 px-4 rounded-lg transition"> |
|
|
<i data-feather="download" class="w-4 h-4 mr-2"></i> |
|
|
Export |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
<div class="overflow-x-auto"> |
|
|
<table class="w-full"> |
|
|
<thead> |
|
|
<tr class="text-gray-300 border-b border-gray-700"> |
|
|
<th class="py-3 px-4 text-left">Clinic</th> |
|
|
<th class="py-3 px-4 text-left">Queue ID</th> |
|
|
<th class="py-3 px-4 text-left">Patient</th> |
|
|
<th class="py-3 px-4 text-left">Doctor</th> |
|
|
<th class="py-3 px-4 text-left">Status</th> |
|
|
<th class="py-3 px-4 text-left">SLA Time</th> |
|
|
</tr> |
|
|
</thead> |
|
|
<tbody> |
|
|
<tr class="border-b border-gray-700"> |
|
|
<td class="py-3 px-4">Main Radiology</td> |
|
|
<td class="py-3 px-4">Q-789456</td> |
|
|
<td class="py-3 px-4">John Doe</td> |
|
|
<td class="py-3 px-4">Dr. Smith (A)</td> |
|
|
<td class="py-3 px-4"><span class="bg-green-900 text-green-300 px-2 py-1 rounded text-xs">In Progress</span></td> |
|
|
<td class="py-3 px-4">12:30</td> |
|
|
</tr> |
|
|
<tr class="border-b border-gray-700"> |
|
|
<td class="py-3 px-4">Cardiology Center</td> |
|
|
<td class="py-3 px-4">Q-654321</td> |
|
|
<td class="py-3 px-4">Sarah Johnson</td> |
|
|
<td class="py-3 px-4">Dr. Lee (B)</td> |
|
|
<td class="py-3 px-4"><span class="bg-yellow-900 text-yellow-300 px-2 py-1 rounded text-xs">Waiting</span></td> |
|
|
<td class="py-3 px-4">45:00</td> |
|
|
</tr> |
|
|
</tbody> |
|
|
</table> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8"> |
|
|
<div class="bg-gray-800 rounded-xl p-6"> |
|
|
<h2 class="text-xl font-semibold mb-4 flex items-center"> |
|
|
<i data-feather="bar-chart-2" class="w-5 h-5 mr-2"></i> |
|
|
KPI Performance |
|
|
</h2> |
|
|
<canvas id="kpiChart" height="300"></canvas> |
|
|
</div> |
|
|
<div class="bg-gray-800 rounded-xl p-6"> |
|
|
<h2 class="text-xl font-semibold mb-4 flex items-center"> |
|
|
<i data-feather="map" class="w-5 h-5 mr-2"></i> |
|
|
Activity Heatmap |
|
|
</h2> |
|
|
<div id="heatmapContainer" class="heatmap-container"></div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-gray-800 rounded-xl p-6"> |
|
|
<h2 class="text-xl font-semibold mb-4 flex items-center"> |
|
|
<i data-feather="alert-triangle" class="w-5 h-5 mr-2"></i> |
|
|
Event Control Center |
|
|
</h2> |
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4"> |
|
|
<div class="bg-gray-700 rounded-lg p-4"> |
|
|
<h3 class="font-medium mb-2">Overdue Cases</h3> |
|
|
<div class="text-2xl font-bold text-red-400 mb-2">12</div> |
|
|
<button class="w-full bg-red-600 hover:bg-red-700 text-white py-2 px-4 rounded text-sm"> |
|
|
Escalate All |
|
|
</button> |
|
|
</div> |
|
|
<div class="bg-gray-700 rounded-lg p-4"> |
|
|
<h3 class="font-medium mb-2">No-Shows</h3> |
|
|
<div class="text-2xl font-bold text-yellow-400 mb-2">5</div> |
|
|
<button class="w-full bg-yellow-600 hover:bg-yellow-700 text-white py-2 px-4 rounded text-sm"> |
|
|
Send Reminders |
|
|
</button> |
|
|
</div> |
|
|
<div class="bg-gray-700 rounded-lg p-4"> |
|
|
<h3 class="font-medium mb-2">Efficiency Alerts</h3> |
|
|
<div class="text-2xl font-bold text-blue-400 mb-2">8</div> |
|
|
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded text-sm"> |
|
|
Review All |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="mt-8 bg-gray-800 rounded-xl p-6"> |
|
|
<h2 class="text-xl font-semibold mb-4 flex items-center"> |
|
|
<i data-feather="code" class="w-5 h-5 mr-2"></i> |
|
|
Admin API Endpoints |
|
|
</h2> |
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> |
|
|
<div class="bg-gray-700 rounded-lg p-4"> |
|
|
<div class="flex items-center mb-2"> |
|
|
<span class="bg-blue-500 text-white text-xs px-2 py-1 rounded mr-2">POST</span> |
|
|
<code class="text-sm">/admin/reassign-doctor</code> |
|
|
</div> |
|
|
<p class="text-sm text-gray-300">Reassign doctor to different group</p> |
|
|
<pre class="mt-2 p-2 bg-gray-900 rounded text-xs overflow-x-auto"> |
|
|
{ |
|
|
"doctorId": "doc123", |
|
|
"newGroup": "A" |
|
|
}</pre> |
|
|
</div> |
|
|
<div class="bg-gray-700 rounded-lg p-4"> |
|
|
<div class="flex items-center mb-2"> |
|
|
<span class="bg-green-500 text-white text-xs px-2 py-1 rounded mr-2">GET</span> |
|
|
<code class="text-sm">/admin/system-stats</code> |
|
|
</div> |
|
|
<p class="text-sm text-gray-300">Retrieve system-wide statistics</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
feather.replace(); |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
|
|
|
const clinicsCtx = document.getElementById('clinicsChart').getContext('2d'); |
|
|
const clinicsChart = new Chart(clinicsCtx, { |
|
|
type: 'bar', |
|
|
data: { |
|
|
labels: ['Radiology', 'Cardiology', 'Neurology', 'Oncology', 'Pediatrics'], |
|
|
datasets: [{ |
|
|
label: 'Active Patients', |
|
|
data: [45, 32, 28, 19, 23], |
|
|
backgroundColor: 'rgba(59, 130, 246, 0.7)', |
|
|
borderColor: 'rgba(59, 130, 246, 1)', |
|
|
borderWidth: 1 |
|
|
}] |
|
|
}, |
|
|
options: { |
|
|
responsive: true, |
|
|
plugins: { |
|
|
legend: { |
|
|
display: false |
|
|
} |
|
|
}, |
|
|
scales: { |
|
|
y: { |
|
|
beginAtZero: true, |
|
|
grid: { |
|
|
color: 'rgba(255, 255, 255, 0.1)' |
|
|
}, |
|
|
ticks: { |
|
|
color: 'rgba(255, 255, 255, 0.7)' |
|
|
} |
|
|
}, |
|
|
x: { |
|
|
grid: { |
|
|
display: false |
|
|
}, |
|
|
ticks: { |
|
|
color: 'rgba(255, 255, 255, 0.7)' |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const kpiCtx = document.getElementById('kpiChart').getContext('2d'); |
|
|
const kpiChart = new Chart(kpiCtx, { |
|
|
type: 'radar', |
|
|
data: { |
|
|
labels: ['SLA Compliance', 'Patient Satisfaction', 'Report Accuracy', 'Efficiency', 'Resource Usage'], |
|
|
datasets: [{ |
|
|
label: 'Current Month', |
|
|
data: [92, 88, 95, 85, 78], |
|
|
backgroundColor: 'rgba(99, 102, 241, 0.2)', |
|
|
borderColor: 'rgba(99, 102, 241, 1)', |
|
|
borderWidth: 2, |
|
|
pointBackgroundColor: 'rgba(99, 102, 241, 1)' |
|
|
}, { |
|
|
label: 'Last Month', |
|
|
data: [88, 85, 92, 80, 75], |
|
|
backgroundColor: 'rgba(236, 72, 153, 0.2)', |
|
|
borderColor: 'rgba(236, 72, 153, 1)', |
|
|
borderWidth: 2, |
|
|
pointBackgroundColor: 'rgba(236, 72, 153, 1)' |
|
|
}] |
|
|
}, |
|
|
options: { |
|
|
responsive: true, |
|
|
scales: { |
|
|
r: { |
|
|
angleLines: { |
|
|
color: 'rgba(255, 255, 255, 0.1)' |
|
|
}, |
|
|
grid: { |
|
|
color: 'rgba(255, 255, 255, 0.1)' |
|
|
}, |
|
|
pointLabels: { |
|
|
color: 'rgba(255, 255, 255, 0.7)' |
|
|
}, |
|
|
ticks: { |
|
|
backdropColor: 'rgba(0, 0, 0, 0)', |
|
|
color: 'rgba(255, 255, 255, 0.5)' |
|
|
} |
|
|
} |
|
|
}, |
|
|
plugins: { |
|
|
legend: { |
|
|
labels: { |
|
|
color: 'rgba(255, 255, 255, 0.7)' |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const heatmapInstance = h337.create({ |
|
|
container: document.getElementById('heatmapContainer'), |
|
|
radius: 35 |
|
|
}); |
|
|
|
|
|
|
|
|
const points = []; |
|
|
const max = 100; |
|
|
const width = document.getElementById('heatmapContainer').offsetWidth; |
|
|
const height = 300; |
|
|
|
|
|
for (let i = 0; i < 50; i++) { |
|
|
points.push({ |
|
|
x: Math.floor(Math.random() * width), |
|
|
y: Math.floor(Math.random() * height), |
|
|
value: Math.floor(Math.random() * max) |
|
|
}); |
|
|
} |
|
|
|
|
|
const data = { |
|
|
max: max, |
|
|
data: points |
|
|
}; |
|
|
|
|
|
heatmapInstance.setData(data); |
|
|
}); |
|
|
|
|
|
|
|
|
document.querySelector('.bg-blue-600').addEventListener('click', function() { |
|
|
alert('Doctor group reassignment modal would open here'); |
|
|
}); |
|
|
|
|
|
|
|
|
document.querySelectorAll('.bg-gray-700 button').forEach(button => { |
|
|
button.addEventListener('click', function() { |
|
|
const action = this.textContent.trim(); |
|
|
alert(`Processing ${action} action...`); |
|
|
}); |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |