feat: Phase 0 – Gerüst (FastAPI+SQLite, Multi-User-Login, React-App-Shell, Deploy)
Grundgerüst für Certain Finance: - Backend: FastAPI + SQLAlchemy + SQLite, Alembic-Migrationen (Batch-Mode), argon2-Passwort-Hashing, server-seitige Sitzungen im Cookie, Erst-Admin, Benutzerverwaltung mit Temporär-Passwort, Einstellungen je Benutzer. - Ein Prozess, ein Port: uvicorn liefert API (/api) und gebautes SPA aus, inkl. SPA-Deeplink-Fallback. - Frontend: React 18 + Vite + JSX, Design-Tokens (Light/Dark), i18n DE/EN, Inline-SVG-Icons (keine Emojis), Login, Passwort-ändern, Dashboard-Platzhalter, Benutzer- und Einstellungsseiten. - Deploy: nativer LXC-Installer + Update-Skript (systemd), env-Vorlage, Doku. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
// Formatierung von Beträgen, Zahlen und Daten – währungs-/gebietsspezifisch.
|
||||
// EUR im deutschen Format (1.234,56 €), CHF im Schweizer Format (CHF 1'234.56).
|
||||
// Datum als TT.MM.JJJJ. Beträge liegen intern als Ganzzahl in Cent/Rappen vor.
|
||||
|
||||
export function moneyLocale(currency) {
|
||||
return currency === "CHF" ? "de-CH" : "de-DE";
|
||||
}
|
||||
|
||||
/** Formatiert einen Cent-Betrag als Währungstext (z. B. 123456 -> "1.234,56 €"). */
|
||||
export function formatMoney(cents, currency = "EUR") {
|
||||
const value = (Number(cents) || 0) / 100;
|
||||
return new Intl.NumberFormat(moneyLocale(currency), {
|
||||
style: "currency",
|
||||
currency,
|
||||
}).format(value);
|
||||
}
|
||||
|
||||
/** Formatiert einen Cent-Betrag ohne Währungssymbol (für Eingaben/Tabellen). */
|
||||
export function formatAmount(cents, currency = "EUR") {
|
||||
const value = (Number(cents) || 0) / 100;
|
||||
return new Intl.NumberFormat(moneyLocale(currency), {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
}).format(value);
|
||||
}
|
||||
|
||||
/** ISO-Datum (YYYY-MM-DD oder ISO-Zeitstempel) als TT.MM.JJJJ. */
|
||||
export function formatDate(iso, locale = "de") {
|
||||
if (!iso) return "";
|
||||
const d = new Date(String(iso).length <= 10 ? `${iso}T00:00:00` : iso);
|
||||
if (Number.isNaN(d.getTime())) return String(iso);
|
||||
return new Intl.DateTimeFormat(locale === "en" ? "en-GB" : "de-DE").format(d);
|
||||
}
|
||||
Reference in New Issue
Block a user