|
|
|
|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>ComSync Pro - Team Communication Dashboard</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<script src="https://unpkg.com/feather-icons"></script> |
|
|
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> |
|
|
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.net.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; |
|
|
} |
|
|
.gradient-map { |
|
|
background: linear-gradient(135deg, #e0f7fa 0%, #b2ebf2 50%, #80deea 100%); |
|
|
} |
|
|
.signal-bar { |
|
|
width: 4px; |
|
|
margin: 0 1px; |
|
|
} |
|
|
.animate-pulse { |
|
|
animation: pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite; |
|
|
} |
|
|
@keyframes pulse { |
|
|
0%, 100% { opacity: 1; } |
|
|
50% { opacity: 0.5; } |
|
|
} |
|
|
.scrollbar-hide::-webkit-scrollbar { |
|
|
display: none; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="bg-gray-900 text-gray-100"> |
|
|
<custom-navbar></custom-navbar> |
|
|
<div id="vanta-bg" class="fixed inset-0 z-0"></div> |
|
|
<div class="relative z-10 min-h-screen p-4 md:p-6"> |
|
|
|
|
|
<header class="bg-gray-800/80 backdrop-blur-md rounded-xl p-4 mb-6 border border-gray-700/50 shadow-lg"> |
|
|
<div class="flex flex-col md:flex-row justify-between items-start md:items-center gap-4"> |
|
|
<div class="flex items-center space-x-3"> |
|
|
<i data-feather="radio" class="w-8 h-8 text-blue-400"></i> |
|
|
<h1 class="text-2xl font-bold bg-gradient-to-r from-blue-400 to-green-400 bg-clip-text text-transparent">ComSync Pro</h1> |
|
|
</div> |
|
|
<div class="flex flex-wrap items-center gap-4"> |
|
|
<div class="status-pill flex items-center px-3 py-1 rounded-full text-sm bg-green-900/30 text-green-400"> |
|
|
<i data-feather="check-circle" class="w-4 h-4 mr-1"></i> |
|
|
CRM: Connected |
|
|
</div> |
|
|
<div class="flex items-center space-x-1"> |
|
|
<i data-feather="wifi" class="w-5 h-5 text-green-400"></i> |
|
|
<div class="flex h-4"> |
|
|
<div class="signal-bar h-1 bg-green-500"></div> |
|
|
<div class="signal-bar h-2 bg-green-500"></div> |
|
|
<div class="signal-bar h-3 bg-green-500"></div> |
|
|
<div class="signal-bar h-4 bg-green-500"></div> |
|
|
<div class="signal-bar h-4 bg-gray-600"></div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex items-center space-x-1"> |
|
|
<i data-feather="battery" class="w-5 h-5 text-green-400"></i> |
|
|
<span class="text-sm">85%</span> |
|
|
</div> |
|
|
<div class="flex items-center space-x-1"> |
|
|
<i data-feather="clock" class="w-5 h-5"></i> |
|
|
<span class="text-sm" id="current-time">14:45:32</span> |
|
|
</div> |
|
|
<button class="settings-btn p-2 bg-gray-700/50 hover:bg-gray-600/50 rounded-lg transition-all"> |
|
|
<i data-feather="settings" class="w-5 h-5"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</header> |
|
|
|
|
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6"> |
|
|
|
|
|
<div class="lg:col-span-1 space-y-6"> |
|
|
|
|
|
<div class="bg-gray-800/80 backdrop-blur-md rounded-xl p-5 border border-gray-700/50 shadow-lg"> |
|
|
<div class="flex items-center justify-between mb-4"> |
|
|
<h2 class="text-lg font-semibold flex items-center"> |
|
|
<i data-feather="volume-2" class="w-5 h-5 mr-2 text-blue-400"></i> |
|
|
Channels |
|
|
</h2> |
|
|
<span class="text-xs bg-blue-900/30 text-blue-400 px-2 py-1 rounded-full">12 Active</span> |
|
|
</div> |
|
|
<div class="space-y-2"> |
|
|
<div class="channel-card" data-channel="Channel 1" data-dept="Operations"> |
|
|
<div class="channel-content bg-blue-600/20 border-l-4 border-blue-400 p-3 rounded-lg cursor-pointer transition-all hover:bg-blue-600/30"> |
|
|
<div class="flex justify-between items-center"> |
|
|
<div> |
|
|
<h3 class="font-medium">Channel 1</h3> |
|
|
<p class="text-sm text-blue-200">Operations</p> |
|
|
</div> |
|
|
<div class="flex items-center space-x-1"> |
|
|
<i data-feather="users" class="w-4 h-4"></i> |
|
|
<span class="text-xs">12</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="channel-card" data-channel="Channel 2" data-dept="Logistics"> |
|
|
<div class="channel-content bg-gray-700/50 hover:bg-gray-600/50 p-3 rounded-lg cursor-pointer transition-all"> |
|
|
<div class="flex justify-between items-center"> |
|
|
<div> |
|
|
<h3 class="font-medium">Channel 2</h3> |
|
|
<p class="text-sm text-gray-300">Logistics</p> |
|
|
</div> |
|
|
<div class="flex items-center space-x-1"> |
|
|
<i data-feather="users" class="w-4 h-4"></i> |
|
|
<span class="text-xs">8</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="channel-card" data-channel="Channel 3" data-dept="Medical"> |
|
|
<div class="channel-content bg-gray-700/50 hover:bg-gray-600/50 p-3 rounded-lg cursor-pointer transition-all"> |
|
|
<div class="flex justify-between items-center"> |
|
|
<div> |
|
|
<h3 class="font-medium">Channel 3</h3> |
|
|
<p class="text-sm text-gray-300">Medical</p> |
|
|
</div> |
|
|
<div class="flex items-center space-x-1"> |
|
|
<i data-feather="users" class="w-4 h-4"></i> |
|
|
<span class="text-xs">5</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="channel-card" data-channel="Channel 4" data-dept="Security"> |
|
|
<div class="channel-content bg-gray-700/50 hover:bg-gray-600/50 p-3 rounded-lg cursor-pointer transition-all"> |
|
|
<div class="flex justify-between items-center"> |
|
|
<div> |
|
|
<h3 class="font-medium">Channel 4</h3> |
|
|
<p class="text-sm text-gray-300">Security</p> |
|
|
</div> |
|
|
<div class="flex items-center space-x-1"> |
|
|
<i data-feather="users" class="w-4 h-4"></i> |
|
|
<span class="text-xs">15</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-gray-800/80 backdrop-blur-md rounded-xl p-5 border border-gray-700/50 shadow-lg"> |
|
|
<div class="flex items-center justify-between mb-4"> |
|
|
<h2 class="text-lg font-semibold flex items-center"> |
|
|
<i data-feather="users" class="w-5 h-5 mr-2 text-green-400"></i> |
|
|
Team Status |
|
|
</h2> |
|
|
<span class="text-xs bg-green-900/30 text-green-400 px-2 py-1 rounded-full">4 Online</span> |
|
|
</div> |
|
|
|
|
|
<div class="relative mb-4"> |
|
|
<i data-feather="search" class="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400"></i> |
|
|
<input id="team-search" type="text" placeholder="Search team..." class="w-full pl-10 pr-4 py-2 bg-gray-700/50 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm"> |
|
|
</div> |
|
|
|
|
|
<div class="space-y-3 max-h-[420px] overflow-y-auto scrollbar-hide"> |
|
|
<div class="team-member" data-member="John Smith"> |
|
|
<div class="team-member-content bg-blue-900/20 p-3 rounded-lg flex items-center justify-between cursor-pointer transition-all hover:bg-blue-900/40 border border-transparent hover:border-blue-500"> |
|
|
<div class="flex items-center space-x-3"> |
|
|
<div class="w-2 h-2 rounded-full bg-green-500 animate-pulse"></div> |
|
|
<div> |
|
|
<p class="font-medium text-sm">John Smith</p> |
|
|
<div class="flex items-center text-xs text-gray-400"> |
|
|
<i data-feather="map-pin" class="w-3 h-3 mr-1"></i> |
|
|
<span>Sector 7</span> |
|
|
</div> |
|
|
<div class="text-xs text-gray-500">Field Operator • Operations</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex items-center space-x-2"> |
|
|
<button class="video-call-btn p-1.5 bg-blue-600 rounded hover:bg-blue-700 transition-colors"> |
|
|
<i data-feather="video" class="w-3 h-3"></i> |
|
|
</button> |
|
|
<div class="flex items-center"> |
|
|
<i data-feather="battery" class="w-3 h-3 mr-1"></i> |
|
|
<span class="text-xs">92%</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="team-member" data-member="Maria Garcia"> |
|
|
<div class="team-member-content bg-gray-700/50 hover:bg-gray-600/50 p-3 rounded-lg flex items-center justify-between cursor-pointer transition-all"> |
|
|
<div class="flex items-center space-x-3"> |
|
|
<div class="w-2 h-2 rounded-full bg-green-500"></div> |
|
|
<div> |
|
|
<p class="font-medium text-sm">Maria Garcia</p> |
|
|
<div class="flex items-center text-xs text-gray-400"> |
|
|
<i data-feather="map-pin" class="w-3 h-3 mr-1"></i> |
|
|
<span>Base Camp</span> |
|
|
</div> |
|
|
<div class="text-xs text-gray-500">Logistics Coordinator • Logistics</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex items-center space-x-2"> |
|
|
<button class="video-call-btn p-1.5 bg-blue-600 rounded hover:bg-blue-700 transition-colors"> |
|
|
<i data-feather="video" class="w-3 h-3"></i> |
|
|
</button> |
|
|
<div class="flex items-center"> |
|
|
<i data-feather="battery" class="w-3 h-3 mr-1"></i> |
|
|
<span class="text-xs">78%</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="team-member" data-member="Robert Johnson"> |
|
|
<div class="team-member-content bg-gray-700/50 hover:bg-gray-600/50 p-3 rounded-lg flex items-center justify-between cursor-pointer transition-all"> |
|
|
<div class="flex items-center space-x-3"> |
|
|
<div class="w-2 h-2 rounded-full bg-red-500"></div> |
|
|
<div> |
|
|
<p class="font-medium text-sm">Robert Johnson</p> |
|
|
<div class="flex items-center text-xs text-gray-400"> |
|
|
<i data-feather="map-pin" class="w-3 h-3 mr-1"></i> |
|
|
<span>Sector 3</span> |
|
|
</div> |
|
|
<div class="text-xs text-gray-500">Maintenance Tech • Support</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex items-center space-x-2"> |
|
|
<div class="flex items-center"> |
|
|
<i data-feather="battery" class="w-3 h-3 mr-1"></i> |
|
|
<span class="text-xs">45%</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="lg:col-span-3 space-y-6"> |
|
|
|
|
|
<div class="bg-gray-800/80 backdrop-blur-md rounded-xl p-5 border border-gray-700/50 shadow-lg"> |
|
|
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-4 gap-3"> |
|
|
<h2 class="text-lg font-semibold flex items-center"> |
|
|
<i data-feather="map-pin" class="w-5 h-5 mr-2 text-green-400"></i> |
|
|
Live Location Tracking |
|
|
</h2> |
|
|
<div class="flex items-center space-x-3"> |
|
|
<div class="text-sm bg-blue-900/30 px-3 py-1 rounded-full flex items-center"> |
|
|
<i data-feather="monitor" class="w-4 h-4 mr-1"></i> |
|
|
Selected: John Smith |
|
|
</div> |
|
|
<button id="refresh-btn" class="p-2 bg-gray-700/50 hover:bg-gray-600/50 rounded-lg transition-all"> |
|
|
<i data-feather="refresh-cw" class="w-4 h-4"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="relative w-full h-96 bg-gradient-to-br from-blue-50 to-green-50 rounded-lg overflow-hidden border-2 border-gray-600/30"> |
|
|
|
|
|
<iframe |
|
|
src="https://www.google.com/maps/embed?pb=!1m14!1m12!1m3!1d3022.21537388927!2d-73.98784468459382!3d40.74844047932893!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!5e0!3m2!1sen!2sus!4v1620000000000!5m2!1sen!2sus" |
|
|
style="border:0;" |
|
|
allowfullscreen="" |
|
|
loading="lazy" |
|
|
class="w-full h-full" |
|
|
></iframe> |
|
|
|
|
|
<div class="absolute top-4 right-4 bg-white/90 rounded-lg p-2 shadow-lg"> |
|
|
<div class="flex flex-col space-y-2"> |
|
|
<button id="map-zoom-in" class="w-8 h-8 bg-gray-200 rounded flex items-center justify-center hover:bg-gray-300"> |
|
|
<i data-feather="plus" class="w-4 h-4 text-gray-700"></i> |
|
|
</button> |
|
|
<button id="map-zoom-out" class="w-8 h-8 bg-gray-200 rounded flex items-center justify-center hover:bg-gray-300"> |
|
|
<i data-feather="minus" class="w-4 h-4 text-gray-700"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="mt-4 p-4 bg-gray-700/50 rounded-lg"> |
|
|
<div class="flex flex-col md:flex-row justify-between items-start md:items-center gap-4"> |
|
|
<div> |
|
|
<h3 id="selected-member-name" class="font-semibold text-lg">John Smith</h3> |
|
|
<div class="flex items-center text-sm text-gray-300 mt-1"> |
|
|
<i data-feather="map-pin" class="w-4 h-4 mr-1"></i> |
|
|
<span id="selected-member-coords">40.74844° N, -73.98566° W</span> |
|
|
</div> |
|
|
<div class="text-sm text-gray-400 mt-1"> |
|
|
Last seen: <span id="last-seen">2 minutes ago</span> |
|
|
</div> |
|
|
<div id="selected-member-role" class="text-sm text-gray-300 mt-1"> |
|
|
Role: Field Operator • Dept: Operations |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex flex-col items-end gap-2"> |
|
|
<div id="selected-member-status-indicator" class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-green-900/30 text-green-400"> |
|
|
Online |
|
|
</div> |
|
|
<div class="flex space-x-3"> |
|
|
<button id="video-call-btn" class="flex items-center px-3 py-1.5 rounded text-sm bg-blue-600 hover:bg-blue-700 transition-colors"> |
|
|
<i data-feather="video" class="w-4 h-4 mr-1"></i> |
|
|
Video Call |
|
|
</button> |
|
|
<div class="text-sm flex items-center"> |
|
|
<i data-feather="battery" class="w-4 h-4 mr-1"></i> |
|
|
<span id="selected-member-battery">92%</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6"> |
|
|
|
|
|
<div class="bg-gray-800/80 backdrop-blur-md rounded-xl p-5 border border-gray-700/50 shadow-lg"> |
|
|
<div class="flex justify-between items-center mb-4"> |
|
|
<h2 class="text-lg font-semibold"><span id="current-channel">Channel 1</span> - Operations</h2> |
|
|
<div class="flex items-center space-x-2"> |
|
|
<div class="w-2 h-2 rounded-full bg-green-500 animate-pulse"></div> |
|
|
<span class="text-xs">READY</span> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="flex justify-center my-6"> |
|
|
<button id="transmit-btn" class="transmit-btn w-24 h-24 rounded-full bg-blue-600 hover:bg-blue-500 hover:scale-105 transition-all flex items-center justify-center shadow-lg"> |
|
|
<i data-feather="mic" class="w-10 h-10 text-white"></i> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<p class="text-center text-gray-400 text-sm">Press and hold to transmit</p> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-gray-800/80 backdrop-blur-md rounded-xl p-5 border border-gray-700/50 shadow-lg"> |
|
|
<h2 class="text-lg font-semibold mb-4">Recent Communications</h2> |
|
|
<div class="space-y-3 max-h-72 overflow-y-auto scrollbar-hide"> |
|
|
<div class="bg-gray-700/50 p-3 rounded-lg"> |
|
|
<div class="flex justify-between items-start mb-2"> |
|
|
<div class="flex items-center space-x-2"> |
|
|
<span class="font-medium text-blue-400">Team Alpha</span> |
|
|
<span class="text-xs bg-gray-600/50 px-2 py-1 rounded">Channel 1</span> |
|
|
</div> |
|
|
<span class="text-xs text-gray-400">14:32</span> |
|
|
</div> |
|
|
<p class="text-gray-200 mb-2">Moving to sector 7</p> |
|
|
<div class="flex items-center text-xs text-gray-400"> |
|
|
<i data-feather="map-pin" class="w-3 h-3 mr-1"></i> |
|
|
<span>Location recorded</span> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="bg-gray-700/50 p-3 rounded-lg"> |
|
|
<div class="flex justify-between items-start mb-2"> |
|
|
<div class="flex items-center space-x-2"> |
|
|
<span class="font-medium text-blue-400">Medical Team</span> |
|
|
<span class="text-xs bg-gray-600/50 px-2 py-1 rounded">Channel 3</span> |
|
|
</div> |
|
|
<span class="text-xs text-gray-400">14:28</span> |
|
|
</div> |
|
|
<p class="text-gray-200 mb-2">Patient status stable</p> |
|
|
<div class="flex items-center text-xs text-gray-400"> |
|
|
<i data-feather="map-pin" class="w-3 h-3 mr-1"></i> |
|
|
<span>Location recorded</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4"> |
|
|
<div class="bg-green-900/30 p-4 rounded-lg text-center border border-green-900/30"> |
|
|
<i data-feather="check-circle" class="w-6 h-6 text-green-400 mx-auto mb-2"></i> |
|
|
<p class="text-sm">Network</p> |
|
|
<p class="text-lg font-semibold text-green-400">Online</p> |
|
|
</div> |
|
|
<div class="bg-green-900/30 p-4 rounded-lg text-center border border-green-900/30"> |
|
|
<i data-feather="check-circle" class="w-6 h-6 text-green-400 mx-auto mb-2"></i> |
|
|
<p class="text-sm">GPS</p> |
|
|
<p class="text-lg font-semibold text-green-400">Active</p> |
|
|
</div> |
|
|
<div class="bg-yellow-900/30 p-4 rounded-lg text-center border border-yellow-900/30"> |
|
|
<i data-feather="alert-triangle" class="w-6 h-6 text-yellow-400 mx-auto mb-2"></i> |
|
|
<p class="text-sm">Signal</p> |
|
|
<p class="text-lg font-semibold text-yellow-400">Good</p> |
|
|
</div> |
|
|
<div class="bg-green-900/30 p-4 rounded-lg text-center border border-green-900/30"> |
|
|
<i data-feather="check-circle" class="w-6 h-6 text-green-400 mx-auto mb-2"></i> |
|
|
<p class="text-sm">Battery</p> |
|
|
<p class="text-lg font-semibold text-green-400">85%</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div id="settings-modal" class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 hidden"> |
|
|
<div class="flex items-center justify-center min-h-screen p-4"> |
|
|
<div class="bg-gray-800 rounded-xl p-6 w-full max-w-md border border-gray-700 shadow-2xl"> |
|
|
<div class="flex justify-between items-center mb-4"> |
|
|
<h2 class="text-xl font-semibold">Settings</h2> |
|
|
<button id="close-settings" class="p-2 hover:bg-gray-700 rounded-lg"> |
|
|
<i data-feather="x" class="w-5 h-5"></i> |
|
|
</button> |
|
|
</div> |
|
|
<div class="space-y-4"> |
|
|
<div> |
|
|
<label class="block text-sm font-medium mb-2">Audio Output</label> |
|
|
<select class="w-full bg-gray-700 rounded-lg px-3 py-2"> |
|
|
<option>Speaker</option> |
|
|
<option>Headphones</option> |
|
|
<option>Bluetooth</option> |
|
|
</select> |
|
|
</div> |
|
|
<div> |
|
|
<label class="block text-sm font-medium mb-2">Push-to-Talk Key</label> |
|
|
<input type="text" value="SPACE" class="w-full bg-gray-700 rounded-lg px-3 py-2" readonly> |
|
|
</div> |
|
|
<div> |
|
|
<label class="block text-sm font-medium mb-2">Map Refresh Rate</label> |
|
|
<select class="w-full bg-gray-700 rounded-lg px-3 py-2"> |
|
|
<option>5 seconds</option> |
|
|
<option>10 seconds</option> |
|
|
<option>30 seconds</option> |
|
|
</select> |
|
|
</div> |
|
|
<div class="flex items-center justify-between"> |
|
|
<span class="text-sm font-medium">Notifications</span> |
|
|
<button id="notifications-toggle" class="w-12 h-6 bg-blue-600 rounded-full relative"> |
|
|
<div class="w-5 h-5 bg-white rounded-full absolute top-0.5 left-0.5 transition-transform"></div> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<script> |
|
|
|
|
|
VANTA.NET({ |
|
|
el: "#vanta-bg", |
|
|
mouseControls: true, |
|
|
touchControls: true, |
|
|
gyroControls: false, |
|
|
minHeight: 200.00, |
|
|
minWidth: 200.00, |
|
|
scale: 1.00, |
|
|
scaleMobile: 1.00, |
|
|
color: 0x3a82ff, |
|
|
backgroundColor: 0x111827, |
|
|
points: 10.00, |
|
|
maxDistance: 22.00, |
|
|
spacing: 18.00 |
|
|
}); |
|
|
|
|
|
|
|
|
function updateTime() { |
|
|
const now = new Date(); |
|
|
document.getElementById('current-time').textContent = now.toLocaleTimeString(); |
|
|
} |
|
|
setInterval(updateTime, 1000); |
|
|
updateTime(); |
|
|
|
|
|
|
|
|
feather.replace(); |
|
|
|
|
|
|
|
|
let currentSelectedMember = 'John Smith'; |
|
|
let currentSelectedChannel = 'Channel 1'; |
|
|
let transmitActive = false; |
|
|
|
|
|
|
|
|
const teamMembers = { |
|
|
'John Smith': { |
|
|
position: { lat: 40.74844, lng: -73.98566 }, |
|
|
status: 'online', |
|
|
battery: 92, |
|
|
role: 'Field Operator', |
|
|
department: 'Operations', |
|
|
location: 'Sector 7' |
|
|
}, |
|
|
'Maria Garcia': { |
|
|
position: { lat: 40.74890, lng: -73.98750 }, |
|
|
status: 'online', |
|
|
battery: 78, |
|
|
role: 'Logistics Coordinator', |
|
|
department: 'Logistics', |
|
|
location: 'Base Camp' |
|
|
}, |
|
|
'Robert Johnson': { |
|
|
position: { lat: 40.74780, lng: -73.98620 }, |
|
|
status: 'offline', |
|
|
battery: 45, |
|
|
role: 'Maintenance Tech', |
|
|
department: 'Support', |
|
|
location: 'Sector 3' |
|
|
} |
|
|
}; |
|
|
|
|
|
function updateMemberDetails(member) { |
|
|
const details = teamMembers[member]; |
|
|
document.querySelector('#selected-member-name').textContent = member; |
|
|
document.querySelector('#selected-member-coords').textContent = `${details.position.lat.toFixed(5)}° N, ${details.position.lng.toFixed(5)}° W`; |
|
|
document.querySelector('#selected-member-battery').textContent = `${details.battery}%`; |
|
|
document.querySelector('#selected-member-role').textContent = `Role: ${details.role} • Dept: ${details.department}`; |
|
|
|
|
|
|
|
|
const statusIndicator = document.querySelector('#selected-member-status-indicator'); |
|
|
statusIndicator.className = `inline-flex items-center px-3 py-1 rounded-full text-xs font-medium ${details.status === 'online' ? 'bg-green-900/30 text-green-400' : 'bg-red-900/30 text-red-400'}`; |
|
|
statusIndicator.textContent = details.status === 'online' ? 'Online' : 'Offline'; |
|
|
|
|
|
|
|
|
document.querySelectorAll('.team-member-content').forEach(el => { |
|
|
el.classList.remove('bg-blue-900/20', 'border-blue-500'); |
|
|
el.classList.add('bg-gray-700/50', 'hover:bg-gray-600/50'); |
|
|
}); |
|
|
const selectedEl = document.querySelector(`[data-member="${member}"] .team-member-content`); |
|
|
if (selectedEl) { |
|
|
selectedEl.classList.remove('bg-gray-700/50', 'hover:bg-gray-600/50'); |
|
|
selectedEl.classList.add('bg-blue-900/20', 'border-blue-500'); |
|
|
} |
|
|
|
|
|
currentSelectedMember = member; |
|
|
} |
|
|
|
|
|
|
|
|
document.querySelectorAll('.team-member').forEach(member => { |
|
|
member.addEventListener('click', (e) => { |
|
|
if (!e.target.closest('.video-call-btn')) { |
|
|
const memberName = member.dataset.member; |
|
|
updateMemberDetails(memberName); |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
document.querySelectorAll('.video-call-btn').forEach(btn => { |
|
|
btn.addEventListener('click', (e) => { |
|
|
e.stopPropagation(); |
|
|
const memberName = btn.closest('.team-member').dataset.member; |
|
|
alert(`Initiating video call with ${memberName}...`); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
document.querySelectorAll('.channel-card').forEach(card => { |
|
|
card.addEventListener('click', () => { |
|
|
const channelName = card.dataset.channel; |
|
|
const deptName = card.dataset.dept; |
|
|
|
|
|
|
|
|
document.querySelectorAll('.channel-content').forEach(el => { |
|
|
el.classList.remove('bg-blue-600/20', 'border-l-4', 'border-blue-400'); |
|
|
el.classList.add('bg-gray-700/50', 'hover:bg-gray-600/50'); |
|
|
}); |
|
|
const selectedEl = card.querySelector('.channel-content'); |
|
|
selectedEl.classList.remove('bg-gray-700/50', 'hover:bg-gray-600/50'); |
|
|
selectedEl.classList.add('bg-blue-600/20', 'border-l-4', 'border-blue-400'); |
|
|
|
|
|
|
|
|
document.getElementById('current-channel').textContent = channelName; |
|
|
document.querySelector('.transmit-panel h2').innerHTML = `${channelName} - <span class="text-blue-400">${deptName}</span>`; |
|
|
|
|
|
currentSelectedChannel = channelName; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
const transmitBtn = document.getElementById('transmit-btn'); |
|
|
let transmitInterval; |
|
|
|
|
|
function startTransmit() { |
|
|
if (transmitActive) return; |
|
|
transmitActive = true; |
|
|
transmitBtn.classList.add('bg-red-600', 'animate-pulse'); |
|
|
transmitBtn.classList.remove('bg-blue-600'); |
|
|
|
|
|
|
|
|
transmitInterval = setInterval(() => { |
|
|
console.log(`Transmitting on ${currentSelectedChannel}...`); |
|
|
}, 1000); |
|
|
} |
|
|
|
|
|
function stopTransmit() { |
|
|
if (!transmitActive) return; |
|
|
transmitActive = false; |
|
|
transmitBtn.classList.remove('bg-red-600', 'animate-pulse'); |
|
|
transmitBtn.classList.add('bg-blue-600'); |
|
|
clearInterval(transmitInterval); |
|
|
} |
|
|
|
|
|
|
|
|
transmitBtn.addEventListener('mousedown', startTransmit); |
|
|
transmitBtn.addEventListener('mouseup', stopTransmit); |
|
|
transmitBtn.addEventListener('mouseleave', stopTransmit); |
|
|
|
|
|
|
|
|
transmitBtn.addEventListener('touchstart', (e) => { |
|
|
e.preventDefault(); |
|
|
startTransmit(); |
|
|
}); |
|
|
transmitBtn.addEventListener('touchend', (e) => { |
|
|
e.preventDefault(); |
|
|
stopTransmit(); |
|
|
}); |
|
|
|
|
|
|
|
|
const settingsBtn = document.querySelector('.settings-btn'); |
|
|
const settingsModal = document.getElementById('settings-modal'); |
|
|
const closeSettings = document.getElementById('close-settings'); |
|
|
|
|
|
settingsBtn.addEventListener('click', () => { |
|
|
settingsModal.classList.remove('hidden'); |
|
|
feather.replace(); |
|
|
}); |
|
|
|
|
|
closeSettings.addEventListener('click', () => { |
|
|
settingsModal.classList.add('hidden'); |
|
|
}); |
|
|
|
|
|
settingsModal.addEventListener('click', (e) => { |
|
|
if (e.target === settingsModal) { |
|
|
settingsModal.classList.add('hidden'); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const notificationsToggle = document.getElementById('notifications-toggle'); |
|
|
let notificationsOn = true; |
|
|
notificationsToggle.addEventListener('click', () => { |
|
|
notificationsOn = !notificationsOn; |
|
|
const toggle = notificationsToggle.querySelector('div'); |
|
|
if (notificationsOn) { |
|
|
notificationsToggle.classList.remove('bg-gray-600'); |
|
|
notificationsToggle.classList.add('bg-blue-600'); |
|
|
toggle.style.transform = 'translateX(0)'; |
|
|
} else { |
|
|
notificationsToggle.classList.remove('bg-blue-600'); |
|
|
notificationsToggle.classList.add('bg-gray-600'); |
|
|
toggle.style.transform = 'translateX(24px)'; |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const searchInput = document.getElementById('team-search'); |
|
|
searchInput.addEventListener('input', (e) => { |
|
|
const query = e.target.value.toLowerCase(); |
|
|
document.querySelectorAll('.team-member').forEach(member => { |
|
|
const memberName = member.dataset.member.toLowerCase(); |
|
|
const memberText = member.textContent.toLowerCase(); |
|
|
if (memberName.includes(query) || memberText.includes(query)) { |
|
|
member.style.display = 'block'; |
|
|
} else { |
|
|
member.style.display = 'none'; |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
document.getElementById('refresh-btn').addEventListener('click', () => { |
|
|
|
|
|
document.getElementById('refresh-btn').classList.add('animate-spin'); |
|
|
setTimeout(() => { |
|
|
document.getElementById('refresh-btn').classList.remove('animate-spin'); |
|
|
updateMemberDetails(currentSelectedMember); |
|
|
}, 1000); |
|
|
}); |
|
|
|
|
|
|
|
|
let zoomLevel = 15; |
|
|
document.getElementById('map-zoom-in').addEventListener('click', () => { |
|
|
zoomLevel = Math.min(zoomLevel + 1, 20); |
|
|
console.log(`Zooming in to level ${zoomLevel}`); |
|
|
|
|
|
}); |
|
|
|
|
|
document.getElementById('map-zoom-out').addEventListener('click', () => { |
|
|
zoomLevel = Math.max(zoomLevel - 1, 10); |
|
|
console.log(`Zooming out to level ${zoomLevel}`); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
document.getElementById('video-call-btn').addEventListener('click', () => { |
|
|
alert(`Initiating video call with ${currentSelectedMember}...`); |
|
|
}); |
|
|
|
|
|
function simulateRealTimeUpdates() { |
|
|
|
|
|
Object.keys(teamMembers).forEach(member => { |
|
|
if (teamMembers[member].battery > 0) { |
|
|
const drain = Math.random() > 0.7 ? Math.floor(Math.random() * 3) : 0; |
|
|
teamMembers[member].battery = Math.max(0, teamMembers[member].battery - drain); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const batteryElement = document.querySelector('.flex.items-center.space-x-1:nth-child(3) span'); |
|
|
if (batteryElement) { |
|
|
const currentBattery = parseInt(batteryElement.textContent); |
|
|
const newBattery = Math.max(0, currentBattery - Math.floor(Math.random() * 2)); |
|
|
batteryElement.textContent = `${newBattery}%`; |
|
|
} |
|
|
|
|
|
|
|
|
if (currentSelectedMember) { |
|
|
updateMemberDetails(currentSelectedMember); |
|
|
} |
|
|
|
|
|
|
|
|
const signalBars = document.querySelectorAll('.signal-bar'); |
|
|
const strength = Math.floor(Math.random() * 5) + 1; |
|
|
signalBars.forEach((bar, index) => { |
|
|
if (index < strength) { |
|
|
bar.classList.remove('bg-gray-600'); |
|
|
bar.classList.add('bg-green-500'); |
|
|
} else { |
|
|
bar.classList.remove('bg-green-500'); |
|
|
bar.classList.add('bg-gray-600'); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
const lastSeenElement = document.getElementById('last-seen'); |
|
|
if (lastSeenElement) { |
|
|
const minutes = Math.floor(Math.random() * 10) + 1; |
|
|
lastSeenElement.textContent = `${minutes} minute${minutes > 1 ? 's' : ''} ago`; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
setInterval(simulateRealTimeUpdates, 5000); |
|
|
|
|
|
|
|
|
document.getElementById('map-zoom-in').addEventListener('click', function() { |
|
|
this.classList.add('bg-gray-300'); |
|
|
setTimeout(() => this.classList.remove('bg-gray-300'), 200); |
|
|
}); |
|
|
|
|
|
document.getElementById('map-zoom-out').addEventListener('click', function() { |
|
|
this.classList.add('bg-gray-300'); |
|
|
setTimeout(() => this.classList.remove('bg-gray-300'), 200); |
|
|
}); |
|
|
|
|
|
|
|
|
document.querySelectorAll('.bg-gray-700\\/50.p-3.rounded-lg').forEach(item => { |
|
|
item.addEventListener('click', function() { |
|
|
const channel = this.querySelector('.bg-gray-600\\/50').textContent; |
|
|
const sender = this.querySelector('.font-medium').textContent; |
|
|
|
|
|
|
|
|
document.querySelectorAll('.bg-gray-700\\/50.p-3.rounded-lg').forEach(el => { |
|
|
el.classList.remove('bg-blue-900/20', 'border', 'border-blue-500'); |
|
|
}); |
|
|
this.classList.add('bg-blue-900/20', 'border', 'border-blue-500'); |
|
|
|
|
|
|
|
|
if (channel === 'Channel 1') { |
|
|
document.querySelectorAll('.channel-content').forEach(el => { |
|
|
el.classList.remove('bg-blue-600/20', 'border-l-4', 'border-blue-400'); |
|
|
el.classList.add('bg-gray-700/50', 'hover:bg-gray-600/50'); |
|
|
}); |
|
|
document.querySelector('[data-channel="Channel 1"] .channel-content').classList.remove('bg-gray-700/50', 'hover:bg-gray-600/50'); |
|
|
document.querySelector('[data-channel="Channel 1"] .channel-content').classList.add('bg-blue-600/20', 'border-l-4', 'border-blue-400'); |
|
|
document.getElementById('current-channel').textContent = 'Channel 1'; |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
document.addEventListener('keydown', (e) => { |
|
|
if (e.code === 'Space' && !transmitActive && !e.target.matches('input')) { |
|
|
e.preventDefault(); |
|
|
startTransmit(); |
|
|
} |
|
|
}); |
|
|
|
|
|
document.addEventListener('keyup', (e) => { |
|
|
if (e.code === 'Space' && transmitActive) { |
|
|
e.preventDefault(); |
|
|
stopTransmit(); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
updateMemberDetails(currentSelectedMember); |
|
|
</script> |
|
|
<script src="components/navbar.js"></script> |
|
|
</body> |
|
|
</html> |
|
|
|