summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/index.html12
-rw-r--r--client/map.html41
-rw-r--r--client/shoppingbasket.html10
-rw-r--r--client/src/index.js10
-rw-r--r--client/src/map.js41
-rw-r--r--client/src/templateImplementations.js12
-rw-r--r--client/src/utils.js11
-rw-r--r--client/style/main.css207
-rw-r--r--client/style/map.css5
-rw-r--r--client/style/shoppingbasket.css4
-rw-r--r--main.js11
-rw-r--r--package.json9
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">&euro;</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">&euro;</span><span class="price">32,-</span></div>
+ <div class="kidsprice">Kids: <span class="sign">&euro;</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">&euro;</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;
+}
diff --git a/main.js b/main.js
index dc187a2..6233490 100644
--- a/main.js
+++ b/main.js
@@ -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"
}
}