Inital Commit
This commit is contained in:
64
.gitignore
vendored
Normal file
64
.gitignore
vendored
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Typescript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
#Database Config
|
||||||
|
database.js
|
||||||
58
BikeRides.sql
Normal file
58
BikeRides.sql
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
-- SQL Dump
|
||||||
|
-- Server version: 8.0.31
|
||||||
|
|
||||||
|
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||||
|
START TRANSACTION;
|
||||||
|
SET time_zone = "+00:00";
|
||||||
|
|
||||||
|
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||||
|
/*!40101 SET NAMES utf8mb4 */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Database: `BikeTesting`
|
||||||
|
--
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `BikeRides`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE `BikeRides` (
|
||||||
|
`id` int NOT NULL,
|
||||||
|
`start_point` varchar(30) NOT NULL,
|
||||||
|
`end_point` varchar(30) NOT NULL,
|
||||||
|
`route_id` int NOT NULL,
|
||||||
|
`time_taken` int NOT NULL,
|
||||||
|
`average_speed` int NOT NULL,
|
||||||
|
`departure` datetime NOT NULL,
|
||||||
|
`arival` datetime NOT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Indexes for dumped tables
|
||||||
|
--
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Indexes for table `BikeRides`
|
||||||
|
--
|
||||||
|
ALTER TABLE `BikeRides`
|
||||||
|
ADD PRIMARY KEY (`id`);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- AUTO_INCREMENT for dumped tables
|
||||||
|
--
|
||||||
|
|
||||||
|
--
|
||||||
|
-- AUTO_INCREMENT for table `BikeRides`
|
||||||
|
--
|
||||||
|
ALTER TABLE `BikeRides`
|
||||||
|
MODIFY `id` int NOT NULL AUTO_INCREMENT;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||||
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
8
Readme.md
Normal file
8
Readme.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# BikeRideViewer
|
||||||
|
|
||||||
|
|
||||||
|
Install using `npm install`
|
||||||
|
Dev-Enviroment: NodeJS 18 and MySQL
|
||||||
|
Build with Express.JS framework
|
||||||
|
|
||||||
|
Based on this [Soure](https://www.webslesson.info/2022/04/insert-update-delete-data-from-mysql-in-node-js-using-express-js.html#step3)
|
||||||
64
app.js
Normal file
64
app.js
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
var createError = require('http-errors');
|
||||||
|
var express = require('express');
|
||||||
|
var path = require('path');
|
||||||
|
var cookieParser = require('cookie-parser');
|
||||||
|
var logger = require('morgan');
|
||||||
|
|
||||||
|
var session = require('express-session');
|
||||||
|
|
||||||
|
var flash = require('connect-flash');
|
||||||
|
|
||||||
|
var indexRouter = require('./routes/index');
|
||||||
|
|
||||||
|
var app = express();
|
||||||
|
|
||||||
|
// view engine setup
|
||||||
|
app.set('views', path.join(__dirname, 'views'));
|
||||||
|
app.set('view engine', 'ejs');
|
||||||
|
|
||||||
|
app.use(logger('dev'));
|
||||||
|
app.use(express.json());
|
||||||
|
app.use(express.urlencoded({ extended: false }));
|
||||||
|
app.use(cookieParser());
|
||||||
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
|
||||||
|
|
||||||
|
// Load MDI
|
||||||
|
app.use("/css/materialdesignicons.min.css", express.static(path.join(__dirname, "node_modules/@mdi/font/css/materialdesignicons.min.css")));
|
||||||
|
app.use("/css/materialdesignicons.css.map", express.static(path.join(__dirname, "node_modules/@mdi/font/css/materialdesignicons.css.map")));
|
||||||
|
app.use("/fonts/materialdesignicons-webfont.eot", express.static(path.join(__dirname, "node_modules/@mdi/font/fonts/materialdesignicons-webfont.eot")));
|
||||||
|
app.use("/fonts/materialdesignicons-webfont.ttf", express.static(path.join(__dirname, "node_modules/@mdi/font/fonts/materialdesignicons-webfont.ttf")));
|
||||||
|
app.use("/fonts/materialdesignicons-webfont.woff", express.static(path.join(__dirname, "node_modules/@mdi/font/fonts/materialdesignicons-webfont.woff")));
|
||||||
|
app.use("/fonts/materialdesignicons-webfont.woff2", express.static(path.join(__dirname, "node_modules/@mdi/font/fonts/materialdesignicons-webfont.woff2")));
|
||||||
|
|
||||||
|
//Load table-sort-js
|
||||||
|
app.use("/js/table-sort.js", express.static(path.join(__dirname, "node_modules/table-sort-js/table-sort.js")));
|
||||||
|
|
||||||
|
app.use(session({
|
||||||
|
secret : 'ANL8cIXDN2f4nHDJSdoUAegACr7KfrYR',
|
||||||
|
cookie : {maxAge : 60000},
|
||||||
|
saveUninitialized : false,
|
||||||
|
resave : false
|
||||||
|
}));
|
||||||
|
|
||||||
|
app.use(flash());
|
||||||
|
|
||||||
|
app.use('/', indexRouter);
|
||||||
|
|
||||||
|
// catch 404 and forward to error handler
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
90
bin/www
Executable file
90
bin/www
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var app = require('../app');
|
||||||
|
var debug = require('debug')('biketable:server');
|
||||||
|
var http = require('http');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get port from environment and store in Express.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var port = normalizePort(process.env.PORT || '3000');
|
||||||
|
app.set('port', port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create HTTP server.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var server = http.createServer(app);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen on provided port, on all network interfaces.
|
||||||
|
*/
|
||||||
|
|
||||||
|
server.listen(port);
|
||||||
|
server.on('error', onError);
|
||||||
|
server.on('listening', onListening);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize a port into a number, string, or false.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function normalizePort(val) {
|
||||||
|
var port = parseInt(val, 10);
|
||||||
|
|
||||||
|
if (isNaN(port)) {
|
||||||
|
// named pipe
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port >= 0) {
|
||||||
|
// port number
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event listener for HTTP server "error" event.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onError(error) {
|
||||||
|
if (error.syscall !== 'listen') {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bind = typeof port === 'string'
|
||||||
|
? 'Pipe ' + port
|
||||||
|
: 'Port ' + port;
|
||||||
|
|
||||||
|
// handle specific listen errors with friendly messages
|
||||||
|
switch (error.code) {
|
||||||
|
case 'EACCES':
|
||||||
|
console.error(bind + ' requires elevated privileges');
|
||||||
|
process.exit(1);
|
||||||
|
break;
|
||||||
|
case 'EADDRINUSE':
|
||||||
|
console.error(bind + ' is already in use');
|
||||||
|
process.exit(1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event listener for HTTP server "listening" event.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function onListening() {
|
||||||
|
var addr = server.address();
|
||||||
|
var bind = typeof addr === 'string'
|
||||||
|
? 'pipe ' + addr
|
||||||
|
: 'port ' + addr.port;
|
||||||
|
debug('Listening on ' + bind);
|
||||||
|
}
|
||||||
21
database.js.examle
Normal file
21
database.js.examle
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
const mysql = require('mysql');
|
||||||
|
|
||||||
|
var connection = mysql.createConnection({
|
||||||
|
host : 'localhost',
|
||||||
|
database : 'testing',
|
||||||
|
user : 'root',
|
||||||
|
password : ''
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.connect(function(error){
|
||||||
|
if(error)
|
||||||
|
{
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
console.log('MySQL Database is connected Successfully');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = connection;
|
||||||
1225
package-lock.json
generated
Normal file
1225
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
21
package.json
Normal file
21
package.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "biketable",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"start": "node ./bin/www"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mdi/font": "^7.1.96",
|
||||||
|
"connect-flash": "^0.1.1",
|
||||||
|
"cookie-parser": "~1.4.4",
|
||||||
|
"debug": "~2.6.9",
|
||||||
|
"ejs": "~2.6.1",
|
||||||
|
"express": "~4.16.1",
|
||||||
|
"express-session": "^1.17.3",
|
||||||
|
"http-errors": "~1.6.3",
|
||||||
|
"morgan": "~1.9.1",
|
||||||
|
"mysql": "^2.18.1",
|
||||||
|
"table-sort-js": "^1.8.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
60
public/css/button.css
Normal file
60
public/css/button.css
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*Genral Button Style*/
|
||||||
|
.btn {
|
||||||
|
display: inline-block;
|
||||||
|
align-items: center;
|
||||||
|
background: none;
|
||||||
|
border: 1px solid #bdbdbd;
|
||||||
|
height: 48px;
|
||||||
|
letter-spacing: 0.25px;
|
||||||
|
border-radius: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn .mdi {
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Delete Button Style*/
|
||||||
|
.btn-delete {
|
||||||
|
font-size: 16px;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-delete:hover, .btn-delete:focus {
|
||||||
|
background-color: var(--btn-hover-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-delete > .mdi-delete-empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-delete:hover > .mdi-delete-empty {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
}
|
||||||
|
.btn-delete:hover > .mdi-delete {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Info Button Style*/
|
||||||
|
.btn-info {
|
||||||
|
font-size: 16px;
|
||||||
|
color: skyblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-info > .mdi-information {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-info:hover > .mdi-information {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-info:hover > .mdi-information-outline {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
70
public/css/modal.css
Normal file
70
public/css/modal.css
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*Modal Style*/
|
||||||
|
.modal {
|
||||||
|
margin: 100px auto;
|
||||||
|
padding: 20px;
|
||||||
|
background: var(--bg-color);
|
||||||
|
border: 1px solid #666;
|
||||||
|
width: 300px;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 0 50px rgba(0, 0, 0, 0.5);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal .close {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
opacity: 0.8;
|
||||||
|
transition: all 200ms;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--txt-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal .close:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal .content {
|
||||||
|
max-height: 400px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal p {
|
||||||
|
margin: 0 0 1em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal p:last-child {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
/*Modal background Style*/
|
||||||
|
.overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
transition: opacity 200ms;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay .cancel {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay:target {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
78
public/css/style.css
Normal file
78
public/css/style.css
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/*Ligt theme colors*/
|
||||||
|
:root {
|
||||||
|
--bg-color: #f8f8f8;
|
||||||
|
--txt-color: #212121;
|
||||||
|
--lnk-color: #0033cc;
|
||||||
|
--table-border-color:#eeeeee ;
|
||||||
|
--table-bg-color: #ffffff;
|
||||||
|
--table-bg-hover-color:#f3f3f3;
|
||||||
|
--btn-hover-bg-color: #d2d2d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark theme colors*/
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--bg-color: #383c4a;
|
||||||
|
--txt-color: #bbc0ca;
|
||||||
|
--lnk-color: #809fff;
|
||||||
|
--table-border-color: #373c48 ;
|
||||||
|
--table-bg-color:#2a2e3a ;
|
||||||
|
--table-bg-hover-color: #373b46;
|
||||||
|
--btn-hover-bg-color: #2a2e3a;
|
||||||
|
--color-footer: #2e323e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Genral Style*/
|
||||||
|
body {
|
||||||
|
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
||||||
|
color: var(--txt-color);
|
||||||
|
background: var(--bg-color);
|
||||||
|
font: 100% system-ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container{
|
||||||
|
padding: 1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--lnk-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.HeadIcon {
|
||||||
|
color: #0046a1;
|
||||||
|
font-size: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert.alert-danger {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 50px;
|
||||||
|
border: 2px darkred solid;
|
||||||
|
background: red;
|
||||||
|
max-width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px 0;
|
||||||
|
background-color: var(--color-footer);
|
||||||
|
color: var(--txt-color);
|
||||||
|
}
|
||||||
|
footer >.right {
|
||||||
|
float: right;
|
||||||
|
padding-right: 1%;
|
||||||
|
|
||||||
|
}
|
||||||
|
footer > .left {
|
||||||
|
float: left;
|
||||||
|
padding-left: 1%;
|
||||||
|
}
|
||||||
41
public/css/table.css
Normal file
41
public/css/table.css
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
tbody > tr:hover {
|
||||||
|
background-color: var(--table-bg-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border: 1px solid var(--table-border-color);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-top-left-radius: 10px;
|
||||||
|
border-top-right-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
table caption {
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin: .5em 0 .75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tbody tr {
|
||||||
|
background-color: var(--table-bg-color);
|
||||||
|
border: 1px solid var(--table-border-color);
|
||||||
|
padding: .35em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead tr {
|
||||||
|
background-color: #404652;
|
||||||
|
border: 1px solid var(--table-border-color);
|
||||||
|
padding: .35em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th, table td {
|
||||||
|
padding: .625em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th {
|
||||||
|
font-size: .85em;
|
||||||
|
letter-spacing: .1em;
|
||||||
|
}
|
||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
64
routes/index.js
Normal file
64
routes/index.js
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
var express = require('express');
|
||||||
|
|
||||||
|
var router = express.Router();
|
||||||
|
|
||||||
|
var database = require('../database');
|
||||||
|
|
||||||
|
router.get("/", function(request, response, next){
|
||||||
|
|
||||||
|
var query = "SELECT * FROM BikeRides ORDER BY id DESC";
|
||||||
|
|
||||||
|
database.query(query, function(error, data){
|
||||||
|
|
||||||
|
if(error)
|
||||||
|
{
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.render('index', {title:'BikeRides', action:'list', TheData:data, message:request.flash('error')});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/view/:id', function(request, response, next){
|
||||||
|
|
||||||
|
var id = request.params.id;
|
||||||
|
|
||||||
|
var query = `SELECT * FROM BikeRides WHERE id = "${id}"`;
|
||||||
|
|
||||||
|
database.query(query, function(error, data){
|
||||||
|
response.render('index', {title: 'View ride', action:'view', data:data[0]});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
router.get('/delete/:id', function(request, response, next){
|
||||||
|
|
||||||
|
var id = request.params.id;
|
||||||
|
|
||||||
|
var query = `
|
||||||
|
DELETE FROM BikeRides WHERE id = "${id}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
database.query(query, function(error, data){
|
||||||
|
|
||||||
|
if(error)
|
||||||
|
{
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request.flash('error', 'Ride removed');
|
||||||
|
response.redirect("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
3
views/error.ejs
Normal file
3
views/error.ejs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<h1><%= message %></h1>
|
||||||
|
<h2><%= error.status %></h2>
|
||||||
|
<pre><%= error.stack %></pre>
|
||||||
113
views/index.ejs
Normal file
113
views/index.ejs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- Required meta tags -->
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<!-- CSS -->
|
||||||
|
<link rel='stylesheet' href='/css/materialdesignicons.min.css' />
|
||||||
|
<link rel='stylesheet' href='/css/style.css' />
|
||||||
|
<!-- JS Scripts -->
|
||||||
|
<script src="/js/table-sort.js"></script>
|
||||||
|
<title><%= title %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<% if(action == 'view') { %>
|
||||||
|
<!-- Ride Page -->
|
||||||
|
<link rel='stylesheet' href='/css/modal.css' />
|
||||||
|
<link rel='stylesheet' href='/css/button.css' />
|
||||||
|
<div id="modal" class="overlay">
|
||||||
|
<a class="cancel" href="#" onclick="history.go(-1)"></a>
|
||||||
|
<div class="modal">
|
||||||
|
<h2>Ride info</h2>
|
||||||
|
<div class="content">
|
||||||
|
<% if( data !== undefined ) {%>
|
||||||
|
<p>Date: <%= data.date %></p>
|
||||||
|
<p>From: <%= data.start_point %></p>
|
||||||
|
<p>To: <%= data.end_point %></p>
|
||||||
|
<p>RoutID <%= data.route_id %></p>
|
||||||
|
<p>Time Taken: <%= data.time_taken %> Min</p>
|
||||||
|
<p>Average speed: <%= data.average_speed %> Km/h</p>
|
||||||
|
<p>Departed : <%= new Date (data.departure).toLocaleTimeString("en-US" , { hour: 'numeric', minute: 'numeric'}); %> <br> <%= new Date (data.departure).toLocaleDateString("en-GB", { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'}) %> </p>
|
||||||
|
<p>Arived : <%= new Date (data.arival).toLocaleTimeString("en-US" , { hour: 'numeric', minute: 'numeric'}); %> <br> <%= new Date (data.arival).toLocaleDateString("en-GB", { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric'}) %></p>
|
||||||
|
<button class="btn btn-delete" onclick="location.href='/delete/<%= data.id %>'">
|
||||||
|
<span class="mdi mdi-delete mdi-24px"></span>
|
||||||
|
<span class="mdi mdi-delete-empty mdi-24px"></span>
|
||||||
|
</button>
|
||||||
|
<% } else { %>
|
||||||
|
<p style="color: red;"> Error: This ride does not exist</p>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } else { %>
|
||||||
|
<!-- Overview Page -->
|
||||||
|
<link rel='stylesheet' href='/css/table.css' />
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="text-center mt-3 mb-3">
|
||||||
|
<span class="mdi mdi-bicycle HeadIcon"></span><br>
|
||||||
|
<%= title %>
|
||||||
|
</h1>
|
||||||
|
<% if(message.length > 0) { %>
|
||||||
|
<div class="alert alert-danger"><%= message %></div>
|
||||||
|
<% } %>
|
||||||
|
<div style="overflow-x:auto;">
|
||||||
|
<table class="table table-sort table-arrows">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>From</th>
|
||||||
|
<th>To</th>
|
||||||
|
<th>Time taken</th>
|
||||||
|
<th>Avg. Speed</th>
|
||||||
|
<!-- Uncomment next line to add an action row (Delete and Info button) to the table
|
||||||
|
<th class="TableActions">Action</th>
|
||||||
|
-->
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- Check if there Rides loaded from DB -->
|
||||||
|
<%
|
||||||
|
if(TheData.length > 0)
|
||||||
|
<!-- If there are Rides output as table -->
|
||||||
|
{ TheData.forEach(function(data){
|
||||||
|
%>
|
||||||
|
<tr onclick="location.href='/view/<%= data.id %>'">
|
||||||
|
<td><%= new Date (data.departure).toLocaleDateString("en-GB", { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric'}) %></td>
|
||||||
|
<td><%= data.start_point %></td>
|
||||||
|
<td><%= data.end_point %></td>
|
||||||
|
<td><%= data.time_taken %> Min</td>
|
||||||
|
<td><%= data.average_speed %> Km/h</td>
|
||||||
|
<!-- Uncomment next lines to add an action row (Delete and Info button) to the table
|
||||||
|
<td class="TableActions">
|
||||||
|
<button class="btn btn-delete" onclick="location.href='/delete/<%= data.id %>'">
|
||||||
|
<span class="mdi mdi-delete mdi-24px"></span>
|
||||||
|
<span class="mdi mdi-delete-empty mdi-24px"></span>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-info" onclick="location.href='/view/<%= data.id %>'">
|
||||||
|
<span class="mdi mdi-information-outline mdi-24px"></span>
|
||||||
|
<span class="mdi mdi-information mdi-24px"></span>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
-->
|
||||||
|
</tr>
|
||||||
|
<% }); } else { %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="5">No Data Found</td>
|
||||||
|
</tr>
|
||||||
|
<% } %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
<footer>
|
||||||
|
<div class="left">
|
||||||
|
<p>BikeRideViewer | By brammp</p>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<p><a href="https://git.bprieshof.nl/brammp/BikeRideViewer"><span class="mdi mdi-git mdi-18px"></span>SourceCode</a></p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user