This commit is contained in:
louiscklaw
2025-01-31 21:26:01 +08:00
parent c9ec760f31
commit 7d30025aed
211 changed files with 144112 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var logger = require('morgan');
// use lab6-db
var monk = require('monk');
var db = monk('127.0.0.1:27017/lab6-db');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
// Make our db accessible to routers
app.use(function(req,res,next){
req.db = db;
next();
});
app.use('/', indexRouter);
app.use('/users', usersRouter);
// for requests not matching the above routes, create 404 error 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 environment
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;

View File

@@ -0,0 +1,90 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('lab6: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);
}

View File

@@ -0,0 +1,18 @@
var conn = new Mongo();
var db = conn.getDB("lab6-db");
var topic_name = ["www", "html", "css", "javascript", "nodejs", "jquery"];
var topic_status = ["no", "no", "no", "no", "no", "no"];
var topic_hour = [2, 4, 4, 6, 10, 6];
db.topicList.remove({});
for(let i = 0; i < topic_name.length; i++){
db.topicList.insert(
{
'name': topic_name[i],
'hour': topic_hour[i],
'status': topic_status[i]
}
)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
{
"name": "lab6",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"jade": "~1.11.0",
"monk": "^7.3.4",
"morgan": "~1.9.1",
"pug": "^3.0.2"
}
}

Binary file not shown.

View File

@@ -0,0 +1,75 @@
$(document).ready(function() {
showAllTopics()
});
// step 7.2
function showAllTopics(){
var table_content = `
<tr><th>Topic Name</th>
<th>Study Hour</th>
<th>Chosen Status</th>
<th>Operation</th></tr>
`
$.getJSON('/users/get_table').then((docs)=>{
$.each(docs, function(i, row){
if(row.status == 'yes'){
row_class = "highlight"
row_operation = "remove"
}else{
row_class = ""
row_operation = "add"
}
table_content += `
<tr class=${row_class}><td>${row.name}</td>
<td>${row.hour}</td>
<td>${row.status}</td>
<td><a href="#" class="operation" rel="${row._id}">${row_operation}</a></td></tr>
`
})
$('#plan_table').html(table_content)
})
}
$("#plan_table").on('click', '.operation', operateTopic)
// step 8.2
function operateTopic(event){
event.preventDefault()
var id = $(this).attr('rel')
var op = $(this).html()
$.ajax({
type: 'PUT',
url: '/users/update_status',
data: {
_id: id,
op: op
}
}).done(function(msg){
alert(msg);
showAllTopics()
});
}
$("#submit_delete").on('click', deleteTopic)
// step 9.2
function deleteTopic(event){
event.preventDefault()
var topic_name = $("#input_name").val()
if($(`td:contains("${topic_name}")`).length != 0){
$.ajax({
type: 'DELETE',
url: '/users/delete_topic/' + topic_name
}).done(function(msg){
alert(msg);
showAllTopics();
});
}else alert("No such topic in the table!")
}

View File

@@ -0,0 +1,159 @@
body {
margin: 0;
background: #163a50;
font: 300 100%/120% "Tahoma", Arial, Helvetica, sans-serif;
}
header {
overflow: hidden;
}
header, nav, .contents, footer {
box-sizing: border-box;
max-width: 1080px;
margin-left: auto;
margin-right: auto;
}
header, nav, footer {
background: #0f2736;
}
h1, h2, h3, h4 {
font-weight: bold
}
.contents {
padding: 1em 2em 2.5em 2em;
}
/* increase line spacing for main title */
h1 {
line-height: 120%;
margin-top: 0.5em;
float: left;
width: auto;
}
header img {
float: left;
}
/* change color and remove underline for links */
footer a {
color: inherit;
text-decoration: none;
}
#plan_table a {
color: rgb(0, 47, 255);
}
/* size and margin for logo image */
header img {
max-width: 100%;
max-height: 100%;
margin: 0.5em;
}
form {
padding: 1em 2em;
}
input[type="number"] {
min-width: 4em;
}
/* style for footer */
footer {
margin: auto;
text-align: center;
}
footer div {
padding: 1em;
}
.contents h2 {
text-align: center;
}
button {
margin-top: 1em;
margin-bottom: 1em;
width: 5em;
height: 2em;
}
input {
width: 5em;
height: 1.6em;
margin-right: 2em;
}
#delete_div p{
color: gray;
}
header *, nav * {
color: #FFFFFF;
}
.contents {
background: #FFFFFF;
}
.subtitle {
font-size: 0.6em;
font-weight: normal;
}
@media screen and (max-width: 1080px) {
header,nav {
overflow: hidden;
}
}
@media screen and (max-width: 720px) {
header img {
display: none;
}
header h1 {
padding: 0 0.5em;
}
nav div {
width: 100%;
}
}
.contents {
text-align: center;
}
.contents li{
text-align: left;
}
/* style for the table */
table, th, td {
border: 1.8px solid black;
border-collapse: collapse;
text-align: center;
vertical-align: center;
margin: auto;
width: 400px;
height: 50px;
}
th {
background-color: rgb(178, 177, 177);
}
.highlight {
background-color: rgb(255, 0, 0);
}
#plan_table {
margin-bottom: 2em;
}

View File

@@ -0,0 +1,9 @@
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;

View File

@@ -0,0 +1,6 @@
extends layout
block content
h1= message
h2= error.status
pre #{error.stack}

View File

@@ -0,0 +1,26 @@
extends layout
block content
header
img(src='/images/logo.png' width="128" height="128")
h1 Course Study Plan
br
span(class="subtitle") COMP3322A Modern Technologies on World Wide Web
section(class="contents")
h2 Instruction
ul
li Add/Remove a topic to/from your study plan by clicking the respective operation.
li Delete a topic permanently by typing its name into the input box and clicking the "Delete" button.
hr
h2 Topic Plan
div
table#plan_table
div#delete_div
p Fill in a topic name to delete it from the table permanently:
input#input_name(type='text', placeholder='topic name')
button#submit_delete Delete
footer
div <a href="#">Back to top</a>

View File

@@ -0,0 +1,10 @@
doctype html
html
head
title= "lab6"
link(rel='stylesheet', href='/stylesheets/style.css')
meta(name="viewport" content="width=device-width, initial-scale=1.0")
body
block content
script(src='https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js')
script(src='/javascripts/externalJS.js')