export function formatCurrency( amount: number | string, currency: string, ): string { const num = Number(amount) || 0; switch (currency) { case "EUR": return `${num.toLocaleString("cs-CZ", { minimumFractionDigits: 2, maximumFractionDigits: 2 })} €`; case "USD": return `$${num.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; case "CZK": return `${num.toLocaleString("cs-CZ", { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Kč`; case "GBP": return `£${num.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; default: return `${num.toFixed(2)} ${currency}`; } } /** * Joins per-currency amounts into a single display string * (e.g. `"1 234,00 Kč · 50,00 €"`). Typed structurally so it stays decoupled * from the React Query layer's `CurrencyAmount`. Empty/invalid input → * `formatCurrency(0, "CZK")`. */ export function formatMultiCurrency( amounts: Array<{ amount: number; currency: string }>, ): string { if (!Array.isArray(amounts) || amounts.length === 0) return formatCurrency(0, "CZK"); return amounts.map((a) => formatCurrency(a.amount, a.currency)).join(" · "); } export function formatDate(dateStr: string | null | undefined): string { if (!dateStr) return "—"; const d = new Date(dateStr); return d.toLocaleDateString("cs-CZ"); } /** * Today's date as `YYYY-MM-DD` in LOCAL (Prague) time — use this for * date-input defaults. `new Date().toISOString().slice(0, 10)` gives the UTC * date, which is a day behind the Czech date during the post-midnight window * (Prague is UTC+1/+2), so a "today" default could land on yesterday. */ export function todayLocalStr(): string { const d = new Date(); const m = String(d.getMonth() + 1).padStart(2, "0"); const day = String(d.getDate()).padStart(2, "0"); return `${d.getFullYear()}-${m}-${day}`; } /** * Coerce a server-returned numeric (number | decimal-string | null/undefined) * to a number, falling back ONLY when the value is missing or not numeric — * NEVER on a legitimate 0 (e.g. a 0% VAT rate / reverse charge). The * `Number(x) || fallback` idiom silently turns stored zeros into the fallback. */ export function numberOr(raw: unknown, fallback: number): number { if (raw == null || raw === "") return fallback; const n = Number(raw); return Number.isFinite(n) ? n : fallback; } export function formatKm(km: number | string): string { return new Intl.NumberFormat("cs-CZ").format(Number(km) || 0); } export function czechPlural( n: number, one: string, few: string, many: string, ): string { if (n === 1) return one; if (n >= 2 && n <= 4) return few; return many; } /** * Quill 2's semantic HTML saves blank lines as truly empty
, which * collapse to zero height outside the editor — restore the]*)>\s*<\/p>/gi, "