Jul 28 - Update schedule page's referred time
This commit is contained in:
@@ -271,6 +271,9 @@ body{
|
||||
outline:none;border-color:var(--aqua);box-shadow:0 0 0 3px rgba(23,176,166,.16);
|
||||
}
|
||||
.hint{margin:0;font-size:.8rem;color:var(--muted)}
|
||||
/* availability messages from demo-booking.js (slot taken, day closed, …) */
|
||||
.hint--warn{color:#8C5A12;font-weight:500}
|
||||
.field select:disabled{background:var(--paper-2);color:var(--muted);cursor:not-allowed}
|
||||
|
||||
.book__submit{
|
||||
align-self:flex-start;margin-top:6px;padding:16px 38px;border:none;cursor:pointer;
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/* Demo booking form: keep the time picker in step with the chosen date.
|
||||
*
|
||||
* Pick a date -> ask /demo/slots what's still free that day -> rebuild the time
|
||||
* dropdown from the answer, so a slot someone else has already booked is never
|
||||
* offered. Weekends and out-of-range dates come back closed, with the reason.
|
||||
*
|
||||
* Progressive enhancement: without JS (or if the fetch fails) the select keeps
|
||||
* the full server-rendered list and the POST handler still rejects a taken slot
|
||||
* — the server is the authority either way, this just stops the customer
|
||||
* choosing a time that was never going to be accepted.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var form = document.querySelector('[data-slots-url]');
|
||||
if (!form) return;
|
||||
|
||||
var url = form.getAttribute('data-slots-url');
|
||||
var dateEl = document.getElementById('preferred_date');
|
||||
var timeEl = document.getElementById('preferred_time');
|
||||
var noteEl = document.getElementById('slot-note');
|
||||
if (!dateEl || !timeEl || !noteEl) return;
|
||||
|
||||
var placeholder = 'Select a time…';
|
||||
var baseNote = noteEl.textContent; // e.g. "Eastern Time."
|
||||
var request = 0; // drops out-of-order responses
|
||||
|
||||
function note(message, kind) {
|
||||
noteEl.textContent = message;
|
||||
noteEl.className = 'hint' + (kind ? ' hint--' + kind : '');
|
||||
}
|
||||
|
||||
function fill(slots, keep) {
|
||||
timeEl.innerHTML = '';
|
||||
var first = document.createElement('option');
|
||||
first.value = '';
|
||||
first.textContent = slots.length ? placeholder : 'No times available';
|
||||
timeEl.appendChild(first);
|
||||
|
||||
slots.forEach(function (slot) {
|
||||
var option = document.createElement('option');
|
||||
option.value = slot;
|
||||
option.textContent = slot;
|
||||
if (slot === keep) option.selected = true;
|
||||
timeEl.appendChild(option);
|
||||
});
|
||||
timeEl.disabled = slots.length === 0;
|
||||
}
|
||||
|
||||
function load() {
|
||||
var value = dateEl.value;
|
||||
if (!value) {
|
||||
note(baseNote);
|
||||
return;
|
||||
}
|
||||
var ticket = ++request;
|
||||
var wanted = timeEl.value;
|
||||
timeEl.disabled = true;
|
||||
note('Checking availability…');
|
||||
|
||||
fetch(url + '?date=' + encodeURIComponent(value), {
|
||||
headers: { 'Accept': 'application/json' }
|
||||
}).then(function (res) {
|
||||
return res.json().then(function (body) {
|
||||
if (!res.ok) throw new Error(body.error || 'Could not load times.');
|
||||
return body;
|
||||
});
|
||||
}).then(function (data) {
|
||||
if (ticket !== request) return; // a newer date won the race
|
||||
if (!data.open) {
|
||||
fill([], null);
|
||||
note(data.reason || 'That date is not available.', 'warn');
|
||||
return;
|
||||
}
|
||||
fill(data.slots, wanted);
|
||||
if (!data.slots.length) {
|
||||
note('Every time on that day is booked — please choose another date.', 'warn');
|
||||
} else if (wanted && data.slots.indexOf(wanted) === -1) {
|
||||
// The time they had chosen went while they were filling the form in.
|
||||
note('That time has just been booked. Please pick another.', 'warn');
|
||||
} else {
|
||||
note(baseNote);
|
||||
}
|
||||
}).catch(function () {
|
||||
if (ticket !== request) return;
|
||||
// Fail open: leave whatever is in the select and let the server decide.
|
||||
timeEl.disabled = false;
|
||||
note("Couldn't check availability — we'll confirm your time by email.", 'warn');
|
||||
});
|
||||
}
|
||||
|
||||
dateEl.addEventListener('change', load);
|
||||
// A date can survive a failed submit or a browser restore.
|
||||
if (dateEl.value) load();
|
||||
})();
|
||||
Reference in New Issue
Block a user