|
- // 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' };
- }
|