wip
This commit is contained in:
parent
9f46ff8824
commit
35c30c058d
1 changed files with 273 additions and 77 deletions
|
|
@ -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 @@
|
|||
<swp-availability-list>
|
||||
<swp-availability-row data-enabled="true">
|
||||
<swp-availability-day>Mandag</swp-availability-day>
|
||||
<swp-availability-time>
|
||||
<select>
|
||||
<option selected>Hele dagen</option>
|
||||
<option>Formiddag (før 12:00)</option>
|
||||
<option>Eftermiddag (efter 12:00)</option>
|
||||
<option>Brugerdefineret</option>
|
||||
</select>
|
||||
</swp-availability-time>
|
||||
<swp-toggle-slider data-value="yes">
|
||||
<swp-toggle-option>Ja</swp-toggle-option>
|
||||
<swp-toggle-option>Nej</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
<swp-availability-time>
|
||||
<swp-time-range>
|
||||
<swp-time-range-slider>
|
||||
<swp-time-range-track></swp-time-range-track>
|
||||
<swp-time-range-fill></swp-time-range-fill>
|
||||
<input type="range" class="range-start" min="0" max="60" value="8" step="1">
|
||||
<input type="range" class="range-end" min="0" max="60" value="48" step="1">
|
||||
</swp-time-range-slider>
|
||||
<swp-time-range-label>08:00 – 18:00</swp-time-range-label>
|
||||
</swp-time-range>
|
||||
</swp-availability-time>
|
||||
</swp-availability-row>
|
||||
<swp-availability-row data-enabled="true">
|
||||
<swp-availability-day>Tirsdag</swp-availability-day>
|
||||
<swp-availability-time>
|
||||
<select>
|
||||
<option selected>Hele dagen</option>
|
||||
<option>Formiddag (før 12:00)</option>
|
||||
<option>Eftermiddag (efter 12:00)</option>
|
||||
<option>Brugerdefineret</option>
|
||||
</select>
|
||||
</swp-availability-time>
|
||||
<swp-toggle-slider data-value="yes">
|
||||
<swp-toggle-option>Ja</swp-toggle-option>
|
||||
<swp-toggle-option>Nej</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
<swp-availability-time>
|
||||
<swp-time-range>
|
||||
<swp-time-range-slider>
|
||||
<swp-time-range-track></swp-time-range-track>
|
||||
<swp-time-range-fill></swp-time-range-fill>
|
||||
<input type="range" class="range-start" min="0" max="60" value="8" step="1">
|
||||
<input type="range" class="range-end" min="0" max="60" value="48" step="1">
|
||||
</swp-time-range-slider>
|
||||
<swp-time-range-label>08:00 – 18:00</swp-time-range-label>
|
||||
</swp-time-range>
|
||||
</swp-availability-time>
|
||||
</swp-availability-row>
|
||||
<swp-availability-row data-enabled="true">
|
||||
<swp-availability-day>Onsdag</swp-availability-day>
|
||||
<swp-availability-time>
|
||||
<select>
|
||||
<option selected>Hele dagen</option>
|
||||
<option>Formiddag (før 12:00)</option>
|
||||
<option>Eftermiddag (efter 12:00)</option>
|
||||
<option>Brugerdefineret</option>
|
||||
</select>
|
||||
</swp-availability-time>
|
||||
<swp-toggle-slider data-value="yes">
|
||||
<swp-toggle-option>Ja</swp-toggle-option>
|
||||
<swp-toggle-option>Nej</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
<swp-availability-time>
|
||||
<swp-time-range>
|
||||
<swp-time-range-slider>
|
||||
<swp-time-range-track></swp-time-range-track>
|
||||
<swp-time-range-fill></swp-time-range-fill>
|
||||
<input type="range" class="range-start" min="0" max="60" value="8" step="1">
|
||||
<input type="range" class="range-end" min="0" max="60" value="48" step="1">
|
||||
</swp-time-range-slider>
|
||||
<swp-time-range-label>08:00 – 18:00</swp-time-range-label>
|
||||
</swp-time-range>
|
||||
</swp-availability-time>
|
||||
</swp-availability-row>
|
||||
<swp-availability-row data-enabled="true">
|
||||
<swp-availability-day>Torsdag</swp-availability-day>
|
||||
<swp-availability-time>
|
||||
<select>
|
||||
<option>Hele dagen</option>
|
||||
<option selected>Formiddag (før 12:00)</option>
|
||||
<option>Eftermiddag (efter 12:00)</option>
|
||||
<option>Brugerdefineret</option>
|
||||
</select>
|
||||
</swp-availability-time>
|
||||
<swp-toggle-slider data-value="yes">
|
||||
<swp-toggle-option>Ja</swp-toggle-option>
|
||||
<swp-toggle-option>Nej</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
<swp-availability-time>
|
||||
<swp-time-range>
|
||||
<swp-time-range-slider>
|
||||
<swp-time-range-track></swp-time-range-track>
|
||||
<swp-time-range-fill></swp-time-range-fill>
|
||||
<input type="range" class="range-start" min="0" max="60" value="8" step="1">
|
||||
<input type="range" class="range-end" min="0" max="60" value="24" step="1">
|
||||
</swp-time-range-slider>
|
||||
<swp-time-range-label>08:00 – 12:00</swp-time-range-label>
|
||||
</swp-time-range>
|
||||
</swp-availability-time>
|
||||
</swp-availability-row>
|
||||
<swp-availability-row data-enabled="true">
|
||||
<swp-availability-day>Fredag</swp-availability-day>
|
||||
<swp-availability-time>
|
||||
<select>
|
||||
<option selected>Hele dagen</option>
|
||||
<option>Formiddag (før 12:00)</option>
|
||||
<option>Eftermiddag (efter 12:00)</option>
|
||||
<option>Brugerdefineret</option>
|
||||
</select>
|
||||
</swp-availability-time>
|
||||
<swp-toggle-slider data-value="yes">
|
||||
<swp-toggle-option>Ja</swp-toggle-option>
|
||||
<swp-toggle-option>Nej</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
<swp-availability-time>
|
||||
<swp-time-range>
|
||||
<swp-time-range-slider>
|
||||
<swp-time-range-track></swp-time-range-track>
|
||||
<swp-time-range-fill></swp-time-range-fill>
|
||||
<input type="range" class="range-start" min="0" max="60" value="8" step="1">
|
||||
<input type="range" class="range-end" min="0" max="60" value="48" step="1">
|
||||
</swp-time-range-slider>
|
||||
<swp-time-range-label>08:00 – 18:00</swp-time-range-label>
|
||||
</swp-time-range>
|
||||
</swp-availability-time>
|
||||
</swp-availability-row>
|
||||
<swp-availability-row data-enabled="false">
|
||||
<swp-availability-day>Lørdag</swp-availability-day>
|
||||
<swp-availability-time>
|
||||
<select disabled>
|
||||
<option selected>Hele dagen</option>
|
||||
<option>Formiddag (før 12:00)</option>
|
||||
<option>Eftermiddag (efter 12:00)</option>
|
||||
<option>Brugerdefineret</option>
|
||||
</select>
|
||||
</swp-availability-time>
|
||||
<swp-toggle-slider data-value="no">
|
||||
<swp-toggle-option>Ja</swp-toggle-option>
|
||||
<swp-toggle-option>Nej</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
<swp-availability-time>
|
||||
<swp-time-range>
|
||||
<swp-time-range-slider>
|
||||
<swp-time-range-track></swp-time-range-track>
|
||||
<swp-time-range-fill></swp-time-range-fill>
|
||||
<input type="range" class="range-start" min="0" max="60" value="8" step="1" disabled>
|
||||
<input type="range" class="range-end" min="0" max="60" value="48" step="1" disabled>
|
||||
</swp-time-range-slider>
|
||||
<swp-time-range-label>08:00 – 18:00</swp-time-range-label>
|
||||
</swp-time-range>
|
||||
</swp-availability-time>
|
||||
</swp-availability-row>
|
||||
<swp-availability-row data-enabled="false">
|
||||
<swp-availability-day>Søndag</swp-availability-day>
|
||||
<swp-availability-time>
|
||||
<select disabled>
|
||||
<option selected>Hele dagen</option>
|
||||
<option>Formiddag (før 12:00)</option>
|
||||
<option>Eftermiddag (efter 12:00)</option>
|
||||
<option>Brugerdefineret</option>
|
||||
</select>
|
||||
</swp-availability-time>
|
||||
<swp-toggle-slider data-value="no">
|
||||
<swp-toggle-option>Ja</swp-toggle-option>
|
||||
<swp-toggle-option>Nej</swp-toggle-option>
|
||||
</swp-toggle-slider>
|
||||
<swp-availability-time>
|
||||
<swp-time-range>
|
||||
<swp-time-range-slider>
|
||||
<swp-time-range-track></swp-time-range-track>
|
||||
<swp-time-range-fill></swp-time-range-fill>
|
||||
<input type="range" class="range-start" min="0" max="60" value="8" step="1" disabled>
|
||||
<input type="range" class="range-end" min="0" max="60" value="48" step="1" disabled>
|
||||
</swp-time-range-slider>
|
||||
<swp-time-range-label>08:00 – 18:00</swp-time-range-label>
|
||||
</swp-time-range>
|
||||
</swp-availability-time>
|
||||
</swp-availability-row>
|
||||
</swp-availability-list>
|
||||
</swp-card>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue