Added more details and a landing page
Build, Test & Push Frontend / quality-check (push) Successful in 6s
Build, Test & Push Frontend / docker (push) Successful in 26s

This commit is contained in:
Andreas Dahm committed 2026-05-04 15:13:24 +02:00
1 parent 950f7d2b80
commit 38976e3240
8 files changed
+654 -40

No files matched your search

+40
View File
@@ -0,0 +1,40 @@
import {useEffect, useState} from 'react';
function useCountUp(target, durationMs = 1600) {
const [value, setValue] = useState(0);
useEffect(() => {
const safeTarget = typeof target === 'number' && Number.isFinite(target) ? target : 0;
if (safeTarget === 0) {
setValue(0);
return;
}
let raf;
let start;
const step = (ts) => {
if (start === undefined) start = ts;
const progress = Math.min((ts - start) / durationMs, 1);
setValue(Math.floor(progress * safeTarget));
if (progress < 1) raf = requestAnimationFrame(step);
};
raf = requestAnimationFrame(step);
return () => cancelAnimationFrame(raf);
}, [target, durationMs]);
return value;
}
export default function StatCard({label, value, icon, suffix}) {
const animated = useCountUp(value);
return (
<div className="flex flex-col items-center justify-center p-6 bg-white dark:bg-slate-800 rounded-xl shadow-sm border border-slate-200 dark:border-slate-700">
{icon && (
<i className={`mdi ${icon} text-3xl text-blue-600 dark:text-blue-400 mb-2`}></i>
)}
<div className="text-4xl font-black text-slate-900 dark:text-white tabular-nums">
{animated.toLocaleString()}{suffix ?? ''}
</div>
<div className="text-xs uppercase tracking-wider text-slate-500 dark:text-slate-400 mt-2 text-center">
{label}
</div>
</div>
);
}