api/
ved/
admin/
modules/
gyar/
admin/
cron/
weuweb01/ved/admin/js/changeTimetable.js1 lines
import { vedAPI as api, getAuthHeader, httpErrorMessage } from "./modules.js";
var auth = getAuthHeader();
var bookingData;
const appendAlert = (wrapper, message, type = "danger") => {
wrapper.innerHTML = "";
const alertBox = document.createElement("div")
alertBox.innerHTML = [
`<div class="alert alert-${type} alert-dismissible" role="alert">`,
` <div>${message}</div>`,
' <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>',
'</div>'
].join('')
wrapper.append(alertBox);
}
function wrapApiResponse(wrapper, response, successMessage) {
if (!response.ok) {
appendAlert(wrapper, httpErrorMessage(response.status));
return;
}
if (successMessage)
appendAlert(wrapper, successMessage, "success");
}
// Schemed opening hours
var timetableForm = document.getElementById("timetable-form");
var timetableFormError = document.getElementById("timetable-form-error");
var bookingIntervalInput = document.querySelector("[name=bookingInterval]");
var bookingLengthInput = document.querySelector("[name=bookingLength]");
var seatCountInput = document.querySelector("[name=seatCount]");
const weekdays = ["Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag", "Söndag"];
function registerTimeSelector(timeSelector) {
let isOpenSwitch = timeSelector.querySelector(".day-is-open");
let openingInput = timeSelector.querySelector(".day-opening");
let closingInput = timeSelector.querySelector(".day-closing");
let enable = () => isOpenSwitch.checked = true;
openingInput.addEventListener("change", enable);
closingInput.addEventListener("change", enable);
isOpenSwitch.addEventListener("change", () => {
if (isOpenSwitch.checked) return;
openingInput.value = "";
closingInput.value = "";
});
return {
switch: isOpenSwitch,
opening: openingInput,
closing: closingInput
};
}
var dayTimes = document.getElementById("dayTimes");
var weekdayTimeSelectors = [];
for (let i = 0; i < weekdays.length; i++) {
let timeSelector = document.createElement("div")
timeSelector.classList.add("row");
timeSelector.innerHTML = `<label for="opening-hours-day${i}-1" class="col pt-1">
${weekdays[i]}:
</label>
<div class="col">
<div class="form-check form-switch pt-2 pd-2 float-end">
<input class="form-check-input day-is-open" type="checkbox" role="switch"
id="switchCheckDefault" name="isOpen{$i}">
</div>
</div>
<div class="col">
<div class="input-group mb-3" style="width: 7rem">
<input id="opening-hours-day${i}-1" type="time" class="form-control day-opening" name="opening{$i}">
</div>
</div>
<div class="col">
<div class="input-group mb-3" style="width: 7rem">
<input id="opening-hours-day${i}-2" type="time" class="form-control day-closing" name="closing{$i}">
</div>
</div>`;
dayTimes.append(timeSelector);
let object = registerTimeSelector(timeSelector);
weekdayTimeSelectors.push(object);
}
async function processTimetableForm(e) {
if (e.preventDefault) e.preventDefault();
timetableFormError.innerHTML = "";
let bookingInterval = Number(bookingIntervalInput.value);
let bookingLength = Number(bookingLengthInput.value);
if (bookingLength % bookingInterval != 0) {
appendAlert(timetableFormError, "Bokningsintervall måste passa in i bokningslängd!");
return;
}
let data = {
"seatCount": Number(seatCountInput.value),
"bookingInterval": bookingInterval,
"bookingLength": bookingLength,
"openingHours": []
};
for (let i = 0; i < weekdayTimeSelectors.length; i++) {
let timeSelector = weekdayTimeSelectors[i];
if (!timeSelector.switch.checked) {
data.openingHours.push({ "openingTime": null, "closingTime": null });
continue;
}
if (timeSelector.opening.value == "" || timeSelector.closing.value == "") {
appendAlert(timetableFormError, `Ogiltig tid för ${weekdays[i].toLowerCase()}!`);
return;
}
data.openingHours.push({ "openingTime": timeSelector.opening.value, "closingTime": timeSelector.closing.value });
let [openHours, openMins] = timeSelector.opening.value.split(":");
let [closeHours, closeMins] = timeSelector.closing.value.split(":");
let dayLength = closeHours * 60 + Number(closeMins) - (openHours * 60 + Number(openMins));
if (!dayLength || dayLength < bookingLength) {
appendAlert(timetableFormError, `Ogiltig tid för ${weekdays[i].toLowerCase()}!`);
return;
}
if (dayLength % bookingInterval != 0) {
appendAlert(timetableFormError, `Bokningsintervall måste passa in i ${weekdays[i].toLowerCase()}!`);
return;
}
}
let res = await api.fetch("bookingData", "PUT", { "body": JSON.stringify(data), "headers": { "Authorization": auth } });
wrapApiResponse(timetableFormError, res, "Uppdaterat!");
if (!res.ok)
return;
bookingData = data;
}
if (timetableForm.attachEvent) {
timetableForm.attachEvent("submit", processTimetableForm);
} else {
timetableForm.addEventListener("submit", processTimetableForm);
}
async function loadBookingData() {
let res = await api.fetch("bookingData");
wrapApiResponse(timetableFormError, res);
if (!res.ok)
return;
let data = await res.json();
bookingData = data;
seatCountInput.value = data.seatCount;
bookingIntervalInput.value = data.bookingInterval;
bookingLengthInput.value = data.bookingLength;
for (let i = 0; i < data.openingHours.length; i++) {
let openingHours = data.openingHours[i];
if (!openingHours.openingTime || !openingHours.openingTime)
continue;
let group = weekdayTimeSelectors[i];
group.opening.value = openingHours.openingTime;
group.closing.value = openingHours.closingTime;
group.switch.checked = true;
}
}
loadBookingData();
// Opening hours exceptions adder
var exceptionForm = document.getElementById("exception-form");
var exceptionFormError = document.getElementById("exception-form-error");
var exceptionDay1Input = document.getElementById("exception-day1");
var exceptionDay2Input = document.getElementById("exception-day2");
var exceptionTimeSelector = registerTimeSelector(document.getElementById("exception-time"));
var multiDayCheck = document.getElementById("multi-day");
multiDayCheck.checked = false;
multiDayCheck.addEventListener("change", () => {
document.querySelector("#exception-single-day label").innerText = multiDayCheck.checked ? "Från:" : "Datum:";
let mdd = document.getElementById("exception-multi-day");
let ed2 = document.getElementById("exception-day2");
if (multiDayCheck.checked) {
mdd.removeAttribute("hidden");
ed2.setAttribute("required", "");
}
else {
mdd.setAttribute("hidden", "");
ed2.removeAttribute("required");
}
});
async function processExceptionForm(e) {
if (e.preventDefault) e.preventDefault();
exceptionFormError.innerHTML = "";
if (exceptionTimeSelector.switch.checked) {
let [openHours, openMins] = exceptionTimeSelector.opening.value.split(":");
let [closeHours, closeMins] = exceptionTimeSelector.closing.value.split(":");
let dayLength = closeHours * 60 + Number(closeMins) - (openHours * 60 + Number(openMins));
if (!dayLength || dayLength < bookingData["bookingLength"]) {
appendAlert(exceptionFormError, "Ogiltig tid!");
return;
}
if (dayLength % bookingData["bookingInterval"] != 0) {
appendAlert(exceptionFormError, "Bokningsintervall måste passa in i tiderna!");
return;
}
}
let data = {
"openingTime": exceptionTimeSelector.opening.value,
"closingTime": exceptionTimeSelector.closing.value,
"date": exceptionDay1Input.value,
}
if (multiDayCheck.checked)
data["date2"] = exceptionDay2Input.value;
if (exceptionDay2Input.value) {
let date1 = new Date(exceptionDay1Input.value);
let date2 = new Date(exceptionDay2Input.value);
if (date1.getTime() >= date2.getTime()) {
appendAlert(exceptionFormError, "Ogiltiga datum!");
return;
}
}
for (let key in data)
if (data[key] == "") data[key] = null;
let res = await api.fetch("openingHoursException", "POST", { "body": JSON.stringify(data), "headers": { "Authorization": auth } });
wrapApiResponse(exceptionFormError, res, "Tillagt!");
if (res.ok)
updateExceptionsList();
}
if (exceptionForm.attachEvent) {
exceptionForm.attachEvent("submit", processExceptionForm);
} else {
exceptionForm.addEventListener("submit", processExceptionForm);
}
// Opening hours exceptions list
var exceptionListError = document.getElementById("exception-list-error");
var exceptionListEmpty = document.getElementById("exception-list-empty");
var exceptionListContainer = document.getElementById("exception-list-container");
async function updateExceptionsList() {
let res = await api.fetch("openingHoursException", "GET", { "headers": { "Authorization": auth } });
wrapApiResponse(exceptionListError, res);
if (!res.ok)
return;
let data = await res.json();
if (data.length == 0)
exceptionListEmpty.removeAttribute("hidden");
else
exceptionListEmpty.setAttribute("hidden", "");
exceptionListContainer.innerHTML = "";
for (let i = 0; i < data.length; i++) {
let exceptionData = data[i];
let dateText = exceptionData["date2"] ? `${exceptionData["date1"]} — ${exceptionData["date2"]}` : exceptionData["date1"];
let timeText = (exceptionData["openingTime"] && exceptionData["closingTime"]) ? `${exceptionData["openingTime"]} — ${exceptionData["closingTime"]}` : "Stängt";
const box = document.createElement("div");
box.classList.add("card");
box.classList.add("m-1");
box.innerHTML = `<div class="card-body">
<button class="btn btn-danger float-end mt-1">Ta bort</button>
<span>Datum: ${dateText}</span>
<br>
<span>Tider: ${timeText}</span>
</div>`;
box.querySelector("button").addEventListener("click", async () => {
let res = await api.fetch("openingHoursException", "DELETE", { "body": JSON.stringify({ "exceptionId": exceptionData["exceptionId"] }), "headers": { "Authorization": auth } });
wrapApiResponse(exceptionListError, res);
if (!res.ok) return;
exceptionListContainer.removeChild(box);
if (exceptionListContainer.children.length == 0)
exceptionListEmpty.removeAttribute("hidden");
});
exceptionListContainer.append(box);
}
}
updateExceptionsList();