diff options
| author | Jakob L. Kreuze <zerodaysfordays@sdf.org> | 2022-04-12 20:05:58 -0400 |
|---|---|---|
| committer | Jakob L. Kreuze <zerodaysfordays@sdf.org> | 2022-05-08 19:10:19 -0400 |
| commit | c3ef51bc753f48607032e77d0b344453c7142141 (patch) | |
| tree | 67dcba87051ad42d67393e3f63886ea3954a722c /haunt | |
| parent | f6bd35e8e10faf4db80d6c8ccb45a5beae44c2be (diff) | |
[scheme] Initial RSVP implementation
Diffstat (limited to 'haunt')
| -rw-r--r-- | haunt/pages/rsvp.sxml | 37 | ||||
| -rw-r--r-- | haunt/static/css/style.css | 16 | ||||
| -rw-r--r-- | haunt/static/js/rsvp.js | 118 |
3 files changed, 171 insertions, 0 deletions
diff --git a/haunt/pages/rsvp.sxml b/haunt/pages/rsvp.sxml new file mode 100644 index 0000000..617350f --- /dev/null +++ b/haunt/pages/rsvp.sxml @@ -0,0 +1,37 @@ +(use-modules (jakob theme) + (jakob utils sxml)) + +(theme + #:title "You've Been Invited to an Event!" + #:content + `((div (@ (id "rsvp")) + (div (@ (id "loading")) + ,(image "hourglass.gif") + (p "Loading...")) + (div (@ (id "event-info"))) + (form (@ (id "rsvp-input") (hidden #t)) + (fieldset + (legend "Your Info") + (label (@ (for "name")) "Name:") + (input (@ (type "text") (id "name") (name "name") (required #t) (size 24))) + (label (@ (for "email")) "Email:") + (input (@ (type "text") (id "email") (name "email") (required #t) (size 24)))) + (fieldset + (legend "RSVP Status") + (input (@ (type "radio") (id "attending") (name "rsvp"))) + (label (@ (for "attending")) "Attending") + (input (@ (type "radio") (id "tentative") (name "rsvp"))) + (label (@ (for "tentative")) "Tentative") + (input (@ (type "radio") (id "not-attending") (name "rsvp"))) + (label (@ (for "not-attending")) "Not Attending")) + (fieldset + (legend "Guests") + (div (@ (id "guest-view"))) + (input (@ (type "button") (id "add-entry") (value "+"))) + (input (@ (type "button") (id "remove-entry") (value "-")))) + (fieldset + (legend "All Set?") + (input (@ (type "button") (id "submit-form") (value "Submit"))))) + (div (@ (id "rsvp-global")))) + + ,(script "rsvp.js"))) diff --git a/haunt/static/css/style.css b/haunt/static/css/style.css index f6a1c08..58db3a9 100644 --- a/haunt/static/css/style.css +++ b/haunt/static/css/style.css @@ -408,3 +408,19 @@ button { background-position: 1.5em 50%; padding: 0.25em 1em 0.25em 7em; } + +#loading { + border: 1px solid; + width: fit-content; + padding: 5px; + margin: auto; +} + +fieldset { + padding: 12px; + margin: 15px; +} + +#rsvp-input input { + margin: 0px 16px; +} diff --git a/haunt/static/js/rsvp.js b/haunt/static/js/rsvp.js new file mode 100644 index 0000000..9ba98ac --- /dev/null +++ b/haunt/static/js/rsvp.js @@ -0,0 +1,118 @@ +/* + * rsvp.js -- Simple web-based RSVP tool. + * Copyright © 2022 Jakob L. Kreuze <zerodaysfordays@sdf.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ + +const urlParams = new URLSearchParams(window.location.search); +if (!urlParams.get("i")) { + document.getElementById("loading").remove(); + let elem = document.createElement("p"); + elem.innerHTML = "No invitation code provided."; + document.getElementById("rsvp").appendChild(elem); +} else { + let xhr = new XMLHttpRequest(); + xhr.open("GET", `http://localhost:8081/api/rsvp/event-info?i=${urlParams.get("i")}`); + xhr.send(); + xhr.onload = function(data) { + document.getElementById("loading").remove(); + if (xhr.status != 200) { + let elem = document.createElement("p"); + elem.innerHTML = "Invalid invitation code."; + document.getElementById("rsvp").appendChild(elem); + } else { + document.getElementById("rsvp-input").hidden = false; + + let response = JSON.parse(xhr.response); + + let elem = document.createElement("h1"); + elem.innerHTML = response.title; + document.getElementById("event-info").appendChild(elem); + + elem = document.createElement("p"); + elem.innerHTML = `Where: ${response.location}`; + document.getElementById("event-info").appendChild(elem); + + elem = document.createElement("p"); + elem.innerHTML = `When: ${response.date}`; + document.getElementById("event-info").appendChild(elem); + + elem = document.createElement("p"); + elem.innerHTML = response.description; + document.getElementById("event-info").appendChild(elem); + + if (response.hasOwnProperty("rsvps")) { + elem = document.createElement("h2"); + elem.innerHTML = "Current RSVPs"; + document.getElementById("rsvp-global").appendChild(elem); + + elem = document.createElement("table"); + document.getElementById("rsvp-global").appendChild(elem); + + for (let rsvp of response.rsvps) { + console.log(rsvp.name); + let container = document.createElement("tr"); + let field = document.createElement("td"); + field.textContent = rsvp.name; + container.append(field); + field = document.createElement("td"); + field.textContent = rsvp.email; + container.append(field); + field = document.createElement("td"); + field.textContent = rsvp.guests.replace(',', ', '); + container.append(field); + field = document.createElement("td"); + field.textContent = rsvp.attending; + container.append(field); + elem.appendChild(container); + } + } + + console.log(response); + } + } + xhr.onerror = function(error) { + throw new Error(`Request failed: ${error}`); + } +} + +const guestView = document.getElementById("guest-view"); +const addEntry = document.getElementById("add-entry"); +const removeEntry = document.getElementById("remove-entry"); +const submitButton = document.getElementById("submit-form"); +const form = document.getElementById("rsvp-input"); + +addEntry.addEventListener("click", () => { + let i = guestView.childNodes.length; + let elem = document.createElement("input"); + elem.type = "text"; + elem.id = `guest-${i}`; + guestView.appendChild(elem); +}); + +removeEntry.addEventListener("click", () => { + if (guestView.lastChild) { + guestView.lastChild.remove(); + } +}); + +function submitForm() { + let data = new FormData(form); + console.log(data); +} + +submitButton.addEventListener("click", submitForm); +submitButton.addEventListener("submit", submitForm); |