-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.php
More file actions
230 lines (210 loc) · 16.5 KB
/
app.php
File metadata and controls
230 lines (210 loc) · 16.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Aegis Responder</title>
<link rel="manifest" href="manifest.json">
<link rel="icon" type="image/png" href="icon.png">
<link rel="apple-touch-icon" href="icon.png">
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
body { font-family: 'Inter', sans-serif; touch-action: manipulation; }
.severity-btn.active { background-color: #fbbf24; color: black; border-color: #fbbf24; transform: scale(1.1); }
.help-btn.active { background-color: #2563eb; border-color: #2563eb; color: white; }
@keyframes fade-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.animate-fade-in { animation: fade-in 0.3s ease-out forwards; }
</style>
<script>
// SECURITY CHECK
if (!localStorage.getItem('aegis_auth')) {
window.location.href = 'index.php';
} else {
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('app-view').classList.remove('hidden');
document.getElementById('display-badge').innerText = localStorage.getItem('aegis_user') || 'Unknown';
});
}
</script>
</head>
<body class="bg-[#0f172a] text-slate-200 min-h-screen pb-20">
<div id="app-view" class="hidden max-w-lg mx-auto min-h-screen flex flex-col relative">
<div class="bg-gradient-to-br from-slate-900 via-blue-900 to-slate-900 p-8 pb-10 rounded-b-[3rem] shadow-2xl z-10 relative overflow-hidden border-b border-white/10">
<div class="absolute -top-10 -right-10 w-64 h-64 bg-blue-500/20 rounded-full blur-3xl pointer-events-none"></div>
<div class="absolute top-10 -left-10 w-40 h-40 bg-indigo-500/20 rounded-full blur-2xl pointer-events-none"></div>
<div class="flex justify-between items-start relative z-10">
<div>
<h1 class="text-4xl font-black text-white tracking-tighter drop-shadow-sm">Aegis</h1>
<p class="text-blue-200 text-sm font-medium mt-1 tracking-wide">Rapid Response Unit</p>
</div>
<button onclick="logout()" class="bg-white/10 hover:bg-white/20 text-white p-3 rounded-full backdrop-blur-md transition-all border border-white/10 shadow-lg active:scale-95">
<i class="fa-solid fa-power-off text-sm"></i>
</button>
</div>
<div class="mt-6 inline-flex items-center gap-3 px-4 py-2 bg-black/30 rounded-full border border-white/10 backdrop-blur-md shadow-inner">
<span class="relative flex h-3 w-3">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-3 w-3 bg-green-500"></span>
</span>
<span class="text-xs font-bold text-gray-300 tracking-wider">ID: <span id="display-badge" class="text-white font-mono">...</span></span>
</div>
</div>
<div id="status-bar" class="text-[10px] font-bold text-center py-1 pb-3 pt-12 -mt-10 rounded-b-[3rem] bg-slate-800 text-slate-500 uppercase tracking-widest z-0 transition-all duration-300 shadow-md">
Checking Connection...
</div>
<div class="p-5 -mt-2 space-y-6">
<form id="incident-form" class="space-y-6">
<div class="space-y-2">
<label class="text-sm font-semibold text-slate-400 uppercase tracking-wide">Incident Type</label>
<div class="relative">
<select id="type-select" class="w-full bg-slate-800 text-white p-4 rounded-xl border border-slate-700 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none appearance-none font-medium text-lg transition-all shadow-lg">
<option value="Landslide">Landslide</option>
<option value="Flood">Flood</option>
<option value="Road Blocked">Road Blocked</option>
<option value="Power Down">Power Line Down</option>
<option value="Fire">Fire / Wildfire</option>
<option value="Medical">Medical Emergency</option>
</select>
<div class="absolute right-4 top-1/2 -translate-y-1/2 pointer-events-none text-slate-400">
<i class="fa-solid fa-chevron-down"></i>
</div>
</div>
<div id="safety-alert" class="hidden animate-fade-in mt-2">
<div class="bg-red-500/10 border border-red-500/20 rounded-xl p-4 flex gap-3 text-red-100">
<div class="pt-1"><i class="fa-solid fa-triangle-exclamation text-red-500"></i></div>
<div class="text-sm">
<p class="font-bold text-red-400 mb-1" id="safety-title">Safety Warning</p>
<p id="safety-msg" class="opacity-90 leading-relaxed"></p>
</div>
</div>
</div>
<input type="hidden" id="type" value="Landslide">
</div>
<div class="space-y-3">
<div class="flex justify-between items-end">
<label class="text-sm font-semibold text-slate-400 uppercase tracking-wide">Severity Level</label>
<span class="text-xs font-bold text-yellow-500 bg-yellow-500/10 px-2 py-1 rounded border border-yellow-500/20">
Level <span id="sev-display">3</span>
</span>
</div>
<div class="flex justify-between items-center bg-slate-800 p-2 rounded-2xl border border-slate-700 shadow-inner">
<span class="text-[10px] font-bold text-slate-500 pl-2">MINOR</span>
<div class="flex gap-2">
<button type="button" class="severity-btn w-10 h-10 rounded-full border border-slate-600 bg-slate-700 text-slate-300 font-bold transition-all flex items-center justify-center" onclick="setSeverity(1)">1</button>
<button type="button" class="severity-btn w-10 h-10 rounded-full border border-slate-600 bg-slate-700 text-slate-300 font-bold transition-all flex items-center justify-center" onclick="setSeverity(2)">2</button>
<button type="button" class="severity-btn w-10 h-10 rounded-full border-yellow-500/50 bg-yellow-500 text-black font-bold transition-all flex items-center justify-center active scale-110 shadow-[0_0_15px_rgba(234,179,8,0.3)]" onclick="setSeverity(3)">3</button>
<button type="button" class="severity-btn w-10 h-10 rounded-full border border-slate-600 bg-slate-700 text-slate-300 font-bold transition-all flex items-center justify-center" onclick="setSeverity(4)">4</button>
<button type="button" class="severity-btn w-10 h-10 rounded-full border border-slate-600 bg-slate-700 text-slate-300 font-bold transition-all flex items-center justify-center" onclick="setSeverity(5)">5</button>
</div>
<span class="text-[10px] font-bold text-red-500 pr-2">CRIT</span>
</div>
<input type="hidden" id="severity" value="3">
</div>
<div class="p-4 bg-slate-800/50 rounded-2xl border border-slate-700/50">
<label class="text-sm font-semibold text-slate-400 uppercase tracking-wide mb-3 block">Assistance Needed</label>
<div class="grid grid-cols-2 gap-3 mb-4">
<button type="button" class="help-btn p-3 rounded-xl bg-slate-800 border border-slate-600 flex flex-col items-center gap-2 transition-all hover:bg-slate-700 active:scale-95 active:bg-slate-600" onclick="toggleHelp(this, 'Medical')">
<i class="fa-solid fa-truck-medical text-xl text-red-400"></i> <span class="text-xs font-bold text-slate-300">Medical</span>
</button>
<button type="button" class="help-btn p-3 rounded-xl bg-slate-800 border border-slate-600 flex flex-col items-center gap-2 transition-all hover:bg-slate-700 active:scale-95 active:bg-slate-600" onclick="toggleHelp(this, 'Trapped')">
<i class="fa-solid fa-life-ring text-xl text-pink-500"></i> <span class="text-xs font-bold text-slate-300">Trapped (SOS)</span>
</button>
<button type="button" class="help-btn p-3 rounded-xl bg-slate-800 border border-slate-600 flex flex-col items-center gap-2 transition-all hover:bg-slate-700 active:scale-95 active:bg-slate-600" onclick="toggleHelp(this, 'Rescue')">
<i class="fa-solid fa-helicopter text-xl text-blue-400"></i> <span class="text-xs font-bold text-slate-300">Rescue</span>
</button>
<button type="button" class="help-btn p-3 rounded-xl bg-slate-800 border border-slate-600 flex flex-col items-center gap-2 transition-all hover:bg-slate-700 active:scale-95 active:bg-slate-600" onclick="toggleHelp(this, 'Supplies')">
<i class="fa-solid fa-box-open text-xl text-amber-200"></i> <span class="text-xs font-bold text-slate-300">Supplies</span>
</button>
</div>
<label class="text-xs font-bold text-slate-500 uppercase mb-2 block">Headcount (Approx)</label>
<input type="number" id="headcount" value="1" min="1" max="500" step="1" inputmode="numeric" class="w-full bg-slate-900 border border-slate-700 rounded-lg p-3 text-white focus:border-blue-500 outline-none" placeholder="1-500">
</div>
<input type="hidden" id="lat" value="0">
<input type="hidden" id="lng" value="0">
<div class="space-y-2">
<label class="text-sm font-semibold text-slate-400 uppercase tracking-wide">Additional Details</label>
<textarea id="details" rows="2" class="w-full bg-slate-900 border border-slate-700 rounded-xl p-4 text-white focus:border-blue-500 outline-none resize-none placeholder-slate-600" placeholder="Describe the situation..."></textarea>
</div>
<div class="space-y-2">
<label class="text-sm font-semibold text-slate-400 uppercase tracking-wide">Photo Evidence</label>
<input type="file" id="cameraInput" accept="image/*" capture="environment" class="hidden">
<div id="camera-trigger" onclick="document.getElementById('cameraInput').click()" class="border-2 border-dashed border-slate-600 bg-slate-800/50 hover:bg-slate-800 rounded-2xl p-8 flex flex-col items-center justify-center gap-3 cursor-pointer transition-all group">
<div class="w-12 h-12 rounded-full bg-slate-700 flex items-center justify-center group-hover:bg-blue-600 transition-colors"><i class="fa-solid fa-camera text-xl text-white"></i></div>
<div class="text-center"><p class="text-sm font-bold text-slate-300">Tap to Capture</p><p class="text-xs text-slate-500">JPG, PNG up to 5MB</p></div>
</div>
<div id="preview-area" class="hidden mt-3 relative rounded-xl overflow-hidden border border-slate-600">
<img id="preview-img" class="w-full h-48 object-cover">
<button type="button" onclick="clearImage()" class="absolute top-2 right-2 bg-red-600 text-white w-6 h-6 rounded-full text-xs shadow-lg">✕</button>
</div>
</div>
<button type="submit" class="w-full bg-gradient-to-r from-blue-600 to-blue-500 hover:from-blue-500 hover:to-blue-400 py-4 rounded-xl font-bold text-lg shadow-lg shadow-blue-900/30 flex items-center justify-center gap-2 transition-transform transform active:scale-95 border-t border-blue-400/20">
<i class="fa-solid fa-paper-plane"></i> SUBMIT REPORT
</button>
<button type="button" onclick="sendSMS()" class="w-full bg-slate-800 hover:bg-slate-700 py-3 rounded-xl font-bold text-sm text-slate-400 shadow-lg flex items-center justify-center gap-2 transition-transform transform active:scale-95 border border-slate-700">
<i class="fa-solid fa-comment-sms"></i> NO INTERNET? SEND VIA SMS
</button>
</form>
<div id="status-feed" class="hidden mt-6 bg-slate-800/80 rounded-xl border border-slate-600 p-4 animate-fade-in">
<h3 class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-3">Live Updates</h3>
<div id="my-reports-list" class="space-y-2"></div>
</div>
<div class="text-center pb-8 opacity-60">
<p class="text-[10px] uppercase font-bold text-slate-500">Offline Queue</p>
<p class="text-2xl font-black text-slate-400" id="queue-count">0</p>
</div>
</div>
</div>
<!-- EMERGENCY OVERLAY -->
<div id="emergency-alert" class="fixed inset-0 z-[999] bg-red-600/90 backdrop-blur-md hidden flex flex-col items-center justify-center p-8 text-center animate-fade-in">
<div class="bg-white/10 p-6 rounded-full mb-6 border-4 border-white animate-pulse">
<i class="fa-solid fa-bullhorn text-5xl text-white"></i>
</div>
<h1 class="text-4xl font-black text-white mb-2 uppercase tracking-tighter drop-shadow-lg">Emergency Alert</h1>
<div class="w-24 h-1 bg-white mx-auto mb-6 rounded-full"></div>
<p class="text-xl font-bold text-white mb-8 max-w-sm leading-relaxed" id="alert-msg">...</p>
<button onclick="dismissAlert()" class="bg-white text-red-600 px-8 py-3 rounded-xl font-black text-lg shadow-xl active:scale-95 transition-transform uppercase">
I Understand
</button>
<p class="mt-8 text-white/50 text-xs font-mono" id="alert-time">...</p>
</div>
<script src="app.js"></script>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => navigator.serviceWorker.register('/sw.js'));
}
// --- BROADCAST POLLING ---
let lastAlertTime = localStorage.getItem('last_alert_seen') || 0;
async function checkBroadcast() {
try {
const res = await fetch('broadcast_api.php?t=' + Date.now()); // Prevent caching
const data = await res.json();
if (data.active && data.message) {
if (data.timestamp > lastAlertTime) {
// New Alert!
document.getElementById('alert-msg').innerText = data.message;
document.getElementById('alert-time').innerText = "Issued: " + new Date(data.timestamp * 1000).toLocaleTimeString();
document.getElementById('emergency-alert').classList.remove('hidden');
// Vibrate phone if supported
if (navigator.vibrate) navigator.vibrate([500, 200, 500, 200, 1000]);
// Store temporarily so we know THIS specific alert is currently being shown
window.currentAlertTimestamp = data.timestamp;
}
}
} catch(e) { console.log("Connection check skipped"); }
}
function dismissAlert() {
document.getElementById('emergency-alert').classList.add('hidden');
// Save that we've seen this alert
if (window.currentAlertTimestamp) {
lastAlertTime = window.currentAlertTimestamp;
localStorage.setItem('last_alert_seen', lastAlertTime);
}
}
// Poll every 10 seconds
setInterval(checkBroadcast, 10000);
checkBroadcast(); // Initial check
</script>
</body>
</html>