mirror of
https://github.com/xodivorce/infra-xodivorce-in.git
synced 2026-02-04 11:02:21 +05:30
fix: normalize category mismatch and enable live service status updates
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
#### A real-time map-based reporting system for campus infrastructure issues, built to improve visibility, accountability, and resolution efficiency.
|
#### A real-time map-based reporting system for campus infrastructure issues, built to improve visibility, accountability, and resolution efficiency.
|
||||||
|
|
||||||
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
||||||
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
||||||
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
[](https://github.com/xodivorce/infra-xodivorce-in/)
|
||||||
|
|
||||||
> **🥰 Like this project? Please consider giving it a Star (🌟) on GitHub to show us your appreciation. Thank you!**
|
> **🥰 Like this project? Please consider giving it a Star (🌟) on GitHub to show us your appreciation. Thank you!**
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
$departments = [
|
$departments = [
|
||||||
'WiFi & Network Issue',
|
'WiFi & Network Issue',
|
||||||
'Electrical Issue',
|
'Electrical Issue',
|
||||||
@@ -11,22 +12,19 @@ $departments = [
|
|||||||
'Library & Study Issue',
|
'Library & Study Issue',
|
||||||
'Lost & Stolen Issue',
|
'Lost & Stolen Issue',
|
||||||
'Medical/Health Issue',
|
'Medical/Health Issue',
|
||||||
'Other Issues',
|
'Other Issue',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
$services = [];
|
|
||||||
|
|
||||||
$sql = "
|
$sql = "
|
||||||
SELECT
|
SELECT
|
||||||
REPLACE(category, '&', '&') AS category,
|
REPLACE(category, '&', '&') AS category,
|
||||||
SUM(TRIM(status) = 'Opened') AS opened_count,
|
SUM(status = 'Opened') AS opened_count,
|
||||||
SUM(TRIM(status) = 'In Progress') AS progress_count
|
SUM(status = 'In Progress') AS progress_count
|
||||||
FROM reports
|
FROM reports
|
||||||
|
WHERE status IN ('Opened', 'In Progress')
|
||||||
GROUP BY category
|
GROUP BY category
|
||||||
";
|
";
|
||||||
|
|
||||||
|
|
||||||
$result = $conn->query($sql);
|
$result = $conn->query($sql);
|
||||||
|
|
||||||
$deptStats = [];
|
$deptStats = [];
|
||||||
@@ -34,6 +32,15 @@ while ($row = $result->fetch_assoc()) {
|
|||||||
$deptStats[$row['category']] = $row;
|
$deptStats[$row['category']] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($departments as $dept) {
|
||||||
|
if (!isset($deptStats[$dept])) {
|
||||||
|
$deptStats[$dept] = [
|
||||||
|
'opened_count' => 0,
|
||||||
|
'progress_count' => 0
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getStatusConfig($status) {
|
function getStatusConfig($status) {
|
||||||
switch ($status) {
|
switch ($status) {
|
||||||
case 'Operational':
|
case 'Operational':
|
||||||
@@ -78,7 +85,7 @@ function getIconPath($name) {
|
|||||||
return 'M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z';
|
return 'M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$services = [];
|
||||||
$activeServices = 0;
|
$activeServices = 0;
|
||||||
$maintenanceCount = 0;
|
$maintenanceCount = 0;
|
||||||
$highPriority = 0;
|
$highPriority = 0;
|
||||||
@@ -110,8 +117,6 @@ foreach ($departments as $dept) {
|
|||||||
|
|
||||||
$totalServices = count($services);
|
$totalServices = count($services);
|
||||||
|
|
||||||
$activeIncidents = $maintenanceCount + $highPriority;
|
|
||||||
|
|
||||||
if ($highPriority > 0) {
|
if ($highPriority > 0) {
|
||||||
$sysData = [
|
$sysData = [
|
||||||
'status' => 'System Alert',
|
'status' => 'System Alert',
|
||||||
@@ -143,6 +148,20 @@ if ($highPriority > 0) {
|
|||||||
'svg' => '<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"/>'
|
'svg' => '<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"/>'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($_GET['ajax']) && $_GET['ajax'] === '1') {
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
echo json_encode([
|
||||||
|
'services' => $services,
|
||||||
|
'stats' => [
|
||||||
|
'activeServices' => $activeServices,
|
||||||
|
'maintenance' => $maintenanceCount,
|
||||||
|
'outage' => $highPriority,
|
||||||
|
'system' => $sysData
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="space-y-6 max-w-7xl mx-auto pb-10">
|
<div class="space-y-6 max-w-7xl mx-auto pb-10">
|
||||||
@@ -197,7 +216,7 @@ if ($highPriority > 0) {
|
|||||||
<div>
|
<div>
|
||||||
<p class="text-xs font-semibold text-neutral-400 uppercase tracking-wider">Active System</p>
|
<p class="text-xs font-semibold text-neutral-400 uppercase tracking-wider">Active System</p>
|
||||||
<div class="flex items-baseline gap-1 mt-1">
|
<div class="flex items-baseline gap-1 mt-1">
|
||||||
<p class="text-2xl font-bold text-white"><?= $activeServices ?></p>
|
<p class="text-2xl font-bold text-white" id="activeServices"><?= $activeServices ?></p>
|
||||||
<span class="text-sm text-neutral-400">/ <?= $totalServices ?></span>
|
<span class="text-sm text-neutral-400">/ <?= $totalServices ?></span>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-neutral-400 mt-1"><?= ($totalServices - $activeServices) ?> services inactive</p>
|
<p class="text-xs text-neutral-400 mt-1"><?= ($totalServices - $activeServices) ?> services inactive</p>
|
||||||
@@ -210,7 +229,7 @@ if ($highPriority > 0) {
|
|||||||
<div class="bg-neutral-800 border border-neutral-700/50 rounded-xl p-5 flex items-center justify-between hover:border-yellow-500/50 transition-colors duration-300">
|
<div class="bg-neutral-800 border border-neutral-700/50 rounded-xl p-5 flex items-center justify-between hover:border-yellow-500/50 transition-colors duration-300">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-xs font-semibold text-neutral-400 uppercase tracking-wider">In Maintenance</p>
|
<p class="text-xs font-semibold text-neutral-400 uppercase tracking-wider">In Maintenance</p>
|
||||||
<p class="text-2xl font-bold text-white mt-1"><?= $maintenanceCount ?></p>
|
<p class="text-2xl font-bold text-white mt-1" id="maintenanceCount"><?= $maintenanceCount ?></p>
|
||||||
<p class="text-xs text-neutral-400 mt-1">Fixing the things</p>
|
<p class="text-xs text-neutral-400 mt-1">Fixing the things</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-12 h-12 rounded-lg bg-yellow-500/10 border border-yellow-500/20 flex items-center justify-center text-yellow-500">
|
<div class="w-12 h-12 rounded-lg bg-yellow-500/10 border border-yellow-500/20 flex items-center justify-center text-yellow-500">
|
||||||
@@ -221,7 +240,7 @@ if ($highPriority > 0) {
|
|||||||
<div class="bg-neutral-800 border border-neutral-700/50 rounded-xl p-5 flex items-center justify-between hover:border-red-500/50 transition-colors duration-300">
|
<div class="bg-neutral-800 border border-neutral-700/50 rounded-xl p-5 flex items-center justify-between hover:border-red-500/50 transition-colors duration-300">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-xs font-semibold text-neutral-400 uppercase tracking-wider">Outage System</p>
|
<p class="text-xs font-semibold text-neutral-400 uppercase tracking-wider">Outage System</p>
|
||||||
<p class="text-2xl font-bold text-white mt-1"><?= $highPriority ?></p>
|
<p class="text-2xl font-bold text-white mt-1" id="outageCount"><?= $highPriority ?></p>
|
||||||
<p class="text-xs text-neutral-400 mt-1">Take an action now</p>
|
<p class="text-xs text-neutral-400 mt-1">Take an action now</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-12 h-12 rounded-lg bg-red-500/10 border border-red-500/20 flex items-center justify-center text-red-500 <?php echo ($highPriority > 0) ? 'animate-pulse' : ''; ?>">
|
<div class="w-12 h-12 rounded-lg bg-red-500/10 border border-red-500/20 flex items-center justify-center text-red-500 <?php echo ($highPriority > 0) ? 'animate-pulse' : ''; ?>">
|
||||||
@@ -237,7 +256,7 @@ if ($highPriority > 0) {
|
|||||||
Services Status
|
Services Status
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
<div id="servicesGrid" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
<?php foreach ($services as $s):
|
<?php foreach ($services as $s):
|
||||||
$config = getStatusConfig($s['status']);
|
$config = getStatusConfig($s['status']);
|
||||||
$icon = getIconPath($s['name']);
|
$icon = getIconPath($s['name']);
|
||||||
|
|||||||
@@ -376,3 +376,37 @@ async function handleChatSubmit() {
|
|||||||
appendGeminiError("Unable to connect to Gemini. Please try again later.");
|
appendGeminiError("Unable to connect to Gemini. Please try again later.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function refreshStatus() {
|
||||||
|
try {
|
||||||
|
const res = await fetch(window.location.pathname + '?ajax=1');
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
document.getElementById('activeServices').textContent = data.stats.activeServices;
|
||||||
|
document.getElementById('maintenanceCount').textContent = data.stats.maintenance;
|
||||||
|
document.getElementById('outageCount').textContent = data.stats.outage;
|
||||||
|
|
||||||
|
const grid = document.getElementById('servicesGrid');
|
||||||
|
grid.innerHTML = '';
|
||||||
|
|
||||||
|
data.services.forEach(s => {
|
||||||
|
const color =
|
||||||
|
s.status === 'Outage' ? 'red' :
|
||||||
|
s.status === 'Maintenance' ? 'yellow' :
|
||||||
|
'green';
|
||||||
|
|
||||||
|
grid.innerHTML += `
|
||||||
|
<div class="bg-neutral-800 border border-neutral-700/50 rounded-xl p-4">
|
||||||
|
<h3 class="font-semibold text-white text-sm">${s.name}</h3>
|
||||||
|
<p class="text-xs text-neutral-400">${s.msg}</p>
|
||||||
|
<span class="inline-block mt-2 w-2 h-2 rounded-full bg-${color}-500"></span>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Status refresh failed', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(refreshStatus, 3000);
|
||||||
@@ -229,7 +229,7 @@ if (isset($_GET['code'])) {
|
|||||||
Need Help? Checkout Github Docs</a>
|
Need Help? Checkout Github Docs</a>
|
||||||
<span class="w-px h-3 bg-slate-800"></span>
|
<span class="w-px h-3 bg-slate-800"></span>
|
||||||
<span
|
<span
|
||||||
class="text-xs font-bold text-blue-400 bg-blue-500/10 px-2 py-0.5 rounded-full border border-blue-500/20">v1.3.7</span>
|
class="text-xs font-bold text-blue-400 bg-blue-500/10 px-2 py-0.5 rounded-full border border-blue-500/20">v1.3.8</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user