Live update + class progress
This commit is contained in:
1 parent
a404f5a61b
commit
3307307025
14 files changed
+8225
-147
No files matched your search
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
# Port to start server on.
|
# Port to start server on.
|
||||||
PORT=5000
|
PORT=8080
|
||||||
|
|
||||||
# MongoDB connection URI.
|
# MongoDB connection URI.
|
||||||
DB_URI=mongodb://localhost/knoldus
|
DB_URI=mongodb://localhost/27017
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
School Project
|
School Project
|
||||||
This school project is for my teacher to have students
|
This school project is for my teacher to have students
|
||||||
log in and check out their XP and assignments.
|
log in and check out their XP and assignments.
|
||||||
|
This website application is not available online, this is just a locally run website at our school.
|
||||||
|
|
||||||
### Requirements :
|
### Requirements :
|
||||||
1. [Node.js](https://nodejs.org/en/)
|
1. [Node.js](https://nodejs.org/en/)
|
||||||
@@ -14,7 +15,7 @@ log in and check out their XP and assignments.
|
|||||||
3. Run `npm install` to install dependencies.
|
3. Run `npm install` to install dependencies.
|
||||||
4. Duplicate `.env.example` and rename the new file to `.env`. Edit to your configurations.
|
4. Duplicate `.env.example` and rename the new file to `.env`. Edit to your configurations.
|
||||||
1. Run `npm start` to boot up server.
|
1. Run `npm start` to boot up server.
|
||||||
1. Go to http://localhost:5000. Or Whatever you set it to in the `.env` file.
|
1. Go to http://localhost:8080. Or Whatever you set it to in the `.env` file.
|
||||||
|
|
||||||
### Accessing the Database
|
### Accessing the Database
|
||||||
1. Locally this will use any db you set the DB_URI to in the `.env` file.
|
1. Locally this will use any db you set the DB_URI to in the `.env` file.
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ const passport = require('passport');
|
|||||||
const flash = require('connect-flash');
|
const flash = require('connect-flash');
|
||||||
const session = require('express-session');
|
const session = require('express-session');
|
||||||
const bodyParser = require('body-parser');
|
const bodyParser = require('body-parser');
|
||||||
var path = require('path');
|
const http = require('http');
|
||||||
var fs = require('fs');
|
const path = require('path');
|
||||||
var dotenv = require('dotenv');
|
const fs = require('fs');
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
const socket = require('socket.io');
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
@@ -21,7 +23,7 @@ const db = require('./config/keys').mongoURI;
|
|||||||
// Connect to MongoDB
|
// Connect to MongoDB
|
||||||
mongoose
|
mongoose
|
||||||
.connect(
|
.connect(
|
||||||
process.env.DB_URI || 'mongodb://localhost/knoldus',
|
process.env.DB_URI || 'mongodb://localhost/27017',
|
||||||
{ useNewUrlParser: true, useUnifiedTopology: true}
|
{ useNewUrlParser: true, useUnifiedTopology: true}
|
||||||
)
|
)
|
||||||
.then(() => console.log('MongoDB Connected'))
|
.then(() => console.log('MongoDB Connected'))
|
||||||
@@ -63,6 +65,16 @@ app.use(function(req, res, next) {
|
|||||||
app.use('/', require('./routes/index.js'));
|
app.use('/', require('./routes/index.js'));
|
||||||
app.use('/users', require('./routes/users.js'));
|
app.use('/users', require('./routes/users.js'));
|
||||||
|
|
||||||
const PORT = process.env.PORT || 5000;
|
const PORT = process.env.PORT || 8080;
|
||||||
|
const server = app.listen(PORT, function() {
|
||||||
|
console.log(`Server listening on port ${PORT}`);
|
||||||
|
});
|
||||||
|
let io = socket(server);
|
||||||
|
|
||||||
app.listen(PORT, console.log(`Server started on port ${PORT}`));
|
io.on('connection', function(socket) {
|
||||||
|
console.log('connected');
|
||||||
|
|
||||||
|
socket.on('add:xp', function(data) {
|
||||||
|
io.sockets.emit("added:xp", data);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const CourseSchema = new mongoose.Schema({
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
grade: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const Course = mongoose.model('Course', CourseSchema);
|
||||||
|
|
||||||
|
module.exports = Course;
|
||||||
@@ -20,6 +20,9 @@ const QuestSchema = new mongoose.Schema({
|
|||||||
instruction: {
|
instruction: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
referenceClass: {
|
||||||
|
type: [String]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,16 @@ const UserSchema = new mongoose.Schema({
|
|||||||
xp: {
|
xp: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
|
},
|
||||||
|
class: {
|
||||||
|
className: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
questIndex: {
|
||||||
|
type: Number,
|
||||||
|
defualt: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Generated
+215
-5
@@ -4,6 +4,26 @@
|
|||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/component-emitter": {
|
||||||
|
"version": "1.2.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
|
||||||
|
"integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
|
||||||
|
},
|
||||||
|
"@types/cookie": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg=="
|
||||||
|
},
|
||||||
|
"@types/cors": {
|
||||||
|
"version": "2.8.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz",
|
||||||
|
"integrity": "sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg=="
|
||||||
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "14.14.20",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz",
|
||||||
|
"integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A=="
|
||||||
|
},
|
||||||
"abbrev": {
|
"abbrev": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||||
@@ -185,6 +205,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"base64-arraybuffer": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
|
||||||
|
"integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
|
||||||
|
},
|
||||||
|
"base64id": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
|
||||||
|
},
|
||||||
"bcryptjs": {
|
"bcryptjs": {
|
||||||
"version": "2.4.3",
|
"version": "2.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
|
||||||
@@ -196,6 +226,15 @@
|
|||||||
"integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==",
|
"integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"bl": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz",
|
||||||
|
"integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==",
|
||||||
|
"requires": {
|
||||||
|
"readable-stream": "^2.3.5",
|
||||||
|
"safe-buffer": "^5.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"bluebird": {
|
"bluebird": {
|
||||||
"version": "3.5.1",
|
"version": "3.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
|
||||||
@@ -566,6 +605,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||||
},
|
},
|
||||||
|
"cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"requires": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"crc": {
|
"crc": {
|
||||||
"version": "3.4.4",
|
"version": "3.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz",
|
||||||
@@ -664,6 +712,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"denque": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ=="
|
||||||
|
},
|
||||||
"depd": {
|
"depd": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||||
@@ -741,6 +794,48 @@
|
|||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||||
},
|
},
|
||||||
|
"engine.io": {
|
||||||
|
"version": "4.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.0.6.tgz",
|
||||||
|
"integrity": "sha512-rf7HAVZpcRrcKEKddgIzYUnwg0g5HE1RvJaTLwkcfJmce4g+po8aMuE6vxzp6JwlK8FEq/vi0KWN6tA585DjaA==",
|
||||||
|
"requires": {
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"base64id": "2.0.0",
|
||||||
|
"cookie": "~0.4.1",
|
||||||
|
"cors": "~2.8.5",
|
||||||
|
"debug": "~4.3.1",
|
||||||
|
"engine.io-parser": "~4.0.0",
|
||||||
|
"ws": "~7.4.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"cookie": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"engine.io-parser": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
|
||||||
|
"requires": {
|
||||||
|
"base64-arraybuffer": "0.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"escape-html": {
|
"escape-html": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
@@ -2020,6 +2115,12 @@
|
|||||||
"resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||||
},
|
},
|
||||||
|
"memory-pager": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"merge-descriptors": {
|
"merge-descriptors": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
@@ -2121,13 +2222,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mongodb": {
|
"mongodb": {
|
||||||
"version": "3.3.2",
|
"version": "3.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.3.tgz",
|
||||||
"integrity": "sha512-fqJt3iywelk4yKu/lfwQg163Bjpo5zDKhXiohycvon4iQHbrfflSAz9AIlRE6496Pm/dQKQK5bMigdVo2s6gBg==",
|
"integrity": "sha512-rOZuR0QkodZiM+UbQE5kDsJykBqWi0CL4Ec2i1nrGrUI3KO11r6Fbxskqmq3JK2NH7aW4dcccBuUujAP0ERl5w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bson": "^1.1.1",
|
"bl": "^2.2.1",
|
||||||
|
"bson": "^1.1.4",
|
||||||
|
"denque": "^1.4.1",
|
||||||
"require_optional": "^1.0.1",
|
"require_optional": "^1.0.1",
|
||||||
"safe-buffer": "^5.1.2"
|
"safe-buffer": "^5.1.2",
|
||||||
|
"saslprep": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bson": {
|
||||||
|
"version": "1.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz",
|
||||||
|
"integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mongoose": {
|
"mongoose": {
|
||||||
@@ -2148,6 +2259,16 @@
|
|||||||
"sliced": "1.0.1"
|
"sliced": "1.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"mongodb": {
|
||||||
|
"version": "3.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.3.2.tgz",
|
||||||
|
"integrity": "sha512-fqJt3iywelk4yKu/lfwQg163Bjpo5zDKhXiohycvon4iQHbrfflSAz9AIlRE6496Pm/dQKQK5bMigdVo2s6gBg==",
|
||||||
|
"requires": {
|
||||||
|
"bson": "^1.1.1",
|
||||||
|
"require_optional": "^1.0.1",
|
||||||
|
"safe-buffer": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
@@ -2687,6 +2808,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
},
|
},
|
||||||
|
"saslprep": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"sparse-bitfield": "^3.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.6.0",
|
"version": "5.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
|
||||||
@@ -2899,6 +3029,72 @@
|
|||||||
"kind-of": "^3.2.0"
|
"kind-of": "^3.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"socket.io": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-5yWQ43P/4IttmPCGKDQ3CVocBiJWGpibyhYJxgUhf69EHMzmK8XW0DkmHIoYdLmZaVZJyiEkUqpeC7rSCIqekw==",
|
||||||
|
"requires": {
|
||||||
|
"@types/cookie": "^0.4.0",
|
||||||
|
"@types/cors": "^2.8.8",
|
||||||
|
"@types/node": "^14.14.10",
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"base64id": "~2.0.0",
|
||||||
|
"debug": "~4.3.1",
|
||||||
|
"engine.io": "~4.0.6",
|
||||||
|
"socket.io-adapter": "~2.0.3",
|
||||||
|
"socket.io-parser": "~4.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket.io-adapter": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-2wo4EXgxOGSFueqvHAdnmi5JLZzWqMArjuP4nqC26AtLh5PoCPsaRbRdah2xhcwTAMooZfjYiNVNkkmmSMaxOQ=="
|
||||||
|
},
|
||||||
|
"socket.io-parser": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-m4ybFiP4UYVORRt7jcdqf8UWx+ywVdAqqsJyruXxAdD3Sv6MDemijWij34mOWdMJ55bEdIb9jACBhxUgNK6sxw==",
|
||||||
|
"requires": {
|
||||||
|
"@types/component-emitter": "^1.2.10",
|
||||||
|
"component-emitter": "~1.3.0",
|
||||||
|
"debug": "~4.3.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"component-emitter": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"source-map-resolve": {
|
"source-map-resolve": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
|
||||||
@@ -2918,6 +3114,15 @@
|
|||||||
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
|
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"sparse-bitfield": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
|
||||||
|
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"memory-pager": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"split-string": {
|
"split-string": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||||
@@ -3281,6 +3486,11 @@
|
|||||||
"signal-exit": "^3.0.2"
|
"signal-exit": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ws": {
|
||||||
|
"version": "7.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
|
||||||
|
"integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA=="
|
||||||
|
},
|
||||||
"xdg-basedir": {
|
"xdg-basedir": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
|
||||||
|
|||||||
+3
-1
@@ -23,10 +23,12 @@
|
|||||||
"express": "^4.16.4",
|
"express": "^4.16.4",
|
||||||
"express-ejs-layouts": "^2.5.0",
|
"express-ejs-layouts": "^2.5.0",
|
||||||
"express-session": "^1.15.6",
|
"express-session": "^1.15.6",
|
||||||
|
"mongodb": "^3.6.3",
|
||||||
"mongoose": "^5.7.5",
|
"mongoose": "^5.7.5",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"passport": "^0.4.0",
|
"passport": "^0.4.0",
|
||||||
"passport-local": "^1.0.0"
|
"passport-local": "^1.0.0",
|
||||||
|
"socket.io": "^3.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nodemon": "^1.18.9"
|
"nodemon": "^1.18.9"
|
||||||
|
|||||||
+7417
File diff suppressed because it is too large.
Load diff
+8
-4
@@ -4,14 +4,16 @@ const { ensureAuthenticated, forwardAuthenticated } = require('../config/auth');
|
|||||||
// DB Config
|
// DB Config
|
||||||
const db = require('../config/keys').mongoURI;
|
const db = require('../config/keys').mongoURI;
|
||||||
let MongoClient = require('mongodb').MongoClient;
|
let MongoClient = require('mongodb').MongoClient;
|
||||||
let UserModal = require('../models/User.js');
|
let UserModal = require('../models/User');
|
||||||
let QuestModal = require('../models/Quest.js')
|
let QuestModal = require('../models/Quest')
|
||||||
|
let CourseModal = require('../models/Course')
|
||||||
// Welcome Page
|
// Welcome Page
|
||||||
router.get('/', forwardAuthenticated, (req, res) => res.render('welcome'));
|
router.get('/', forwardAuthenticated, (req, res) => res.render('welcome'));
|
||||||
|
|
||||||
// Dashboard
|
// Dashboard
|
||||||
router.get('/dashboard', ensureAuthenticated, function(req, res) {
|
router.get('/dashboard', ensureAuthenticated, function(req, res) {
|
||||||
|
//Collects Course Data
|
||||||
|
CourseModal.find({}, function(err, courses) {
|
||||||
// Collects Quest Data
|
// Collects Quest Data
|
||||||
QuestModal.find({}, function(err, quests) {
|
QuestModal.find({}, function(err, quests) {
|
||||||
// Collects User Data
|
// Collects User Data
|
||||||
@@ -19,7 +21,9 @@ router.get('/dashboard', ensureAuthenticated, function(req, res) {
|
|||||||
res.render('dashboard', {
|
res.render('dashboard', {
|
||||||
user : req.user,
|
user : req.user,
|
||||||
members: data,
|
members: data,
|
||||||
quests: quests
|
quests: quests,
|
||||||
|
courses: courses
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+78
-9
@@ -6,6 +6,10 @@ const passport = require('passport');
|
|||||||
const MongoClient = require('mongodb').MongoClient;
|
const MongoClient = require('mongodb').MongoClient;
|
||||||
const ObjectId = require('mongodb').ObjectId;
|
const ObjectId = require('mongodb').ObjectId;
|
||||||
const Quest = require('../models/Quest');
|
const Quest = require('../models/Quest');
|
||||||
|
const Course = require('../models/Course');
|
||||||
|
const socket = require('socket.io');
|
||||||
|
const server = require('../app.js').server;
|
||||||
|
const io = socket(server);
|
||||||
|
|
||||||
// Load Profanity filter
|
// Load Profanity filter
|
||||||
const Filter = require('bad-words');
|
const Filter = require('bad-words');
|
||||||
@@ -16,7 +20,7 @@ const User = require('../models/User');
|
|||||||
const { forwardAuthenticated } = require('../config/auth');
|
const { forwardAuthenticated } = require('../config/auth');
|
||||||
|
|
||||||
// DB Config
|
// DB Config
|
||||||
const db = require('../config/keys').mongoURI;
|
const url = require('../config/keys').mongoURI;
|
||||||
|
|
||||||
// Loads libraries for uploading img functions
|
// Loads libraries for uploading img functions
|
||||||
let fs = require('fs');
|
let fs = require('fs');
|
||||||
@@ -52,6 +56,70 @@ router.get('/register', forwardAuthenticated, (req, res) => res.render('register
|
|||||||
// Edit page
|
// Edit page
|
||||||
router.get('/edit', (req, res) => res.render('edit'));
|
router.get('/edit', (req, res) => res.render('edit'));
|
||||||
|
|
||||||
|
// Create Course / Class
|
||||||
|
router.post('/createClass', (req, res, next) => {
|
||||||
|
const { name, description, grade } = req.body;
|
||||||
|
|
||||||
|
let errors = [];
|
||||||
|
|
||||||
|
//Checks if Class Already Exists
|
||||||
|
Course.findOne({ name: name }).then(course => {
|
||||||
|
if (course) {
|
||||||
|
errors.push({ msg: 'Course Name Already Exists' })
|
||||||
|
// Redirect to dashboard page with errors
|
||||||
|
res.render('dashboard', {
|
||||||
|
errors,
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
grade
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// Creates new Course Object
|
||||||
|
const newCourse = new Course({
|
||||||
|
name: name,
|
||||||
|
description: description,
|
||||||
|
grade: grade
|
||||||
|
});
|
||||||
|
newCourse
|
||||||
|
.save()
|
||||||
|
.then(course => {
|
||||||
|
req.flash(
|
||||||
|
'success_msg'
|
||||||
|
);
|
||||||
|
// Takes to Dashboard on success
|
||||||
|
let value = encodeURIComponent('createdClass')
|
||||||
|
res.redirect('/dashboard?successRate=' + value);
|
||||||
|
})
|
||||||
|
.catch(err => console.log(err));
|
||||||
|
} catch (err) {
|
||||||
|
if (err) throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete User
|
||||||
|
router.post('/deleteUser', (req, res, next) => {
|
||||||
|
const id = req.body.delete_id;
|
||||||
|
|
||||||
|
// Deletes User
|
||||||
|
MongoClient.connect(url, {
|
||||||
|
useUnifiedTopology: true,
|
||||||
|
useNewUrlParser: true}, function(err, db) {
|
||||||
|
if (err) throw err;
|
||||||
|
let dbo = db.db("XPmockDB");
|
||||||
|
dbo.collection("students").deleteOne({ _id: ObjectId(id) }, function(err, obj) {
|
||||||
|
if (err) throw err;
|
||||||
|
db.close();
|
||||||
|
});
|
||||||
|
// Takes to Dahsboard on success
|
||||||
|
let value = encodeURIComponent('deletedUser');
|
||||||
|
res.redirect('/dashboard?successRate=' + value);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// Create Quest
|
// Create Quest
|
||||||
router.post('/createQuest', (req, res, next) => {
|
router.post('/createQuest', (req, res, next) => {
|
||||||
const { title, amount, expiry, instructions, campaign} = req.body;
|
const { title, amount, expiry, instructions, campaign} = req.body;
|
||||||
@@ -83,7 +151,7 @@ router.post('/createQuest', (req, res, next) => {
|
|||||||
});
|
});
|
||||||
newQuest
|
newQuest
|
||||||
.save()
|
.save()
|
||||||
.then(user => {
|
.then(quest => {
|
||||||
req.flash(
|
req.flash(
|
||||||
'success_msg'
|
'success_msg'
|
||||||
);
|
);
|
||||||
@@ -128,7 +196,7 @@ router.post('/addXP', (req, res, next) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Updates user xp
|
// Updates user xp
|
||||||
MongoClient.connect(db, {
|
MongoClient.connect(url, {
|
||||||
useUnifiedTopology: true,
|
useUnifiedTopology: true,
|
||||||
useNewUrlParser: true}, function(err, db) {
|
useNewUrlParser: true}, function(err, db) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -138,8 +206,9 @@ router.post('/addXP', (req, res, next) => {
|
|||||||
db.close()
|
db.close()
|
||||||
});
|
});
|
||||||
// Takes to Dahsboard on success
|
// Takes to Dahsboard on success
|
||||||
let value = encodeURIComponent(amount.toString())
|
let value1 = encodeURIComponent(amount.toString())
|
||||||
res.redirect('/dashboard?successRate=' + value);
|
let value2 = encodeURIComponent(_id_add);
|
||||||
|
res.redirect('/dashboard?successRate='+value1+'&id='+value2);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -281,7 +350,7 @@ router.post('/edit', upload.single('image'), (req, res, next) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Updates user and redirects to dashboard
|
//Updates user and redirects to dashboard
|
||||||
MongoClient.connect(db, {
|
MongoClient.connect(url, {
|
||||||
useUnifiedTopology: true,
|
useUnifiedTopology: true,
|
||||||
useNewUrlParser: true}, function(err, db) {
|
useNewUrlParser: true}, function(err, db) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -335,7 +404,7 @@ router.post('/edit', upload.single('image'), (req, res, next) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Updates user and redirects to dashboard
|
//Updates user and redirects to dashboard
|
||||||
MongoClient.connect(db, {
|
MongoClient.connect(url, {
|
||||||
useUnifiedTopology: true,
|
useUnifiedTopology: true,
|
||||||
useNewUrlParser: true}, function(err, db) {
|
useNewUrlParser: true}, function(err, db) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -448,8 +517,8 @@ router.post('/registerTeacher', upload.single('image'), (req, res, next) => {
|
|||||||
'success_msg'
|
'success_msg'
|
||||||
);
|
);
|
||||||
// Takes to Dashboard on success
|
// Takes to Dashboard on success
|
||||||
let value = encodeURIComponent('success')
|
let value = encodeURIComponent('createdTeacher')
|
||||||
res.redirect('/dashboard?createTeacher=' + value);
|
res.redirect('/dashboard?successRate=' + value);
|
||||||
})
|
})
|
||||||
.catch(err => console.log(err));
|
.catch(err => console.log(err));
|
||||||
});
|
});
|
||||||
|
|||||||
+92
-11
@@ -1,8 +1,12 @@
|
|||||||
<!-- Simple Styling for layout -->
|
<!-- Simple Styling for layout -->
|
||||||
<style>
|
<style>
|
||||||
.members {
|
.members {
|
||||||
|
position: absolute;
|
||||||
|
top: 150px;
|
||||||
|
left: 25px;
|
||||||
width: 230px;
|
width: 230px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
max-height: 30px
|
||||||
}
|
}
|
||||||
.buttons-container {
|
.buttons-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -15,6 +19,19 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background-color: rgba(112, 196, 255, .3);
|
background-color: rgba(112, 196, 255, .3);
|
||||||
}
|
}
|
||||||
|
.alert {
|
||||||
|
max-width: 58%;
|
||||||
|
}
|
||||||
|
.admin-detail {
|
||||||
|
position: absolute;
|
||||||
|
left: 25px;
|
||||||
|
}
|
||||||
|
#div-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 30%;
|
||||||
|
margin-left: 25vm;
|
||||||
|
margin-right: 25vm;
|
||||||
|
}
|
||||||
#newTeacher-btn {
|
#newTeacher-btn {
|
||||||
margin-left: 25px;
|
margin-left: 25px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
@@ -73,13 +90,32 @@
|
|||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
background: #f6f6f6;
|
background: #f6f6f6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
.alert {
|
||||||
|
max-width: 55%;
|
||||||
|
}
|
||||||
|
#div-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 25px;
|
||||||
|
top: 125px;
|
||||||
|
margin-left: 25vm;
|
||||||
|
margin-right: 25vm;
|
||||||
|
max-height: 125px;
|
||||||
|
}
|
||||||
|
.members {
|
||||||
|
position: absolute;
|
||||||
|
left: 24px;
|
||||||
|
top: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<h1 class="mt-4">Site Admin</h1>
|
|
||||||
<div class='head'>
|
<div class='head'>
|
||||||
<div id='teacher-container'>
|
<div id='teacher-container'>
|
||||||
<div>
|
<div class='admin-detail'>
|
||||||
|
<h1 class="mt-4">Site Admin</h1>
|
||||||
<p id='welcome' class="lead mb-3">Welcome Admin</p>
|
<p id='welcome' class="lead mb-3">Welcome Admin</p>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
@@ -87,7 +123,7 @@
|
|||||||
<!-- Action Buttons -->
|
<!-- Action Buttons -->
|
||||||
<a id='logout-btn' href="/users/logout" class="btn btn-outline-info btn-sm">Logout</a>
|
<a id='logout-btn' href="/users/logout" class="btn btn-outline-info btn-sm">Logout</a>
|
||||||
<!-- Button trigger modal -->
|
<!-- Button trigger modal -->
|
||||||
<button id="newTeacher-btn" onClick='openModal()' type="button" class="btn btn-outline-info btn-sm">
|
<button id="newTeacher-btn" onClick='openModal("#exampleModal")' type="button" class="btn btn-outline-info btn-sm">
|
||||||
Create New Teacher
|
Create New Teacher
|
||||||
</button>
|
</button>
|
||||||
<a id='bug-btn' href="https://github.com/Braeden57/XP-System/issues" target="_blank" class='btn btn-outline-info btn-sm'>Report Bug</a>
|
<a id='bug-btn' href="https://github.com/Braeden57/XP-System/issues" target="_blank" class='btn btn-outline-info btn-sm'>Report Bug</a>
|
||||||
@@ -97,8 +133,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
function openModal() {
|
function openModal(modalName) {
|
||||||
$("#exampleModal").modal()
|
$(modalName).modal()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates unique ID
|
// Creates unique ID
|
||||||
@@ -117,10 +153,10 @@
|
|||||||
let id = makeid(8);
|
let id = makeid(8);
|
||||||
|
|
||||||
if (type == 'error') {
|
if (type == 'error') {
|
||||||
document.getElementById('div-container').innerHTML += '<div id="new-div-'+id+'" style="display: none;" class="alert alert-warning alert-dismissible fade show" role="alert">';
|
document.getElementById('div-container').innerHTML += '<div id="new-div-'+id+'" style="display: none; clear: right;" class="alert alert-warning alert-dismissible fade show" role="alert">';
|
||||||
}
|
}
|
||||||
if (type == 'message') {
|
if (type == 'message') {
|
||||||
document.getElementById('div-container').innerHTML += '<div id="new-div-'+id+'" style="display: none;" class="alert alert-info alert-dismissible fade show" role="alert">';
|
document.getElementById('div-container').innerHTML += '<div id="new-div-'+id+'" style="display: none; clear: right;" class="alert alert-info alert-dismissible fade show" role="alert">';
|
||||||
}
|
}
|
||||||
document.getElementById('new-div-'+id).innerHTML += '<div id="message'+id+'">'+message+'</div>';
|
document.getElementById('new-div-'+id).innerHTML += '<div id="message'+id+'">'+message+'</div>';
|
||||||
document.getElementById('new-div-'+id).innerHTML += '<button id="close-btn-'+id+'" class="close" data-dismiss="alert" aria-label="Close"></button>';
|
document.getElementById('new-div-'+id).innerHTML += '<button id="close-btn-'+id+'" class="close" data-dismiss="alert" aria-label="Close"></button>';
|
||||||
@@ -135,9 +171,12 @@
|
|||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
const queryString = window.location.search;
|
const queryString = window.location.search;
|
||||||
const urlParams = new URLSearchParams(queryString);
|
const urlParams = new URLSearchParams(queryString);
|
||||||
const isSuccess = urlParams.get('createTeacher')
|
const successRate = urlParams.get('successRate')
|
||||||
if(isSuccess == 'success') {
|
if(successRate == 'createdTeacher') {
|
||||||
createDiv('message', 'Successfully Created Teacher')
|
createDiv('message', 'Successfully Created Teacher');
|
||||||
|
}
|
||||||
|
if(successRate == 'deletedUser') {
|
||||||
|
createDiv('message', "Successfully Deleted User");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -171,7 +210,32 @@
|
|||||||
<!-- Alert container -->
|
<!-- Alert container -->
|
||||||
<div id='div-container'></div>
|
<div id='div-container'></div>
|
||||||
|
|
||||||
<!-- Modal -->
|
<!-- Delete User Warning Modal -->
|
||||||
|
<div class="modal fade" id="warningModal" tabindex="-1" role="dialog" aria-labelledby="warningModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="warningModalLabel">Are you sure you wish to delete this user?</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form action="/users/deleteUser" method="POST" enctype="multipart/form-data">
|
||||||
|
<input id='delete_id' type='text' name='delete_id' value='' style='display: none'></input>
|
||||||
|
<button type="submit" class="btn btn-primary btn-block">
|
||||||
|
Yes, Continue and Delete This User
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Create Teacher Modal -->
|
||||||
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@@ -264,6 +328,11 @@
|
|||||||
<p>XP: <%= member.xp %></p>
|
<p>XP: <%= member.xp %></p>
|
||||||
|
|
||||||
<p><%= member.role %></p>
|
<p><%= member.role %></p>
|
||||||
|
|
||||||
|
<!-- Delete User Option -->
|
||||||
|
<button id="delete-btn" onClick='deleteUser("<%= member._id %>")' type="button" class="btn btn-outline-warning btn-sm">
|
||||||
|
Delete User
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -294,6 +363,13 @@
|
|||||||
|
|
||||||
// Display Rank
|
// Display Rank
|
||||||
document.getElementById('userRank-<%= member.id %>').innerHTML = currRank;
|
document.getElementById('userRank-<%= member.id %>').innerHTML = currRank;
|
||||||
|
|
||||||
|
// Delete User Function
|
||||||
|
function deleteUser(id) {
|
||||||
|
document.getElementById('delete_id').value = id;
|
||||||
|
openModal("#warningModal");
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
@@ -308,6 +384,11 @@
|
|||||||
<p class='lead mb-3'><%= member.email %></p>
|
<p class='lead mb-3'><%= member.email %></p>
|
||||||
<div>
|
<div>
|
||||||
<p><%= member.role %></p>
|
<p><%= member.role %></p>
|
||||||
|
|
||||||
|
<!-- Delete User Option -->
|
||||||
|
<button id="delete-btn" onClick='deleteUser("<%= member._id %>")' type="button" class="btn btn-outline-warning btn-sm">
|
||||||
|
Delete User
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+160
-27
@@ -2,7 +2,7 @@
|
|||||||
<style>
|
<style>
|
||||||
.quests-container {
|
.quests-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 650px;
|
width: 625px;
|
||||||
height: 645px;
|
height: 645px;
|
||||||
top: 100px;
|
top: 100px;
|
||||||
left: 450px;
|
left: 450px;
|
||||||
@@ -15,9 +15,13 @@
|
|||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
.quest-buttons {
|
.quest-buttons {
|
||||||
margin-left: 25px;
|
margin-left: 10px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#option1 {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
#myProgress {
|
#myProgress {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
@@ -40,6 +44,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 1%;
|
height: 1%;
|
||||||
background-color: #46c7f2;
|
background-color: #46c7f2;
|
||||||
|
transition: 1s;
|
||||||
}
|
}
|
||||||
#pro-pic {
|
#pro-pic {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -103,6 +108,24 @@
|
|||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
background: #f6f6f6;
|
background: #f6f6f6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
.quest-all {
|
||||||
|
position: absolute;
|
||||||
|
top: 770px;
|
||||||
|
right: 1145px;
|
||||||
|
}
|
||||||
|
#quest-title {
|
||||||
|
transform: translate(-125px, 0px);
|
||||||
|
}
|
||||||
|
.quest-container {
|
||||||
|
width: 400px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: rgba(0, 0, 0, .2);
|
||||||
|
border-radius: 15px;
|
||||||
|
background-color: rgba(0, 0, 0, .2);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="student-container">
|
<div class="student-container">
|
||||||
@@ -123,7 +146,7 @@
|
|||||||
<!-- User Data -->
|
<!-- User Data -->
|
||||||
<div>
|
<div>
|
||||||
<h1 id='userRank'></h1>
|
<h1 id='userRank'></h1>
|
||||||
<h1>XP: <%= user.xp %></h1>
|
<h1 id='userXP'>XP: <%= user.xp %></h1>
|
||||||
<p id='XP-Till'></p>
|
<p id='XP-Till'></p>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
@@ -135,7 +158,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div class="quest-all">
|
||||||
<h1 id="quest-title">Quests</h1>
|
<h1 id="quest-title">Quests</h1>
|
||||||
<div class='quests-container'>
|
<div class='quests-container'>
|
||||||
<div class='quest-buttons'>
|
<div class='quest-buttons'>
|
||||||
@@ -186,8 +209,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Quest Display -->
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
let socket = io.connect('http://localhost:5000');
|
||||||
|
|
||||||
|
socket.on("added:xp", function(data) {
|
||||||
|
if(data.userID == '<%=user._id%>') {
|
||||||
|
reCalculate(data.addXP);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
calculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
let xp = <%= user.xp %>;
|
||||||
|
|
||||||
|
// Passing user _id to edit page script
|
||||||
|
function passData() {
|
||||||
|
let url = '/users/edit?name=' + encodeURIComponent('<%= user._id %>');
|
||||||
|
|
||||||
|
document.location.href = url;
|
||||||
|
}
|
||||||
|
|
||||||
function showHTML() {
|
function showHTML() {
|
||||||
let state = document.getElementById('HTML-Display').style.display;
|
let state = document.getElementById('HTML-Display').style.display;
|
||||||
if (state == "block") {
|
if (state == "block") {
|
||||||
@@ -220,23 +264,6 @@
|
|||||||
document.getElementById('JS-Display').style.display = 'block';
|
document.getElementById('JS-Display').style.display = 'block';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Passing user _id to edit page script -->
|
|
||||||
<script>
|
|
||||||
function passData() {
|
|
||||||
let url = '/users/edit?name=' + encodeURIComponent('<%= user._id %>');
|
|
||||||
|
|
||||||
document.location.href = url;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Calculate Rank Data Script -->
|
|
||||||
<script>
|
|
||||||
let xp = <%= user.xp %>;
|
|
||||||
let currRank;
|
|
||||||
let rankUp;
|
|
||||||
let remain;
|
|
||||||
|
|
||||||
let ranks = [
|
let ranks = [
|
||||||
{"Digital Noob": 0}, // index 0
|
{"Digital Noob": 0}, // index 0
|
||||||
@@ -254,14 +281,28 @@
|
|||||||
{"Master Digital Crafter": 800} // index 12
|
{"Master Digital Crafter": 800} // index 12
|
||||||
]
|
]
|
||||||
|
|
||||||
// Get current rank
|
// Global old variables
|
||||||
|
let currRank;
|
||||||
|
let rankUp;
|
||||||
|
let remain;
|
||||||
|
let goal;
|
||||||
|
let total;
|
||||||
|
let progress;
|
||||||
|
let percent;
|
||||||
let indexes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12]
|
let indexes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12]
|
||||||
|
|
||||||
|
// Initial calculate from 0 to current XP
|
||||||
|
function calculate() {
|
||||||
|
// Get current rank
|
||||||
if (xp < 800) {
|
if (xp < 800) {
|
||||||
for(var i = 0; i < ranks.length; i++) {
|
for(var i = 0; i < ranks.length; i++) {
|
||||||
for (let rank in ranks[i]) {
|
for (let rank in ranks[i]) {
|
||||||
let nextIndex = indexes[i];
|
let nextIndex = indexes[i];
|
||||||
|
// Gets rank after current rank
|
||||||
for (let nextRank in ranks[nextIndex]) {
|
for (let nextRank in ranks[nextIndex]) {
|
||||||
|
// Verifies current XP is > currentRank xp level && current XP < nextRank xp level
|
||||||
if (xp >= ranks[i][rank] && xp < ranks[nextIndex][nextRank]) {
|
if (xp >= ranks[i][rank] && xp < ranks[nextIndex][nextRank]) {
|
||||||
|
// Sets global old variables
|
||||||
currRank = rank;
|
currRank = rank;
|
||||||
currRankXP = ranks[i][rank]
|
currRankXP = ranks[i][rank]
|
||||||
// Calculate xp till next Rank
|
// Calculate xp till next Rank
|
||||||
@@ -269,13 +310,13 @@
|
|||||||
i++;
|
i++;
|
||||||
let nextRank = ranks[i];
|
let nextRank = ranks[i];
|
||||||
for (let r in nextRank) {
|
for (let r in nextRank) {
|
||||||
let goal = nextRank[r];
|
goal = nextRank[r];
|
||||||
rankUp = r;
|
rankUp = r;
|
||||||
remain = goal - xp;
|
remain = goal - xp;
|
||||||
// Calculate progress bar
|
// Calculate progress bar
|
||||||
let total = goal - currRankXP;
|
total = goal - currRankXP;
|
||||||
let progress = xp - currRankXP;
|
progress = xp - currRankXP;
|
||||||
let percent = (progress/total)*100;
|
percent = (progress/total)*100;
|
||||||
let elem = document.getElementById("myBar");
|
let elem = document.getElementById("myBar");
|
||||||
elem.style.height = percent + '%';
|
elem.style.height = percent + '%';
|
||||||
document.getElementById('percent').innerHTML = progress + '|' + total;
|
document.getElementById('percent').innerHTML = progress + '|' + total;
|
||||||
@@ -299,6 +340,98 @@
|
|||||||
// Display Data
|
// Display Data
|
||||||
document.getElementById('userRank').innerHTML = currRank;
|
document.getElementById('userRank').innerHTML = currRank;
|
||||||
document.getElementById('XP-Till').innerHTML = remain + 'XP till your next Rank: ' + rankUp;
|
document.getElementById('XP-Till').innerHTML = remain + 'XP till your next Rank: ' + rankUp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re calculate recaculates all the data from oldXP + addxp to newxp
|
||||||
|
function reCalculate(addXP) {
|
||||||
|
let newXP = xp + parseInt(addXP);
|
||||||
|
console.log(newXP);
|
||||||
|
// Get current rank
|
||||||
|
if (newXP < 800) {
|
||||||
|
for(var i = 0; i < ranks.length; i++) {
|
||||||
|
for (let rank in ranks[i]) {
|
||||||
|
let nextIndex = indexes[i];
|
||||||
|
for (let nextRank in ranks[nextIndex]) {
|
||||||
|
if (newXP >= ranks[i][rank] && newXP < ranks[nextIndex][nextRank]) {
|
||||||
|
let newCurrRank = rank;
|
||||||
|
let newCurrRankXP = ranks[i][rank]
|
||||||
|
// Calculate xp till next Rank
|
||||||
|
if (i < 12) {
|
||||||
|
i++;
|
||||||
|
let newNextRank = ranks[i];
|
||||||
|
for (let r in newNextRank) {
|
||||||
|
let newRankUp = r;
|
||||||
|
let newPercent;
|
||||||
|
let diff = addXP;
|
||||||
|
let newProgress = progress+diff
|
||||||
|
let newRemain;
|
||||||
|
let newGoal;
|
||||||
|
let newTotal;
|
||||||
|
// If new Progress doesnt go over current total
|
||||||
|
if (newProgress < total) {
|
||||||
|
// Set new percent and new remain
|
||||||
|
let diffPercent=(diff/total)*100;
|
||||||
|
newRemain = remain - diff;
|
||||||
|
newTotal = total;
|
||||||
|
let elem = document.getElementById("myBar");
|
||||||
|
newPercent = percent + diffPercent;
|
||||||
|
elem.style.height = newPercent + "%";
|
||||||
|
document.getElementById('percent').innerHTML = newProgress + "|" + total;
|
||||||
|
// Update Display with new Data
|
||||||
|
document.getElementById('userXP').innerHTML = "XP: " + newXP;
|
||||||
|
document.getElementById('XP-Till').innerHTML = newRemain + "XP till your next Rank: " + rankUp;
|
||||||
|
document.getElementById('userRank').innerHTML = currRank;
|
||||||
|
// If new progress goes over current total
|
||||||
|
} else if (newProgress >= total) {
|
||||||
|
// Set new variables
|
||||||
|
newGoal = newNextRank[r];
|
||||||
|
newTotal = newGoal - newCurrRankXP;
|
||||||
|
newProgress = newXP - newCurrRankXP;
|
||||||
|
newRemain = newTotal - newProgress;
|
||||||
|
// Update percent from current percent to new percent
|
||||||
|
let elem = document.getElementById("myBar");
|
||||||
|
newPercent = Math.round((newProgress/newTotal)*100);
|
||||||
|
elem.style.height = newPercent + "%";
|
||||||
|
// Adds 1 to progress till progress == total
|
||||||
|
let progressDiff = total-progress;
|
||||||
|
document.getElementById('percent').innerHTML = newProgress + "|" + newTotal;
|
||||||
|
// Update Display with new Data
|
||||||
|
document.getElementById('XP-Till').innerHTML = newRemain + "XP till your next Rank: " + newRankUp;
|
||||||
|
document.getElementById('userXP').innerHTML = "XP: " + newXP;
|
||||||
|
document.getElementById('userRank').innerHTML = newCurrRank;
|
||||||
|
document.getElementById('percent').innerHTML = newProgress + "|" + newTotal;
|
||||||
|
}
|
||||||
|
// Set Main Variables to new values
|
||||||
|
currRank = newCurrRank;
|
||||||
|
rankUp = newRankUp;
|
||||||
|
remain = newRemain;
|
||||||
|
goal = newGoal;
|
||||||
|
total = newTotal;
|
||||||
|
progress = newProgress;
|
||||||
|
percent = newPercent;
|
||||||
|
xp = newXP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Display data for max level
|
||||||
|
document.getElementById('percent').innerHTML = '800|800';
|
||||||
|
currRank = "Master Digital Crafter";
|
||||||
|
remain = 0;
|
||||||
|
xp = 800;
|
||||||
|
rankUp = 'No higher Rank, Good Job!';
|
||||||
|
let elem = document.getElementById("myBar");
|
||||||
|
let percent = 100;
|
||||||
|
elem.style.height = percent + '%';
|
||||||
|
// Display Data
|
||||||
|
document.getElementById('userXP').innerHTML = "XP: " + xp;
|
||||||
|
document.getElementById('userRank').innerHTML = currRank;
|
||||||
|
document.getElementById('XP-Till').innerHTML = remain + 'XP till your next Rank: ' + rankUp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function redirect(id) {
|
function redirect(id) {
|
||||||
let url = '/users/quests?id=' + encodeURIComponent(id);
|
let url = '/users/quests?id=' + encodeURIComponent(id);
|
||||||
|
|||||||
+197
-81
@@ -40,6 +40,20 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
}
|
}
|
||||||
|
.course-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 1000px;
|
||||||
|
background: rgba(0, 0, 0, .2);
|
||||||
|
border-radius: 24px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: rgba(0, 0, 0, .2);
|
||||||
|
}
|
||||||
|
.course-content {
|
||||||
|
margin-left: 15px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-right: 15px;
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
.quest {
|
.quest {
|
||||||
color: #e05f3a;
|
color: #e05f3a;
|
||||||
}
|
}
|
||||||
@@ -66,7 +80,7 @@
|
|||||||
}
|
}
|
||||||
.buttons-container {
|
.buttons-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 425px;
|
top: 380px;
|
||||||
right: 180px;
|
right: 180px;
|
||||||
}
|
}
|
||||||
.button-content {
|
.button-content {
|
||||||
@@ -145,17 +159,9 @@
|
|||||||
<button onClick='passData()' class='button-content btn btn-outline-info btn-sm'>Edit</button>
|
<button onClick='passData()' class='button-content btn btn-outline-info btn-sm'>Edit</button>
|
||||||
<a href="https://github.com/Braeden57/XP-System/issues" target="_blank" class='button-content btn btn-outline-info btn-sm'>Report Bug</a>
|
<a href="https://github.com/Braeden57/XP-System/issues" target="_blank" class='button-content btn btn-outline-info btn-sm'>Report Bug</a>
|
||||||
<button class="button-content btn btn-outline-info btn-sm" data-toggle="modal" data-target="#createQuest">New Quest</button>
|
<button class="button-content btn btn-outline-info btn-sm" data-toggle="modal" data-target="#createQuest">New Quest</button>
|
||||||
|
<button class="button-content btn btn-outline-info btn-sm" data-toggle="modal" data-target="#createClass">New Class</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Passing user _id to edit page script -->
|
|
||||||
<script>
|
|
||||||
function passData() {
|
|
||||||
let url = '/users/edit?name=' + encodeURIComponent('<%= user._id %>');
|
|
||||||
|
|
||||||
document.location.href = url;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -192,7 +198,7 @@
|
|||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title" id="exampleModalLabel"</h5>
|
<h5 class="modal-title" id="exampleModalLabel">Add XP</h5>
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -203,10 +209,6 @@
|
|||||||
<input id='_id_add' type='text' name='_id_add' value='' style='display: none'></input>
|
<input id='_id_add' type='text' name='_id_add' value='' style='display: none'></input>
|
||||||
<input id="current_xp" type="text" name="current_xp" value="" style="display: none"></input>
|
<input id="current_xp" type="text" name="current_xp" value="" style="display: none"></input>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<p>Minimum: 1</p>
|
|
||||||
<p>Maximum: 50</p>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="amount">Amount</label>
|
<label for="amount">Amount</label>
|
||||||
<input
|
<input
|
||||||
@@ -214,7 +216,6 @@
|
|||||||
name="amount"
|
name="amount"
|
||||||
type="number"
|
type="number"
|
||||||
min="1"
|
min="1"
|
||||||
max="50"
|
|
||||||
value=""
|
value=""
|
||||||
class="form-control"
|
class="form-control"
|
||||||
>
|
>
|
||||||
@@ -236,7 +237,7 @@
|
|||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title" id="createQuestLabel"</h5>
|
<h5 class="modal-title" id="createQuestLabel">Create Quest</h5>
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -309,68 +310,63 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<!-- Create Class Modal -->
|
||||||
// Creates unique ID
|
<div class="modal fade" id="createClass" tabindex="-1" role="dialog" aria-labelledby="createClassLabel" aria-hidden="true">
|
||||||
function makeid(length) {
|
<div class="modal-dialog" role="document">
|
||||||
var result = '';
|
<div class="modal-content">
|
||||||
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
<div class="modal-header">
|
||||||
var charactersLength = characters.length;
|
<h5 class="modal-title" id="createClassLabel">Create Class</h5>
|
||||||
for ( var i = 0; i < length; i++ ) {
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
<span aria-hidden="true">×</span>
|
||||||
}
|
</button>
|
||||||
return result;
|
</div>
|
||||||
}
|
<div class="modal-body">
|
||||||
|
<form action="/users/createClass" method="POST">
|
||||||
// Create Div
|
<div>
|
||||||
function createDiv(type, message) {
|
<label for="name">Class Name</label>
|
||||||
let id = makeid(8);
|
<input
|
||||||
|
id="name"
|
||||||
if (type == 'error') {
|
name="name"
|
||||||
document.getElementById('div-container').innerHTML += '<div id="new-div-'+id+'" style="display: none;" class="alert alert-warning alert-dismissible fade show" role="alert">';
|
type="text"
|
||||||
}
|
value=""
|
||||||
if (type == 'message') {
|
class="form-control"
|
||||||
document.getElementById('div-container').innerHTML += '<div id="new-div-'+id+'" style="display: none;" class="alert alert-info alert-dismissible fade show" role="alert">';
|
required
|
||||||
}
|
>
|
||||||
document.getElementById('new-div-'+id).innerHTML += '<div id="message'+id+'">'+message+'</div>';
|
</div>
|
||||||
document.getElementById('new-div-'+id).innerHTML += '<button id="close-btn-'+id+'" class="close" data-dismiss="alert" aria-label="Close"></button>';
|
<div>
|
||||||
document.getElementById('close-btn-'+id).innerHTML += '<span aria-hidden="true">×</span>';
|
<label for="description">Class Description</label>
|
||||||
document.getElementById('new-div-'+id).style.display = "block";
|
<textarea
|
||||||
}
|
id="description"
|
||||||
|
name="description"
|
||||||
// Pass name to Modal
|
value=""
|
||||||
function passName(name, xp, member_id) {
|
class="form-control"
|
||||||
if (xp < 800) {
|
required
|
||||||
document.getElementById("exampleModalLabel").innerHTML = "Give " + name + " XP";
|
></textarea>
|
||||||
document.getElementById("_id_add").value = member_id;
|
</div>
|
||||||
document.getElementById("current_xp").value = xp;
|
<div>
|
||||||
$("#exampleModal").modal()
|
<label for="grade">Grade</label>
|
||||||
}
|
<input
|
||||||
if (xp >= 800) {
|
id="grade"
|
||||||
// Construct and show Max XP Alert
|
name="grade"
|
||||||
message = name + ' has reached max XP!';
|
type="number"
|
||||||
createDiv('message', message);
|
min="8"
|
||||||
}
|
max="12"
|
||||||
}
|
value=""
|
||||||
|
class="form-control"
|
||||||
// Catching url Parameters
|
required
|
||||||
window.onload = function () {
|
>
|
||||||
const queryString = window.location.search;
|
</div>
|
||||||
const urlParams = new URLSearchParams(queryString);
|
<button type="submit" class="btn btn-primary">
|
||||||
const successRate = urlParams.get('successRate')
|
Create Class
|
||||||
if(successRate == 'addXP > 50') {
|
</button>
|
||||||
createDiv('error', "Can't add more than 50 XP")
|
</form>
|
||||||
}
|
</div>
|
||||||
if(successRate == 'addXP <= 0') {
|
<div class="modal-footer">
|
||||||
createDiv('error', "XP Must be Greater than 0");
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||||
}
|
</div>
|
||||||
if(parseInt(successRate) > 0 && parseInt(successRate) < 50 || parseInt(successRate) == 50) {
|
</div>
|
||||||
createDiv('message', "Gave " + successRate + "XP to a Student");
|
</div>
|
||||||
}
|
</div>
|
||||||
if(successRate == 'createdQuest') {
|
|
||||||
createDiv('message', "Successfully Created Quest");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="members-container">
|
<div class="members-container">
|
||||||
<!-- List of all site students (not teachers) -->
|
<!-- List of all site students (not teachers) -->
|
||||||
@@ -442,13 +438,126 @@
|
|||||||
<!-- List of Quests -->
|
<!-- List of Quests -->
|
||||||
<div class='quest-content'>
|
<div class='quest-content'>
|
||||||
<h2>All Quests</h2>
|
<h2>All Quests</h2>
|
||||||
|
<ul>
|
||||||
<% quests.forEach(function (quest) { %>
|
<% quests.forEach(function (quest) { %>
|
||||||
<p class='quest'><%= quest.title %></p>
|
<li><button class='list-button btn btn-outline-success mt-2' onclick="redirect('<%= quest._id %>')"><%= quest.title %></button></li>
|
||||||
<% }) %>
|
<% }) %>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Script for show/hide user profile data -->
|
<div class="course-container">
|
||||||
|
<!-- List of Courses -->
|
||||||
|
<div class='course-content'>
|
||||||
|
<h2>All Courses</h2>
|
||||||
|
<% courses.forEach(function (course) { %>
|
||||||
|
<div class='course'>
|
||||||
|
<p><%= course.name %>: Grade <%= course.grade %></p>
|
||||||
|
</div>
|
||||||
|
<% }) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
let socket = io.connect('http://localhost:5000');
|
||||||
|
|
||||||
|
// Creates unique ID
|
||||||
|
function makeid(length) {
|
||||||
|
var result = '';
|
||||||
|
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
var charactersLength = characters.length;
|
||||||
|
for ( var i = 0; i < length; i++ ) {
|
||||||
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function passData() {
|
||||||
|
let url = '/users/edit?name=' + encodeURIComponent('<%= user._id %>');
|
||||||
|
|
||||||
|
document.location.href = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Div
|
||||||
|
function createDiv(type, message) {
|
||||||
|
let id = makeid(8);
|
||||||
|
|
||||||
|
if (type == 'error') {
|
||||||
|
document.getElementById('div-container').innerHTML += '<div id="new-div-'+id+'" style="display: none;" class="alert alert-warning alert-dismissible fade show" role="alert">';
|
||||||
|
}
|
||||||
|
if (type == 'message') {
|
||||||
|
document.getElementById('div-container').innerHTML += '<div id="new-div-'+id+'" style="display: none;" class="alert alert-info alert-dismissible fade show" role="alert">';
|
||||||
|
}
|
||||||
|
document.getElementById('new-div-'+id).innerHTML += '<div id="message'+id+'">'+message+'</div>';
|
||||||
|
document.getElementById('new-div-'+id).innerHTML += '<button id="close-btn-'+id+'" class="close" data-dismiss="alert" aria-label="Close"></button>';
|
||||||
|
document.getElementById('close-btn-'+id).innerHTML += '<span aria-hidden="true">×</span>';
|
||||||
|
document.getElementById('new-div-'+id).style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass name to Modal
|
||||||
|
function passName(name, xp, member_id) {
|
||||||
|
if (xp < 800) {
|
||||||
|
document.getElementById("exampleModalLabel").innerHTML = "Give " + name + " XP";
|
||||||
|
document.getElementById("_id_add").value = member_id;
|
||||||
|
document.getElementById("current_xp").value = xp;
|
||||||
|
$("#exampleModal").modal()
|
||||||
|
}
|
||||||
|
if (xp >= 800) {
|
||||||
|
// Construct and show Max XP Alert
|
||||||
|
message = name + ' has reached max XP!';
|
||||||
|
createDiv('message', message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let getParameterByName = function() {
|
||||||
|
let queries = location.search.substring(1).split('&'),
|
||||||
|
processed = {};
|
||||||
|
for (let query of queries) {
|
||||||
|
let [name, value] = query.split('=');
|
||||||
|
processed[decodeURIComponent(name)] = value? decodeURIComponent(value) : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(name) {
|
||||||
|
if (typeof processed[name] !== 'undefined')
|
||||||
|
return processed[name];
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
|
||||||
|
function updateXP(addXP, id) {
|
||||||
|
let data = {
|
||||||
|
userID: id,
|
||||||
|
addXP: addXP
|
||||||
|
}
|
||||||
|
socket.emit('add:xp', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Catching url Parameters
|
||||||
|
window.onload = function () {
|
||||||
|
const queryString = window.location.search;
|
||||||
|
const urlParams = new URLSearchParams(queryString);
|
||||||
|
const successRate = urlParams.get('successRate')
|
||||||
|
if(successRate == 'addXP > 50') {
|
||||||
|
createDiv('error', "Can't add more than 50 XP")
|
||||||
|
}
|
||||||
|
if(successRate == 'addXP <= 0') {
|
||||||
|
createDiv('error', "XP Must be Greater than 0");
|
||||||
|
}
|
||||||
|
if(parseInt(successRate) > 0) {
|
||||||
|
createDiv('message', "Gave " + successRate + "XP to a Student");
|
||||||
|
updateXP(successRate, getParameterByName('id'));
|
||||||
|
}
|
||||||
|
if(successRate == 'createdQuest') {
|
||||||
|
createDiv('message', "Successfully Created Quest");
|
||||||
|
}
|
||||||
|
if(successRate == 'createdClass') {
|
||||||
|
createDiv('message', "Successfully created Course");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Script for show/hide user profile data
|
||||||
function openProfile(id) {
|
function openProfile(id) {
|
||||||
let state = document.getElementById(id).style.display;
|
let state = document.getElementById(id).style.display;
|
||||||
if (state == "block") {
|
if (state == "block") {
|
||||||
@@ -457,4 +566,11 @@
|
|||||||
document.getElementById(id).style.display = 'block';
|
document.getElementById(id).style.display = 'block';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Script for redirecting to selected Quest
|
||||||
|
function redirect(id) {
|
||||||
|
let url = '/users/quests?id=' + encodeURIComponent(id);
|
||||||
|
|
||||||
|
document.location.href = url;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
Reference in new issue
Block a user