fix(i18n): relative-time strings vollständig lokalisiert

relativeTime() in Dashboard, relTime() in WireGuard Clients+Servers und
CertExpiry() im Cluster-Page haben bisher hardcodiertes Deutsch
(„vor 5s", „abgelaufen vor X Tagen") gerendert, unabhängig von der
gewählten UI-Sprache.

Neu: gemeinsame i18n-Keys common.relTime.{Xs,Xm,Xh,Xd,never} in EN+DE,
sowie cluster.{certDaysRemaining,certExpiredDaysAgo}. Alle Helper-
Funktionen nehmen jetzt t() als Parameter und sind damit sprachunabhängig.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-24 12:02:27 +02:00
parent 3c95bc58d9
commit e18037375f
8 changed files with 52 additions and 31 deletions

View File

@@ -131,13 +131,13 @@ function formatBytes(n: number): string {
while (v >= 1024 && i < u.length - 1) { v /= 1024; i++ }
return `${v.toFixed(1)} ${u[i]}`
}
function relativeTime(unix: number): string {
if (!unix) return 'nie'
function relativeTime(unix: number, t: (k: string, v?: Record<string, unknown>) => string): string {
if (!unix) return t('common.relTime.never')
const sec = Math.max(0, Math.floor(Date.now() / 1000) - unix)
if (sec < 60) return `vor ${sec}s`
if (sec < 3600) return `vor ${Math.floor(sec / 60)}m`
if (sec < 86400) return `vor ${Math.floor(sec / 3600)}h`
return `vor ${Math.floor(sec / 86400)}d`
if (sec < 60) return t('common.relTime.Xs', { n: sec })
if (sec < 3600) return t('common.relTime.Xm', { n: Math.floor(sec / 60) })
if (sec < 86400) return t('common.relTime.Xh', { n: Math.floor(sec / 3600) })
return t('common.relTime.Xd', { n: Math.floor(sec / 86400) })
}
function formatUptime(sec: number): string {
if (sec < 60) return `${sec}s`
@@ -148,10 +148,10 @@ function formatUptime(sec: number): string {
if (h > 0) return `${h}h ${m}m`
return `${m}m`
}
function relativeFromIso(iso: string): string {
const t = new Date(iso).getTime()
if (!t) return ''
return relativeTime(Math.floor(t / 1000))
function relativeFromIso(iso: string, t: (k: string, v?: Record<string, unknown>) => string): string {
const ts = new Date(iso).getTime()
if (!ts) return ''
return relativeTime(Math.floor(ts / 1000), t)
}
// ── Page ──────────────────────────────────────────────────────
@@ -438,7 +438,7 @@ export default function DashboardPage() {
<Tag color="blue" style={{ margin: 0, fontSize: 10 }}>{e.action}</Tag>
<Text style={{ fontSize: 12 }}><b>{e.actor}</b></Text>
{e.subject && <Text type="secondary" style={{ fontSize: 11 }}>{e.subject}</Text>}
<Text type="secondary" style={{ fontSize: 11, marginLeft: 'auto' }}>{relativeFromIso(e.created_at)}</Text>
<Text type="secondary" style={{ fontSize: 11, marginLeft: 'auto' }}>{relativeFromIso(e.created_at, t)}</Text>
</Space>
</div>
))}
@@ -493,7 +493,7 @@ export default function DashboardPage() {
{status.map(s => (
<div key={s.peer_public_key} style={{ fontSize: 12, color: '#64748B', marginTop: 2 }}>
{s.endpoint && <span>{s.endpoint} · </span>}
<span>{relativeTime(s.last_handshake_unix)}</span>
<span>{relativeTime(s.last_handshake_unix, t)}</span>
{' · ▼'}{formatBytes(s.transfer_rx)}{' · ▲'}{formatBytes(s.transfer_tx)}
</div>
))}