diff --git a/wwwroot/poc-service-detail.html b/wwwroot/poc-service-detail.html index 1dc3bf2..65b627a 100644 --- a/wwwroot/poc-service-detail.html +++ b/wwwroot/poc-service-detail.html @@ -981,35 +981,106 @@ swp-availability-time { flex: 1; + display: flex; + flex-direction: column; + gap: 4px; } - swp-availability-time select { + swp-time-range { + display: flex; + align-items: center; + gap: 12px; + } + + swp-time-range-slider { + position: relative; + flex: 1; + height: 20px; + display: flex; + align-items: center; + } + + swp-time-range-track { + position: absolute; width: 100%; - max-width: 200px; - padding: 6px 10px; - font-size: 13px; - font-family: inherit; - border: 1px solid var(--color-border); - border-radius: 4px; - background: var(--color-background-alt); - color: var(--color-text); + height: 4px; + background: var(--color-border); + border-radius: 2px; + } + + swp-time-range-fill { + position: absolute; + height: 4px; + background: var(--color-teal); + border-radius: 2px; + cursor: grab; + } + + swp-time-range-fill:active { + cursor: grabbing; + } + + swp-time-range-fill.disabled { + pointer-events: none; + cursor: default; + } + + swp-time-range-slider input[type="range"] { + position: absolute; + width: 100%; + height: 4px; + -webkit-appearance: none; + appearance: none; + background: transparent; + pointer-events: none; + margin: 0; + } + + swp-time-range-slider input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 14px; + height: 14px; + background: var(--color-teal); + border: 2px solid white; + border-radius: 50%; cursor: pointer; - transition: all 150ms ease; + pointer-events: auto; + box-shadow: 0 1px 3px rgba(0,0,0,0.2); } - swp-availability-time select:hover:not(:disabled) { - background: var(--color-background); + swp-time-range-slider input[type="range"]::-moz-range-thumb { + width: 14px; + height: 14px; + background: var(--color-teal); + border: 2px solid white; + border-radius: 50%; + cursor: pointer; + pointer-events: auto; + box-shadow: 0 1px 3px rgba(0,0,0,0.2); } - swp-availability-time select:focus { - outline: none; - border-color: var(--color-teal); - background: var(--color-surface); + swp-time-range-label { + font-size: 12px; + font-family: var(--font-mono); + color: var(--color-text); + min-width: 90px; + text-align: center; + background: var(--color-background-alt); + padding: 3px 8px; + border-radius: 4px; } - swp-availability-time select:disabled { + swp-availability-row[data-enabled="false"] swp-time-range-slider input[type="range"]::-webkit-slider-thumb { + background: var(--color-text-secondary); + } + + swp-availability-row[data-enabled="false"] swp-time-range-fill { + background: var(--color-text-secondary); + } + + swp-availability-row[data-enabled="false"] swp-time-range-label { opacity: 0.5; - cursor: not-allowed; } /* ========================================== @@ -1887,108 +1958,129 @@ Mandag - - - Ja Nej + + + + + + + + + 08:00 – 18:00 + + Tirsdag - - - Ja Nej + + + + + + + + + 08:00 – 18:00 + + Onsdag - - - Ja Nej + + + + + + + + + 08:00 – 18:00 + + Torsdag - - - Ja Nej + + + + + + + + + 08:00 – 12:00 + + Fredag - - - Ja Nej + + + + + + + + + 08:00 – 18:00 + + Lørdag - - - Ja Nej + + + + + + + + + 08:00 – 18:00 + + Søndag - - - Ja Nej + + + + + + + + + 08:00 – 18:00 + + @@ -2094,6 +2186,106 @@ }); }); + // ========================================== + // TIME RANGE SLIDERS + // ========================================== + function valueToTime(value) { + // value 0-60 represents 06:00-21:00 in 15-min intervals + const totalMinutes = (value * 15) + (6 * 60); // Add 6 hour offset + const hours = Math.floor(totalMinutes / 60); + const minutes = totalMinutes % 60; + return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`; + } + + const TIME_RANGE_MAX = 60; // 15 hours (06:00-21:00) * 4 intervals + + function updateTimeRange(slider) { + const startInput = slider.querySelector('.range-start'); + const endInput = slider.querySelector('.range-end'); + const fill = slider.querySelector('swp-time-range-fill'); + const label = slider.closest('swp-time-range').querySelector('swp-time-range-label'); + + let startVal = parseInt(startInput.value); + let endVal = parseInt(endInput.value); + + // Ensure start doesn't exceed end + if (startVal > endVal) { + if (startInput === document.activeElement) { + startInput.value = endVal; + startVal = endVal; + } else { + endInput.value = startVal; + endVal = startVal; + } + } + + // Update fill bar position + const startPercent = (startVal / TIME_RANGE_MAX) * 100; + const endPercent = (endVal / TIME_RANGE_MAX) * 100; + fill.style.left = startPercent + '%'; + fill.style.width = (endPercent - startPercent) + '%'; + + // Update label + label.textContent = valueToTime(startVal) + ' – ' + valueToTime(endVal); + } + + document.querySelectorAll('swp-time-range-slider').forEach(slider => { + const startInput = slider.querySelector('.range-start'); + const endInput = slider.querySelector('.range-end'); + const fill = slider.querySelector('swp-time-range-fill'); + const track = slider.querySelector('swp-time-range-track'); + + // Initialize + updateTimeRange(slider); + + startInput.addEventListener('input', () => updateTimeRange(slider)); + endInput.addEventListener('input', () => updateTimeRange(slider)); + + // Drag fill bar to move entire range + let isDragging = false; + let dragStartX = 0; + let dragStartValues = { start: 0, end: 0 }; + + fill.addEventListener('mousedown', (e) => { + if (startInput.disabled) return; + isDragging = true; + dragStartX = e.clientX; + dragStartValues.start = parseInt(startInput.value); + dragStartValues.end = parseInt(endInput.value); + e.preventDefault(); + }); + + document.addEventListener('mousemove', (e) => { + if (!isDragging) return; + + const sliderWidth = track.offsetWidth; + const deltaX = e.clientX - dragStartX; + const deltaValue = Math.round((deltaX / sliderWidth) * TIME_RANGE_MAX); + + const duration = dragStartValues.end - dragStartValues.start; + let newStart = dragStartValues.start + deltaValue; + let newEnd = dragStartValues.end + deltaValue; + + // Clamp to bounds + if (newStart < 0) { + newStart = 0; + newEnd = duration; + } + if (newEnd > TIME_RANGE_MAX) { + newEnd = TIME_RANGE_MAX; + newStart = TIME_RANGE_MAX - duration; + } + + startInput.value = newStart; + endInput.value = newEnd; + updateTimeRange(slider); + }); + + document.addEventListener('mouseup', () => { + isDragging = false; + }); + }); + // ========================================== // TOGGLE SLIDERS (Ja/Nej) // ========================================== @@ -2109,9 +2301,13 @@ if (availabilityRow) { const isEnabled = newValue === 'yes'; availabilityRow.dataset.enabled = isEnabled; - const select = availabilityRow.querySelector('select'); - if (select) { - select.disabled = !isEnabled; + const rangeInputs = availabilityRow.querySelectorAll('input[type="range"]'); + rangeInputs.forEach(input => { + input.disabled = !isEnabled; + }); + const fill = availabilityRow.querySelector('swp-time-range-fill'); + if (fill) { + fill.classList.toggle('disabled', !isEnabled); } } });