summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbvdoord <bvdoord@sogyo.nl>2019-02-11 08:13:57 +0100
committerbvdoord <bvdoord@sogyo.nl>2019-02-11 08:13:57 +0100
commitc8a75a5fec45cf3cc5d0957b062f77ebaf4dd5b8 (patch)
tree568c58dad5b45793082e6ec4e9e0c45652797b94
Initial commit
-rw-r--r--client/admin.html49
-rw-r--r--client/img/favicon.icobin0 -> 6261 bytes
-rw-r--r--client/img/logo_sogyo_rgb_199x200-1.jpgbin0 -> 5184 bytes
-rw-r--r--client/index.html196
-rw-r--r--client/map.html54
-rw-r--r--client/orderplaced.html50
-rw-r--r--client/orders.html50
-rw-r--r--client/shoppingbasket.html57
-rw-r--r--client/src/admin.js0
-rw-r--r--client/src/index.js0
-rw-r--r--client/src/myorders.js0
-rw-r--r--client/src/shoppingbasket.js0
-rw-r--r--client/style/main.css66
-rw-r--r--client/style/map.css15
-rw-r--r--client/style/shoppingbasket.css3
-rw-r--r--main.js119
-rw-r--r--package.json9
-rw-r--r--readme.md114
18 files changed, 782 insertions, 0 deletions
diff --git a/client/admin.html b/client/admin.html
new file mode 100644
index 0000000..291f79f
--- /dev/null
+++ b/client/admin.html
@@ -0,0 +1,49 @@
+<!doctype html>
+
+<html lang="nl">
+ <head>
+ <meta charset="utf-8">
+
+ <title>Sogyo Adventure</title>
+ <meta name="description" content="The ticket shop for Sogyo employees">
+
+ <link rel="stylesheet" href="style/main.css">
+ </head>
+
+ <body>
+
+ <header id="logo-header">
+ <img src="img/logo_sogyo_rgb_199x200-1.jpg">
+ </header>
+ <header id="mainheader">
+ Sogyo Adventure
+ </header>
+ <nav>
+ <a id="home" href="index.html">
+ Home
+ </a>
+ |
+ <a id="map" href="map.html">
+ Discover
+ </a>
+ |
+ <a id="shoppingbasket" href="shoppingbasket.html">
+ Shopping basket <div class="badge">0</div>
+ </a>
+ |
+ <a id="myorders" href="orders.html">
+ My orders
+ </a>
+ |
+ <a id="admin" href="admin.html">
+ Admin
+ </a>
+ </nav>
+
+ <main>
+
+
+
+ </main>
+ </body>
+</html> \ No newline at end of file
diff --git a/client/img/favicon.ico b/client/img/favicon.ico
new file mode 100644
index 0000000..a4fe44e
--- /dev/null
+++ b/client/img/favicon.ico
Binary files differ
diff --git a/client/img/logo_sogyo_rgb_199x200-1.jpg b/client/img/logo_sogyo_rgb_199x200-1.jpg
new file mode 100644
index 0000000..9104922
--- /dev/null
+++ b/client/img/logo_sogyo_rgb_199x200-1.jpg
Binary files differ
diff --git a/client/index.html b/client/index.html
new file mode 100644
index 0000000..41f966b
--- /dev/null
+++ b/client/index.html
@@ -0,0 +1,196 @@
+<!doctype html>
+
+<html lang="nl">
+ <head>
+ <meta charset="utf-8">
+
+ <title>Sogyo Adventure</title>
+ <meta name="description" content="The ticket shop for Sogyo employees">
+
+ <link rel="stylesheet" href="style/main.css">
+ </head>
+
+ <body>
+
+ <header id="logo-header">
+ <img src="img/logo_sogyo_rgb_199x200-1.jpg">
+ </header>
+ <header id="mainheader">
+ Sogyo Adventure
+ </header>
+ <nav>
+ <a id="home" href="index.html">
+ Home
+ </a>
+ |
+ <a id="map" href="map.html">
+ Discover
+ </a>
+ |
+ <a id="shoppingbasket" href="shoppingbasket.html">
+ Shopping basket <div class="badge">0</div>
+ </a>
+ |
+ <a id="myorders" href="orders.html">
+ My orders
+ </a>
+ |
+ <a id="admin" href="admin.html">
+ Admin
+ </a>
+ </nav>
+
+ <main>
+
+ <article>
+ <div class="parkname">De Efteling</div>
+ <div class="parkdescription">
+ The Netherlands's most famous theme park. Located in Kaatsheuvel.
+ </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>
+ <label>Adults: </label><input placeholder="adults" type="number" class="numberofadults" />
+ <label>Kids: </label><input placeholder="kids" type="number" class="numberofkids" />
+ <div class="total"><span class="sign">&euro;</span><span class="price">0,-</span></div>
+ <button class="orderbutton">Add to shopping basket</button>
+ </div>
+ </article>
+
+ <article>
+ <div class="parkname">Madurodam</div>
+ <div class="parkdescription">
+ The Netherlands smallest theme park.
+ </div>
+ <div class="order">
+ <div class="prices">
+ <div class="adultprice">Adults: <span class="sign">&euro;</span><span class="price">25,-</span></div>
+ <div class="kidsprice">Kids: <span class="sign">&euro;</span><span class="price">20,-</span></div>
+ <div class="discountrequirement">
+ <em>Family ticket:</em>
+ Buy <span class="adults">1</span> adult tickets & <span class="child">2</span> kid tickets for a <span class="percentage">25</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="total"><span class="sign">&euro;</span><span class="price">0,-</span></div>
+ <button class="orderbutton">Add to shopping basket</button>
+ </div>
+ </article>
+
+ <article>
+ <div class="parkname">Toverland</div>
+ <div class="parkdescription">
+ Experience magic and wonder.
+ </div>
+ <div class="order">
+ <div class="prices">
+ <div class="adultprice">Adults: <span class="sign">&euro;</span><span class="price">30,-</span></div>
+ <div class="kidsprice">Kids: <span class="sign">&euro;</span><span class="price">30,-</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">33</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="total"><span class="sign">&euro;</span><span class="price">0,-</span></div>
+ <button class="orderbutton">Add to shopping basket</button>
+ </div>
+ </article>
+
+ <article>
+ <div class="parkname">Walibi Holland</div>
+ <div class="parkdescription">
+ Need an Adrenaline Rush?
+ </div>
+ <div class="order">
+ <div class="prices">
+ <div class="adultprice">Adults: <span class="sign">&euro;</span><span class="price">37,-</span></div>
+ <div class="kidsprice">Kids: <span class="sign">&euro;</span><span class="price">37,-</span></div>
+ <div class="discountrequirement">
+ <em>Family ticket:</em>
+ Buy <span class="adults">4</span> adult tickets & <span class="child">0</span> kid tickets for a <span class="percentage">10</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="total"><span class="sign">&euro;</span><span class="price">0,-</span></div>
+ <button class="orderbutton">Add to shopping basket</button>
+ </div>
+ </article>
+
+ <article>
+ <div class="parkname">Duinrell</div>
+ <div class="parkdescription">
+ From the Kikkerbaan to the Tikibad.
+ </div>
+ <div class="order">
+ <div class="prices">
+ <div class="adultprice">Adults: <span class="sign">&euro;</span><span class="price">22,-</span></div>
+ <div class="kidsprice">Kids: <span class="sign">&euro;</span><span class="price">19,-</span></div>
+ <div class="discountrequirement">
+ <em>Family ticket:</em>
+ Buy <span class="adults">1</span> adult tickets & <span class="child">3</span> kid tickets for a <span class="percentage">20</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="total"><span class="sign">&euro;</span><span class="price">0,-</span></div>
+ <button class="orderbutton">Add to shopping basket</button>
+ </div>
+ </article>
+
+ <article>
+ <div class="parkname">Slagharen</div>
+ <div class="parkdescription">
+ Fun for the whole family in a true western style.
+ </div>
+ <div class="order">
+ <div class="prices">
+ <div class="adultprice">Adults: <span class="sign">&euro;</span><span class="price">28,-</span></div>
+ <div class="kidsprice">Kids: <span class="sign">&euro;</span><span class="price">20,-</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">50</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="total"><span class="sign">&euro;</span><span class="price">0,-</span></div>
+ <button class="orderbutton">Add to shopping basket</button>
+ </div>
+ </article>
+
+ <article>
+ <div class="parkname">Drievliet</div>
+ <div class="parkdescription">
+ Come and experience our wonderful attractions.
+ </div>
+ <div class="order">
+ <div class="prices">
+ <div class="adultprice">Adults: <span class="sign">&euro;</span><span class="price">26,-</span></div>
+ <div class="kidsprice">Kids: <span class="sign">&euro;</span><span class="price">24,-</span></div>
+ <div class="discountrequirement">
+ <em>Family ticket:</em>
+ Buy <span class="adults">1</span> adult tickets & <span class="child">2</span> kid tickets for a <span class="percentage">25</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="total"><span class="sign">&euro;</span><span class="price">0,-</span></div>
+ <button class="orderbutton">Add to shopping basket</button>
+ </div>
+ </article>
+
+ </main>
+
+ <script src="src/index.js"></script>
+ </body>
+</html> \ No newline at end of file
diff --git a/client/map.html b/client/map.html
new file mode 100644
index 0000000..35347a8
--- /dev/null
+++ b/client/map.html
@@ -0,0 +1,54 @@
+<!doctype html>
+
+<html lang="nl">
+ <head>
+ <meta charset="utf-8">
+
+ <title>Sogyo Adventure</title>
+ <meta name="description" content="The ticket shop for Sogyo employees">
+
+ <link rel="stylesheet" href="style/main.css">
+ <link rel="stylesheet" href="style/map.css">
+ </head>
+
+ <body>
+
+ <header id="logo-header">
+ <img src="img/logo_sogyo_rgb_199x200-1.jpg">
+ </header>
+ <header id="mainheader">
+ Sogyo Adventure
+ </header>
+ <nav>
+ <a id="home" href="index.html">
+ Home
+ </a>
+ |
+ <a id="map" href="map.html">
+ Discover
+ </a>
+ |
+ <a id="shoppingbasket" href="shoppingbasket.html">
+ Shopping basket <div class="badge">0</div>
+ </a>
+ |
+ <a id="myorders" href="orders.html">
+ My orders
+ </a>
+ |
+ <a id="admin" href="admin.html">
+ Admin
+ </a>
+ </nav>
+
+ <main>
+
+ <div id="discoverablemap">
+
+ </div>
+
+ </main>
+
+ <script src="src/index.js"></script>
+ </body>
+</html> \ No newline at end of file
diff --git a/client/orderplaced.html b/client/orderplaced.html
new file mode 100644
index 0000000..e012cd7
--- /dev/null
+++ b/client/orderplaced.html
@@ -0,0 +1,50 @@
+<!doctype html>
+
+<html lang="nl">
+ <head>
+ <meta charset="utf-8">
+
+ <title>Sogyo Adventure</title>
+ <meta name="description" content="The ticket shop for Sogyo employees">
+
+ <link rel="stylesheet" href="style/main.css">
+ </head>
+
+ <body>
+
+ <header id="logo-header">
+ <img src="img/logo_sogyo_rgb_199x200-1.jpg">
+ </header>
+ <header id="mainheader">
+ Sogyo Adventure
+ </header>
+ <nav>
+ <a id="home" href="index.html">
+ Home
+ </a>
+ |
+ <a id="map" href="map.html">
+ Discover
+ </a>
+ |
+ <a id="shoppingbasket" href="shoppingbasket.html">
+ Shopping basket <div class="badge">0</div>
+ </a>
+ |
+ <a id="myorders" href="orders.html">
+ My orders
+ </a>
+ |
+ <a id="admin" href="admin.html">
+ Admin
+ </a>
+ </nav>
+
+ <main>
+
+ Your order has been placed.
+
+ </main>
+
+ </body>
+</html> \ No newline at end of file
diff --git a/client/orders.html b/client/orders.html
new file mode 100644
index 0000000..ab936be
--- /dev/null
+++ b/client/orders.html
@@ -0,0 +1,50 @@
+<!doctype html>
+
+<html lang="nl">
+ <head>
+ <meta charset="utf-8">
+
+ <title>Sogyo Adventure</title>
+ <meta name="description" content="The ticket shop for Sogyo employees">
+
+ <link rel="stylesheet" href="style/main.css">
+ </head>
+
+ <body>
+
+ <header id="logo-header">
+ <img src="img/logo_sogyo_rgb_199x200-1.jpg">
+ </header>
+ <header id="mainheader">
+ Sogyo Adventure
+ </header>
+ <nav>
+ <a id="home" href="index.html">
+ Home
+ </a>
+ |
+ <a id="map" href="map.html">
+ Discover
+ </a>
+ |
+ <a id="shoppingbasket" href="shoppingbasket.html">
+ Shopping basket <div class="badge">0</div>
+ </a>
+ |
+ <a id="myorders" href="orders.html">
+ My orders
+ </a>
+ |
+ <a id="admin" href="admin.html">
+ Admin
+ </a>
+ </nav>
+
+ <main>
+
+
+ </main>
+
+ <script src="src/myorders.js"></script>
+ </body>
+</html> \ No newline at end of file
diff --git a/client/shoppingbasket.html b/client/shoppingbasket.html
new file mode 100644
index 0000000..707e147
--- /dev/null
+++ b/client/shoppingbasket.html
@@ -0,0 +1,57 @@
+<!doctype html>
+
+<html lang="nl">
+ <head>
+ <meta charset="utf-8">
+
+ <title>Sogyo Adventure</title>
+ <meta name="description" content="The ticket shop for Sogyo employees">
+
+ <link rel="stylesheet" href="style/main.css">
+ </head>
+
+ <body>
+
+ <header id="logo-header">
+ <img src="img/logo_sogyo_rgb_199x200-1.jpg">
+ </header>
+ <header id="mainheader">
+ Sogyo Adventure
+ </header>
+ <nav>
+ <a id="home" href="index.html">
+ Home
+ </a>
+ |
+ <a id="map" href="map.html">
+ Discover
+ </a>
+ |
+ <a id="shoppingbasket" href="shoppingbasket.html">
+ Shopping basket <div class="badge">0</div>
+ </a>
+ |
+ <a id="myorders" href="orders.html">
+ My orders
+ </a>
+ |
+ <a id="admin" href="admin.html">
+ Admin
+ </a>
+ </nav>
+
+ <main>
+ <button id="finalizepaymentbutton">Pay now</button>
+ </main>
+
+ <template id="ticket">
+ <article>
+ <div>Parkname</div>
+ <div>Adults: </div>
+ <div>Kids:</div>
+ <button>Cancel order</button>
+ </article>
+ </template>
+
+ </body>
+</html> \ No newline at end of file
diff --git a/client/src/admin.js b/client/src/admin.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/client/src/admin.js
diff --git a/client/src/index.js b/client/src/index.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/client/src/index.js
diff --git a/client/src/myorders.js b/client/src/myorders.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/client/src/myorders.js
diff --git a/client/src/shoppingbasket.js b/client/src/shoppingbasket.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/client/src/shoppingbasket.js
diff --git a/client/style/main.css b/client/style/main.css
new file mode 100644
index 0000000..b7edb5b
--- /dev/null
+++ b/client/style/main.css
@@ -0,0 +1,66 @@
+body {
+ font-family: 'Lato', sans-serif;
+ padding: 0px;
+ margin: 0px;
+
+ --primary-color: #007936;
+ --accent-color: #eee;
+ --light-text-color: rgb(107, 107, 107);
+}
+
+/* Describes the styling of the one and only emenent with id="mainheader", note the # in front of mainheader */
+#mainheader {
+ background-color: var(--primary-color);
+ font-size: 3rem;
+ color: white;
+}
+
+#logo-header {
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+}
+
+#logo-header img {
+ margin-left: 30px;
+}
+
+main {
+ padding: 25px;
+}
+
+nav
+{
+ height: 2rem;
+ line-height: 2rem;
+ background-color: var(--accent-color);
+}
+
+/* Describes the styling of all elements with class="parkname", note the . in front of parkname */
+.parkname {
+ background-color: var(--primary-color);
+ color: white;
+ font-size: 2rem;
+ font-weight: bold;
+ text-transform: uppercase;
+}
+
+/* Describes the styling of all <article> elements */
+article {
+ border: 1px solid var(--primary-color);
+ color: var(--light-text-color);
+ margin: 5px;
+}
+
+.order {
+ padding-top: 25px;
+}
+
+.badge {
+ background-color: red;
+ display: none;
+ color: white;
+ font-weight: bold;
+ width: 25px;
+ border-radius: 25px;
+} \ No newline at end of file
diff --git a/client/style/map.css b/client/style/map.css
new file mode 100644
index 0000000..f8254d3
--- /dev/null
+++ b/client/style/map.css
@@ -0,0 +1,15 @@
+#discoverablemap {
+ height: 100%;
+ width: 100%;
+ background-color: brown;
+}
+
+body {
+ height: 100vh;
+ width: 100vw;
+}
+
+main {
+ height: 100%;
+ width: 100%;
+} \ No newline at end of file
diff --git a/client/style/shoppingbasket.css b/client/style/shoppingbasket.css
new file mode 100644
index 0000000..44990ad
--- /dev/null
+++ b/client/style/shoppingbasket.css
@@ -0,0 +1,3 @@
+article {
+ height: auto;
+} \ No newline at end of file
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..9cdc9df
--- /dev/null
+++ b/main.js
@@ -0,0 +1,119 @@
+const express = require('express');
+const app = express();
+/** Host alle bestanden in de client folder als static resources */
+app.use(express.static('client'));
+
+app.use(express.json());
+
+const attractions = [
+ {
+ name: "De Efteling",
+ description: "The Dutch fairy tale themed park. In high demand!",
+ adultPrice: 32,
+ kidsPrice: 32,
+ minimumNumberOfAdults: 2,
+ minimumNumberOfKids: 1,
+ discount: 15,
+ available: 1,
+ location: { lon: 5.043689, lat: 51.649718, },
+ },
+
+ {
+ name: "Madurodam",
+ description: "The Netherlands smallest theme park.",
+ adultPrice: 25,
+ kidsPrice: 20,
+ minimumNumberOfAdults: 1,
+ minimumNumberOfKids: 2,
+ discount: 25,
+ available: 5,
+ location: { lat: 52.0994779, lon: 4.299619900000039 },
+ },
+
+ {
+ name: "Toverland",
+ description: "Experience magic and wonder.",
+ adultPrice: 30,
+ kidsPrice: 30,
+ minimumNumberOfAdults: 2,
+ minimumNumberOfKids: 2,
+ discount: 33,
+ available: 3,
+ location: { lat: 52.0994779, lon: 4.299619900000039 },
+ },
+
+ {
+ name: "Walibi Holland",
+ description: "Need an Adrenaline Rush?",
+ adultPrice: 37,
+ kidsPrice: 37,
+ minimumNumberOfAdults: 4,
+ minimumNumberOfKids: 0,
+ discount: 10,
+ available: 20,
+ location: { lon: 5.766986, lat: 52.438554, },
+ },
+
+ {
+ name: "Duinrell",
+ description: "From the Kikkerbaan to the Tikibad.",
+ adultPrice: 22,
+ kidsPrice: 19,
+ minimumNumberOfAdults: 1,
+ minimumNumberOfKids: 3,
+ discount: 7,
+ available: 20,
+ location: { lon: 4.383922, lat: 52.147433, },
+ },
+
+ {
+ name: "Slagharen",
+ description: "Fun for the whole family in a true western style.",
+ adultPrice: 28,
+ kidsPrice: 20,
+ minimumNumberOfAdults: 2,
+ minimumNumberOfKids: 2,
+ discount: 50,
+ available: 2,
+ location: { lat: 52.6249522, lon: 6.563149500000009 },
+ },
+
+ {
+ name: "Drievliet",
+ description: "Come and experience our wonderful attractions.",
+ adultPrice: 26,
+ kidsPrice: 24,
+ minimumNumberOfAdults: 1,
+ minimumNumberOfKids: 2,
+ discount: 25,
+ available: 0,
+ location: { lon: 4.352633, lat: 52.052608, },
+ },
+]
+
+app.post("/api/attractions", (request, response) => {
+ console.log("Api call received for /attractions");
+ response.json(attractions)
+})
+
+app.post("/api/tickets", (request, response) => {
+ console.log("Api call received for /placeorder");
+ response.json(attractions)
+})
+
+app.post("/api/placeorder", (request, response) => {
+ console.log("Api call received for /placeorder");
+ response.sendStatus(200);
+});
+
+app.get("/api/myorders", (request, response) => {
+ console.log("Api call received for /myorders");
+ response.sendStatus(200);
+});
+
+app.get("/api/admin/edit", (request, response) => {
+ console.log("Api call received for /admin/edit");
+ response.sendStatus(200);
+});
+
+app.listen(8000, () => console.log('Example app listening on port 8000!')); \ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..0997564
--- /dev/null
+++ b/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "ticketshop",
+ "version": "1.0.0",
+ "description": "Het project voor de Ticketshop opdracht",
+ "main": "main.js",
+ "dependencies": {
+ "express": "^4.16.4"
+ }
+}
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..5508eb5
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,114 @@
+** Introduction **
+
+Sogyo Adventure is a new service for Sogyo employees to buy family tickets for amusement parks with attractive discounts. The goal of Sogyo Adventure is to make it as easy as possible to buy tickets. That means that the webshop itself should be as easy to use as possible. According to market research the user base is split almost exactly between desktop, tablet and mobile devices. This means the site should work on every device - large and small.
+
+Because Sogyo Adventure wants a single, consistent theme throughout their site, the styling defined in `main.css` should be used across all pages. The stylesheet has already been referenced on the index page (also known as a home page) and should be included in the same manner on all other pages.
+
+The target market being Sogyo employees the webshop can get away with assuming its userbase uses the latest version of Chrome, Firefox, Edge and other up to date browsers. This means that even though it's commonly advised to support as many older browsers as possible, Sogyo Adventure has the freedom to use the latest web technology. This includes (but is not limited to):
+* Flexbox
+* CSS grid
+* CSS variables
+* JavaScript modules
+* Classes
+* Interpolated string literals
+* Promises
+* Async await
+
+To get an idea of what Sogyo Adventure could look like, a prototype will first be build. Your assignment is to make that first prototype. For now you won't have to worry about security, authorisation, payment and other such things. Of course all of those are important in real life applications, but not in the prototype.
+
+Open `index.html` in your browser of choice to see what the the application looks like to users. Also open `index.html` in your favorite editor. If you make changes to the html file, you'll need to reload that page in your browser. By using the developer tools within your browser, you can usually edit the html and/or css on the go, but changes aren't saved.
+
+** Task 1: styling **
+
+There's a few requirements to the look and feel of the page:
+* The header should always be at the top of the page, even if the user scrolls down, so that the shopping basket is easily accessible
+* The links in the menu should be center aligned
+* The links in the menu should be white, whether they've been visited before or not
+* The links in the menu should be highlighted in a contrasting color when hovering over them
+* Style the 'add to shopping basket' button so it doesn't look like the default.
+* Set a favicon (the tiny icon shown in the browsers tab bar next to the tab name)
+
+The layout should be responsive, i.e. work on desktop, tablet and phone. Use CSS media queries to set three breakpoints in your layout: smaller than 480px in width, smaller than 780px in width and bigger than that.
+
+On small devices:
+* The Sogyo Adventure title bar should use 1.5rem size fonts and be 45px in height
+* The blocks with available parks should take up the whole screen width
+* The white bar with the Sogyo logo shouldn't be shown
+* The navigation bar should be 32px in height
+
+On medium devices:
+* The Sogyo Adventure title bar should use 2rem size fonts and be 60px in height
+* Two parks should be shown next to each other
+* The white bar with the Sogyo should be 200px high
+* The navigation bar should be 32px in height
+
+On large devices:
+* The Sogyo Adventure title bar should use 3rem size fonts and be 80px in height
+* At least three parks should be shown next to each other
+* The white bar with the Sogyo should be 200px high
+* The navigation bar should be 32px in height
+
+On `map.html`:
+* The div `#discoverablemap` should be 100vw (view width) wide and 100vh (view height) tall, minus the whole width of the white logo bar, the title bar and the navigation bar. This should result in the map taking up all remaining space.
+
+Otherwise get creative! Try changing colors, fonts, color gradients, borders, rounded corners, shadows, transforms, animations, etc. Don't forget that the different pages should look and feel similar, yet clearly distinct from each other. It helps if you get comfortable with the idea of CSS selectors. `main.css` uses different three different kinds of CSS selectors by default, with comments describing what they do, but CSS selectors can be composed and there's more advanced ones as well.
+
+You have about a day for this task (working on the requirements first before getting creative).
+
+** Task 2: the index page **
+
+The buttons to order tickets will all get the same functionality. A so called event listener that gets fired when the user clicks on one of those buttons. The following steps will guide you through the process of registering event listeners and implementing their behavior. Don't worry about the discounts for family tickets just yet.
+
+1. Define a function on the top level of your script that will act as the event listener for the "order" buttons. Name this function `orderButtonClicked`. Register it on every button using `document.querySelectorAll()` with a CSS selector as the first argument, iterating over all matching elements and finally calling `.addEventListener()` of type `"click"`.
+2. Add a call to `console.log()`to the body of `orderButtonClicked`. Open the developer tools in your browser. Click on the order the buttons. Is the call properly logged? If not: debug!
+3. Write a separate function named `saveOrderInShoppingBasket` that will be called from `orderButtonClicked`. This function should receive three arguments: the name of the chosen attraction, the number of adults and the number of children. Give each of the parameters a sensible name.
+4. Your event listener receives information on the event as the first argument. Add it to the parameter list, so it can be accessed from within the function. This object has a `.target` property, in our case the element the user clicked on (the order button.) Use this element reference as a starting point and walk the DOM tree using methods and properties like `parentNode`, `classList.contains()`, `nextElementSibling`, `previousElementSibling`, among others. We are interested in three nodes: the `<div>` containing the attraction name as the text content and two `<input>` elements for the user to enter numbers.
+5. From your event listener pass the following information to `saveOrderInShoppingBasket`: the name of the attraction (obtained by calling `.innerText` on the `<div>` element), the number of adults (obtained by calling `.value` on the `<input>` element and casting the result to a number) and the number of children (obtained the same way).
+6. Implement `saveOrderInShoppingBasket`. The order should be saved locally on the clients machine in a way that allows the user to close the browser without the order being lost by using `localStorage`. The `localStorage` is a key-value pair store that works with string values only. You'll need to think of a way to persist/save several orders at once.
+7. Once the order is added to the shopping basket the number of items in the shopping basket should be updated. It's displayed in the element with class `"badge"` under the `"#shoppingbasket"`.
+
+** Task 3: Shopping Basket **
+
+We'll now implement the shopping basket, in `shoppingbasket.html` and `shoppingbasket.js`.
+
+1. The shopping basket page will have to show the user the current state of their shopping basket. To do this, first read their current orders from the `localStorage`, essentially reversing the process you used to persist it. Make sure to cast any numbers in your data back from a string to a number.
+2. `shoppingbasket.html` defines a template, i.e. the HTML that should be used for each of the users ordered tickets, but the template itself is never shown to the user. Iterate over each ticket in the shopping basket and add a node to the `<main>` element for each ticket, based on the pre-defined `<template>`. Make sure to display the correct park name, number of adults and number of children on each ticket. The button to finalize the order should remain at the bottom of the page.
+3. Add an event listener to the finalize payment method. As this is only a prototype, we skip handling the actual payment. Instead simply call `api/placeorder` using the `fetch()` method. After the request has been handled clear the users shopping basket and redirect them to `orderplaced.html`. The fetch probably fails right now. That's because there's no server to fetch the resources from.
+
+** Task 4: The server **
+
+1. Install the Node.js webserver (https://nodejs.org/en/) and run the `npm install` command in the main folder of the project. This downloads the project dependencies defined in `package.json`. Finally run the project using `node main.js` and going to `localhost:8000` in your browser. You should see the working version of the Sogyo Adventure webshop so far.
+2. Open `main.js` and look at the various routes defined there. Before continuing with the other tasks, understand what each of the routes does and what they might do.
+3. Go back to `index.html` and update it so that the various attractions are no longer hard coded. Abstract the common HTML used for every attraction into a common `<template>` (like the one used in the shopping basket). When loading the page make a call to `api/attractions` and instantiate a template for each of the available attractions. Dynamically show the park name, the minimum number of adults and minimum number of kids for the family discount, as well as the discount (displayed in human readable percentages.)
+4. When a call to `api/placeorder` is made, there should be one less ticket available. Also the order should be saved into a separate array similar to the one that contains the attraction information.
+5. If there are no more tickets available for a certain attraction, the order button should be disabled.
+6. Update `index.html` in a way to display the discount in real time. When the user enters a value for the number of adults or kids or changes the number, the total price should be shown. The discount should of course be factored into the total price, if eligible.
+7. Display the total price for a ticket in the shopping basket.
+
+It helps if you're familiar with the basics of API's. Look into: HTTP requests, HTTP verbs and HTTP response codes.
+
+** Task 5: Discoverable Map **
+
+1. Install Leaflet.js (https://leafletjs.com/) and follow the instructions on https://maps.stamen.com (specifically those for Leaflet), replacing `"element_id"` in the example code with `"map"`. Stamen provides rendered map tiles based on the Open Street Map data, Leaflet is a library to work with those map tiles. As a starting point choose `(52.1026406, 5.175044799999999)` with a zoom level of 10. This should result in a large map of The Netherlands. Note: you're free to choose between the Toner, Terrain or Watercolor maps Stamen offers.
+2. After the map has done loading, fetch all attractions from `api/attractions` and display a marker for each attraction. The user should be able to click on the marker to see the attraction name and description.
+
+** Task 6: Finalizing the prototype (optional) **
+
+If you're done with tasks 1 through 5 and have some time left, look into the following additional tasks to really complete the shop:
+
+* Implement `admin.html` and a way to edit the ticket prizes, the requirements for the discount and the discount itself.
+* Allow users to order tickets from the discoverable map
+* Display a list of attractions ordered by prize. Allow the user to sort from highest to lowest or lowest to highest. In addition you may also allow sorting nearby to far away.
+* Update your client side code to TypeScript instead of JavaScript. At the very least, define parameter types and return value types. The compiler should be able to infer the types of variables based on these other two type definitions.
+
+** Task 7: Integration with a Database **
+
+This step should only be completed after the Database case has been completed.
+
+Depending on the database you chose to use in the databases case, the exact steps to hook up your Node.js backend to the database can be quite different. The steps described below are a very general overview of what needs to be done.
+
+1. Look up if a NPM package (Node Package Manager) exists for your chosen database. If so, install it by running `npm install [package-name] --save` from the command prompt in the top level directory of your project. Otherwise you might need to manually download a library and place its source code in a subdirectory of your project root.
+2. Import the newly installed dependency in `main.js`, similar to how Express is imported.
+3. Remove the hard coded arrays containing the database
+4. Create a connection to the database, most often this is done at the top level of the script (with the connection being reused every time data is retrieved from the database). Common methods are a connection string (which includes the location the database runs at, the username and password) or a config object (containing the same information).
+5. Replace reads and writes from and to the hard coded arrays you removed earlier with the queries you wrote previously. \ No newline at end of file