Team-API, Sidebar-Zaehler und Format-Hilfen fuer Gutschriften, Angebote und E-Mail-Speicher
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
813c6a7e18
commit
91d526e909
13 files changed
+487
-47
No files matched your search
@@ -0,0 +1,49 @@
|
||||
// Gemeinsame Formate fuer die Bereiche aus dem Admin-Panel (Gutschriften, Angebote, E-Mail-Speicher).
|
||||
// Deutsche Zeit (Europe/Berlin), Euro wie Intl de-DE. Rein, unter Node testbar.
|
||||
|
||||
const EURO = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' })
|
||||
|
||||
/** 123456 -> "1.234,56 €" (mit geschuetztem Leerzeichen wie Intl) */
|
||||
export const formatCents = (cents) => EURO.format((Number(cents) || 0) / 100)
|
||||
|
||||
/** "12,5" / "12.50" -> 1250; leer oder ungueltig -> null */
|
||||
export function parseEuroToCents(text) {
|
||||
const s = String(text ?? '').trim().replace(/\s|€/g, '')
|
||||
if (!s) return null
|
||||
const normal = s.includes(',') ? s.replace(/\./g, '').replace(',', '.') : s
|
||||
if (!/^-?\d+(\.\d{1,2})?$/.test(normal)) return null
|
||||
return Math.round(Number(normal) * 100)
|
||||
}
|
||||
|
||||
const parts = (value, options) =>
|
||||
Object.fromEntries(
|
||||
new Intl.DateTimeFormat('de-DE', { timeZone: 'Europe/Berlin', hourCycle: 'h23', ...options })
|
||||
.formatToParts(new Date(value))
|
||||
.map((p) => [p.type, p.value])
|
||||
)
|
||||
const valid = (value) => value && !Number.isNaN(new Date(value).getTime())
|
||||
|
||||
/** dd.mm.yyyy (deutsche Zeit); leer -> "–" */
|
||||
export function fmtDate(value) {
|
||||
if (!valid(value)) return value ? String(value) : '–'
|
||||
const p = parts(value, { day: '2-digit', month: '2-digit', year: 'numeric' })
|
||||
return `${p.day}.${p.month}.${p.year}`
|
||||
}
|
||||
|
||||
/** dd.mm.yy, hh:mm (deutsche Zeit) wie im Admin-Panel; leer -> "–" */
|
||||
export function fmtDateTime(value) {
|
||||
if (!valid(value)) return value ? String(value) : '–'
|
||||
const p = parts(value, { day: '2-digit', month: '2-digit', year: '2-digit', hour: '2-digit', minute: '2-digit' })
|
||||
return `${p.day}.${p.month}.${p.year}, ${p.hour}:${p.minute}`
|
||||
}
|
||||
|
||||
/** Datumsfeld "2026-10-27" -> "27.10.2026" ohne Zeitzonen-Umweg */
|
||||
export const fmtYmd = (ymd) => String(ymd || '').split('-').reverse().join('.')
|
||||
|
||||
/** Zeitpunkt -> Kalendertag in Deutschland (YYYY-MM-DD) */
|
||||
export const berlinYmd = (value) => new Date(value).toLocaleDateString('sv-SE', { timeZone: 'Europe/Berlin' })
|
||||
|
||||
export const fmtBerlin = (value) => fmtYmd(berlinYmd(value))
|
||||
|
||||
export const PRODUCT_LABEL = { hosting: 'Hosting-Abo', wartung: 'Wartungs-Abo' }
|
||||
export const productLabelOf = (key) => PRODUCT_LABEL[key] || (key ? String(key) : 'Abo')
|
||||
Reference in new issue
Block a user