diff options
Diffstat (limited to 'client/src')
| -rw-r--r-- | client/src/admin.js | 28 | ||||
| -rw-r--r-- | client/src/adminArticle.js | 117 | ||||
| -rw-r--r-- | client/src/attractionArticle.js | 253 | ||||
| -rw-r--r-- | client/src/functions.js | 21 | ||||
| -rw-r--r-- | client/src/index.js | 264 | ||||
| -rw-r--r-- | client/src/map.js | 22 | ||||
| -rw-r--r-- | client/src/myorders.js | 24 | ||||
| -rw-r--r-- | client/src/orderArticle.js | 34 | ||||
| -rw-r--r-- | client/src/shoppingbasket.js | 49 | ||||
| -rw-r--r-- | client/src/templateImplementations.js | 73 | ||||
| -rw-r--r-- | client/src/utils.js | 79 |
11 files changed, 596 insertions, 368 deletions
diff --git a/client/src/admin.js b/client/src/admin.js index e69de29..a857055 100644 --- a/client/src/admin.js +++ b/client/src/admin.js @@ -0,0 +1,28 @@ +import { AdminAttraction } from "./templateImplementations.js" + +import { + fetchAttractions, +} from "./utils.js" + +import { + addAttractionInDatabase +} from "./adminArticle.js" + +function displayAdminAttractions(attractions) { + console.log(attractions); + const main = document.querySelector("main"); + const template = document.querySelector("#adminattraction"); + + for (let i = 0; i < attractions.length; i++) { + const attraction = attractions[i]; + const adminAttraction = new AdminAttraction(attraction, template); + adminAttraction.addToNode(main); + } +} + +const newattraction = document.querySelector(".newattraction"); +addbutton.addEventListener("click", addAttractionInDatabase(newattraction)); + +console.log("displaying AdminAttractions") +fetchAttractions() + .then(displayAdminAttractions) diff --git a/client/src/adminArticle.js b/client/src/adminArticle.js new file mode 100644 index 0000000..bc50915 --- /dev/null +++ b/client/src/adminArticle.js @@ -0,0 +1,117 @@ +import { + AdminAttraction +} from "./templateImplementations.js" + +import { + kill, + findParent +} from "./utils.js" + +export function addAttractionInDatabase(newattraction) { + + return async function addAttraction(event) { + const name = newattraction.querySelector("#newattractionname").value; + const description = newattraction.querySelector("#newattractiondescription").value; + const lat = Number.parseFloat(newattraction.querySelector("#newlat").value); + const lon = Number.parseFloat(newattraction.querySelector("#newlong").value); + if (!name || !description) return; + if (Number.isNaN(lat)) return; + if (Number.isNaN(lon)) return; + + console.log("adding " + name + " at lat: " + lat + " and long: " + lon); + try { + const response = await fetch("api/admin/add", + { + method: 'POST', // *GET, POST, PUT, DELETE, etc. + mode: 'cors', // no-cors, *cors, same-origin + cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached + credentials: 'same-origin', // include, *same-origin, omit + headers: { + 'Content-Type': 'application/json' + // 'Content-Type': 'application/x-www-form-urlencoded', + }, + redirect: 'follow', // manual, *follow, error + referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + body: JSON.stringify({name: name, description: description, lat: lat, lon: lon}) // body data type must match "Content-Type" header + }); + + if (!response.ok) { + const message = `An error has occured: ${response.status}`; + throw new Error(message); + } + + const main = findParent(parent => {return parent.tagName === "MAIN"})(event.target) + const template = main.parentNode.querySelector("#adminattraction"); + const attractionJSON = await response.json(); + console.log(attractionJSON) + const newAttraction = new AdminAttraction(attractionJSON, template); + newAttraction.addToNode(main); + + } catch(error) { + console.log("Something went wrong when deleting an attraction: ", error); + } + + } +} + +export function deleteAttractionInDatabase(name) { + return async function deleteAttraction(event) { + console.log("deleting " + name); + try { + const response = await fetch("api/admin/delete", + { + method: 'POST', // *GET, POST, PUT, DELETE, etc. + mode: 'cors', // no-cors, *cors, same-origin + cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached + credentials: 'same-origin', // include, *same-origin, omit + headers: { + 'Content-Type': 'application/json' + // 'Content-Type': 'application/x-www-form-urlencoded', + }, + redirect: 'follow', // manual, *follow, error + referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + body: JSON.stringify({name: name}) // body data type must match "Content-Type" header + }); + + if (!response.ok) { + const message = `An error has occured: ${response.status}`; + throw new Error(message); + } + + } catch(error) { + console.log("Something went wrong when deleting an attraction: ", error); + } + kill(findParent(parent => {return parent.tagName === "ARTICLE"})(event.target)); + } +} + + +export function updateAttractionInDatabase(name, field) { + return async function update(event) { + console.log("updating " + field + " field of " + name); + try { + const response = await fetch("api/admin/edit", + { + method: 'POST', // *GET, POST, PUT, DELETE, etc. + mode: 'cors', // no-cors, *cors, same-origin + cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached + credentials: 'same-origin', // include, *same-origin, omit + headers: { + 'Content-Type': 'application/json' + // 'Content-Type': 'application/x-www-form-urlencoded', + }, + redirect: 'follow', // manual, *follow, error + referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + body: JSON.stringify({name: name, field: field, value: event.target.value}) // body data type must match "Content-Type" header + }); + + if (!response.ok) { + const message = `An error has occured: ${response.status}`; + throw new Error(message); + } + + } catch(error) { + console.log("Something went wrong when editing an attraction: ", error); + } + } +} diff --git a/client/src/attractionArticle.js b/client/src/attractionArticle.js new file mode 100644 index 0000000..493417e --- /dev/null +++ b/client/src/attractionArticle.js @@ -0,0 +1,253 @@ +import { + fetchAttractions, + findParent, + dutchCurrencyFormat, + dutchCurrencyFormatWithSign, + displayNumberOfItemsInShoppingBasketWithBadge +} from "./utils.js" + +export function disableButton(name, button) { + return function receiver(payload) { + console.log('checking if button should be disabled'); + const inputs = button.parentNode.querySelectorAll("input"); + var inputTickets = 0; + for (let i = 0; i < inputs.length; i++) { + if (inputs[i].value > 0) { + inputTickets = inputTickets + Number.parseInt(inputs[i].value); + } + } + + const shoppingBasketArray = JSON.parse(localStorage.getItem("shoppingBasketArray")); + // console.log(shoppingBasketArray); + var shoppingBasketTickets = 0; + + if (shoppingBasketArray) { + for (let i = 0; i < shoppingBasketArray.length; i++) { + if (shoppingBasketArray[i].name === name) { + shoppingBasketTickets = shoppingBasketTickets + shoppingBasketArray[i].numberOfKids + shoppingBasketArray[i].numberOfAdults; + } + } + } + const totalTickets = inputTickets + shoppingBasketTickets; + + function disablerHelper(payload) { + var attraction; + if (Array.isArray(payload)) { + for (let i = 0; i < payload.length; i++) { + if (payload[i].name === name) { + attraction = payload[i]; + } + } + } else attraction = payload; + + var front = button.querySelector(".front"); + if (attraction.available < totalTickets || attraction.available === 0 || attraction.available === shoppingBasketTickets) { + console.log("---> disabling " + attraction.name + " button since the available tickets are " + attraction.available + " and tickets among current order is " + totalTickets); + front.classList.add("disabled"); + button.removeEventListener("click", orderButtonClicked); + } else { + console.log("---> enabling " + attraction.name + " button since the available tickets are " + attraction.available + " and tickets among current order is " + totalTickets); + front.classList.remove("disabled"); + button.addEventListener("click", orderButtonClicked); + } + + } + + // console.log(payload) + if (payload && payload.name) { + if (payload.name) { + // console.log("prevented unnecesary fetch") + disablerHelper(payload); + } + } else { + // console.log("unnecesary fetch") + fetchAttractions() + .then(disablerHelper) + .catch(error => {console.error(error)}); + } + } +} + +export function orderButtonClicked(event) { + console.log("button click"); + var button; + + if (event.target.classList.contains("orderbutton")) { + button = event.target; + } else { + button = event.target.parentNode; + } + + const order = button.parentNode; + const parkArticle = order.parentNode; + + const orderClientSideInfo = { + name: parkArticle.querySelector(".parkname").textContent, + numberOfKids: Number(order.querySelector(".numberofkids").value), + numberOfAdults: Number(order.querySelector(".numberofadults").value), + } + + console.log("---> found this info on the client side:") + console.log(orderClientSideInfo); + + if ((orderClientSideInfo.numberOfKids > 0 && orderClientSideInfo.numberOfAdults >= 0) || (orderClientSideInfo.numberOfAdults > 0 && orderClientSideInfo.numberOfKids >= 0)) { + fetchAttractions() + .then(checkTicketAvailability(button, orderClientSideInfo)) + .then(saveOrderInShoppingBasket(orderClientSideInfo)) + .then(disableButton(orderClientSideInfo.name, button)) + .catch((error) => {console.error(error)}) + } +} + +class TicketsNotAvailableError extends Error { + constructor(message) { + super(message); + this.name = "TicketsNotAvailableError"; + } +} + + +export function checkTicketAvailability(button, orderClientSideInfo) { + + return function serverAttractionsAccepter(serverAttractionsArray) { + var attraction; + for (let i = 0; i < serverAttractionsArray.length; i++) { + if (serverAttractionsArray[i].name === orderClientSideInfo.name) { + attraction = serverAttractionsArray[i] + } + } + + if (attraction.available < orderClientSideInfo.numberOfKids + orderClientSideInfo.numberOfAdults) { + throw new TicketsNotAvailableError("The tickets of the order exceed the available tickets!"); + } + + return serverAttractionsArray; + } +} + +export function saveOrderInShoppingBasket(orderClientSideInfo) { + console.log("---> ---> saving info in shopping basket"); + + return function serverAttractionsAccepter(serverAttractionsArray) { + // const orderClientSideInfo = this; + + var price; + var attraction; + for (let i = 0; i < serverAttractionsArray.length; i++) { + if (serverAttractionsArray[i].name === orderClientSideInfo.name) { + price = calulateTotal( + orderClientSideInfo.numberOfKids, + orderClientSideInfo.numberOfAdults, + serverAttractionsArray[i] + ); + attraction = serverAttractionsArray[i]; + } + } + + orderClientSideInfo.price = price; + console.log("---> ---> price is saved in the shopping basket order"); + console.log(orderClientSideInfo); + + var shoppingBasketArray; + + if (localStorage.getItem("shoppingBasketArray") === null) { + shoppingBasketArray = []; + shoppingBasketArray.push(orderClientSideInfo); + } else { + shoppingBasketArray = JSON.parse(localStorage.getItem("shoppingBasketArray")); + shoppingBasketArray.push(orderClientSideInfo); + } + + localStorage.setItem("shoppingBasketArray", JSON.stringify(shoppingBasketArray)); + console.log("---> ---> order is saved in array in localstorage"); + console.log(localStorage); + displayNumberOfItemsInShoppingBasketWithBadge(); + return attraction; + } +} + +export function calulateTotal(numberOfKids, numberOfAdults, serverSideAttraction) { + console.log("---> calculating total of order in shoppingbasket!"); + console.log("---> ---> fetched this attraction to calculate actual prices!"); + console.log(serverSideAttraction); + + const adultPrice = serverSideAttraction.adultPrice; + const kidsPrice = serverSideAttraction.kidsPrice; + + const discountPercentage = serverSideAttraction.discount; + const minNumberkids = serverSideAttraction.minimumNumberOfKids; + const minNumberAdults = serverSideAttraction.minimumNumberOfAdults; + + var totalPrice = 0; + if (numberOfKids > 0) { + totalPrice = totalPrice + numberOfKids * kidsPrice; + } + if (numberOfAdults > 0) { + totalPrice = totalPrice + numberOfAdults * adultPrice; + } + + if (numberOfKids >= minNumberkids && numberOfAdults >= minNumberAdults) { + var discount = totalPrice * discountPercentage / 100; + totalPrice = totalPrice - discount; + } + + if (discount) { + return {total:totalPrice, discount: discount} + } else { + return {total: totalPrice}; + } +} + +export function displayTotal(event) { + console.log("displaying a total price based on client side info"); + var order = findParent(parent => {return parent.classList.contains("order")})(event.target) + console.log(order) + var total = order.querySelector(".total"); + + var kids = order.querySelector(".numberofkids").value; + var adults = order.querySelector(".numberofadults").value; + if (kids === "") kids = 0; + if (adults === "") adults = 0; + + let re = /\d+/; + var kidsPrice = order.querySelector(".kidsprice") + .textContent + .match(re)[0]; + var adultPrice = order.querySelector(".adultprice") + .textContent + .match(re)[0]; + + var discountReq = order.querySelector(".discountrequirement") + var minNumberkids = discountReq.querySelector(".child") + .textContent + .match(re)[0] + var minNumberadults = discountReq.querySelector(".adults") + .textContent + .match(re)[0] + var discountPercentage = discountReq.querySelector(".percentage") + .textContent + .match(re)[0]; + // console.log(discountPercentage); + + var value = 0; + if (kids > 0) { + value = value + Number.parseInt(kids) * Number.parseFloat(kidsPrice); + } + if (adults > 0) { + value = value + Number.parseInt(adults) * Number.parseFloat(adultPrice); + } + + var discount; + if (Number.parseInt(kids) >= Number.parseInt(minNumberkids) && Number.parseInt(adults) >= Number.parseInt(minNumberadults)) { + discount = value * Number.parseFloat(discountPercentage) / 100 + value = value - discount; + console.log("---> applying the discount of " + discountPercentage + "%, resulting in " + discount + " discount") + } + // console.log(value); + + var priceString = dutchCurrencyFormat(value); + if (!(discount === undefined)) { + priceString = priceString + " discount: " + dutchCurrencyFormatWithSign(discount); + } + total.querySelector(".price").textContent = priceString; +} diff --git a/client/src/functions.js b/client/src/functions.js index a43dbac..e69de29 100644 --- a/client/src/functions.js +++ b/client/src/functions.js @@ -1,21 +0,0 @@ -// client/src/function.js -export async function fetchAttractions() { - - try { - - const response = await fetch("api/attractions"); - - if (!response.ok) { - const message = `An error has occured: ${response.status}`; - throw new Error(message); - } - - const attractions = await response.json(); - return attractions; - - - } catch(error) { - console.log("something went wrong when fetching attractions: ", error); - } - -} diff --git a/client/src/index.js b/client/src/index.js index 0b8e676..5743b5e 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -1,11 +1,13 @@ import { ParkArticle } from "./templateImplementations.js"; + import { + fetchAttractions, displayNumberOfItemsInShoppingBasketWithBadge, dutchCurrencyFormat, dutchCurrencyFormatWithSign, - findParent + findParent, + killChildren, } from "./utils.js"; -import { fetchAttractions } from "./functions.js" // ik struggle een beetje met de database connecten met de api... @@ -14,266 +16,14 @@ import { fetchAttractions } from "./functions.js" function displayArticles(articles) { console.log("displaying attraction articles"); - const parkArticleFunctionality = { - orderButtonClick: orderButtonClicked, - displayTotal: displayTotal, - disableButton: disableButton, - } for (var i = 0; i < articles.length; i++) { var parkArticle = new ParkArticle(articles[i], document.querySelector("#parkarticle")); - parkArticle.addToNode(document.querySelector("#center-articles"), parkArticleFunctionality); - } - -} - -function disableButton(name, button) { - return function receiver(payload) { - console.log('checking if button should be disabled'); - const inputs = button.parentNode.querySelectorAll("input"); - var inputTickets = 0; - for (let i = 0; i < inputs.length; i++) { - if (inputs[i].value > 0) { - inputTickets = inputTickets + Number.parseInt(inputs[i].value); - } - } - - const shoppingBasketArray = JSON.parse(localStorage.getItem("shoppingBasketArray")); - // console.log(shoppingBasketArray); - var shoppingBasketTickets = 0; - - if (shoppingBasketArray) { - for (let i = 0; i < shoppingBasketArray.length; i++) { - if (shoppingBasketArray[i].name === name) { - shoppingBasketTickets = shoppingBasketTickets + shoppingBasketArray[i].numberOfKids + shoppingBasketArray[i].numberOfAdults; - } - } - } - const totalTickets = inputTickets + shoppingBasketTickets; - - function disablerHelper(payload) { - var attraction; - if (Array.isArray(payload)) { - for (let i = 0; i < payload.length; i++) { - if (payload[i].name === name) { - attraction = payload[i]; - } - } - } else attraction = payload; - - var front = button.querySelector(".front"); - if (attraction.available < totalTickets || attraction.available === 0 || attraction.available === shoppingBasketTickets) { - console.log("---> disabling " + attraction.name + " button since the available tickets are " + attraction.available + " and tickets among current order is " + totalTickets); - front.classList.add("disabled"); - button.removeEventListener("click", orderButtonClicked); - } else { - console.log("---> enabling " + attraction.name + " button since the available tickets are " + attraction.available + " and tickets among current order is " + totalTickets); - front.classList.remove("disabled"); - button.addEventListener("click", orderButtonClicked); - } - - } - - // console.log(payload) - if (payload && payload.name) { - if (payload.name) { - // console.log("prevented unnecesary fetch") - disablerHelper(payload); - } - } else { - // console.log("unnecesary fetch") - fetchAttractions() - .then(disablerHelper) - .catch(error => {console.error(error)}); - } - } -} - -function orderButtonClicked(event) { - console.log("button click"); - var button; - - if (event.target.classList.contains("orderbutton")) { - button = event.target; - } else { - button = event.target.parentNode; - } - - const order = button.parentNode; - const parkArticle = order.parentNode; - - const orderClientSideInfo = { - name: parkArticle.querySelector(".parkname").textContent, - numberOfKids: Number(order.querySelector(".numberofkids").value), - numberOfAdults: Number(order.querySelector(".numberofadults").value), - } - - console.log("---> found this info on the client side:") - console.log(orderClientSideInfo); - - if ((orderClientSideInfo.numberOfKids > 0 && orderClientSideInfo.numberOfAdults >= 0) || (orderClientSideInfo.numberOfAdults > 0 && orderClientSideInfo.numberOfKids >= 0)) { - fetchAttractions() - .then(checkTicketAvailability(button, orderClientSideInfo)) - .then(saveOrderInShoppingBasket(orderClientSideInfo)) - .then(disableButton(orderClientSideInfo.name, button)) - .catch((error) => {console.error(error)}) - } -} - -class TicketsNotAvailableError extends Error { - constructor(message) { - super(message); - this.name = "TicketsNotAvailableError"; - } -} - - -export function checkTicketAvailability(button, orderClientSideInfo) { - - return function serverAttractionsAccepter(serverAttractionsArray) { - var attraction; - for (let i = 0; i < serverAttractionsArray.length; i++) { - if (serverAttractionsArray[i].name === orderClientSideInfo.name) { - attraction = serverAttractionsArray[i] - } - } - - if (attraction.available < orderClientSideInfo.numberOfKids + orderClientSideInfo.numberOfAdults) { - throw new TicketsNotAvailableError("The tickets of the order exceed the available tickets!"); - } - - return serverAttractionsArray; - } -} - -function saveOrderInShoppingBasket(orderClientSideInfo) { - console.log("---> ---> saving info in shopping basket"); - - return function serverAttractionsAccepter(serverAttractionsArray) { - // const orderClientSideInfo = this; - - var price; - var attraction; - for (let i = 0; i < serverAttractionsArray.length; i++) { - if (serverAttractionsArray[i].name === orderClientSideInfo.name) { - price = calulateTotal( - orderClientSideInfo.numberOfKids, - orderClientSideInfo.numberOfAdults, - serverAttractionsArray[i] - ); - attraction = serverAttractionsArray[i]; - } - } - - orderClientSideInfo.price = price; - console.log("---> ---> price is saved in the shopping basket order"); - console.log(orderClientSideInfo); - - var shoppingBasketArray; - - if (localStorage.getItem("shoppingBasketArray") === null) { - shoppingBasketArray = []; - shoppingBasketArray.push(orderClientSideInfo); - } else { - shoppingBasketArray = JSON.parse(localStorage.getItem("shoppingBasketArray")); - shoppingBasketArray.push(orderClientSideInfo); - } - - localStorage.setItem("shoppingBasketArray", JSON.stringify(shoppingBasketArray)); - console.log("---> ---> order is saved in array in localstorage"); - console.log(localStorage); - displayNumberOfItemsInShoppingBasketWithBadge(); - return attraction; - } -} - -function calulateTotal(numberOfKids, numberOfAdults, serverSideAttraction) { - console.log("---> calculating total of order in shoppingbasket!"); - console.log("---> ---> fetched this attraction to calculate actual prices!"); - console.log(serverSideAttraction); - - const adultPrice = serverSideAttraction.adultPrice; - const kidsPrice = serverSideAttraction.kidsPrice; - - const discountPercentage = serverSideAttraction.discount; - const minNumberkids = serverSideAttraction.minimumNumberOfKids; - const minNumberAdults = serverSideAttraction.minimumNumberOfAdults; - - var totalPrice = 0; - if (numberOfKids > 0) { - totalPrice = totalPrice + numberOfKids * kidsPrice; - } - if (numberOfAdults > 0) { - totalPrice = totalPrice + numberOfAdults * adultPrice; - } - - if (numberOfKids >= minNumberkids && numberOfAdults >= minNumberAdults) { - var discount = totalPrice * discountPercentage / 100; - totalPrice = totalPrice - discount; + parkArticle.addToNode(document.querySelector("#center-articles")); } - if (discount) { - return {total:totalPrice, discount: discount} - } else { - return {total: totalPrice}; - } } -function displayTotal(event) { - console.log("displaying a total price based on client side info"); - var order = findParent(parent => {return parent.classList.contains("order")})(event.target) - console.log(order) - var total = order.querySelector(".total"); - - var kids = order.querySelector(".numberofkids").value; - var adults = order.querySelector(".numberofadults").value; - if (kids === "") kids = 0; - if (adults === "") adults = 0; - - let re = /\d+/; - var kidsPrice = order.querySelector(".kidsprice") - .textContent - .match(re)[0]; - var adultPrice = order.querySelector(".adultprice") - .textContent - .match(re)[0]; - - var discountReq = order.querySelector(".discountrequirement") - var minNumberkids = discountReq.querySelector(".child") - .textContent - .match(re)[0] - var minNumberadults = discountReq.querySelector(".adults") - .textContent - .match(re)[0] - var discountPercentage = discountReq.querySelector(".percentage") - .textContent - .match(re)[0]; - // console.log(discountPercentage); - - var value = 0; - if (kids > 0) { - value = value + Number.parseInt(kids) * Number.parseFloat(kidsPrice); - } - if (adults > 0) { - value = value + Number.parseInt(adults) * Number.parseFloat(adultPrice); - } - - var discount; - if (Number.parseInt(kids) >= Number.parseInt(minNumberkids) && Number.parseInt(adults) >= Number.parseInt(minNumberadults)) { - discount = value * Number.parseFloat(discountPercentage) / 100 - value = value - discount; - console.log("---> applying the discount of " + discountPercentage + "%, resulting in " + discount + " discount") - } - // console.log(value); - - var priceString = dutchCurrencyFormat(value); - if (!(discount === undefined)) { - priceString = priceString + " discount: " + dutchCurrencyFormatWithSign(discount); - } - total.querySelector(".price").textContent = priceString; -} - - function setStickyNavBar() { console.log("making the navbar sticky"); // Get the header @@ -301,5 +51,9 @@ function setStickyNavBar() { displayNumberOfItemsInShoppingBasketWithBadge(); setStickyNavBar(); +const sortmenu = document.querySelector("#sortmenu"); + +console.log(sortmenu) + fetchAttractions() .then(displayArticles); diff --git a/client/src/map.js b/client/src/map.js index 10f2d66..6af7619 100644 --- a/client/src/map.js +++ b/client/src/map.js @@ -1,4 +1,4 @@ -import { fetchAttractions } from "./functions.js" +import { fetchAttractions } from "./utils.js" import { ParkArticle } from "./templateImplementations.js" // replace "toner" here with "terrain" or "watercolor" @@ -10,6 +10,8 @@ var map = new L.Map("discoverablemap", { map.addLayer(layer); function addMarkersForAttractions(map) { + const template = document.querySelector("#parkpopup"); + return function addMarkers(attractions) { for (let i = 0; i < attractions.length; i++) { const attraction = attractions[i]; @@ -17,20 +19,14 @@ function addMarkersForAttractions(map) { const marker = L.marker([location.lat, location.lon]).addTo(map); - const articleObj = new ParkArticle(attraction, document.querySelector("parkpopup")) - console.log(articleObj) - const parkArticleFunctionality = { - orderButtonClick: orderButtonClicked, - displayTotal: displayTotal, - disableButton: disableButton, - } - const articleHTML = articleObj.toHTML(parkArticleFunctionality); - console.log(articleHTML); + const articleObj = new ParkArticle(attraction, template); + const articleHTML = articleObj.toHTML(); + var div = L.DomUtil.create('div', 'popupcontent'); + const popupcontent = articleHTML; + div.appendChild(popupcontent); - marker.bindPopup( - articleHTML - ) + marker.bindPopup(div) } } diff --git a/client/src/myorders.js b/client/src/myorders.js index e69de29..302cb55 100644 --- a/client/src/myorders.js +++ b/client/src/myorders.js @@ -0,0 +1,24 @@ +import { Order } from "./templateImplementations.js" +import { + displayNumberOfItemsInShoppingBasketWithBadge, + fetchOrders, +} from "./utils.js"; + + +async function displayOrders() { + displayNumberOfItemsInShoppingBasketWithBadge(); + console.log("displaying orders in database"); + + var orders = await fetchOrders(); + if (orders === null || orders.length === 0) { + } + + var main = document.querySelector("main"); + + for (let i = 0; i < orders.length; i++) { + var orderObj = new Order(orders[i], document.querySelector("#ticket")); + orderObj.addToNode(main); + } +} + +displayOrders(); diff --git a/client/src/orderArticle.js b/client/src/orderArticle.js new file mode 100644 index 0000000..be5a75b --- /dev/null +++ b/client/src/orderArticle.js @@ -0,0 +1,34 @@ +import { + fetchOrders, + readOrderArrayFromLocalStorage, + kill, + findParent, + displayNumberOfItemsInShoppingBasketWithBadge +} from "./utils.js" + +export function cancelOrder(event) { + //console.log(event.target); + console.log("cancel button clicked"); + const article = findParent(parent => {return parent.tagName === "ARTICLE"})(event.target); + + var previous = article.previousSibling; + var i = 0; + while (previous) { + if (previous.tagName === "ARTICLE") { + i = i+1; + } + previous = previous.previousSibling; + } + + var orders = readOrderArrayFromLocalStorage(); + console.log("---> canceling order "); + console.log(orders[i]); + console.log("---> removing it from shoppingbasket") + orders.splice(i, 1); + localStorage.setItem("shoppingBasketArray", JSON.stringify(orders)); + + var main = document.querySelector("main"); + console.log("---> refreshing displayed orders") + kill(article); + displayNumberOfItemsInShoppingBasketWithBadge(); +} diff --git a/client/src/shoppingbasket.js b/client/src/shoppingbasket.js index 56e717a..434b8cf 100644 --- a/client/src/shoppingbasket.js +++ b/client/src/shoppingbasket.js @@ -1,20 +1,15 @@ import { Order } from "./templateImplementations.js" -import { displayNumberOfItemsInShoppingBasketWithBadge, findParentWithTag, childKillerUsingTags } from "./utils.js"; +import { + displayNumberOfItemsInShoppingBasketWithBadge, + readOrderArrayFromLocalStorage, +} from "./utils.js"; -function getOrderArray() { - var orders = JSON.parse(localStorage.getItem("shoppingBasketArray")); - return orders; -} - function displayOrders() { displayNumberOfItemsInShoppingBasketWithBadge(); console.log("displaying orders in shopppingbasket"); - const orderFunctionality = { - cancel: cancelOrder, - }; - var orders = getOrderArray(); + var orders = readOrderArrayFromLocalStorage(); if (orders === null || orders.length === 0) { var button = document.querySelector("#finalizepaymentbutton"); var front = button.querySelector(".front"); @@ -30,40 +25,10 @@ function displayOrders() { for (let i = 0; i < orders.length; i++) { var orderObj = new Order(orders[i], document.querySelector("#ticket")); - orderObj.addToNode(main, orderFunctionality); + orderObj.addToNode(main); } } -function cancelOrder(event) { - //console.log(event.target); - console.log("cancel button clicked"); - const article = findParentWithTag.bind(event.target)("article"); - - var previous = article.previousSibling; - var i = 0; - while (previous) { - if (previous.tagName === "ARTICLE") { - i = i+1; - } - previous = previous.previousSibling; - } - - var orders = getOrderArray(); - console.log("---> canceling order "); - console.log(orders[i]); - console.log("---> removing it from shoppingbasket") - orders.splice(i, 1); - localStorage.setItem("shoppingBasketArray", JSON.stringify(orders)); - - var main = document.querySelector("main"); - console.log("---> refreshing displayed orders") - childKillerUsingTags(main)(main.firstChild)("article"); - displayOrders(); -} - - - - function finalizePayment(event) { console.log("finalizing payments"); @@ -71,8 +36,6 @@ function finalizePayment(event) { window.location.replace("orderplaced.html"); } - - document.querySelector("#finalizepaymentbutton").addEventListener("click", finalizePayment); displayOrders(); diff --git a/client/src/templateImplementations.js b/client/src/templateImplementations.js index 5767a84..5940d7e 100644 --- a/client/src/templateImplementations.js +++ b/client/src/templateImplementations.js @@ -1,5 +1,24 @@ -import { dutchCurrencyFormat, dutchCurrencyFormatWithSign } from "./utils.js" -import { fetchAttractions } from "./functions.js" +import { + dutchCurrencyFormat, + dutchCurrencyFormatWithSign, +} from "./utils.js" + +import { + disableButton, + calulateTotal, + checkTicketAvailability, + displayTotal +} from "./attractionArticle.js" + +import { + cancelOrder +} from "./orderArticle.js" + +import { + updateAttractionInDatabase, + deleteAttractionInDatabase +} from "./adminArticle.js" + /** * Abstract class * @@ -21,10 +40,38 @@ class TemplatedNode { } } +export class AdminAttraction extends TemplatedNode { + addToNode(node) { + var clone = this.template.content.cloneNode(true); + clone.querySelector(".parkname").textContent = this.name; + + clone.querySelector(".adultprice").querySelector(".adultPrice").value = this.adultPrice; + clone.querySelector(".kidsprice").querySelector(".kidsPrice").value = this.kidsPrice; + + clone.querySelector(".discountrequirement").querySelector(".minimumNumberOfAdults").value = this.minimumNumberOfAdults; + clone.querySelector(".discountrequirement").querySelector(".minimumNumberOfKids").value = this.minimumNumberOfKids; + clone.querySelector(".discountrequirement").querySelector(".discount").value = this.discount; + + clone.querySelector(".availabletickets").querySelector(".available").value = this.available; + + const inputElements = clone.querySelectorAll("input"); + for (let i = 0; i < inputElements.length; i++) { + const input = inputElements[i]; + const fieldToUpdate = input.className; + input.addEventListener("input", updateAttractionInDatabase(this.name, fieldToUpdate)); + } + + const deletebutton = clone.querySelector("#deletebutton"); + deletebutton.addEventListener("click", deleteAttractionInDatabase(this.name)); + + node.appendChild(clone); + } +} + export class Order extends TemplatedNode { - addToNode(node, orderFunctionality) { + addToNode(node) { // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template var clone = this.template.content.cloneNode(true); @@ -40,7 +87,9 @@ export class Order extends TemplatedNode { } clone.querySelector(".price").textContent = priceString; - clone.querySelector("button").addEventListener("click", orderFunctionality.cancel); + var button = clone.querySelector("button"); + + if (button) button.addEventListener("click", cancelOrder); node.appendChild(clone); } @@ -49,17 +98,17 @@ export class Order extends TemplatedNode { export class ParkArticle extends TemplatedNode { - addToNode(node, parkArticleFunctionality) { - const clone = this.cloneTemplateAndFillInHTML(parkArticleFunctionality); + addToNode(node) { + const clone = this.cloneTemplateAndFillInHTML(); node.appendChild(clone); } - toHTML(parkArticleFunctionality) { - return this.cloneTemplateAndFillInHTML(parkArticleFunctionality); + toHTML() { + return this.cloneTemplateAndFillInHTML(); } - cloneTemplateAndFillInHTML(parkArticleFunctionality) { + cloneTemplateAndFillInHTML() { // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template var clone = this.template.content.cloneNode(true); @@ -94,12 +143,12 @@ export class ParkArticle extends TemplatedNode { } var button = clone.querySelector(".orderbutton"); - parkArticleFunctionality.disableButton(this.name, button)(null); + disableButton(this.name, button)(null); var inputElements = clone.querySelectorAll("input"); for (let i = 0; i < inputElements.length; i++) { - inputElements[i].addEventListener("input", parkArticleFunctionality.displayTotal); - inputElements[i].addEventListener("input", parkArticleFunctionality.disableButton(this.name, button)); + inputElements[i].addEventListener("input", displayTotal); + inputElements[i].addEventListener("input", disableButton(this.name, button)); } return clone; } diff --git a/client/src/utils.js b/client/src/utils.js index 5a0423d..b58da6c 100644 --- a/client/src/utils.js +++ b/client/src/utils.js @@ -1,3 +1,52 @@ +// client/src/function.js +export async function fetchOrders() { + + try { + + const response = await fetch("api/myorders"); + + if (!response.ok) { + const message = `An error has occured: ${response.status}`; + throw new Error(message); + } + + const orders = await response.json(); + return orders; + + + } catch(error) { + console.log("something went wrong when fetching orders: ", error); + } + +} + +export async function fetchAttractions() { + + try { + + const response = await fetch("api/attractions"); + + if (!response.ok) { + const message = `An error has occured: ${response.status}`; + throw new Error(message); + } + + const attractions = await response.json(); + return attractions; + + + } catch(error) { + console.log("something went wrong when fetching attractions: ", error); + } + +} + +export function readOrderArrayFromLocalStorage() { + var orders = JSON.parse(localStorage.getItem("shoppingBasketArray")); + return orders; +} + + export function displayNumberOfItemsInShoppingBasketWithBadge() { var shoppingBasketArray = JSON.parse(localStorage.getItem("shoppingBasketArray")); if (shoppingBasketArray === null) { @@ -20,14 +69,6 @@ export function dutchCurrencyFormatWithSign(number) { } -export function findParentWithTag(tagName) { - if (this.tagName === tagName.toUpperCase()) { - return this; - } else { - return findParentWithTag.bind(this.parentNode)(tagName); - } -} - export function findParent(func) { return function startingFromThisNode(node) { if (func(node)) { @@ -38,22 +79,12 @@ export function findParent(func) { } } +export function kill(node) { + node.parentNode.removeChild(node); +} -export function childKillerUsingTags(parent) { - - return function oneOfMyChildren(child) { - - return function killChildrenWithTag(tag) { - if (child === null) { - return - } else if (child.tagName === tag.toUpperCase()) { - var next = child.nextSibling; - parent.removeChild(child); - return oneOfMyChildren(next)(tag); - } else { - return oneOfMyChildren(child.nextSibling)(tag); - } - } - +export function killChildren(func) { + return function startingFromThisChildNode(node) { } } + |
