// assets/scripts/duration.js // Zentrale Logik für Zeiteingabe – wird von entries.js importiert // ── Konfiguration ───────────────────────────────────────────────────────────── // Auf false setzen um Viertelstunden-Runden zu deaktivieren export const DURATION_CONFIG = { roundToQuarter: true, }; // ── Parser ──────────────────────────────────────────────────────────────────── /** * Parst Zeiteingaben in Minuten. * * Unterstützte Formate: * "1:30" → 90 (Stunden:Minuten) * "8 12" → 240 (von 8 bis 12 Uhr) * "1,75" → 105 (Dezimalstunden mit Komma) * "1.75" → 105 (Dezimalstunden mit Punkt) * "2" → 120 (nur Stunden als ganze Zahl) * "0:00" → 0 (Stopp/Reset) */ export function parseDuration(input) { input = String(input).trim(); if (!input || input === '0' || input === '0:00') return 0; // "8 12" → von 8 bis 12 Uhr if (/^\d+\s+\d+$/.test(input)) { const parts = input.split(/\s+/).map(Number); const minutes = (parts[1] - parts[0]) * 60; return Math.max(0, minutes); } // "1:30" → Stunden:Minuten if (input.includes(':')) { const [h, m] = input.split(':').map(s => parseInt(s) || 0); return h * 60 + m; } // "1,75" oder "1.75" → Dezimalstunden if (input.includes(',') || input.includes('.')) { const hours = parseFloat(input.replace(',', '.')); return isNaN(hours) ? 0 : Math.round(hours * 60); } // "2" → 2 Stunden const hours = parseInt(input); return isNaN(hours) ? 0 : hours * 60; } // ── Rounding ────────────────────────────────────────────────────────────────── /** * Rundet Minuten auf die nächste Viertelstunde auf. * 0 bleibt 0 (Stopp). */ export function roundToQuarter(minutes) { if (!DURATION_CONFIG.roundToQuarter) return minutes; if (minutes === 0) return 0; const interval = window.TT?.trackingInterval ?? 15; return Math.ceil(minutes / interval) * interval; } // ── Formatter ───────────────────────────────────────────────────────────────── export function formatMinutes(minutes) { const h = Math.floor(minutes / 60); const m = minutes % 60; return `${h}:${String(m).padStart(2, '0')}`; } // ── Blur-Handler (global, per Event Delegation) ─────────────────────────────── // Reagiert auf blur an allen Dauer-Inputs, egal ob server-gerendert oder JS-erstellt export function initDurationBlurHandler() { document.addEventListener('blur', e => { if (!(e.target instanceof Element)) return; if (!e.target.matches('#create-duration, .edit-duration')) return; const raw = e.target.value; const minutes = roundToQuarter(parseDuration(raw)); e.target.value = formatMinutes(minutes); }, true); // capture=true, weil blur nicht bubbled } /** * Validiert eine Dauer in Minuten. * > 1440 (24h) → error * > 480 (8h) → warn */ export function validateDuration(minutes) { if (minutes > 1440) return { status: 'error' }; if (minutes > 480) return { status: 'warn' }; return { status: 'ok' }; }