From 32e536f4d4018dda71679cc8e0221ce03029d46a Mon Sep 17 00:00:00 2001 From: Mike Vink Date: Mon, 14 Jun 2021 01:12:21 +0200 Subject: working --- client/admin.html | 1 + client/index.html | 4 +- client/map.html | 1 + client/orders.html | 1 + client/shoppingbasket.html | 1 + client/src/index.js | 88 +++++++++++++++++++++++++++++++++++++++++ client/src/utils.js | 70 ++++++++++++++++++++++++++++++++- main.js | 97 ++++++++++++++++++++++++++++++---------------- 8 files changed, 228 insertions(+), 35 deletions(-) diff --git a/client/admin.html b/client/admin.html index eb8f9a5..5a926ef 100644 --- a/client/admin.html +++ b/client/admin.html @@ -7,6 +7,7 @@ Sogyo Adventure + diff --git a/client/index.html b/client/index.html index 62021bf..73d4027 100644 --- a/client/index.html +++ b/client/index.html @@ -47,13 +47,15 @@
-
diff --git a/client/map.html b/client/map.html index 58ac95c..ca7e8e5 100644 --- a/client/map.html +++ b/client/map.html @@ -6,6 +6,7 @@ Sogyo Adventure + diff --git a/client/orders.html b/client/orders.html index 31c6686..3c5346d 100644 --- a/client/orders.html +++ b/client/orders.html @@ -7,6 +7,7 @@ Sogyo Adventure + diff --git a/client/shoppingbasket.html b/client/shoppingbasket.html index 06143b3..87e4dba 100644 --- a/client/shoppingbasket.html +++ b/client/shoppingbasket.html @@ -7,6 +7,7 @@ Sogyo Adventure + diff --git a/client/src/index.js b/client/src/index.js index 5743b5e..b904e08 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -7,6 +7,9 @@ import { dutchCurrencyFormatWithSign, findParent, killChildren, + getUserGeoLocation, + distanceToUser, + bubbleSort, } from "./utils.js"; @@ -14,6 +17,8 @@ import { // // loop ineens tegen de volgende error aan: +const userLocation = await getUserGeoLocation(); + function displayArticles(articles) { console.log("displaying attraction articles"); @@ -48,10 +53,93 @@ function setStickyNavBar() { } +function sortAttractionsBasedOn(sorter) { + return async function whenButtonIsClicked(event) { + console.log("sorting attractions") + const main = findParent(parent => {return parent.tagName === "MAIN"})(event.target); + const articlesParent = main.querySelector("#center-articles"); + + const clickedButton = findParent(parent => {return parent.tagName === "BUTTON"})(event.target); + const sortMenu = findParent(parent => {return parent.id === "sortmenu"})(clickedButton); + const allSortButtons = sortMenu.querySelectorAll("button"); + + console.log(allSortButtons) + for (let i = 0; i < allSortButtons.length; i++) { + if (!(allSortButtons[i].id === clickedButton.id)) allSortButtons[i].querySelector(".front").textContent = "sort"; + } + + + const frontOfButton = clickedButton.querySelector(".front"); + const buttonText = frontOfButton.textContent.trim(); + console.log(buttonText.trim()) + + var compare; + if (buttonText === "ascending") { + compare = (previousElementKey, elementKey) => {return previousElementKey < elementKey} + frontOfButton.textContent = "descending"; + } else if (buttonText === "descending") { + compare = (previousElementKey, elementKey) => {return previousElementKey > elementKey} + frontOfButton.textContent = "ascending"; + } else { + compare = (previousElementKey, elementKey) => {return previousElementKey > elementKey} + frontOfButton.textContent = "ascending"; + } + + killChildren(child => {return child.tagName === "ARTICLE"})(articlesParent); + + fetchAttractions() + .then(sorter(compare)) + .then(displayArticles) + } +} + +function priceSorter(compare) { + + const sortKey = attraction => { + const adultPrice = attraction.adultPrice; + const kidsPrice = attraction.kidsPrice; + return ((adultPrice + kidsPrice) / 2); + }; + + return function sorted(attractions) { + console.log("sorting on mean price: ") + console.log(attractions) + return bubbleSort(attractions, + sortKey, + compare + ) + } +} + +function locationSorter(compare) { + + const sortKey = attraction => { + return distanceToUser(userLocation)(attraction.location.lat, attraction.location.lon); + }; + + + return function sorted(attractions) { + console.log("sorting on distance to user: ") + console.log(attractions) + return bubbleSort(attractions, + sortKey, + compare + ) + } +} + + displayNumberOfItemsInShoppingBasketWithBadge(); setStickyNavBar(); const sortmenu = document.querySelector("#sortmenu"); +const priceSortButton = sortmenu.querySelector("#sortprice"); +const locationSortButton = sortmenu.querySelector("#sortlocation"); + +console.log(priceSortButton) +priceSortButton.addEventListener("click", sortAttractionsBasedOn(priceSorter)); +locationSortButton.addEventListener("click", sortAttractionsBasedOn(locationSorter)); + console.log(sortmenu) diff --git a/client/src/utils.js b/client/src/utils.js index b58da6c..b088f73 100644 --- a/client/src/utils.js +++ b/client/src/utils.js @@ -84,7 +84,75 @@ export function kill(node) { } export function killChildren(func) { - return function startingFromThisChildNode(node) { + return function givenTheParent(parent) { + console.log("removing children of ") + console.log(parent) + function removeParentsChildren(child) { + if (child === null) return; + else if (func(child)) { + const next = child.nextSibling; + parent.removeChild(child); + return removeParentsChildren(next); + } else { + return removeParentsChildren(child.nextSibling); + } + } + removeParentsChildren(parent.firstChild) + } +} + +export function getUserGeoLocation() { + if (navigator.geolocation) console.log("browser supports geolocation") + + const getCoords = async () => { + const pos = await new Promise((resolve, reject) => { + navigator.geolocation.getCurrentPosition(resolve, reject); + }); + + return { + long: pos.coords.longitude, + lat: pos.coords.latitude, + }; + }; + + return getCoords(); +} + +export function distanceToUser(userLocation) { + return function calculateDistanceBasedOnLatLon(lat, lon) { + const R = 6371e3; // metres + const phi1 = userLocation.lat * Math.PI/180; // φ, λ in radians + const phi2 = lat * Math.PI/180; + const diffPhi = (lat-userLocation.lat) * Math.PI/180; + const diffLambda = (lon-userLocation.long) * Math.PI/180; + + const a = Math.sin(diffPhi/2) * Math.sin(diffPhi/2) + + Math.cos(phi1) * Math.cos(phi2) * + Math.sin(diffLambda/2) * Math.sin(diffLambda/2); + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + + const d = R * c; // in metres + return d; } } +export function bubbleSort(array, key, compare) { + const sorted = [...array]; + console.log("original: " + array); + console.log("copy: " + sorted); + + var tmp; + for (let i = 0; i < array.length; i++) { + for (let j = 1; j < array.length - i; j++) { + + if (compare(key(sorted[j - 1]), key(sorted[j]))) { + tmp = sorted[j]; + sorted[j] = sorted[j-1]; + sorted[j - 1] = tmp; + } + + + } + } + return sorted; +} diff --git a/main.js b/main.js index 2827b45..2459b74 100644 --- a/main.js +++ b/main.js @@ -54,38 +54,64 @@ app.post("/api/placeorder", async function (request, response) { var orders = request.body; for (let i = 0; i < orders.length; i++) { - orders[i] = dbUtils.giveUnique_idField(orders[i]); - const order = orders[i]; await dbUtils.connectToDatabaseAndDo( async (db) => { const attractions = db.collection("attractions"); const attraction = await attractions.findOne({name: order.name}); - const currentOrders = attraction.orders; - - console.log("available after order: " + (attraction.available - order.numberOfKids - order.numberOfAdults)) - - if (!currentOrders) { - attractions.updateOne( - {name: order.name}, - { - $set: {orders: [order._id], available: (attraction.available - order.numberOfKids - order.numberOfAdults)} - } - ) - } else { - attractions.updateOne( - {name: order.name}, - { - $set: {orders: currentOrders.push(order._id), available: (attraction.available - order.numberOfKids - order.numberOfAdults)} - } - ) + + // const availableAfterOrder = -1; + const availableAfterOrder = (attraction.available - order.numberOfKids - order.numberOfAdults); + if (availableAfterOrder < 0) { + response.sendStatus(403); + return; } + } ); } - await dbUtils.connectToDatabaseAndDo(db => {return db.collection("orders").insertMany(orders)}); - response.sendStatus(200); + if (response.statusCode === 200) { + console.log("---> valid order status so far is " + response.statusCode + ", adding to database"); + for (let i = 0; i < orders.length; i++) { + orders[i] = dbUtils.giveUnique_idField(orders[i]); + + const order = orders[i]; + await dbUtils.connectToDatabaseAndDo( + async (db) => { + const attractions = db.collection("attractions"); + const attraction = await attractions.findOne({name: order.name}); + const currentOrders = attraction.orders; + + const availableAfterOrder = (attraction.available - order.numberOfKids - order.numberOfAdults); + console.log("available after order: " + availableAfterOrder) + + if (!currentOrders) { + attractions.updateOne( + {name: order.name}, + { + $set: {orders: [order._id], available: availableAfterOrder} + } + ) + } else { + attractions.updateOne( + {name: order.name}, + { + $set: {orders: currentOrders.push(order._id), available: availableAfterOrder} + } + ) + } + } + ); + } + + + await dbUtils.connectToDatabaseAndDo(db => {return db.collection("orders").insertMany(orders)}); + response.sendStatus(200); + } else { + console.log("---> invalid order status so far is " + response.statusCode) + } + }); app.get("/api/myorders", async function (request, response) { @@ -107,18 +133,23 @@ app.post("/api/admin/edit", function (request, response) { const updateObject = {}; updateObject[field] = value - dbUtils.connectToDatabaseAndDo( - db => { - const attractions = db.collection("attractions"); - attractions.updateOne( - {name: name}, - { - $set: updateObject - } - ) + if (value >= 0) { + dbUtils.connectToDatabaseAndDo( + db => { + const attractions = db.collection("attractions"); + attractions.updateOne( + {name: name}, + { + $set: updateObject + } + ) - } - ) + } + ) + } else { + response.sendStatus(403); + return; + } response.sendStatus(200); }); -- cgit v1.2.3