diff options
| -rw-r--r-- | client/index.html | 12 | ||||
| -rw-r--r-- | client/map.html | 41 | ||||
| -rw-r--r-- | client/shoppingbasket.html | 10 | ||||
| -rw-r--r-- | client/src/index.js | 10 | ||||
| -rw-r--r-- | client/src/map.js | 41 | ||||
| -rw-r--r-- | client/src/templateImplementations.js | 12 | ||||
| -rw-r--r-- | client/src/utils.js | 11 | ||||
| -rw-r--r-- | client/style/main.css | 207 | ||||
| -rw-r--r-- | client/style/map.css | 5 | ||||
| -rw-r--r-- | client/style/shoppingbasket.css | 4 | ||||
| -rw-r--r-- | main.js | 11 | ||||
| -rw-r--r-- | package.json | 9 |
12 files changed, 317 insertions, 56 deletions
diff --git a/client/index.html b/client/index.html index e918f39..af3f5dd 100644 --- a/client/index.html +++ b/client/index.html @@ -11,10 +11,6 @@ </head> <body> - - <div id="testingdivs"> - </div> - <header id="logo-header"> <img src="img/logo_sogyo_rgb_199x200-1.jpg"> </header> @@ -64,8 +60,12 @@ Buy <span class="adults">2</span> adult tickets & <span class="child">2</span> kid tickets for a <span class="percentage">15</span>% discount! </div> </div> - <label>Adults: </label><input placeholder="adults" type="number" class="numberofadults" /> - <label>Kids: </label><input placeholder="kids" type="number" class="numberofkids" /> + <div class="adultinput"> + <label>Adults: </label><input placeholder="adults" type="number" class="numberofadults" /> + </div> + <div class="kidsinput"> + <label>Kids: </label><input placeholder="kids" type="number" class="numberofkids" /> + </div> <div class="total"><span class="sign">€</span><span class="price">0,-</span></div> <button class="orderbutton"> <span class="front"> diff --git a/client/map.html b/client/map.html index 4bcf373..58ac95c 100644 --- a/client/map.html +++ b/client/map.html @@ -9,6 +9,10 @@ <link rel="stylesheet" href="style/main.css"> <link rel="stylesheet" href="style/map.css"> + + <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" + integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" + crossorigin=""/> </head> <body> @@ -51,6 +55,41 @@ </main> - <script src="src/index.js"></script> + <template id="parkpopup"> + <article> + <div class="parkname"></div> + <div class="parkdescription"></div> + <div class="order"> + <div class="prices"> + <div class="adultprice">Adults: <span class="sign">€</span><span class="price">32,-</span></div> + <div class="kidsprice">Kids: <span class="sign">€</span><span class="price">32,-</span></div> + <div class="discountrequirement"> + <em>Family ticket:</em> + Buy <span class="adults">2</span> adult tickets & <span class="child">2</span> kid tickets for a <span class="percentage">15</span>% discount! + </div> + </div> + <div class="adultinput"> + <label>Adults: </label><input placeholder="adults" type="number" class="numberofadults" /> + </div> + <div class="kidsinput"> + <label>Kids: </label><input placeholder="kids" type="number" class="numberofkids" /> + </div> + <div class="total"><span class="sign">€</span><span class="price">0,-</span></div> + <button class="orderbutton"> + <span class="front"> + Add to shopping basket + </span> + </button> + </div> + </article> + </template> + + + + <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" + integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" + crossorigin=""></script> + <script type="text/javascript" src="https://stamen-maps.a.ssl.fastly.net/js/tile.stamen.js?v1.3.0"></script> + <script type = "module" src="src/map.js"></script> </body> </html> diff --git a/client/shoppingbasket.html b/client/shoppingbasket.html index 9bf9a77..ae7ebb3 100644 --- a/client/shoppingbasket.html +++ b/client/shoppingbasket.html @@ -40,12 +40,12 @@ </a> </nav> + <button id="finalizepaymentbutton" onclick="requestPlaceOrder()" class="orderbutton"> + <span class="front"> + Pay now + </span> + </button> <main> - <button id="finalizepaymentbutton" onclick="requestPlaceOrder()" class="orderbutton"> - <span class="front"> - Pay now - </span> - </button> </main> <template id="ticket"> diff --git a/client/src/index.js b/client/src/index.js index f9ee48d..0b8e676 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -1,5 +1,10 @@ import { ParkArticle } from "./templateImplementations.js"; -import { displayNumberOfItemsInShoppingBasketWithBadge, dutchCurrencyFormat, dutchCurrencyFormatWithSign } from "./utils.js"; +import { + displayNumberOfItemsInShoppingBasketWithBadge, + dutchCurrencyFormat, + dutchCurrencyFormatWithSign, + findParent +} from "./utils.js"; import { fetchAttractions } from "./functions.js" @@ -216,7 +221,8 @@ function calulateTotal(numberOfKids, numberOfAdults, serverSideAttraction) { function displayTotal(event) { console.log("displaying a total price based on client side info"); - var order = event.target.parentNode; + 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; diff --git a/client/src/map.js b/client/src/map.js new file mode 100644 index 0000000..10f2d66 --- /dev/null +++ b/client/src/map.js @@ -0,0 +1,41 @@ +import { fetchAttractions } from "./functions.js" +import { ParkArticle } from "./templateImplementations.js" + +// replace "toner" here with "terrain" or "watercolor" +var layer = new L.StamenTileLayer("watercolor"); +var map = new L.Map("discoverablemap", { + center: new L.LatLng(52.1026406, 5.175044799999999), + zoom: 10 +}); +map.addLayer(layer); + +function addMarkersForAttractions(map) { + return function addMarkers(attractions) { + for (let i = 0; i < attractions.length; i++) { + const attraction = attractions[i]; + const location = attraction.location; + + 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); + + + marker.bindPopup( + articleHTML + ) + + } + } +} + + + fetchAttractions() + .then(addMarkersForAttractions(map)); diff --git a/client/src/templateImplementations.js b/client/src/templateImplementations.js index 9db0271..5767a84 100644 --- a/client/src/templateImplementations.js +++ b/client/src/templateImplementations.js @@ -50,6 +50,16 @@ export class Order extends TemplatedNode { export class ParkArticle extends TemplatedNode { addToNode(node, parkArticleFunctionality) { + const clone = this.cloneTemplateAndFillInHTML(parkArticleFunctionality); + node.appendChild(clone); + } + + toHTML(parkArticleFunctionality) { + return this.cloneTemplateAndFillInHTML(parkArticleFunctionality); + + } + + cloneTemplateAndFillInHTML(parkArticleFunctionality) { // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template var clone = this.template.content.cloneNode(true); @@ -91,6 +101,6 @@ export class ParkArticle extends TemplatedNode { inputElements[i].addEventListener("input", parkArticleFunctionality.displayTotal); inputElements[i].addEventListener("input", parkArticleFunctionality.disableButton(this.name, button)); } - node.appendChild(clone); + return clone; } } diff --git a/client/src/utils.js b/client/src/utils.js index 03416f0..5a0423d 100644 --- a/client/src/utils.js +++ b/client/src/utils.js @@ -28,6 +28,17 @@ export function findParentWithTag(tagName) { } } +export function findParent(func) { + return function startingFromThisNode(node) { + if (func(node)) { + return node; + } else { + return startingFromThisNode(node.parentNode); + } + } +} + + export function childKillerUsingTags(parent) { return function oneOfMyChildren(child) { diff --git a/client/style/main.css b/client/style/main.css index c828d62..0159545 100644 --- a/client/style/main.css +++ b/client/style/main.css @@ -9,46 +9,75 @@ body { } /* Describes the styling of the one and only element with id="mainheader", note the # in front of mainheader */ +@media only screen and (max-width: 480px) { #mainheader { background-color: var(--primary-color); - font-size: 3rem; + font-size: 1.5rem; color: white; + height: 45px; } -#sticky-header { - display: block; - z-index: +1; +#center-articles { + position: absolute; + width: 100%; } -#center-articles { - position: relative; +/* Describes the styling of all <article> elements */ +article { + border-radius: 25px; + border: 1px solid var(--primary-color); + color: var(--light-text-color); + width: 96%; + margin: 2% 0 0 2%; +} +#logo-header { + display: none; } -/* The sticky class is added to the header with JS when it reaches its scroll position */ -.sticky { - position: fixed; - top: 0; - width: 100% +#logo-header img { + margin-left: 30px; } -/* Add some top padding to the page content to prevent sudden quick movement (as the header gets a new position at the top of the page (position:fixed and top:0) */ -.sticky + .content { - padding-top: 102px; +nav { + line-height: 2rem; + background-color: darkgrey; + text-align: center; + min-height: 32px; + display: inline-flex; + width: 100%; + justify-content: center; } -a:link, a:visited { - color: white; } -a:hover { - color: cyan; + +@media only screen and (min-width: 480px) { +#mainheader { + background-color: var(--primary-color); + font-size: 2rem; + color: white; + height: 60px; +} +#center-articles { + position: absolute; + display: inline-block; + transform: translate(0, 0); + width: 100%; } -a:link:active, a:visited:active { - color: green; +/* Describes the styling of all <article> elements */ +article { + border-radius: 25px; + border: 1px solid var(--primary-color); + color: var(--light-text-color); + margin: 10px 0 3% 3% ; + display: inline-block; + width: 45%; + position: relative; } #logo-header { + height: 200px; display: flex; justify-content: flex-start; align-items: center; @@ -58,40 +87,137 @@ a:link:active, a:visited:active { margin-left: 30px; } -main { - padding: 25px; +nav +{ + line-height: 2rem; + background-color: darkgrey; + text-align: center; + height: 32px; + display: inline-flex; + width: 100%; + justify-content: center; +} + } +@media only screen and (min-width: 780px) { +#mainheader { + background-color: var(--primary-color); + height: 80px; + font-size: 3rem; + color: white; +} +#center-articles { + position: absolute; + display: inline-block; + width: 100%; +} +/* Describes the styling of all <article> elements */ +article { + border-radius: 25px; + border: 1px solid var(--primary-color); + color: var(--light-text-color); + margin: 10px 0 0 2.3%; + display: inline-block; + width: 30%; + position: relative; +} + +#logo-header { + height: 200px; + display: flex; + justify-content: flex-start; + align-items: center; +} + +#logo-header img { + margin-left: 30px; +} nav { - height: 2rem; line-height: 2rem; background-color: darkgrey; text-align: center; + height: 32px; + display: inline-flex; + width: 100%; + justify-content: center; + +} + + +} + +#sticky-header { + display: block; + z-index: +1; +} + + +/* The sticky class is added to the header with JS when it reaches its scroll position */ +.sticky { + position: fixed; + top: 0; + width: 100% +} + +/* Add some top padding to the page content to prevent sudden quick movement (as the header gets a new position at the top of the page (position:fixed and top:0) */ +.sticky + .content { + padding-top: 102px; +} +a:link, a:visited { + color: white; } +a:hover { + color: brown; +} + +a:link:active, a:visited:active { + color: green; +} + +main { + position: relative; +} + + /* Describes the styling of all elements with class="parkname", note the . in front of parkname */ .parkname { + border-radius: 23px 23px 0 0; background-color: var(--primary-color); color: white; font-size: 2rem; font-weight: bold; text-transform: uppercase; + display: flex; + justify-content: center; + align-items: center; + height: 80px; } -/* Describes the styling of all <article> elements */ -article { - border: 1px solid var(--primary-color); - color: var(--light-text-color); - margin: 5px; - display: block; - top: 50%; - left: 50%; +/* Describes the styling of all elements with class="parkname", note the . in front of parkname */ +.parkdescription { + font-size: 1rem; + text-align: center; + height: 30px; + margin: 15px 15px 0 15px; } .order { padding-top: 25px; + text-align:center; +} + +.prices { + margin-bottom: 15px; + margin-left: 15px; + margin-right: 15px; +} + +.total { + margin: 10px; } .badge { @@ -103,6 +229,13 @@ article { border-radius: 25px; } +.adultinput { + width:100%; +} + +.kidsinput { + width:100%; +} .orderbutton { background: hsl(170deg 0% 64%); @@ -115,10 +248,14 @@ article { } .front { + font-size: 1rem; + padding: 6px 15px; + + padding: 10px 9px; + font-size: 1.2rem; + display: block; - padding: 12px 42px; border-radius: 12px; - font-size: 1.25rem; background: var(--primary-color); color: white; transform: translateY(-4px); @@ -129,12 +266,12 @@ article { .disabled { display: block; - padding: 12px 42px; border-radius: 12px; - font-size: 1.25rem; background: grey; color: white; transform: translateY(-2px); + padding: 10px 9px; + font-size: 1.2rem; } .orderbutton:hover .front { diff --git a/client/style/map.css b/client/style/map.css index 39d3a8a..e64a4cd 100644 --- a/client/style/map.css +++ b/client/style/map.css @@ -1,4 +1,5 @@ #discoverablemap { + position: absolute; height: 100%; width: 100%; background-color: brown; @@ -11,6 +12,6 @@ body { } main { - height: 90%; - width: 95%; + position: relative; + height:100%; } diff --git a/client/style/shoppingbasket.css b/client/style/shoppingbasket.css index 871a380..bd75c42 100644 --- a/client/style/shoppingbasket.css +++ b/client/style/shoppingbasket.css @@ -1,3 +1,7 @@ article { height: auto; } + +#finalizepaymentbutton { + display: block; +} @@ -58,22 +58,25 @@ app.post("/api/placeorder", async function (request, response) { const order = orders[i]; await dbUtils.connectToDatabaseAndDo( - db => { + async (db) => { const attractions = db.collection("attractions"); - const attraction = attractions.findOne({name: order.name}); + 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]} + $set: {orders: [order._id], available: (attraction.available - order.numberOfKids - order.numberOfAdults)} } ) } else { attractions.updateOne( {name: order.name}, { - $set: {orders: currentOrders.push(order._id)} + $set: {orders: currentOrders.push(order._id), available: (attraction.available - order.numberOfKids - order.numberOfAdults)} } ) } diff --git a/package.json b/package.json index 8bf39c5..a2e0af7 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,17 @@ "version": "1.0.0", "description": "Het project voor de Ticketshop opdracht", "main": "main.js", + "scripts": { + "dev": "nodemon main.js" + }, "dependencies": { + "ejs": "^3.1.6", "express": "^4.16.4", + "leaflet": "^1.7.1", "mongodb": "^3.6.9" + }, + "devDependencies": { + "dotenv": "^10.0.0", + "nodemon": "^2.0.7" } } |
