Skip to content

Commit e4e9d0f

Browse files
committed
style(ui): unify premium monitoring aesthetics and add heartbeat telemetry
1 parent b84e9a5 commit e4e9d0f

File tree

1 file changed

+54
-38
lines changed

1 file changed

+54
-38
lines changed

Frontend/src/components/SystemLayersStatus.tsx

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { useChainWardData } from '../context/ChainWardDataProvider';
77
const SystemLayersStatus = () => {
88
const { chainConfig, lastSignalTime: signalTime, lastL1BatchTimestamp: l1Time, isLoading } = useChainWardData();
99

10-
// Derive all statuses from shared data (pure computation — no async!)
1110
const now = Math.floor(Date.now() / 1000);
1211

1312
const governance = !chainConfig ? (isLoading ? 'Loading...' : 'Not Configured')
@@ -27,54 +26,71 @@ const SystemLayersStatus = () => {
2726
const response = !chainConfig ? (isLoading ? 'Loading...' : 'Not Configured')
2827
: chainConfig.isActive ? 'Active' : 'Inactive';
2928

30-
const statusColor = (status: string) => {
31-
if (status === 'Active' || status === 'Configured' || status === 'Healthy' || status === 'Ready' || status === 'Connective') return 'text-success';
32-
if (status === 'Incident') return 'text-danger';
33-
if (status === 'Inactive' || status === 'Not Set' || status === 'Not Configured' || status === 'Not Ready') return 'text-warning';
34-
return 'text-secondary';
29+
const getStatusStyle = (status: string) => {
30+
const success = ['Active', 'Configured', 'Healthy', 'Ready', 'Connective'];
31+
const warning = ['Inactive', 'Not Set', 'Not Configured', 'Not Ready', 'Stale', 'Stalled'];
32+
const danger = ['Incident', 'Degraded'];
33+
34+
if (success.includes(status)) return { color: 'text-emerald-400', bg: 'bg-emerald-500/10' };
35+
if (danger.includes(status)) return { color: 'text-red-400', bg: 'bg-red-500/10' };
36+
if (warning.includes(status)) return { color: 'text-orange-400', bg: 'bg-orange-500/10' };
37+
return { color: 'text-secondary', bg: 'bg-background/20' };
3538
};
3639

37-
const layers = [governance, detection, validation, bridge, incidentHistory, response];
40+
const layers = [
41+
{ label: 'Governance', value: governance, icon: '⚖️' },
42+
{ label: 'Detection', value: detection, icon: '🔍' },
43+
{ label: 'Validation', value: validation, icon: '✓' },
44+
{ label: 'L1 Bridge', value: bridge, icon: '🌉' },
45+
{ label: 'Incident History', value: incidentHistory, icon: '📋' },
46+
{ label: 'Response', value: response, icon: '⚡' }
47+
];
48+
3849
const healthyCount = layers.filter(l =>
39-
l === 'Active' || l === 'Configured' || l === 'Healthy' || l === 'Ready' || l === 'Connective'
50+
['Active', 'Configured', 'Healthy', 'Ready', 'Connective'].includes(l.value)
4051
).length;
4152
const healthPercent = Math.round((healthyCount / layers.length) * 100);
4253

4354
return (
44-
<section className="p-4 sm:p-6 bg-card rounded-xl shadow border border-card-border">
45-
<div className="flex justify-between items-center mb-4">
46-
<h2 className="text-lg sm:text-xl font-bold">System Layers Status</h2>
47-
<div className="flex items-center gap-2">
48-
<div className={`text-lg font-mono font-bold ${healthPercent === 100 ? 'text-green-500' : healthPercent >= 70 ? 'text-yellow-500' : 'text-red-500'}`}>
49-
{healthPercent}%
55+
<section className="p-1 bg-gradient-to-br from-card-border/50 to-transparent rounded-2xl shadow-2xl border border-card-border/40 overflow-hidden">
56+
<div className="bg-card/80 backdrop-blur-xl p-5 sm:p-7 rounded-[14px]">
57+
<div className="flex justify-between items-center mb-6">
58+
<div>
59+
<h2 className="text-xl font-black tracking-tight text-foreground uppercase">System Layers</h2>
60+
<p className="text-[10px] font-bold uppercase tracking-widest text-secondary mt-1 opacity-60">Architectural Integrity</p>
61+
</div>
62+
<div className="flex items-center gap-3">
63+
<div className={`text-2xl font-black font-mono ${healthPercent === 100 ? 'text-emerald-500' : healthPercent >= 70 ? 'text-orange-500' : 'text-red-500'}`}>
64+
{healthPercent}%
65+
</div>
5066
</div>
5167
</div>
52-
</div>
5368

54-
<div className="mb-4 h-2 bg-background rounded-full overflow-hidden">
55-
<div
56-
className={`h-full transition-all duration-1000 ${healthPercent === 100 ? 'bg-green-500' : healthPercent >= 70 ? 'bg-yellow-500' : 'bg-red-500'}`}
57-
style={{ width: `${healthPercent}%` }}
58-
></div>
59-
</div>
69+
<div className="mb-8 relative h-1.5 bg-background/40 rounded-full overflow-hidden">
70+
<div
71+
className={`absolute top-0 left-0 h-full transition-all duration-1000 ease-out ${healthPercent === 100 ? 'bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]' : healthPercent >= 70 ? 'bg-orange-500' : 'bg-red-500'
72+
}`}
73+
style={{ width: `${healthPercent}%` }}
74+
></div>
75+
</div>
6076

61-
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
62-
{[
63-
{ label: 'Governance', value: governance, icon: '⚖️' },
64-
{ label: 'Detection', value: detection, icon: '🔍' },
65-
{ label: 'Validation', value: validation, icon: '✓' },
66-
{ label: 'L1 Bridge', value: bridge, icon: '🌉' },
67-
{ label: 'Incident History', value: incidentHistory, icon: '📋' },
68-
{ label: 'Response', value: response, icon: '⚡' }
69-
].map(({ label, value, icon }) => (
70-
<div key={label} className="flex items-center justify-between p-2 bg-background/30 rounded-lg border border-card-border/50">
71-
<div className="flex items-center gap-2">
72-
<span className="text-lg">{icon}</span>
73-
<span className="text-sm font-semibold opacity-80">{label}</span>
74-
</div>
75-
<span className={`text-sm font-mono font-bold ${statusColor(value)}`}>{value}</span>
76-
</div>
77-
))}
77+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
78+
{layers.map(({ label, value, icon }) => {
79+
const style = getStatusStyle(value);
80+
return (
81+
<div key={label} className="group relative flex items-center justify-between p-3 bg-background/20 rounded-xl border border-card-border/30 hover:border-primary/20 transition-all">
82+
<div className="flex items-center gap-3">
83+
<div className="text-xl group-hover:scale-110 transition-transform">{icon}</div>
84+
<div>
85+
<div className="text-[9px] font-bold uppercase tracking-widest opacity-40">{label}</div>
86+
<div className={`text-xs font-black font-mono ${style.color}`}>{value}</div>
87+
</div>
88+
</div>
89+
<div className={`w-1.5 h-1.5 rounded-full ${style.color.replace('text-', 'bg-')} opacity-40`}></div>
90+
</div>
91+
);
92+
})}
93+
</div>
7894
</div>
7995
</section>
8096
);

0 commit comments

Comments
 (0)