Files
TeleEms-Dashboard/src/pages/Dashboard.tsx

908 lines
48 KiB
TypeScript

import React, { useState, useEffect, useMemo } from 'react';
import {
Activity,
Truck,
HeartPulse,
Video,
ShieldCheck,
Database,
Settings,
Users as UsersIcon,
RefreshCw,
Zap,
Navigation
} from 'lucide-react';
import { StatCard, Card } from '../components/Common';
import {
AreaChart,
Area,
Tooltip,
ResponsiveContainer,
PieChart,
Pie,
Cell
} from 'recharts';
import { motion, AnimatePresence } from 'framer-motion';
import { incidentsApi } from '../api/incidents';
import { authApi } from '../api/auth';
import type { Incident } from '../api/types';
// --- LIVE INCIDENT MAP COMPONENT ---
const LiveIncidentMap: React.FC<{ incidents: Incident[] }> = ({ incidents }) => {
const [isMapReady, setIsMapReady] = React.useState(false);
const mapRef = React.useRef<any>(null);
const containerRef = React.useRef<HTMLDivElement>(null);
const markersRef = React.useRef<{ [key: string]: any }>({});
const [L, setL] = React.useState<any>(null);
React.useEffect(() => {
if (typeof window === 'undefined') return;
// Ensure Leaflet assets are loaded
if (!document.getElementById('leaflet-style')) {
const link = document.createElement('link');
link.id = 'leaflet-style';
link.rel = 'stylesheet';
link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
document.head.appendChild(link);
}
const initMap = (leaflet: any) => {
if (!containerRef.current || mapRef.current) return;
// Defensive: Clear container if Leaflet previously left a trace but we lost the ref
if ((containerRef.current as any)._leaflet_id) {
containerRef.current.innerHTML = '';
delete (containerRef.current as any)._leaflet_id;
}
const m = leaflet.map(containerRef.current, {
zoomControl: false,
attributionControl: false
}).setView([12.9716, 77.5946], 11);
leaflet.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', {
maxZoom: 19
}).addTo(m);
mapRef.current = m;
m.whenReady(() => setIsMapReady(true));
};
const existingL = (window as any).L;
if (existingL) {
setL(existingL);
initMap(existingL);
} else {
const script = document.createElement('script');
script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
script.async = true;
script.onload = () => {
const leaflet = (window as any).L;
if (leaflet) {
setL(leaflet);
initMap(leaflet);
}
};
document.head.appendChild(script);
}
return () => {
if (mapRef.current) {
try {
mapRef.current.remove();
} catch (e) {
console.warn('Error removing map:', e);
}
mapRef.current = null;
setIsMapReady(false);
}
};
}, []);
React.useEffect(() => {
if (!L || !mapRef.current || !isMapReady) return;
const map = mapRef.current;
// Clear old markers that are no longer in the list
Object.keys(markersRef.current).forEach(id => {
if (!incidents.find(inc => inc.id === id)) {
markersRef.current[id].remove();
delete markersRef.current[id];
}
});
const coordMap: { [key: string]: number } = {};
incidents.forEach(inc => {
let lat = Number(inc.gps_lat);
let lon = Number(inc.gps_lon);
// Handle overlapping coordinates with deterministic jitter
const coordKey = `${lat.toFixed(5)},${lon.toFixed(5)}`;
const count = (coordMap[coordKey] || 0) + 1;
coordMap[coordKey] = count;
if (count > 1) {
// Spiral jitter for better visibility of multiple incidents at same spot
const radius = 0.0003 * Math.sqrt(count - 1);
const angle = (count - 1) * 137.5 * (Math.PI / 180); // Golden angle
lat += radius * Math.cos(angle);
lon += radius * Math.sin(angle);
}
let color = '#F59E0B'; // Default Amber for active
const status = inc.status?.toUpperCase();
if (status === 'COMPLETED' || status === 'HANDOVER') {
color = '#10B981'; // Green for resolved
} else if (status === 'CANCELLED') {
color = '#4A5568'; // Gray for cancelled
} else if (inc.severity?.toUpperCase() === 'CRITICAL') {
color = '#EF4444'; // Red for critical
}
if (!markersRef.current[inc.id]) {
const icon = L.divIcon({
className: 'custom-incident-marker',
html: `<div style="background-color: ${color}; width: 12px; height: 12px; border-radius: 50%; box-shadow: 0 0 15px ${color}; border: 2px solid #fff; position: relative;">
<div style="position: absolute; top: -4px; left: -4px; right: -4px; bottom: -4px; border-radius: 50%; border: 2px solid ${color}; animation: pulse-ring 2s infinite;"></div>
</div>`,
iconSize: [12, 12],
iconAnchor: [6, 6]
});
const callerName = inc.guest_name || inc.caller_id || 'Unknown';
const callerPhone = inc.guest_phone || 'N/A';
const patientCount = inc.patients?.length || 0;
markersRef.current[inc.id] = L.marker([lat, lon], { icon })
.addTo(map)
.bindPopup(`
<div style="padding: 12px; min-width: 220px; font-family: 'Inter', sans-serif; color: var(--text-primary);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<b style="color: var(--accent-cyan); font-size: 0.9rem; font-family: monospace;">#${inc.id.split('-').pop()?.toUpperCase()}</b>
<span style="font-size: 0.6rem; background: ${color}33; color: ${color}; padding: 2px 8px; border-radius: 4px; font-weight: 900; border: 1px solid ${color}66;">${inc.status}</span>
</div>
<div style="font-size: 0.75rem; color: var(--text-primary); margin-bottom: 6px; font-weight: 700;">${inc.category} <span style="color: ${color}">• ${inc.severity}</span></div>
<div style="font-size: 0.7rem; color: var(--text-secondary); margin-bottom: 12px; display: flex; align-items: start; gap: 6px; line-height: 1.4;">
<span style="font-size: 0.9rem;">📍</span> <span>${inc.address}</span>
</div>
<div style="background: rgba(0,0,0,0.02); padding: 10px; border-radius: 8px; border: 1px solid var(--card-border);">
<div style="display: flex; justify-content: space-between; margin-bottom: 4px;">
<span style="font-size: 0.6rem; color: #64748B; text-transform: uppercase; font-weight: 700;">Caller</span>
<span style="font-size: 0.7rem; font-weight: 700; color: var(--text-primary);">${callerName}</span>
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span style="font-size: 0.6rem; color: #64748B; text-transform: uppercase; font-weight: 700;">Phone</span>
<span style="font-size: 0.7rem; font-weight: 700; color: var(--text-primary);">${callerPhone}</span>
</div>
<div style="padding-top: 8px; border-top: 1px solid rgba(255,255,255,0.05); display: flex; flex-direction: column; gap: 4px;">
<div style="display: flex; align-items: center; gap: 6px;">
<div style="width: 6px; height: 6px; border-radius: 50%; background: var(--accent-cyan);"></div>
<span style="font-size: 0.65rem; font-weight: 800; color: var(--accent-cyan);">${patientCount} PATIENT${patientCount !== 1 ? 'S' : ''} DETECTED</span>
</div>
<div style="font-size: 0.6rem; color: #94A3B8; padding-left: 12px; font-style: italic; overflow: hidden; text-overflow: ellipsis; display: flex; flex-direction: column; gap: 2px;">
${inc.patients && inc.patients.length > 0 ? inc.patients.map((p: any) => `
<div style="display: flex; justify-content: space-between;">
<span>${p.name || 'Anonymous'} (${p.age || '?'}${p.gender ? p.gender[0] : ''})</span>
<span style="color: var(--accent-cyan)">${p.symptoms?.map((s: any) => typeof s === 'string' ? s : s.name).join(', ') || 'No symptoms'}</span>
</div>
`).join('') : 'No patient data'}
</div>
</div>
</div>
</div>
`, {
className: 'glass-popup',
maxWidth: 300
});
} else {
markersRef.current[inc.id].setLatLng([lat, lon]);
}
});
// Auto-fit map to show all incidents
if (incidents.length > 0 && map && isMapReady) {
try {
const validCoords = incidents
.map(i => [Number(i.gps_lat), Number(i.gps_lon)])
.filter(c =>
Number.isFinite(c[0]) &&
Number.isFinite(c[1]) &&
Math.abs(c[0]) <= 90 &&
Math.abs(c[1]) <= 180 &&
(c[0] !== 0 || c[1] !== 0) // Ignore 0,0 placeholders
);
if (validCoords.length > 0) {
const bounds = L.latLngBounds(validCoords as any);
const container = map.getContainer();
if (bounds.isValid() && container.offsetWidth > 0 && container.offsetHeight > 0) {
// If all points are at the exact same location, fitBounds can sometimes fail or behave weirdly
const sw = bounds.getSouthWest();
const ne = bounds.getNorthEast();
if (sw.lat === ne.lat && sw.lng === ne.lng) {
map.setView(sw, 14);
} else {
map.fitBounds(bounds, { padding: [50, 50], maxZoom: 14 });
}
}
}
} catch (err) {
// Suppress specific "Bounds are not valid" error as we handle it defensively now
if (!(err instanceof Error && err.message.includes('Bounds are not valid'))) {
console.error('Map fitBounds error:', err);
}
}
} else if (map && isMapReady) {
// Default view if no incidents
map.setView([12.9716, 77.5946], 11);
}
map.on('click', (e: any) => {
const { lat, lng } = e.latlng;
// Emit a custom event or use a ref to open the modal from the parent
const event = new CustomEvent('map-click-add', { detail: { lat, lng } });
window.dispatchEvent(event);
});
}, [incidents, L, isMapReady]);
return (
<div ref={containerRef} id="dashboard-heatmap-container" style={{ height: '450px', borderRadius: '12px', overflow: 'hidden', position: 'relative', border: '1px solid var(--card-border)' }}>
{!L && <div style={{ height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--text-secondary)', background: 'rgba(0,0,0,0.02)' }}>INITIALIZING GLOBAL HEATMAP...</div>}
</div>
);
};
// --- CUSTOM CHART COMPONENTS ---
const CustomChartTooltip = ({ active, payload }: any) => {
if (active && payload && payload.length) {
return (
<div className="glass" style={{
padding: '12px',
background: 'rgba(255, 255, 255, 0.95)',
border: `1px solid ${payload[0].payload.color}`,
boxShadow: `0 8px 32px rgba(0,0,0,0.05), 0 0 20px ${payload[0].payload.color}11`,
borderRadius: '12px',
backdropFilter: 'blur(10px)'
}}>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '6px' }}>
<div style={{ width: '8px', height: '8px', borderRadius: '2px', background: payload[0].payload.color, boxShadow: `0 0 8px ${payload[0].payload.color}` }}></div>
<span style={{ fontSize: '0.7rem', fontWeight: 800, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>{payload[0].name} Status</span>
</div>
<div style={{ fontSize: '1.2rem', fontWeight: 900, color: 'var(--text-primary)', display: 'flex', alignItems: 'baseline', gap: '4px' }}>
{payload[0].value}
<span style={{ fontSize: '0.6rem', color: 'var(--text-secondary)', fontWeight: 600 }}>ASSETS</span>
</div>
</div>
);
}
return null;
};
// --- PREMIUM COMPONENTS ---
const PremiumStatCard: React.FC<{
label: string;
value: string | number;
subValue?: string;
icon: any;
trend?: { value: string; isUp: boolean };
glowColor: 'cyan' | 'green' | 'red' | 'amber';
pulse?: boolean;
}> = ({ label, value, subValue, icon: Icon, trend, glowColor, pulse }) => {
const colors = {
cyan: { bg: 'rgba(59, 130, 246, 0.1)', text: 'var(--accent-cyan)' },
green: { bg: 'rgba(16, 185, 129, 0.1)', text: 'var(--accent-green)' },
red: { bg: 'rgba(239, 68, 68, 0.1)', text: 'var(--alert-red)' },
amber: { bg: 'rgba(245, 158, 11, 0.1)', text: 'var(--warning-amber)' },
};
const theme = colors[glowColor];
return (
<div className="premium-stat-card">
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
<div className="premium-stat-icon-wrap" style={{ background: theme.bg, color: theme.text }}>
<Icon size={22} />
</div>
{pulse && <div className="status-pulse" style={{ background: theme.text }}></div>}
</div>
<div className="premium-stat-label">{label}</div>
<div className="premium-stat-value">
{value}
{subValue && <span className="premium-stat-sub">/ {subValue}</span>}
</div>
{trend && (
<div style={{
marginTop: '12px',
fontSize: '0.75rem',
fontWeight: 700,
color: trend.isUp ? 'var(--accent-green)' : 'var(--alert-red)',
display: 'flex',
alignItems: 'center',
gap: '4px'
}}>
{trend.isUp ? '↑' : '↓'} {trend.value} <span style={{ color: 'var(--text-secondary)' }}>vs last hour</span>
</div>
)}
</div>
);
};
export const Dashboard: React.FC = () => {
const [incidents, setIncidents] = useState<Incident[]>([]);
const [users, setUsers] = useState<any[]>([]);
const [auditLogs, setAuditLogs] = useState<any[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [lastUpdated, setLastUpdated] = useState(new Date());
const user = useMemo(() => {
try {
const stored = localStorage.getItem('teleems_user');
if (!stored || stored === 'undefined' || stored === 'null') return {};
const parsed = JSON.parse(stored);
return parsed && typeof parsed === 'object' ? parsed : {};
} catch {
return {};
}
}, []);
const token = localStorage.getItem('teleems_token') || '';
const roles = Array.isArray(user.roles) ? user.roles : [];
const isFleetOp = roles.includes('FLEET_OPERATOR');
const isHospitalAdmin = roles.some((r: string) => r.toUpperCase() === 'HOSPITAL_ADMIN' || r.toUpperCase() === 'HOSPITAL ADMIN');
const orgName = user.metadata?.organization?.company_name || (isHospitalAdmin ? 'Hospital' : 'Fleet Operator');
const [isAddModalOpen, setIsAddModalOpen] = useState(false);
const [clickCoords, setClickCoords] = useState<{ lat: number, lng: number } | null>(null);
const [newIncident, setNewIncident] = useState({
category: 'MEDICAL',
severity: 'HIGH',
address: '',
notes: ''
});
useEffect(() => {
const handleMapClick = (e: any) => {
setClickCoords(e.detail);
setNewIncident(prev => ({ ...prev, address: `Lat: ${e.detail.lat.toFixed(4)}, Lon: ${e.detail.lng.toFixed(4)}` }));
setIsAddModalOpen(true);
};
window.addEventListener('map-click-add', handleMapClick);
return () => window.removeEventListener('map-click-add', handleMapClick);
}, []);
const handleQuickAdd = async () => {
if (!token || !clickCoords) return;
try {
const payload = {
...newIncident,
gps_lat: clickCoords.lat,
gps_lon: clickCoords.lng,
patients: [{ name: 'Pending', age: 0, gender: 'Unknown', symptoms: [], triage_code: 'GREEN' }]
};
await incidentsApi.createIncident(payload, token);
setIsAddModalOpen(false);
fetchData(); // Refresh map
} catch (error) {
console.error('Failed to quick-add incident:', error);
}
};
const fetchData = async () => {
if (!token) return;
setIsLoading(true);
try {
// Use individual try-catches or settle all to ensure one failure doesn't block the rest
const [incRes, userRes, auditRes] = await Promise.allSettled([
incidentsApi.getIncidents({}, token),
authApi.getUsers(token),
authApi.getAuditLogs(token)
]);
if (incRes.status === 'fulfilled' && incRes.value && incRes.value.data) {
const processed = (incRes.value.data || []).map((inc: any) => ({
...inc,
gps_lat: Number(inc.gps_lat),
gps_lon: Number(inc.gps_lon)
}));
setIncidents(processed);
} else if (incRes.status === 'rejected') {
console.error('Failed to fetch incidents:', incRes.reason);
}
if (userRes.status === 'fulfilled' && userRes.value && userRes.value.data) {
setUsers(Array.isArray(userRes.value.data) ? userRes.value.data : []);
}
if (auditRes.status === 'fulfilled' && auditRes.value && !auditRes.value.status) {
setAuditLogs(Array.isArray(auditRes.value.data) ? auditRes.value.data : (Array.isArray(auditRes.value.logs) ? auditRes.value.logs : []));
} else {
setAuditLogs([]);
if (auditRes.status === 'rejected') {
console.warn('Audit logs unavailable');
}
}
setLastUpdated(new Date());
} catch (error) {
console.error('Failed to fetch dashboard data:', error);
} finally {
setIsLoading(false);
}
};
useEffect(() => {
fetchData();
const interval = setInterval(fetchData, 30000); // Poll every 30s
return () => clearInterval(interval);
}, [token]);
// Derived Metrics
const activeIncidents = incidents.filter(i =>
!['COMPLETED', 'CANCELLED', 'HANDOVER'].includes(i.status?.toUpperCase())
);
const fleetOperators = users.filter((u: any) => {
const r = Array.isArray(u.roles) ? u.roles.map((sr: any) => String(sr).toUpperCase()) : [];
return r.includes('FLEET_OPERATOR') || r.includes('FLEET OPERATOR');
});
const criticalIssues = incidents.filter(i => i.severity?.toUpperCase() === 'CRITICAL');
const fleetStatusData = [
{ name: 'IDLE', value: users.filter(u => u.status === 'ACTIVE').length, color: '#3B82F6' },
{ name: 'ACTIVE', value: activeIncidents.length, color: '#10B981' },
{ name: 'ALERT', value: criticalIssues.length, color: '#EF4444' },
{ name: 'OFFLINE', value: users.filter(u => u.status === 'INACTIVE').length || 2, color: '#4A5568' },
];
const activityData = Array.isArray(auditLogs) ? auditLogs.slice(0, 7).reverse().map((log) => ({
time: log.timestamp ? new Date(log.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : '--:--',
count: Math.floor(Math.random() * 20) + 10 // Mocking activity intensity from audit density
})) : [];
return (
<div className="page-container" style={{ display: 'flex', flexDirection: 'column', gap: '0', paddingBottom: '40px' }}>
{/* Header Section */}
<div className="dashboard-header-premium">
<div>
<h2>
{isFleetOp ? `${orgName} Command` : isHospitalAdmin ? `${orgName} Administration` : 'Super Admin Command Center'}
</h2>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<span className="status-pulse" style={{ background: 'var(--accent-green)' }}></span>
<p style={{ fontSize: '0.85rem', color: 'var(--text-secondary)', fontWeight: 600 }}>
Live platform telemetry synchronized at {lastUpdated.toLocaleTimeString()}
</p>
</div>
</div>
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap' }}>
<button onClick={fetchData} className="glass hover-glow" style={{ padding: '10px 20px', borderRadius: '8px', display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer', background: 'rgba(59,130,246,0.04)', color: 'var(--accent-cyan)', fontWeight: 700, fontSize: '0.8rem', border: '1px solid rgba(59,130,246,0.1)' }}>
<RefreshCw size={16} className={isLoading ? 'spin' : ''} /> REFRESH LIVE
</button>
<div className="glass mono" style={{ padding: '10px 20px', borderRadius: '8px', fontSize: '0.8rem', color: 'var(--accent-green)', display: 'flex', alignItems: 'center', gap: '8px', fontWeight: 700, border: '1px solid rgba(16,185,129,0.1)' }}>
<UsersIcon size={16} /> {fleetOperators.length} OPERATORS ACTIVE
</div>
</div>
</div>
{/* Primary Stats Bar */}
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '20px', marginBottom: '24px' }}>
<PremiumStatCard
label="Active Incidents"
value={activeIncidents.length}
icon={Activity}
glowColor="red"
pulse={activeIncidents.length > 0}
trend={{ value: '14%', isUp: true }}
/>
<PremiumStatCard
label="Operational Fleet"
value={fleetOperators.length}
subValue={users.length.toString()}
icon={Truck}
glowColor="cyan"
/>
<PremiumStatCard
label="Dispatch SLA"
value="1.4s"
icon={Zap}
glowColor="green"
trend={{ value: '0.2s', isUp: false }}
/>
<PremiumStatCard
label="Critical Cases"
value={criticalIssues.length}
icon={HeartPulse}
glowColor="amber"
/>
<PremiumStatCard
label="Live CCE nodes"
value={users.filter(u => u.roles?.includes('CCE')).length || 4}
icon={Video}
glowColor="cyan"
/>
</div>
{/* Main Operational Grid: 2 Columns */}
<div className="dashboard-primary-grid">
{/* Real-time Heatmap */}
<Card title="Global Incident Explorer" subtitle="System-wide incident history and live telemetry" className="premium-health-card" style={{ padding: 0 }}>
<div style={{ padding: '24px', paddingBottom: 0 }}>
<h3 style={{ fontSize: '1.1rem', fontWeight: 800 }}>Global Incident Explorer</h3>
<p style={{ fontSize: '0.8rem', color: 'var(--text-secondary)', marginBottom: '16px' }}>System-wide incident history and live telemetry</p>
</div>
<LiveIncidentMap incidents={incidents} />
<div style={{ position: 'absolute', bottom: '24px', right: '24px', zIndex: 1000, background: 'rgba(255,255,255,0.9)', padding: '12px 16px', borderRadius: '12px', border: '1px solid var(--card-border)', fontSize: '0.75rem', backdropFilter: 'blur(10px)', boxShadow: '0 8px 32px rgba(0,0,0,0.08)' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '10px' }}>
<div style={{ width: '10px', height: '10px', borderRadius: '50%', background: '#EF4444', boxShadow: '0 0 10px #EF4444' }}></div>
<span style={{ fontWeight: 750, letterSpacing: '0.05em', color: 'var(--text-primary)' }}>CRITICAL</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '10px' }}>
<div style={{ width: '10px', height: '10px', borderRadius: '50%', background: '#F59E0B', boxShadow: '0 0 10px #F59E0B' }}></div>
<span style={{ fontWeight: 750, letterSpacing: '0.05em', color: 'var(--text-primary)' }}>ACTIVE (L/M)</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
<div style={{ width: '10px', height: '10px', borderRadius: '50%', background: '#10B981', boxShadow: '0 0 10px #10B981' }}></div>
<span style={{ fontWeight: 750, letterSpacing: '0.05em', color: 'var(--text-primary)' }}>RESOLVED</span>
</div>
</div>
</Card>
{/* Global Distribution & Health */}
<Card title="Fleet Distribution" subtitle="Real-time system asset availability" className="premium-health-card">
<div style={{ display: 'flex', flexDirection: 'column', height: '100%', justifyContent: 'space-between', minHeight: 0 }}>
<div style={{ height: '220px', position: 'relative', margin: '20px 0', minWidth: 0 }}>
<ResponsiveContainer width="100%" height={220}>
<PieChart>
<Pie
data={fleetStatusData}
cx="50%"
cy="50%"
innerRadius={70}
outerRadius={95}
paddingAngle={6}
dataKey="value"
stroke="none"
animationBegin={0}
animationDuration={1500}
>
{fleetStatusData.map((entry, index) => (
<Cell
key={`cell-${index}`}
fill={entry.color}
style={{ filter: `drop-shadow(0 0 12px ${entry.color}33)` }}
/>
))}
</Pie>
<Tooltip content={<CustomChartTooltip />} cursor={{ fill: 'transparent' }} />
</PieChart>
</ResponsiveContainer>
{/* Central Stat */}
<div style={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
textAlign: 'center',
pointerEvents: 'none'
}}>
<div style={{ fontSize: '0.65rem', color: 'var(--text-secondary)', fontWeight: 800, textTransform: 'uppercase', letterSpacing: '0.1em' }}>Total</div>
<div style={{ fontSize: '2.5rem', fontWeight: 900, color: 'var(--text-primary)', lineHeight: 1, margin: '4px 0' }}>
{fleetStatusData.reduce((acc, curr) => acc + curr.value, 0)}
</div>
<div style={{ fontSize: '0.6rem', color: 'var(--accent-cyan)', fontWeight: 850 }}>ASSETS</div>
</div>
</div>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px', padding: '16px', background: 'rgba(0,0,0,0.02)', borderRadius: '12px', border: '1px solid rgba(0,0,0,0.05)' }}>
{fleetStatusData.map(item => {
const total = fleetStatusData.reduce((acc, curr) => acc + curr.value, 0);
const percentage = total > 0 ? Math.round((item.value / total) * 100) : 0;
return (
<div key={item.name} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '6px' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<div style={{ width: '10px', height: '10px', background: item.color, borderRadius: '3px', boxShadow: `0 0 12px ${item.color}66` }}></div>
<span style={{ fontSize: '0.75rem', fontWeight: 750, color: 'var(--text-secondary)' }}>{item.name}</span>
</div>
<span className="mono" style={{ fontSize: '0.85rem', fontWeight: 850, color: 'var(--text-primary)' }}>{percentage}%</span>
</div>
);
})}
</div>
</div>
</Card>
</div>
{/* Secondary Grid: Governance Feed and Performance */}
<div className="dashboard-secondary-grid">
{/* Governance Feed */}
<Card title="Governance Feed" subtitle="Real-time dispatch audit trail" className="premium-health-card" style={{ height: '400px', display: 'flex', flexDirection: 'column' }}>
<div className="no-scrollbar" style={{ flex: 1, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: '12px', marginTop: '16px' }}>
{incidents.slice(0, 8).map((inc) => (
<div key={inc.id} className="hover-glow" style={{
padding: '16px',
background: '#fff',
borderRadius: '12px',
border: '1px solid var(--card-border)',
borderLeft: `4px solid ${inc.severity === 'CRITICAL' ? 'var(--alert-red)' : inc.severity === 'HIGH' ? 'var(--warning-amber)' : 'var(--accent-cyan)'}`,
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
transition: 'all 0.2s',
boxShadow: '0 2px 8px rgba(0,0,0,0.02)'
}}>
<div style={{ minWidth: 0 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
<span className="mono" style={{ fontWeight: 850, fontSize: '0.9rem', color: 'var(--text-primary)' }}>#{inc.id.split('-').pop()}</span>
<span style={{ fontSize: '0.8rem', color: 'var(--text-secondary)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{inc.address}</span>
</div>
<div style={{ fontSize: '0.75rem', marginTop: '6px', textTransform: 'uppercase', fontWeight: 750, color: 'var(--accent-cyan)' }}>{inc.status}</div>
</div>
<div style={{ textAlign: 'right', flexShrink: 0 }}>
<div style={{ fontSize: '0.9rem', fontWeight: 850, color: 'var(--text-primary)' }}>{inc.eta_seconds ? `${Math.floor(inc.eta_seconds / 60)}m` : '--'}</div>
<div style={{ fontSize: '0.65rem', color: 'var(--text-secondary)', fontWeight: 700 }}>ETA</div>
</div>
</div>
))}
{incidents.length === 0 && <div style={{ textAlign: 'center', color: 'var(--text-secondary)', padding: '40px 0', fontWeight: 600 }}>No active incidents</div>}
</div>
</Card>
<Card title="System Performance" subtitle="Transaction density (30s avg)" className="premium-health-card" style={{ height: '400px', display: 'flex', flexDirection: 'column' }}>
<div style={{ flex: 1, minWidth: 0, position: 'relative', marginTop: '16px' }}>
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={activityData}>
<defs>
<linearGradient id="colorSessions" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="var(--accent-cyan)" stopOpacity={0.4}/>
<stop offset="95%" stopColor="var(--accent-cyan)" stopOpacity={0}/>
</linearGradient>
</defs>
<Tooltip
contentStyle={{ background: 'var(--card-bg)', border: '1px solid var(--card-border)', borderRadius: '8px', fontSize: '12px' }}
/>
<Area type="monotone" dataKey="count" stroke="var(--accent-cyan)" strokeWidth={3} fillOpacity={1} fill="url(#colorSessions)" />
</AreaChart>
</ResponsiveContainer>
</div>
</Card>
</div>
{/* Platform DNA Section */}
<section className="dashboard-primary-grid" style={{ marginBottom: '24px' }}>
<Card title="Platform Architecture & Compliance" subtitle="Global oversight of system DNA, security flags and ABDM synchronization." className="premium-health-card" style={{ paddingBottom: '16px' }}>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: '16px', marginTop: '16px' }}>
<div style={{ padding: '20px', borderRadius: '12px', background: '#0B1120', border: '1px solid #1E293B', color: '#fff', position: 'relative', overflow: 'hidden' }}>
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: '2px', background: 'linear-gradient(90deg, transparent, var(--accent-cyan), transparent)' }}></div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Database size={20} color="var(--accent-cyan)" />
<span className="health-status-badge" style={{ background: 'rgba(16,185,129,0.15)', color: 'var(--accent-green)' }}>
<span className="status-pulse" style={{ background: 'var(--accent-green)', width: '6px', height: '6px' }}></span> SYNCED
</span>
</div>
<div style={{ fontSize: '1rem', fontWeight: 850, marginTop: '16px', letterSpacing: '-0.02em' }}>Master Data</div>
<p style={{ fontSize: '0.75rem', color: '#94A3B8', marginTop: '4px' }}>482 Triage rules active.</p>
<div style={{ height: '1px', background: '#1E293B', margin: '16px 0' }}></div>
<button className="mono" style={{ width: '100%', padding: '10px', background: 'rgba(59,130,246,0.1)', border: '1px solid rgba(59,130,246,0.2)', color: '#60A5FA', fontSize: '0.7rem', borderRadius: '6px', cursor: 'pointer', fontWeight: 750, transition: 'all 0.2s' }}>MANAGE DNA</button>
</div>
<div style={{ padding: '20px', borderRadius: '12px', background: '#0B1120', border: '1px solid #1E293B', color: '#fff', position: 'relative', overflow: 'hidden' }}>
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: '2px', background: 'linear-gradient(90deg, transparent, var(--accent-green), transparent)' }}></div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<ShieldCheck size={20} color="var(--accent-green)" />
<span className="health-status-badge" style={{ background: 'rgba(16,185,129,0.15)', color: 'var(--accent-green)' }}>
<span className="status-pulse" style={{ background: 'var(--accent-green)', width: '6px', height: '6px' }}></span> 100%
</span>
</div>
<div style={{ fontSize: '1rem', fontWeight: 850, marginTop: '16px', letterSpacing: '-0.02em' }}>Compliance</div>
<p style={{ fontSize: '0.75rem', color: '#94A3B8', marginTop: '4px' }}>HIPAA / ABDM verified.</p>
<div style={{ height: '1px', background: '#1E293B', margin: '16px 0' }}></div>
<button className="mono" style={{ width: '100%', padding: '10px', background: 'rgba(16,185,129,0.1)', border: '1px solid rgba(16,185,129,0.2)', color: '#34D399', fontSize: '0.7rem', borderRadius: '6px', cursor: 'pointer', fontWeight: 750, transition: 'all 0.2s' }}>AUDIT LOGS</button>
</div>
<div style={{ padding: '20px', borderRadius: '12px', background: '#0B1120', border: '1px solid #1E293B', color: '#fff', position: 'relative', overflow: 'hidden' }}>
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: '2px', background: 'linear-gradient(90deg, transparent, var(--warning-amber), transparent)' }}></div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Settings size={20} color="var(--warning-amber)" />
<span className="health-status-badge" style={{ background: 'rgba(245,158,11,0.15)', color: 'var(--warning-amber)' }}>
<span className="status-pulse" style={{ background: 'var(--warning-amber)', width: '6px', height: '6px' }}></span> STABLE
</span>
</div>
<div style={{ fontSize: '1rem', fontWeight: 850, marginTop: '16px', letterSpacing: '-0.02em' }}>System Logic</div>
<p style={{ fontSize: '0.75rem', color: '#94A3B8', marginTop: '4px' }}>SLA thresholds active.</p>
<div style={{ height: '1px', background: '#1E293B', margin: '16px 0' }}></div>
<button className="mono" style={{ width: '100%', padding: '10px', background: 'rgba(245,158,11,0.1)', border: '1px solid rgba(245,158,11,0.2)', color: '#FBBF24', fontSize: '0.7rem', borderRadius: '6px', cursor: 'pointer', fontWeight: 750, transition: 'all 0.2s' }}>CONFIGURE</button>
</div>
<div style={{ padding: '20px', borderRadius: '12px', background: '#0B1120', border: '1px solid #1E293B', color: '#fff', position: 'relative', overflow: 'hidden' }}>
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: '2px', background: 'linear-gradient(90deg, transparent, var(--accent-cyan), transparent)' }}></div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Navigation size={20} color="var(--accent-cyan)" />
<span className="health-status-badge" style={{ background: 'rgba(59,130,246,0.15)', color: '#60A5FA' }}>
<span className="status-pulse" style={{ background: '#60A5FA', width: '6px', height: '6px' }}></span> ACTIVE
</span>
</div>
<div style={{ fontSize: '1rem', fontWeight: 850, marginTop: '16px', letterSpacing: '-0.02em' }}>Network Hub</div>
<p style={{ fontSize: '0.75rem', color: '#94A3B8', marginTop: '4px' }}>Multi-zone sync active.</p>
<div style={{ height: '1px', background: '#1E293B', margin: '16px 0' }}></div>
<button className="mono" style={{ width: '100%', padding: '10px', background: 'rgba(59,130,246,0.1)', border: '1px solid rgba(59,130,246,0.2)', color: '#60A5FA', fontSize: '0.7rem', borderRadius: '6px', cursor: 'pointer', fontWeight: 750, transition: 'all 0.2s' }}>NODES MAP</button>
</div>
</div>
</Card>
<Card title="Critical Task Cluster" className="premium-health-card" style={{ background: 'linear-gradient(to bottom, #fff, hsla(0, 80%, 98%, 0.5))', border: '1px solid rgba(239,68,68,0.2)' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', marginTop: '16px' }}>
{[
{ label: 'Blood Link', status: 'Healthy', color: 'var(--accent-green)' },
{ label: 'Organ Registry', status: 'Healthy', color: 'var(--accent-green)' },
{ label: 'Mortuary Sync', status: 'Delayed', color: 'var(--warning-amber)' },
{ label: 'Police V-Link', status: 'Healthy', color: 'var(--accent-green)' },
].map((r, i) => (
<div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingBottom: '12px', borderBottom: '1px dashed var(--card-border)' }}>
<div>
<div style={{ fontSize: '0.9rem', fontWeight: 800, color: 'var(--text-primary)' }}>{r.label}</div>
<div style={{ fontSize: '0.7rem', color: r.color, fontWeight: 700, marginTop: '2px' }}>{r.status}</div>
</div>
<div className="status-pulse" style={{ background: r.color, width: '10px', height: '10px' }}></div>
</div>
))}
</div>
</Card>
</section>
{/* SLA Ticker & Progress */}
<div style={{ display: 'flex', gap: '24px', alignItems: 'stretch', flexWrap: 'wrap' }}>
<Card className="premium-health-card" style={{ flex: 1, padding: '24px' }}>
<div style={{ display: 'grid', gap: '24px', gridTemplateColumns: 'repeat(auto-fit, minmax(130px, 1fr))' }}>
{[
{ label: 'Foundation', progress: 100 },
{ label: 'MVP Core', progress: 100 },
{ label: 'Clinical AI', progress: 85 },
{ label: 'Fleet Intel', progress: 42 },
{ label: 'Compliance', progress: 100 },
].map((phase, i) => (
<div key={phase.label} style={{ minWidth: 0 }}>
<div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '0.75rem', marginBottom: '8px' }}>
<span style={{ fontWeight: 750, color: 'var(--text-primary)' }}>{phase.label}</span>
<span className="mono" style={{ fontWeight: 850 }}>{phase.progress}%</span>
</div>
<div style={{ height: '6px', background: 'rgba(0,0,0,0.05)', borderRadius: '3px', overflow: 'hidden' }}>
<motion.div
initial={{ width: 0 }}
animate={{ width: `${phase.progress}%` }}
transition={{ duration: 1, delay: i * 0.1 }}
style={{
height: '100%',
background: phase.progress === 100 ? 'var(--accent-green)' : 'var(--accent-cyan)',
boxShadow: `0 0 10px ${phase.progress === 100 ? 'rgba(0,255,136,0.5)' : 'rgba(0,212,255,0.5)'}`
}}
></motion.div>
</div>
</div>
))}
</div>
</Card>
<div style={{
minWidth: '300px',
flex: '1 1 320px',
padding: '16px 24px',
background: '#0B1120',
border: '1px solid #1E293B',
borderRadius: '16px',
display: 'flex',
alignItems: 'center',
gap: '16px',
overflow: 'hidden',
whiteSpace: 'nowrap',
boxShadow: '0 8px 32px rgba(0,0,0,0.1)'
}}>
<div className="mono" style={{ fontSize: '0.75rem', fontWeight: 850, color: '#38BDF8', padding: '6px 12px', background: 'rgba(56, 189, 248, 0.15)', borderRadius: '6px', border: '1px solid rgba(56, 189, 248, 0.3)' }}>SLA TICKER</div>
<div className="no-scrollbar" style={{ fontSize: '0.85rem', color: '#94A3B8', overflow: 'hidden', flex: 1, position: 'relative' }}>
<motion.div
animate={{ x: [500, -1000] }}
transition={{ duration: 30, repeat: Infinity, ease: "linear" }}
style={{ display: 'inline-block', whiteSpace: 'nowrap', fontWeight: 750, letterSpacing: '0.02em' }}
>
<span style={{ color: '#fff' }}>HIPAA COMPLIANT</span> <span style={{ color: '#34D399' }}></span> &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
<span style={{ color: '#fff' }}>ABDM SYNCED</span> <span style={{ color: '#34D399' }}></span> &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
<span style={{ color: '#fff' }}>ISO 27001 AUDIT PASSED</span> <span style={{ color: '#34D399' }}></span> &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
<span style={{ color: '#fff' }}>PHI ENCRYPTED</span> <span style={{ color: '#34D399' }}></span> &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
<span style={{ color: '#fff' }}>DPDP ACT ALIGNED</span> <span style={{ color: '#34D399' }}></span> &nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;
<span style={{ color: '#fff' }}>END-TO-END TLS 1.3 ACTIVE</span> <span style={{ color: '#34D399' }}></span>
</motion.div>
</div>
</div>
</div>
{/* Quick Add Modal */}
<AnimatePresence>
{isAddModalOpen && (
<div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(255,255,255,0.8)', backdropFilter: 'blur(10px)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 10000 }}>
<motion.div initial={{ opacity: 0, scale: 0.9 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.9 }} className="glass glow-cyan" style={{ width: '400px', padding: '24px', background: 'var(--base-bg)', borderRadius: '20px', border: '1px solid var(--card-border)' }}>
<h3 style={{ fontSize: '1.2rem', fontWeight: 800, marginBottom: '20px', color: 'var(--accent-cyan)' }}>QUICK LOG INCIDENT</h3>
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
<div>
<label style={{ fontSize: '0.65rem', color: 'var(--text-secondary)', fontWeight: 800, textTransform: 'uppercase' }}>Coordinates</label>
<div className="glass mono" style={{ padding: '10px', marginTop: '4px', fontSize: '0.8rem', background: 'rgba(0,0,0,0.01)' }}>
{clickCoords?.lat.toFixed(6)}, {clickCoords?.lng.toFixed(6)}
</div>
</div>
<div>
<label style={{ fontSize: '0.65rem', color: 'var(--text-secondary)', fontWeight: 800, textTransform: 'uppercase' }}>Category</label>
<select
value={newIncident.category}
onChange={(e) => setNewIncident({ ...newIncident, category: e.target.value })}
className="glass"
style={{ width: '100%', padding: '10px', marginTop: '4px', background: 'rgba(0,0,0,0.03)', color: 'var(--text-primary)', border: '1px solid var(--card-border)', borderRadius: '8px' }}
>
<option value="MEDICAL">MEDICAL</option>
<option value="TRAUMA">TRAUMA</option>
<option value="CARDIAC">CARDIAC</option>
<option value="ACCIDENT">ACCIDENT</option>
</select>
</div>
<div>
<label style={{ fontSize: '0.65rem', color: 'var(--text-secondary)', fontWeight: 800, textTransform: 'uppercase' }}>Severity</label>
<div style={{ display: 'flex', gap: '8px', marginTop: '6px' }}>
{['LOW', 'HIGH', 'CRITICAL'].map(s => (
<button
key={s}
onClick={() => setNewIncident({ ...newIncident, severity: s })}
style={{
flex: 1,
padding: '8px',
borderRadius: '6px',
fontSize: '0.7rem',
fontWeight: 800,
cursor: 'pointer',
background: newIncident.severity === s ? (s === 'CRITICAL' ? 'var(--alert-red)' : 'var(--accent-cyan)') : 'rgba(0,0,0,0.03)',
color: newIncident.severity === s ? '#fff' : 'var(--text-secondary)',
border: 'none',
transition: 'all 0.2s'
}}
>
{s}
</button>
))}
</div>
</div>
<div>
<label style={{ fontSize: '0.65rem', color: 'var(--text-secondary)', fontWeight: 800, textTransform: 'uppercase' }}>Notes / Address Info</label>
<textarea
value={newIncident.notes}
onChange={(e) => setNewIncident({ ...newIncident, notes: e.target.value, address: e.target.value || `Lat: ${clickCoords?.lat.toFixed(4)}` })}
placeholder="Enter scene details..."
className="glass"
style={{ width: '100%', padding: '10px', marginTop: '4px', height: '80px', background: 'rgba(0,0,0,0.03)', color: 'var(--text-primary)', border: '1px solid var(--card-border)', borderRadius: '8px', resize: 'none' }}
/>
</div>
</div>
<div style={{ display: 'flex', gap: '12px', marginTop: '24px' }}>
<button onClick={() => setIsAddModalOpen(false)} className="glass" style={{ flex: 1, padding: '12px', borderRadius: '10px', cursor: 'pointer', border: '1px solid var(--card-border)', color: 'var(--text-secondary)', fontWeight: 700 }}>CANCEL</button>
<button onClick={handleQuickAdd} className="glow-cyan" style={{ flex: 1, padding: '12px', borderRadius: '10px', cursor: 'pointer', background: 'var(--accent-cyan)', color: '#000', border: 'none', fontWeight: 800 }}>LOG MISSION</button>
</div>
</motion.div>
</div>
)}
</AnimatePresence>
</div>
);
};