aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--csci4131/hw7/api/utilities.js48
-rw-r--r--csci4131/hw7/create_accounts_table.js41
-rw-r--r--csci4131/hw7/create_contacts_table.js44
-rw-r--r--csci4131/hw7/dbio.js74
-rw-r--r--csci4131/hw7/index.js109
-rw-r--r--csci4131/hw7/insert_into_accounts_table.js45
-rw-r--r--csci4131/hw7/login.html48
-rw-r--r--csci4131/hw7/public/addContact.html106
-rw-r--r--csci4131/hw7/public/contacts.html78
-rw-r--r--csci4131/hw7/public/stock.html124
-rw-r--r--csci4131/hw7/public/welcome.html53
11 files changed, 770 insertions, 0 deletions
diff --git a/csci4131/hw7/api/utilities.js b/csci4131/hw7/api/utilities.js
new file mode 100644
index 0000000..65a087f
--- /dev/null
+++ b/csci4131/hw7/api/utilities.js
@@ -0,0 +1,48 @@
+const express = require('express')
+const db = require ('../dbio')
+const router = express.Router()
+router.use(express.urlencoded({ extended: true }))
+
+router.get('/contacts', function (req, res) {
+ db.getContacts().then(function(table) {
+ res.send(table)
+ });
+});
+
+router.post('/login', async function(req, res) {
+ var loginInfo = req.body;
+ var login = loginInfo.login;
+ var pwd = loginInfo.password;
+ let rows = [];
+
+ // Query the database tbl_login with login and hashed password
+ db.query(login, pwd).then(function(rows) {
+ // Provided there is no error, and the results set is assigned to a variable named rows:
+ if (rows.length >= 1) {// the length should be 0 or 1, but this will work for now
+ //success, set the session, return success
+ req.session.user = login;
+ res.json({ status: 'success' });
+ } else {
+ res.json({ status: 'fail' });
+ }
+ });
+
+});
+
+router.get('/logout', function(req, res) {
+ if(!req.session.user) {
+ res.send('Session not started, can not logout!');
+ } else {
+ req.session.destroy();
+ res.redirect('/login');
+ }
+});
+
+router.post('/addContact', function(req, res) {
+ var contact = req.body;
+ db.addContact(contact).then(function() {
+ res.redirect('/contacts');
+ });
+});
+
+module.exports = router;
diff --git a/csci4131/hw7/create_accounts_table.js b/csci4131/hw7/create_accounts_table.js
new file mode 100644
index 0000000..61b2602
--- /dev/null
+++ b/csci4131/hw7/create_accounts_table.js
@@ -0,0 +1,41 @@
+/*
+TO DO:
+-----
+READ ALL COMMENTS AND REPLACE VALUES ACCORDINGLY
+*/
+
+const mysql = require("mysql");
+
+const dbCon = mysql.createConnection({
+ host: "cse-mysql-classes-01.cse.umn.edu",
+ user: "C4131S21U83", // replace with the database user provided to you
+ password: "6919", // replace with the database password provided to you
+ database: "C4131S21U83", // replace with the database user provided to you
+ port: 3306
+});
+
+console.log("Attempting database connection");
+dbCon.connect(function (err) {
+ if (err) {
+ throw err;
+ }
+ console.log("Connected to database!");
+
+ const sql = `CREATE TABLE tbl_accounts (
+ acc_id INT NOT NULL AUTO_INCREMENT,
+ acc_name VARCHAR(20),
+ acc_login VARCHAR(20),
+ acc_password VARCHAR(200),
+ PRIMARY KEY (acc_id)
+ )`;
+
+ console.log("Attempting to create table: tbl_accounts");
+ dbCon.query(sql, function (err, result) {
+ if (err) {
+ throw err;
+ }
+ console.log("Table tbl_accounts created");
+ });
+
+ dbCon.end();
+});
diff --git a/csci4131/hw7/create_contacts_table.js b/csci4131/hw7/create_contacts_table.js
new file mode 100644
index 0000000..bcad389
--- /dev/null
+++ b/csci4131/hw7/create_contacts_table.js
@@ -0,0 +1,44 @@
+/*
+TO DO:
+-----
+READ ALL COMMENTS AND REPLACE VALUES ACCORDINGLY
+*/
+
+const mysql = require("mysql");
+
+const dbCon = mysql.createConnection({
+ host: "cse-mysql-classes-01.cse.umn.edu",
+ user: "C4131S21U83", // replace with the database user provided to you
+ password: "6919", // replace with the database password provided to you
+ database: "C4131S21U83", // replace with the database user provided to you
+ port: 3306
+});
+
+console.log("Attempting database connection");
+dbCon.connect(function (err) {
+ if (err) {
+ throw err;
+ }
+ console.log("Connected to database!");
+
+ const sql = `CREATE TABLE tbl_contacts (
+ contact_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(30),
+ category VARCHAR(40),
+ location VARCHAR(300),
+ contact_info VARCHAR(200),
+ email VARCHAR(30),
+ website VARCHAR(300),
+ website_url VARCHAR(300)
+ )`;
+
+ console.log("Attempting to create table: tbl_contacts");
+ dbCon.query(sql, function (err, result) {
+ if (err) {
+ throw err;
+ }
+ console.log("Table tbl_accounts created");
+ });
+
+ dbCon.end();
+});
diff --git a/csci4131/hw7/dbio.js b/csci4131/hw7/dbio.js
new file mode 100644
index 0000000..302334b
--- /dev/null
+++ b/csci4131/hw7/dbio.js
@@ -0,0 +1,74 @@
+var mysql = require("mysql");
+var bcrypt = require("bcrypt");
+
+var connection = mysql.createConnection({
+ host: "cse-mysql-classes-01.cse.umn.edu",
+ user: "C4131S21U83",
+ password: "6919",
+ database: "C4131S21U83",
+ port: 3306
+});
+
+connection.connect(function(err) {
+ if (err) {
+ throw err;
+ };
+ console.log("Connected to MYSQL database!");
+});
+
+function passcheck(user,pass) {
+ return new Promise(function(resolve, reject) {
+ connection.query('SELECT * FROM tbl_accounts', function(err, rows, fields) {
+ let ret = [];
+ if (err) {
+ return reject(err);
+ }
+ for (var i = 0; i < rows.length; i++) {
+ if (rows[i].acc_login.localeCompare(user) === 0) {
+ if (bcrypt.compareSync(pass, rows[i].acc_password)) {
+ ret += rows[i];
+ }
+ }
+ }
+ resolve(ret);
+ });
+ });
+}
+
+function getContacts() {
+ return new Promise (function(resolve, reject) {
+ let conTab = []
+ connection.query('SELECT * FROM tbl_contacts', function (err, rows, fields) {
+ if (err) {
+ return reject(err);
+ }
+ resolve(rows);
+ });
+ });
+}
+
+function addContacts(contact) {
+ let newCon = {
+ name: contact.name,
+ category: contact.category,
+ location: contact.location,
+ contact_info: contact.contact,
+ email: contact.email,
+ website_url: contact.website_name,
+ }
+ return new Promise(function(resolve, reject) {
+ connection.query('INSERT tbl_contacts SET ?', newCon, function (err, result) { //Parameterized insert
+ if (err) throw err;
+ console.log("Values inserted");
+ resolve();
+ });
+ });
+
+}
+
+
+
+
+exports.addContact = addContacts;
+exports.query = passcheck;
+exports.getContacts = getContacts;
diff --git a/csci4131/hw7/index.js b/csci4131/hw7/index.js
new file mode 100644
index 0000000..851b096
--- /dev/null
+++ b/csci4131/hw7/index.js
@@ -0,0 +1,109 @@
+// YOU CAN USE THIS FILE AS REFERENCE FOR SERVER DEVELOPMENT
+const createError = require('http-errors');
+
+// Include the express module
+const express = require('express');
+
+// helps in extracting the body portion of an incoming request stream
+var bodyparser = require('body-parser');
+
+// Path module - provides utilities for working with file and directory paths.
+const path = require('path');
+
+// Helps in managing user sessions
+const session = require('express-session');
+
+// include the mysql module
+var mysql = require('mysql');
+
+// Bcrypt library for comparing password hashes
+const bcrypt = require('bcrypt');
+
+// Include the express router.
+const utilities = require('./api/utilities');
+
+const port = 9001;
+
+// create an express application
+const app = express();
+
+// Use express-session
+// In-memory session is sufficient for this assignment
+app.use(session({
+ secret: "csci4131secretkey",
+ saveUninitialized: true,
+ resave: false
+ }
+));
+
+// middle ware to serve static files
+app.use(express.static(path.join(__dirname, 'public')));
+
+// server listens on port for incoming connections
+app.listen(port, () => console.log('Listening on port', port));
+
+app.get('/', function (req, res) {
+ res.sendFile(path.join(__dirname, 'public/welcome.html'));
+});
+
+// GET method route for the contacts page.
+// It serves contact.html present in public folder
+app.get('/contacts', function(req, res) {
+ if(!req.session.user) {
+ res.redirect('/login');
+ } else {
+ res.sendFile(path.join(__dirname, 'public/contacts.html'));
+ }
+});
+
+app.get('/stocks', function(req, res) {
+ res.redirect('/stock');
+})
+
+app.get('/stock', function (req, res) {
+ if (!req.session.user) {
+ res.redirect('/login');
+ } else {
+ res.sendFile(path.join(__dirname, 'public/stock.html'));
+ }
+});
+
+app.get('/addContact', function (req, res) {
+ if (!req.session.user) {
+ res.redirect('/login');
+ } else {
+ res.sendFile(path.join(__dirname, 'public/addContact.html'));
+ }
+});
+
+app.get('/login', function (req, res) {
+ if (req.session.user) {
+ res.redirect('/contacts');
+ } else {
+ res.sendFile(path.join(__dirname, 'login.html'));
+ }
+});
+
+app.get('/logout', function(req, res) {
+ res.redirect('/api/logout')
+});
+
+// Makes Express use a router called utilities
+app.use('/api', utilities);
+
+// function to return the 404 message and error to client
+app.use(function (req, res, next) {
+ next(createError(404));
+});
+
+// error handler
+app.use(function (err, req, res, next) {
+ // set locals, only providing error in development
+ res.locals.message = err.message;
+ res.locals.error = req.app.get('env') === 'development' ? err : {};
+
+ // render the error page
+ res.status(err.status || 500);
+ // res.render('error');
+ res.send();
+});
diff --git a/csci4131/hw7/insert_into_accounts_table.js b/csci4131/hw7/insert_into_accounts_table.js
new file mode 100644
index 0000000..3157ce3
--- /dev/null
+++ b/csci4131/hw7/insert_into_accounts_table.js
@@ -0,0 +1,45 @@
+/*
+TO DO:
+-----
+READ ALL COMMENTS AND REPLACE VALUES ACCORDINGLY
+*/
+
+const mysql = require("mysql");
+const bcrypt = require('bcrypt');
+
+const dbCon = mysql.createConnection({
+ host: "cse-mysql-classes-01.cse.umn.edu",
+ user: "C4131S21U83", // replace with the database user provided to you
+ password: "6919", // replace with the database password provided to you
+ database: "C4131S21U83", // replace with the database user provided to you
+ port: 3306
+});
+
+console.log("Attempting database connection");
+dbCon.connect(function (err) {
+ if (err) {
+ throw err;
+ }
+
+ console.log("Connected to database!");
+
+ const saltRounds = 10;
+ const myPlaintextPassword = 'tango'; // replace with password chosen by you OR retain the same value
+ const passwordHash = bcrypt.hashSync(myPlaintextPassword, saltRounds);
+
+ const rowToBeInserted = {
+ acc_name: 'charlie', // replace with acc_name chosen by you OR retain the same value
+ acc_login: 'charlie', // replace with acc_login chosen by you OR retain the same value
+ acc_password: passwordHash
+ };
+
+ console.log("Attempting to insert record into tbl_accounts");
+ dbCon.query('INSERT tbl_accounts SET ?', rowToBeInserted, function (err, result) {
+ if (err) {
+ throw err;
+ }
+ console.log("Table record inserted!");
+ });
+
+ dbCon.end();
+});
diff --git a/csci4131/hw7/login.html b/csci4131/hw7/login.html
new file mode 100644
index 0000000..9bb80cc
--- /dev/null
+++ b/csci4131/hw7/login.html
@@ -0,0 +1,48 @@
+<html>
+
+<head>
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+ <script src="https://code.jquery.com/jquery-2.2.4.min.js"integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+</head>
+
+<body>
+ <div class="jumbotron" style="background: DarkSeaGreen !important">
+ <h1>Login Page</h1>
+ <div id="error"></div>
+ <br><br>
+ <form id="myForm" name="myForm" style="list-style-type:none">
+ <div>
+ <label for="login">login:</label>
+ <input type="text" id="login" name="login" required>
+ </div>
+ <div>
+ <label for="password">password:</label>
+ <input id="password" name="password" type="password" required>
+ </div>
+ <input type="submit"value="Submit!">
+ </form>
+ </div>
+ <script>
+ //jQuery below. Tread with caution as sneezing near here may rupture the fabric of reality.
+ $(document).ready(function () {
+ $('#myForm').submit(function (event) {
+ event.preventDefault();//collect the form data using Id Selector for whatever data you need to send to server
+ let login=$('#login').val();
+ let password=$('#password').val();
+ $.post('api/login',
+ {"login": login,"password": password},
+ (data) => {
+ if(data.status === 'success'){
+ //pseudo code
+ //Make sure error message is not displayed
+ //Re-direct to contacts page,
+ window.location.href='contacts';}
+ else{
+ //Display error message
+ $('#error').html("<b>Login failed. Please try again.</b>")
+ }});
+ });
+ });</script>
+
+</html>
diff --git a/csci4131/hw7/public/addContact.html b/csci4131/hw7/public/addContact.html
new file mode 100644
index 0000000..629f9b2
--- /dev/null
+++ b/csci4131/hw7/public/addContact.html
@@ -0,0 +1,106 @@
+<!doctype html>
+<html lang="en">
+
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+ </head>
+
+ <body>
+ <nav class="navbar navbar-default">
+ <div class="container-fluid">
+ <ul class="nav navbar-nav">
+ <li><a href="/"><b>Home</b></a></li>
+ <li><a href="contacts"><b>Contacts</b></a></li>
+ <li><a href="addContact"><b>Add Contact</b></a></li>
+ <li><a href="stock"><b>Stock Page</b></a></li>
+ <li><a href="logout"><b>Logout</b></a></li>
+ </ul>
+ </div>
+ </nav>
+ <br><br>
+
+ <div class="container">
+ <div class="row">
+ <p><br /></p>
+ </div>
+
+ <div class="row">
+ <div class="col-md-4"></div>
+ <div class="col-md-4">
+ <div class="panel panel-default">
+ <form name="addContact" method="post" action="/api/addContact">
+ <p></p>
+ <table class="table table-bordered table-hover">
+ <tbody>
+ <tr>
+ <td class="col-md-6">Name</td>
+ <td class="col-md-6">
+ <div class="form-group">
+ <input type="text" class="form-control" name="name" required>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="col-md-6">Category</td>
+ <td class="col-md-6">
+ <div class="form-group">
+ <select class="form-control" name="category">
+ <option>Personal</option>
+ <option>Academic</option>
+ <option>Industry</option>
+ </select>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="col-md-6">Location</td>
+ <td class="col-md-6">
+ <div class="form-group">
+ <input type="text" class="form-control" name="location" required>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="col-md-6">Contact Information</td>
+ <td class="col-md-6">
+ <div class="form-group">
+ <input type="text" class="form-control" name="contact" required>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="col-md-6">Email</td>
+ <td class="col-md-6">
+ <div class="form-group">
+ <input type="email" class="form-control" name="email" required>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="col-md-6">Website Name</td>
+ <td class="col-md-6">
+ <div class="form-group">
+ <input type="url" class="form-control" name="website_name" required maxlength="100">
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td class="col-md-6"></td>
+ <td class="col-md-6">
+ <input type="submit" value="Submit">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </form>
+ </div>
+ </div>
+ <div class="col-md-4"></div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/csci4131/hw7/public/contacts.html b/csci4131/hw7/public/contacts.html
new file mode 100644
index 0000000..5cd2907
--- /dev/null
+++ b/csci4131/hw7/public/contacts.html
@@ -0,0 +1,78 @@
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+ <script type="text/javascript" defer>
+ //Get JSON
+ var xmlhttp = new XMLHttpRequest();
+ var url = "api/contacts";
+ xmlhttp.onreadystatechange = function () {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
+ var parse = JSON.parse(xmlhttp.responseText);
+ process(parse);
+ }
+ }
+ xmlhttp.open("GET", url, true);
+ xmlhttp.send();
+
+ function process(a) {
+ var table = document.getElementsByTagName("tbody")[0];
+ var contacts = a;
+ for (let i = 0; i < contacts.length; i++) {
+ var contact = contacts[i];
+ var row = table.insertRow();
+ for (var j in contact) {
+ if (j === "contact_id") continue;
+ if (j === "website_url") {
+ var url = row.insertCell();
+ url.innerHTML = "<a href =" + contact[j] + ">" + contact[j] + "</a>";
+ } else if (j === "email") {
+ var email = row.insertCell();
+ email.innerHTML = "<a href =mailto://" + contact[j] + ">" + contact[j] + "</a>";
+ } else {
+ var value = row.insertCell();
+ value.innerHTML = contact[j];
+ }
+ }
+ }
+ }
+
+ </script>
+ </head>
+ <body>
+ <nav class="navbar navbar-default">
+ <div class="container-fluid">
+ <ul class="nav navbar-nav">
+ <li><a href="/"><b>Home</b></a></li>
+ <li><a href="contacts"><b>Contacts</b></a></li>
+ <li><a href="addContact"><b>Add Contact</b></a></li>
+ <li><a href="stock"><b>Stock Page</b></a></li>
+ <li><a href="logout"><b>Logout</b></a></li>
+ </ul>
+ </div>
+ </nav>
+ <br><br>
+
+ <div class="container">
+ <table class="table" id="contactsTable">
+ <thead>
+ <tr>
+ <th scope="col">Name</th>
+ <th scope="col">Category</th>
+ <th scope="col">Location</th>
+ <th scope="col">Contact Information</th>
+ <th scope="col">Email</th>
+ <th scope="col">Website <br> (URL) </th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
+ <script type="text/javascript">
+
+ </script>
+ </body>
+</html>
diff --git a/csci4131/hw7/public/stock.html b/csci4131/hw7/public/stock.html
new file mode 100644
index 0000000..d63b233
--- /dev/null
+++ b/csci4131/hw7/public/stock.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+ <style>
+ pre {
+ max-height: 12em;
+ }
+ textarea {
+ width: 100%;
+ min-height: 30rem;
+ background-color: black;
+ font-family: "Lucida Console", Monaco, monospace;
+ font-size: 0.75 rem;
+ line-height: 1.2;
+ color: #fff;
+ }
+ </style>
+</head>
+
+<body>
+ <nav class="navbar navbar-default">
+ <div class="container-fluid">
+ <ul class="nav navbar-nav">
+ <li><a href="/"><b>Home</b></a></li>
+ <li><a href="contacts"><b>Contacts</b></a></li>
+ <li><a href="addContact"><b>Add Contact</b></a></li>
+ <li><a href="stock"><b>Stock Page</b></a></li>
+ <li><a href="logout"><b>Logout</b></a></li>
+ </ul>
+ </div>
+ </nav>
+ <br><br>
+
+ <div class="container">
+ <div class="panel panel-default">
+ <div class="panel-body"><center>Welcome to Stock Page</center></div>
+ </div>
+ </div>
+
+ <div class="container">
+ <div class="row">
+ <div class="col">
+ <table class="table table-bordered table-hover">
+ <tbody>
+ <tr>
+ <td class="col-md-6">Company</td>
+ <td class="col-md-6">
+ <div class="form-group">
+ <select id="Company" name="Company">
+ <option value="GME">Gamestop</option>
+ <option value="MSFT">Microsoft</option>
+ <option value="BA">Boeing Company</option>
+ <option value="AAPL">Apple Inc</option>
+ <option value="AMZN">Amazon</option>
+ <option value="NVDA">NVIDIA Corporation</option>
+ </select>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <button type="button" onclick="Click()">Get Data</button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+ <div class="container">
+ <div id="chartContainer"></div>
+ </div>
+
+ <div class="container">
+ <table class="table" id="StockData">
+ <thead>
+ <tr>
+ <th scope="col" id="meta">Company-MetaData</th>
+ <th scope="col" id="Time">Stock-Info</th>
+ </tr>
+ </thead>
+ <pre>
+ <tbody></tbody>
+ </pre>
+ </table>
+ </div>
+
+ <script>
+ function Click() {
+ var comp = document.getElementById("Company").value;
+ var xmlhttp = new XMLHttpRequest();
+ var url = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=" + comp + "&apikey=8MWSNPDWKH0BTBH2";
+ xmlhttp.onreadystatechange = function () {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
+ var parse = JSON.parse(xmlhttp.responseText);
+ var table = document.getElementById("StockData").getElementsByTagName("tbody")[0];
+ var row = table.insertRow();
+ for (var i in parse) {
+ var cell = row.insertCell();
+ cell.innerHTML = "<pre>" + JSON.stringify(parse[i], undefined, 2) + "</pre>";
+ }
+ }
+ }
+ xmlhttp.open("GET", url, true);
+ xmlhttp.send();
+
+ }
+ /* TODO:
+ / Bonus 1. Request the TIME_SERIES_DAILY endpoint of alphavantage API
+ / for the company selected in the dropdown. Display the JSON
+ / in the result according to the write up.
+ / Bonus 2. Take the JSON from the alphavantage API and chart it to a
+ / line chart using Chart.js to the chartContainer div. Ensure
+ / the chart meets all requirements from the HW writeup.
+ /*/
+ </script>
+</body>
+</html>
diff --git a/csci4131/hw7/public/welcome.html b/csci4131/hw7/public/welcome.html
new file mode 100644
index 0000000..095023e
--- /dev/null
+++ b/csci4131/hw7/public/welcome.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+ <title>Welcome to Node.js</title>
+ <style type="text/css">
+ .jumbotron {
+ text-align: center;
+ }
+ </style>
+</head>
+
+<body>
+<div class="jumbotron" style="background: DarkSeaGreen !important">
+ <h1>Welcome to Express (Node.js)</h1>
+ <p>The objective of this assignment is to develop a basic website with:</p>
+ <p><b>Express</b> which is a Node.js web application framework.</p>
+ <br/>
+ <p>Following are some useful resources:</p>
+
+ <ul style="list-style-type:none">
+ <li><a href="https://expressjs.com/">Express website</a></li>
+ <li><a href="https://expressjs.com/en/starter/installing.html">Express installation</a></li>
+ <li><a href="https://expressjs.com/en/starter/hello-world.html">Hello world example</a></li>
+ <li><a href="https://expressjs.com/en/starter/basic-routing.html">Basic routing</a></li>
+ <li><a href="https://expressjs.com/en/starter/static-files.html">Serving static files in Express</a></li>
+ <li><a href="https://expressjs.com/en/starter/faq.html">FAQ</a></li>
+ <li><a href="https://expressjs.com/en/guide/routing.html">Routing</a></li>
+ <li><a href="https://expressjs.com/en/4x/api.html">API Reference</a></li>
+ <li><a href="https://expressjs.com/en/resources/books-blogs.html">Books and blogs</a></li>
+ <li><a href="https://docs.npmjs.com/getting-started/what-is-npm">NPM introduction</a></li>
+ </ul>
+
+ <br/>
+ <br/>
+
+</div>
+
+<div class="row">
+ <div class="col-md-1"></div>
+ <div class="col-md-10">
+ <button id="myButton" type="button" class="btn btn-primary btn-block" onclick="location.href ='/login'">
+ Navigate to website
+ </button>
+ </div>
+ <div class="col-md-1"></div>
+</div>
+</body>
+</html>