feat(dashboard): SSL card expired/expiring split + HAProxy frontend labels

Expired certs now show a red error alert ("renew immediately") instead
of being silently folded into the orange "expiring soon" warning.
HAProxy frontend technical names (public_http, public_https, mgmt_https)
now display as human-readable labels (HTTP In, HTTPS In, Management).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-27 18:51:59 +02:00
parent 123ee6e34f
commit f378771dca
7 changed files with 30 additions and 8 deletions

View File

@@ -283,6 +283,13 @@ export default function DashboardPage() {
const now = Date.now()
const maintenanceDomains = (domains.data ?? []).filter(d => d.maintenance_mode)
// HAProxy frontend technical name → display label.
const HA_FRONTEND_LABELS: Record<string, string> = {
public_http: 'HTTP In',
public_https: 'HTTPS In',
mgmt_https: 'Management',
}
// eg_backend_<id> → friendly name lookup for HAProxy stats display.
const backendIdToName = useMemo(() => {
const m = new Map<number, string>()
@@ -320,10 +327,14 @@ export default function DashboardPage() {
return down
})()
const certsExpired = (tlsCerts.data ?? []).filter(c => {
if (!c.not_after) return false
return new Date(c.not_after).getTime() < now
})
const certsSoon = (tlsCerts.data ?? []).filter(c => {
if (!c.not_after) return false
const exp = new Date(c.not_after).getTime()
return exp - now < 30 * 86_400_000
return exp >= now && exp - now < 30 * 86_400_000
})
return (
@@ -501,7 +512,7 @@ export default function DashboardPage() {
{(haproxyStats.data?.frontends ?? []).map((f) => (
<div key={f.name} style={{ fontSize: 12, color: '#334155' }}>
<Space size={6} wrap>
<code style={{ fontSize: 11 }}>{f.name}</code>
<code style={{ fontSize: 11 }}>{HA_FRONTEND_LABELS[f.name] ?? f.name}</code>
<Text type="secondary" style={{ fontSize: 11 }}>
{f.sessions} sess
{f.req_rate > 0 ? ` · ${f.req_rate}/s` : ''}
@@ -650,14 +661,23 @@ export default function DashboardPage() {
<Col xs={24} md={12} xl={8}>
<Card size="small" title={<><SafetyCertificateOutlined /> {t('dashboard.sslCard.title')}</>} className="h-100">
<Statistic title={t('dashboard.sslCard.total')} value={(tlsCerts.data ?? []).length} />
{certsSoon.length > 0 ? (
{certsExpired.length > 0 && (
<Alert
style={{ marginTop: 8 }}
type="error"
showIcon
message={t('dashboard.sslCard.certExpired', { count: certsExpired.length })}
/>
)}
{certsSoon.length > 0 && (
<Alert
style={{ marginTop: 8 }}
type="warning"
showIcon
message={t('dashboard.sslCard.expiringSoon', { count: certsSoon.length })}
/>
) : (
)}
{certsExpired.length === 0 && certsSoon.length === 0 && (
<div style={{ marginTop: 8, fontSize: 12, color: '#64748B' }}>
{t('dashboard.sslCard.allFresh')}
</div>