53 lines
1.3 KiB
TypeScript
53 lines
1.3 KiB
TypeScript
// frontend\src\components\ui\LastUpdatedText.tsx
|
|
|
|
import { useEffect, useMemo, useState } from 'react'
|
|
|
|
function formatAgoDE(diffMs: number) {
|
|
const s = Math.max(0, Math.floor(diffMs / 1000))
|
|
if (s < 5) return 'gerade eben'
|
|
if (s < 60) return `vor ${s} Sekunden`
|
|
|
|
const m = Math.floor(s / 60)
|
|
if (m === 1) return 'vor 1 Minute'
|
|
if (m < 60) return `vor ${m} Minuten`
|
|
|
|
const h = Math.floor(m / 60)
|
|
if (h === 1) return 'vor 1 Stunde'
|
|
if (h < 24) return `vor ${h} Stunden`
|
|
|
|
const d = Math.floor(h / 24)
|
|
if (d === 1) return 'vor 1 Tag'
|
|
return `vor ${d} Tagen`
|
|
}
|
|
|
|
type Props = {
|
|
fetchedAt?: string | null
|
|
enabled?: boolean
|
|
}
|
|
|
|
export default function LastUpdatedText({ fetchedAt, enabled = true }: Props) {
|
|
const [now, setNow] = useState(() => Date.now())
|
|
|
|
useEffect(() => {
|
|
if (!enabled) return
|
|
|
|
const t = window.setInterval(() => setNow(Date.now()), 1_000)
|
|
return () => window.clearInterval(t)
|
|
}, [enabled])
|
|
|
|
const text = useMemo(() => {
|
|
if (!enabled) return ''
|
|
|
|
const raw = String(fetchedAt ?? '').trim()
|
|
if (!raw) return '(zuletzt aktualisiert: noch kein erfolgreicher Pull)'
|
|
|
|
const ts = Date.parse(raw)
|
|
if (!Number.isFinite(ts)) {
|
|
return '(zuletzt aktualisiert: unbekannt)'
|
|
}
|
|
|
|
return `(zuletzt aktualisiert: ${formatAgoDE(now - ts)})`
|
|
}, [enabled, fetchedAt, now])
|
|
|
|
return <>{text}</>
|
|
} |