feat: integrate hospital management module with advanced UI styling and analytics components
This commit is contained in:
@@ -285,6 +285,54 @@ const CustomChartTooltip = ({ active, payload }: any) => {
|
||||
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[]>([]);
|
||||
@@ -306,7 +354,8 @@ export const Dashboard: React.FC = () => {
|
||||
const token = localStorage.getItem('teleems_token') || '';
|
||||
const roles = Array.isArray(user.roles) ? user.roles : [];
|
||||
const isFleetOp = roles.includes('FLEET_OPERATOR');
|
||||
const orgName = user.metadata?.organization?.company_name || '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);
|
||||
@@ -418,34 +467,34 @@ export const Dashboard: React.FC = () => {
|
||||
})) : [];
|
||||
|
||||
return (
|
||||
<div className="page-container" style={{ display: 'flex', flexDirection: 'column', gap: '24px', paddingBottom: '40px' }}>
|
||||
<div className="page-container" style={{ display: 'flex', flexDirection: 'column', gap: '0', paddingBottom: '40px' }}>
|
||||
{/* Header Section */}
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '12px', flexWrap: 'wrap' }}>
|
||||
<div className="dashboard-header-premium">
|
||||
<div>
|
||||
<h2 style={{ fontSize: '1.8rem', fontWeight: 800, background: 'linear-gradient(to right, var(--text-primary), var(--accent-cyan))', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent' }}>
|
||||
{isFleetOp ? `${orgName} Command` : 'Super Admin Command Center'}
|
||||
<h2>
|
||||
{isFleetOp ? `${orgName} Command` : isHospitalAdmin ? `${orgName} Administration` : 'Super Admin Command Center'}
|
||||
</h2>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginTop: '4px' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<span className="status-pulse" style={{ background: 'var(--accent-green)' }}></span>
|
||||
<p style={{ fontSize: '0.8rem', color: 'var(--text-secondary)' }}>
|
||||
<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: '8px 16px', display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer', background: 'rgba(59,130,246,0.02)', color: 'var(--accent-cyan)', fontWeight: 600, fontSize: '0.8rem' }}>
|
||||
<RefreshCw size={14} className={isLoading ? 'spin' : ''} /> REFRESH LIVE
|
||||
<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: '8px 16px', fontSize: '0.75rem', color: 'var(--accent-green)', display: 'flex', alignItems: 'center', gap: '6px' }}>
|
||||
<UsersIcon size={14} /> {fleetOperators.length} OPERATORS ACTIVE
|
||||
<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 className="stats-bar" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', marginBottom: 0 }}>
|
||||
<StatCard
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: '20px', marginBottom: '24px' }}>
|
||||
<PremiumStatCard
|
||||
label="Active Incidents"
|
||||
value={activeIncidents.length}
|
||||
icon={Activity}
|
||||
@@ -453,110 +502,73 @@ export const Dashboard: React.FC = () => {
|
||||
pulse={activeIncidents.length > 0}
|
||||
trend={{ value: '14%', isUp: true }}
|
||||
/>
|
||||
<StatCard
|
||||
<PremiumStatCard
|
||||
label="Operational Fleet"
|
||||
value={fleetOperators.length}
|
||||
subValue={users.length.toString()}
|
||||
icon={Truck}
|
||||
glowColor="cyan"
|
||||
/>
|
||||
<StatCard
|
||||
<PremiumStatCard
|
||||
label="Dispatch SLA"
|
||||
value="1.4s"
|
||||
icon={Zap}
|
||||
glowColor="green"
|
||||
trend={{ value: '0.2s', isUp: false }}
|
||||
/>
|
||||
<StatCard
|
||||
<PremiumStatCard
|
||||
label="Critical Cases"
|
||||
value={criticalIssues.length}
|
||||
icon={HeartPulse}
|
||||
glowColor="amber"
|
||||
/>
|
||||
<StatCard
|
||||
<PremiumStatCard
|
||||
label="Live CCE nodes"
|
||||
value={users.filter(u => u.roles?.includes('CCE')).length || 4}
|
||||
icon={Video}
|
||||
glowColor="cyan"
|
||||
/>
|
||||
<StatCard
|
||||
label="Node Integrity"
|
||||
value="100%"
|
||||
icon={ShieldCheck}
|
||||
glowColor="green"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Main Operational Grid */}
|
||||
<div className="main-grid" style={{ gridTemplateColumns: '1.5fr 1fr 1fr', height: 'auto', alignItems: 'start' }}>
|
||||
{/* 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">
|
||||
<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} />
|
||||
|
||||
{/* Legend Overlay (Absolute in Card) */}
|
||||
<div style={{ position: 'absolute', bottom: '32px', right: '32px', zIndex: 1000, background: 'rgba(255,255,255,0.85)', padding: '12px', borderRadius: '10px', border: '1px solid var(--card-border)', fontSize: '0.7rem', backdropFilter: 'blur(10px)', boxShadow: '0 8px 32px rgba(0,0,0,0.05)', pointerEvents: 'none' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '8px' }}>
|
||||
<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: 700, letterSpacing: '0.05em' }}>CRITICAL</span>
|
||||
<span style={{ fontWeight: 750, letterSpacing: '0.05em', color: 'var(--text-primary)' }}>CRITICAL</span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '10px', marginBottom: '8px' }}>
|
||||
<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: 700, letterSpacing: '0.05em' }}>ACTIVE (L/M)</span>
|
||||
<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: 700, letterSpacing: '0.05em' }}>RESOLVED</span>
|
||||
<span style={{ fontWeight: 750, letterSpacing: '0.05em', color: 'var(--text-primary)' }}>RESOLVED</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* Governance Feed */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
|
||||
<Card title="Governance Feed" subtitle="Real-time dispatch audit trail" style={{ height: '450px', display: 'flex', flexDirection: 'column' }}>
|
||||
<div className="no-scrollbar" style={{ flex: 1, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: '12px' }}>
|
||||
{incidents.slice(0, 8).map((inc) => (
|
||||
<div key={inc.id} className="hover-glow" style={{
|
||||
padding: '14px',
|
||||
background: 'rgba(0,0,0,0.01)',
|
||||
borderRadius: '10px',
|
||||
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'
|
||||
}}>
|
||||
<div style={{ minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<span className="mono" style={{ fontWeight: 800, fontSize: '0.85rem', color: 'var(--accent-cyan)' }}>{inc.id.split('-').pop()}</span>
|
||||
<span style={{ fontSize: '0.7rem', color: 'var(--text-secondary)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{inc.address}</span>
|
||||
</div>
|
||||
<div style={{ fontSize: '0.75rem', marginTop: '4px', textTransform: 'uppercase', fontWeight: 600 }}>{inc.status}</div>
|
||||
</div>
|
||||
<div style={{ textAlign: 'right', flexShrink: 0 }}>
|
||||
<div style={{ fontSize: '0.75rem', fontWeight: 800 }}>{inc.eta_seconds ? `${Math.floor(inc.eta_seconds / 60)}m` : '--'}</div>
|
||||
<div style={{ fontSize: '0.6rem', color: 'var(--text-secondary)' }}>ETA</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{incidents.length === 0 && <div style={{ textAlign: 'center', color: 'var(--text-secondary)', padding: '40px 0' }}>No active incidents</div>}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Global Distribution & Health */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px', minHeight: 0 }}>
|
||||
<Card title="Fleet Distribution" subtitle="Real-time system asset availability">
|
||||
<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: '180px', position: 'relative', margin: '10px 0', minWidth: 0 }}>
|
||||
<ResponsiveContainer width="100%" height="180">
|
||||
<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={60}
|
||||
outerRadius={80}
|
||||
paddingAngle={8}
|
||||
innerRadius={70}
|
||||
outerRadius={95}
|
||||
paddingAngle={6}
|
||||
dataKey="value"
|
||||
stroke="none"
|
||||
animationBegin={0}
|
||||
@@ -566,7 +578,7 @@ export const Dashboard: React.FC = () => {
|
||||
<Cell
|
||||
key={`cell-${index}`}
|
||||
fill={entry.color}
|
||||
style={{ filter: `drop-shadow(0 0 8px ${entry.color}44)` }}
|
||||
style={{ filter: `drop-shadow(0 0 12px ${entry.color}33)` }}
|
||||
/>
|
||||
))}
|
||||
</Pie>
|
||||
@@ -583,35 +595,71 @@ export const Dashboard: React.FC = () => {
|
||||
textAlign: 'center',
|
||||
pointerEvents: 'none'
|
||||
}}>
|
||||
<div style={{ fontSize: '0.6rem', color: 'var(--text-secondary)', fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.1em' }}>Total</div>
|
||||
<div style={{ fontSize: '1.6rem', fontWeight: 900, color: 'var(--text-primary)', lineHeight: 1 }}>
|
||||
<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.5rem', color: 'var(--accent-cyan)', fontWeight: 800, marginTop: '2px' }}>ASSETS</div>
|
||||
<div style={{ fontSize: '0.6rem', color: 'var(--accent-cyan)', fontWeight: 850 }}>ASSETS</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px', padding: '12px', background: 'rgba(0,0,0,0.01)', borderRadius: '12px', border: '1px solid var(--card-border)' }}>
|
||||
<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: '4px 8px' }}>
|
||||
<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: '8px', height: '8px', background: item.color, borderRadius: '2px', boxShadow: `0 0 10px ${item.color}66` }}></div>
|
||||
<span style={{ fontSize: '0.65rem', fontWeight: 700, color: 'var(--text-secondary)' }}>{item.name}</span>
|
||||
<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.7rem', fontWeight: 800, color: 'var(--text-primary)' }}>{percentage}%</span>
|
||||
<span className="mono" style={{ fontSize: '0.85rem', fontWeight: 850, color: 'var(--text-primary)' }}>{percentage}%</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Card title="System Performance" subtitle="Transaction density (30s avg)">
|
||||
<div style={{ height: '140px', minWidth: 0, position: 'relative' }}>
|
||||
<ResponsiveContainer width="100%" height={140}>
|
||||
{/* 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">
|
||||
@@ -622,78 +670,89 @@ export const Dashboard: React.FC = () => {
|
||||
<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={2} fillOpacity={1} fill="url(#colorSessions)" />
|
||||
<Area type="monotone" dataKey="count" stroke="var(--accent-cyan)" strokeWidth={3} fillOpacity={1} fill="url(#colorSessions)" />
|
||||
</AreaChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Platform DNA Section */}
|
||||
<section style={{ display: 'grid', gridTemplateColumns: '2.5fr 1fr', gap: '24px' }}>
|
||||
<Card title="Platform Architecture & Compliance" subtitle="Global oversight of system DNA, security flags and ABDM synchronization.">
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '16px', marginTop: '8px' }}>
|
||||
<div className="glass hover-glow" style={{ padding: '20px', borderRadius: '12px', border: '1px solid var(--card-border)' }}>
|
||||
<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={22} color="var(--accent-cyan)" />
|
||||
<span className="mono" style={{ fontSize: '0.6rem', color: 'var(--accent-green)' }}>SYNCED</span>
|
||||
<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: '0.9rem', fontWeight: 800, marginTop: '16px' }}>Master Data</div>
|
||||
<p style={{ fontSize: '0.65rem', color: 'var(--text-secondary)', marginTop: '6px' }}>482 Triage rules active.</p>
|
||||
<div style={{ height: '2px', background: 'rgba(0,0,0,0.02)', margin: '12px 0' }}></div>
|
||||
<button className="mono" style={{ width: '100%', padding: '8px', background: 'rgba(59,130,246,0.1)', border: 'none', color: 'var(--accent-cyan)', fontSize: '0.6rem', borderRadius: '4px', cursor: 'pointer', fontWeight: 700 }}>MANAGE DNA</button>
|
||||
<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 className="glass hover-glow" style={{ padding: '20px', borderRadius: '12px', border: '1px solid var(--card-border)' }}>
|
||||
<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={22} color="var(--accent-green)" />
|
||||
<span className="mono" style={{ fontSize: '0.6rem', color: 'var(--accent-green)' }}>100%</span>
|
||||
<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: '0.9rem', fontWeight: 800, marginTop: '16px' }}>Compliance</div>
|
||||
<p style={{ fontSize: '0.65rem', color: 'var(--text-secondary)', marginTop: '6px' }}>HIPAA / ABDM verified.</p>
|
||||
<div style={{ height: '2px', background: 'rgba(0,0,0,0.02)', margin: '12px 0' }}></div>
|
||||
<button className="mono" style={{ width: '100%', padding: '8px', background: 'rgba(16,185,129,0.1)', border: 'none', color: 'var(--accent-green)', fontSize: '0.6rem', borderRadius: '4px', cursor: 'pointer', fontWeight: 700 }}>AUDIT LOGS</button>
|
||||
<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 className="glass hover-glow" style={{ padding: '20px', borderRadius: '12px', border: '1px solid var(--card-border)' }}>
|
||||
<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={22} color="var(--warning-amber)" />
|
||||
<span className="mono" style={{ fontSize: '0.6rem', color: 'var(--warning-amber)' }}>STABLE</span>
|
||||
<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: '0.9rem', fontWeight: 800, marginTop: '16px' }}>System Logic</div>
|
||||
<p style={{ fontSize: '0.65rem', color: 'var(--text-secondary)', marginTop: '6px' }}>SLA thresholds active.</p>
|
||||
<div style={{ height: '2px', background: 'rgba(0,0,0,0.02)', margin: '12px 0' }}></div>
|
||||
<button className="mono" style={{ width: '100%', padding: '8px', background: 'rgba(245,158,0,0.1)', border: 'none', color: 'var(--warning-amber)', fontSize: '0.6rem', borderRadius: '4px', cursor: 'pointer', fontWeight: 700 }}>CONFIGURE</button>
|
||||
<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 className="glass hover-glow" style={{ padding: '20px', borderRadius: '12px', border: '1px solid var(--card-border)' }}>
|
||||
<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={22} color="var(--accent-cyan)" />
|
||||
<span className="mono" style={{ fontSize: '0.6rem', color: 'var(--accent-cyan)' }}>ACTIVE</span>
|
||||
<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: '0.9rem', fontWeight: 800, marginTop: '16px' }}>Network Hub</div>
|
||||
<p style={{ fontSize: '0.65rem', color: 'var(--text-secondary)', marginTop: '6px' }}>Multi-zone sync active.</p>
|
||||
<div style={{ height: '2px', background: 'rgba(0,0,0,0.02)', margin: '12px 0' }}></div>
|
||||
<button className="mono" style={{ width: '100%', padding: '8px', background: 'rgba(59,130,246,0.1)', border: 'none', color: 'var(--accent-cyan)', fontSize: '0.6rem', borderRadius: '4px', cursor: 'pointer', fontWeight: 700 }}>NODES MAP</button>
|
||||
<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" style={{ background: 'rgba(255, 59, 59, 0.03)' }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '14px' }}>
|
||||
<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: '8px', borderBottom: '1px solid rgba(0,0,0,0.02)' }}>
|
||||
<div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingBottom: '12px', borderBottom: '1px dashed var(--card-border)' }}>
|
||||
<div>
|
||||
<div style={{ fontSize: '0.8rem', fontWeight: 700 }}>{r.label}</div>
|
||||
<div style={{ fontSize: '0.6rem', color: r.color }}>{r.status}</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 }}></div>
|
||||
<div className="status-pulse" style={{ background: r.color, width: '10px', height: '10px' }}></div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -702,8 +761,8 @@ export const Dashboard: React.FC = () => {
|
||||
|
||||
{/* SLA Ticker & Progress */}
|
||||
<div style={{ display: 'flex', gap: '24px', alignItems: 'stretch', flexWrap: 'wrap' }}>
|
||||
<Card style={{ flex: 1, padding: '16px 24px' }}>
|
||||
<div style={{ display: 'grid', gap: '16px', gridTemplateColumns: 'repeat(auto-fit, minmax(130px, 1fr))' }}>
|
||||
<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 },
|
||||
@@ -712,11 +771,11 @@ export const Dashboard: React.FC = () => {
|
||||
{ label: 'Compliance', progress: 100 },
|
||||
].map((phase, i) => (
|
||||
<div key={phase.label} style={{ minWidth: 0 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '0.65rem', marginBottom: '6px' }}>
|
||||
<span style={{ fontWeight: 600 }}>{phase.label}</span>
|
||||
<span className="mono">{phase.progress}%</span>
|
||||
<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: '4px', background: 'rgba(0,0,0,0.02)', borderRadius: '2px', overflow: 'hidden' }}>
|
||||
<div style={{ height: '6px', background: 'rgba(0,0,0,0.05)', borderRadius: '3px', overflow: 'hidden' }}>
|
||||
<motion.div
|
||||
initial={{ width: 0 }}
|
||||
animate={{ width: `${phase.progress}%` }}
|
||||
@@ -724,7 +783,7 @@ export const Dashboard: React.FC = () => {
|
||||
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.3)' : 'rgba(0,212,255,0.3)'}`
|
||||
boxShadow: `0 0 10px ${phase.progress === 100 ? 'rgba(0,255,136,0.5)' : 'rgba(0,212,255,0.5)'}`
|
||||
}}
|
||||
></motion.div>
|
||||
</div>
|
||||
@@ -733,26 +792,35 @@ export const Dashboard: React.FC = () => {
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<div className="glass" style={{
|
||||
<div style={{
|
||||
minWidth: '300px',
|
||||
flex: '1 1 320px',
|
||||
padding: '16px',
|
||||
border: '1px solid var(--card-border)',
|
||||
padding: '16px 24px',
|
||||
background: '#0B1120',
|
||||
border: '1px solid #1E293B',
|
||||
borderRadius: '16px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '12px',
|
||||
gap: '16px',
|
||||
overflow: 'hidden',
|
||||
whiteSpace: 'nowrap'
|
||||
whiteSpace: 'nowrap',
|
||||
boxShadow: '0 8px 32px rgba(0,0,0,0.1)'
|
||||
}}>
|
||||
<div className="mono" style={{ fontSize: '0.7rem', fontWeight: 800, color: 'var(--accent-cyan)', padding: '4px 8px', background: 'rgba(59,130,246,0.1)', borderRadius: '4px' }}>SLA TICKER</div>
|
||||
<div className="no-scrollbar" style={{ fontSize: '0.75rem', color: 'var(--text-secondary)', overflow: 'hidden', flex: 1, position: 'relative' }}>
|
||||
<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: [400, -800] }}
|
||||
transition={{ duration: 25, repeat: Infinity, ease: "linear" }}
|
||||
style={{ display: 'inline-block', whiteSpace: 'nowrap', fontWeight: 700 }}
|
||||
animate={{ x: [500, -1000] }}
|
||||
transition={{ duration: 30, repeat: Infinity, ease: "linear" }}
|
||||
style={{ display: 'inline-block', whiteSpace: 'nowrap', fontWeight: 750, letterSpacing: '0.02em' }}
|
||||
>
|
||||
HIPAA COMPLIANT ✅ | ABDM SYNCED ✅ | ISO 27001 AUDIT PASSED ✅ | PHI ENCRYPTED ✅ | DPDP ACT ALIGNED ✅ | END-TO-END TLS 1.3 ACTIVE ✅
|
||||
<span style={{ color: '#fff' }}>HIPAA COMPLIANT</span> <span style={{ color: '#34D399' }}>✅</span> |
|
||||
<span style={{ color: '#fff' }}>ABDM SYNCED</span> <span style={{ color: '#34D399' }}>✅</span> |
|
||||
<span style={{ color: '#fff' }}>ISO 27001 AUDIT PASSED</span> <span style={{ color: '#34D399' }}>✅</span> |
|
||||
<span style={{ color: '#fff' }}>PHI ENCRYPTED</span> <span style={{ color: '#34D399' }}>✅</span> |
|
||||
<span style={{ color: '#fff' }}>DPDP ACT ALIGNED</span> <span style={{ color: '#34D399' }}>✅</span> |
|
||||
<span style={{ color: '#fff' }}>END-TO-END TLS 1.3 ACTIVE</span> <span style={{ color: '#34D399' }}>✅</span>
|
||||
</motion.div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user