This commit is contained in:
SowinskiBraeden committed 2021-01-04 10:18:19 -08:00
1 parent 9163477534
commit 9fa4aa179a
12 files changed
+590 -182

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
# Port to start server on.
PORT=5000
# MongoDB connection URI.
DB_URI=mongodb://localhost/knoldus
+8 -1
View File
@@ -1 +1,8 @@
/test # Dependencies.
node_modules/*
# Tests folder.
test/*
# Enviroment variables
.env
+24 -1
View File
@@ -1,5 +1,28 @@
# XP-System # XP-System
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.
(Still not done)!
### Requirements :
1. [Node.js](https://nodejs.org/en/)
1. [MongoDB](https://docs.mongodb.com/manual/administration/install-community/)
### Getting Started with Code :
1. [Set Up MongoDB](#setting-up-mongodb) and start mongodb
2. Clone repo from https://github.com/Braeden57/XP-System.git
3. Run `npm install` to install dependencies.
4. Duplicate `.env.example` and rename the new file to `.env`. Edit to your configurations.
1. Run `npm start` to boot up server.
1. Go to http://localhost:5000.
### Setting up MongoDB
1. Install mongodb via brew. `brew install mongodb`
1. Start mongodb via brew. `brew services restart mongodb`
2. Or Install mongodb compass https://www.mongodb.com/try/download/compass
### Accessing the Database
1. Locally this will use the knoldus db (or whatever you specify manually)
1. launch mongo via your command-line: `mongo`
1. Use `show dbs` to see all that are available. You should see `knoldus` in the list.
1. Lets use that db: `use knoldus`.
+3 -2
View File
@@ -7,7 +7,8 @@ const session = require('express-session');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
var path = require('path'); var path = require('path');
var fs = require('fs'); var fs = require('fs');
require('dotenv/config'); var dotenv = require('dotenv');
dotenv.config();
const app = express(); const app = express();
@@ -20,7 +21,7 @@ const db = require('./config/keys').mongoURI;
// Connect to MongoDB // Connect to MongoDB
mongoose mongoose
.connect( .connect(
db, process.env.DB_URI || 'mongodb://localhost/knoldus',
{ useNewUrlParser: true, useUnifiedTopology: true} { useNewUrlParser: true, useUnifiedTopology: true}
) )
.then(() => console.log('MongoDB Connected')) .then(() => console.log('MongoDB Connected'))
+5 -1
View File
@@ -1,4 +1,8 @@
let dbPassword = 'mongodb+srv://client:backyardpassclient@backyard-pass-data.nbikf.mongodb.net/XPmockDB?retryWrites=true&w=majority'; const dotenv = require('dotenv');
// Load environment variables into process
dotenv.config()
let dbPassword = process.env.DB_URI;
module.exports = { module.exports = {
mongoURI: dbPassword mongoURI: dbPassword
+28
View File
@@ -0,0 +1,28 @@
const mongoose = require('mongoose');
const QuestSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
campaign: {
type: String,
required: true
},
expiry: {
type: Date,
default: Date.now
},
xp: {
type: Number,
required: true
},
instruction: {
type: String,
required: true
}
});
const Quest = mongoose.model('Quest', QuestSchema);
module.exports = Quest;
+6 -6
View File
@@ -1,19 +1,19 @@
{ {
"_from": "dotenv", "_from": "dotenv@^8.2.0",
"_id": "dotenv@8.2.0", "_id": "dotenv@8.2.0",
"_inBundle": false, "_inBundle": false,
"_integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", "_integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
"_location": "/dotenv", "_location": "/dotenv",
"_phantomChildren": {}, "_phantomChildren": {},
"_requested": { "_requested": {
"type": "tag", "type": "range",
"registry": true, "registry": true,
"raw": "dotenv", "raw": "dotenv@^8.2.0",
"name": "dotenv", "name": "dotenv",
"escapedName": "dotenv", "escapedName": "dotenv",
"rawSpec": "", "rawSpec": "^8.2.0",
"saveSpec": null, "saveSpec": null,
"fetchSpec": "latest" "fetchSpec": "^8.2.0"
}, },
"_requiredBy": [ "_requiredBy": [
"#USER", "#USER",
@@ -21,7 +21,7 @@
], ],
"_resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", "_resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
"_shasum": "97e619259ada750eea3e4ea3e26bceea5424b16a", "_shasum": "97e619259ada750eea3e4ea3e26bceea5424b16a",
"_spec": "dotenv", "_spec": "dotenv@^8.2.0",
"_where": "C:\\Users\\flami\\OneDrive\\Desktop\\Projects\\XP-System", "_where": "C:\\Users\\flami\\OneDrive\\Desktop\\Projects\\XP-System",
"bugs": { "bugs": {
"url": "https://github.com/motdotla/dotenv/issues" "url": "https://github.com/motdotla/dotenv/issues"
+15 -6
View File
@@ -1,19 +1,28 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const { ensureAuthenticated, forwardAuthenticated } = require('../config/auth'); const { ensureAuthenticated, forwardAuthenticated } = require('../config/auth');
var UserModel = require('../models/User.js'); // DB Config
const db = require('../config/keys').mongoURI;
let MongoClient = require('mongodb').MongoClient;
let UserModal = require('../models/User.js');
let QuestModal = require('../models/Quest.js')
// 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) {
UserModel.find({}, function(err, data) { // Collects Quest Data
res.render('dashboard', { QuestModal.find({}, function(err, quests) {
user : req.user, // Collects User Data
members: data UserModal.find({}, function(err, data) {
}); res.render('dashboard', {
user : req.user,
members: data,
quests: quests
});
}); });
});
}); });
module.exports = router; module.exports = router;
+57 -1
View File
@@ -5,6 +5,7 @@ const bcrypt = require('bcryptjs');
const passport = require('passport'); 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');
// Load Profanity filter // Load Profanity filter
const Filter = require('bad-words'); const Filter = require('bad-words');
@@ -33,6 +34,15 @@ let storage = multer.diskStorage({
let upload = multer({ storage: storage }); let upload = multer({ storage: storage });
let questsList;
// Collects Quest Data
Quest.find({}, function(err, quests) {
questsList = quests;
});
// Show Quest page
router.get('/quests', (req, res) => res.render('quests', { quests: questsList }));
// Login Page // Login Page
router.get('/login', forwardAuthenticated, (req, res) => res.render('login')); router.get('/login', forwardAuthenticated, (req, res) => res.render('login'));
@@ -42,6 +52,52 @@ 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 Quest
router.post('/createQuest', (req, res, next) => {
const { title, amount, instructions, campaign} = req.body;
let errors = [];
// Checks if Quest with title exists
Quest.findOne({ title: title }).then(quest => {
if (quest) {
errors.push({ msg: 'Quest Already Exists' });
// Redirect to dashboard page with errors
res.render('dashboard', {
errors,
name,
email,
password,
password2
});
} else {
try {
// Creates new User Object
const newQuest = new Quest({
title: title,
campaign: campaign,
xp: amount,
instruction: instructions
});
newQuest
.save()
.then(user => {
req.flash(
'success_msg'
);
// Takes to Dashboard on success
let value = encodeURIComponent('createdQuest')
res.redirect('/dashboard?successRate=' + value);
})
.catch(err => console.log(err));
} catch (err) {
if (err) throw err;
}
}
});
});
// Add XP // Add XP
router.post('/addXP', (req, res, next) => { router.post('/addXP', (req, res, next) => {
const { _id_add, current_xp, amount } = req.body; const { _id_add, current_xp, amount } = req.body;
@@ -59,7 +115,7 @@ router.post('/addXP', (req, res, next) => {
} }
if (amount < 50 && amount > 0 && current_xp < 800) { if (amount < 50 && amount > 0 && current_xp < 800) {
let newXP = current_xp + amount; let newXP = parseInt(current_xp) + parseInt(amount);
if (newXP > 800) { if (newXP > 800) {
newXP = 800; newXP = 800;
} }
+36
View File
@@ -0,0 +1,36 @@
<style>
#back {
position: absolute;
left: 10px;
top: 10px;
}
#div-container {
position: absolute;
left: 300px;
top: 50px;
}
</style>
<script>
// Catch url Parameter
window.onload = function () {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const id = urlParams.get('id');
<% quests.forEach(function (quest) { %>
if('<%= quest._id %>' == id) {
document.getElementById('div-container').innerHTML += '<div id="quest">';
document.getElementById('quest').innerHTML += '<h1 class="title"><%= quest.title %></h1>';
document.getElementById('quest').innerHTML += '<h2 class="title">Campaign: <%= quest.campaign %></h2>'
document.getElementById('quest').innerHTML += '<p class="info">XP: <%= quest.xp %></p>';
document.getElementById('quest').innerHTML += '<p class="info">Expires: <%= quest.expiry %></p>';
document.getElementById('quest').innerHTML += '<h3 class="info">Instructions: <%= quest.instruction %></h3>';
}
<% }) %>
}
</script>
<a id='back' href="/dashboard" class="btn btn-secondary">Back to Dashboard</a>
<!-- Quest container -->
<div id='div-container'></div>
+153 -8
View File
@@ -1,5 +1,23 @@
<!-- Simple Syling for layout --> <!-- Simple Syling for layout -->
<style> <style>
.quests-container {
position: absolute;
width: 650px;
height: 645px;
top: 100px;
left: 450px;
border-style: solid;
border-color: rgba(0, 0, 0, .2);
border-radius: 15px;
background-color: rgba(0, 0, 0, .2);
}
.menu-buttons {
width: 200px;
}
.quest-buttons {
margin-left: 25px;
margin-top: 10px;
}
#myProgress { #myProgress {
position: relative; position: relative;
height: 200px; height: 200px;
@@ -10,7 +28,11 @@
border-radius: 12px; border-radius: 12px;
overflow: hidden; overflow: hidden;
} }
#quest-title {
position: absolute;
left: 720px;
top: 25px;
}
#myBar { #myBar {
position: absolute; position: absolute;
bottom: 0px; bottom: 0px;
@@ -19,11 +41,6 @@
height: 1%; height: 1%;
background-color: #46c7f2; background-color: #46c7f2;
} }
#bug-btn {
position: absolute;
bottom: 60px;
left: 25px;
}
#pro-pic { #pro-pic {
position: absolute; position: absolute;
top: 25px; top: 25px;
@@ -39,7 +56,7 @@
.student-container { .student-container {
position: absolute; position: absolute;
width: 400px; width: 400px;
height: 700px; height: 720px;
top: 25px; top: 25px;
left: 25px; left: 25px;
border: solid #5b94f0 2px; border: solid #5b94f0 2px;
@@ -50,6 +67,42 @@
.content { .content {
margin-left: 25px; margin-left: 25px;
} }
.list-button {
margin-left: 25px;
margin-top: 25px;
}
.quest-box {
margin-top: 15px;
margin-left: 30px;
transition: .2s;
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
li {
font: 200 20px/1.5 Helvetica, Verdana, sans-serif;
border-bottom: 1px solid #ccc;
}
li:last-child {
border: none;
}
li a {
text-decoration: none;
color: #000;
display: block;
width: 200px;
-webkit-transition: font-size 0.3s ease, background-color 0.3s ease;
-moz-transition: font-size 0.3s ease, background-color 0.3s ease;
-o-transition: font-size 0.3s ease, background-color 0.3s ease;
-ms-transition: font-size 0.3s ease, background-color 0.3s ease;
transition: font-size 0.3s ease, background-color 0.3s ease;
}
li a:hover {
font-size: 30px;
background: #f6f6f6;
}
</style> </style>
<div class="student-container"> <div class="student-container">
@@ -78,10 +131,97 @@
<!-- Action Buttons --> <!-- Action Buttons -->
<a href="/users/logout" class="btn btn-secondary">Logout</a> <a href="/users/logout" class="btn btn-secondary">Logout</a>
<button onClick='passData()' class='btn btn-secondary'>Edit</button> <button onClick='passData()' class='btn btn-secondary'>Edit</button>
<a id='bug-btn' href="https://github.com/Braeden57/XP-System/issues" target="_blank" class='btn btn-danger'>Report Bug</a> <a href="https://github.com/Braeden57/XP-System/issues" target="_blank" class='btn btn-danger'>Report Bug</a>
</div> </div>
</div> </div>
<div>
<h1 id="quest-title">Quests</h1>
<div class='quests-container'>
<div class='quest-buttons'>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label onClick="showHTML()" class="menu-buttons btn btn-info active">
<input type="radio" name="options" id="option1" autocomplete="off" checked> HTML
</label>
<label onClick="showCSS()" class="menu-buttons btn btn-info">
<input type="radio" name="options" id="option2" autocomplete="off"> CSS
</label>
<label onClick="showJS()" class="menu-buttons btn btn-info">
<input type="radio" name="options" id="option3" autocomplete="off"> JavaScript
</label>
</div>
</div>
<div class='quests-content'>
<div style="display: none;" id="HTML-Display">
<ul>
<% quests.forEach(function (quest) { %>
<% if(quest.campaign == "HTML") { %>
<!-- Creates Quest Button link -->
<li><button class='list-button btn btn-outline-success mt-2' onclick="redirect('<%= quest._id %>')"><%= quest.title %></button></li>
<% } %>
<% }) %>
</ul>
</div>
<div style="display: none;" id="CSS-Display">
<ul>
<% quests.forEach(function (quest) { %>
<% if(quest.campaign == "CSS") { %>
<!-- Creates Quest Button link -->
<li><button class='list-button btn btn-outline-success mt-2' onclick="redirect('<%= quest._id %>')"><%= quest.title %></button></li>
<% } %>
<% }) %>
</ul>
</div>
<div style="display: none;" id="JS-Display">
<ul>
<% quests.forEach(function (quest) { %>
<% if(quest.campaign == "JS") { %>
<!-- Creates Quest Button link -->
<li><button class='list-button btn btn-outline-success mt-2' onclick="redirect('<%= quest._id %>')"><%= quest.title %></button></li>
<% } %>
<% }) %>
</ul>
</div>
</div>
</div>
</div>
<!-- Quest Display -->
<script>
function showHTML() {
let state = document.getElementById('HTML-Display').style.display;
if (state == "block") {
document.getElementById('HTML-Display').style.display = 'none';
} else {
document.getElementById('JS-Display').style.display = 'none';
document.getElementById('CSS-Display').style.display = 'none';
document.getElementById('HTML-Display').style.display = 'block';
}
}
function showCSS() {
let state = document.getElementById('CSS-Display').style.display;
if (state == "block") {
document.getElementById('CSS-Display').style.display = 'none';
} else {
document.getElementById('HTML-Display').style.display = 'none';
document.getElementById('JS-Display').style.display = 'none';
document.getElementById('CSS-Display').style.display = 'block';
}
}
function showJS() {
let state = document.getElementById('JS-Display').style.display;
if (state == "block") {
document.getElementById('JS-Display').style.display = 'none';
} else {
document.getElementById('HTML-Display').style.display = 'none';
document.getElementById('CSS-Display').style.display = 'none';
document.getElementById('JS-Display').style.display = 'block';
}
}
</script>
<!-- Passing user _id to edit page script --> <!-- Passing user _id to edit page script -->
<script> <script>
function passData() { function passData() {
@@ -160,4 +300,9 @@
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;
function redirect(id) {
let url = '/users/quests?id=' + encodeURIComponent(id);
document.location.href = url;
}
</script> </script>
+250 -156
View File
@@ -5,12 +5,43 @@
display: inline-block; display: inline-block;
} }
.head { .head {
margin-bottom: 100px; position: absolute;
width: 345px;
height: 600px;
top: 25px;
left: 25px;
border: solid #5b94f0 2px;
border-style: solid;
border-radius: 10px;
background-color: rgba(112, 196, 255, .3);
}
.head-content {
position: absolute;
left: 15px;
} }
.teacher-container { .teacher-container {
position: absolute; position: absolute;
width: 300px; width: 300px;
left: 205px; }
.members-container {
position: absolute;
left: 400px;
}
.quests-container {
position: absolute;
left: 800px;
background: rgba(0, 0, 0, .2);
border-radius: 24px;
border-style: solid;
border-color: rgba(0, 0, 0, .2);
}
.quest-content {
margin-left: 15px;
margin-top: 10px;
margin-right: 15px;
}
.quest {
color: #e05f3a;
} }
#pro-pic { #pro-pic {
position: absolute; position: absolute;
@@ -35,14 +66,13 @@
} }
.buttons-container { .buttons-container {
position: absolute; position: absolute;
width: 174px; top: 425px;
height: 500px; right: 180px;
top: 25px; }
right: 25px; .button-content {
border: solid #5b94f0 2px; width: 127px;
border-style: solid; margin-left: 25px;
border-radius: 10px; margin-top: 10px;
background-color: rgba(112, 196, 255, .3);
} }
#edit-btn { #edit-btn {
width: 127px; width: 127px;
@@ -99,9 +129,9 @@
</style> </style>
<!-- Welcome Message & Profile Picture --> <!-- Welcome Message & Profile Picture -->
<h1 class="mt-4">Teacher Dashboard</h1>
<div class='head'> <div class='head'>
<div> <div class='head-content'>
<h1 class="mt-4">Teacher Dashboard</h1>
<div class="teacher-container"> <div class="teacher-container">
<p id='welcome' class="lead mb-3">Welcome <%= user.name %></p> <p id='welcome' class="lead mb-3">Welcome <%= user.name %></p>
<img id='pro-pic' src='data:image/<%=user.image.contentType%>;base64, <img id='pro-pic' src='data:image/<%=user.image.contentType%>;base64,
@@ -111,172 +141,227 @@
<div class="buttons-container"> <div class="buttons-container">
<!-- Action Buttons --> <!-- Action Buttons -->
<a id='logout-btn' href="/users/logout" class="btn btn-outline-info btn-sm">Logout</a> <a href="/users/logout" class="button-content btn btn-outline-info btn-sm">Logout</a>
<button id='edit-btn' onClick='passData()' class='btn btn-outline-info btn-sm'>Edit</button> <button onClick='passData()' class='button-content btn btn-outline-info btn-sm'>Edit</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 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>
</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>
<!-- 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>
<!-- Sets Variables for calculating users data --> <!-- Sets Variables for calculating users data -->
<div> <script>
<script> let xp;
let xp; let currRank;
let currRank; let ranks = [
let ranks = [ {"Digital Noob": 0}, // index 0
{"Digital Noob": 0}, // index 0 {"Digital Novice": 48}, // index 1
{"Digital Novice": 48}, // index 1 {"Digital Novice II": 100}, // index 2
{"Digital Novice II": 100}, // index 2 {"Digital Amature": 148}, // index 3
{"Digital Amature": 148}, // index 3 {"Digital Amature II": 200}, // index 4
{"Digital Amature II": 200}, // index 4 {"Digital Apprentice": 248}, // index 5
{"Digital Apprentice": 248}, // index 5 {"Digital Apprentice II": 300}, // index 6
{"Digital Apprentice II": 300}, // index 6 {"Digital Journeyman": 396}, // index 7
{"Digital Journeyman": 396}, // index 7 {"Digital Journeyman II": 476}, // index 8
{"Digital Journeyman II": 476}, // index 8 {"Digital Journeyman III": 532}, // index 9
{"Digital Journeyman III": 532}, // index 9 {"Digital Crafter": 580}, // index 10
{"Digital Crafter": 580}, // index 10 {"Expert Digital Crafter": 648}, // index 11
{"Expert Digital Crafter": 648}, // index 11 {"Master Digital Crafter": 800} // index 12
{"Master Digital Crafter": 800} // index 12 ]
] 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]
// Students should't be on this page sooooo... // Students should't be on this page sooooo...
console.log("Students Shouldnt be here"); console.log("Students Shouldnt be here");
</script> </script>
<!-- Alert container --> <!-- Alert container -->
<div id='div-container'></div> <div id='div-container'></div>
<!-- Modal --> <!-- Add XP 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">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel"</h5> <h5 class="modal-title" id="exampleModalLabel"</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">&times;</span> <span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form action="/users/addXP" method="POST">
<div>
<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>
</div>
<div>
<p>Minimum: 1</p>
<p>Maximum: 50</p>
</div>
<div class="form-group">
<label for="amount">Amount</label>
<input
id="amount"
name="amount"
type="number"
min="1"
max="50"
value=""
class="form-control"
>
</div>
<button type="submit" class="btn btn-primary">
Add XP
</button> </button>
</div> </form>
<div class="modal-body"> </div>
<form action="/users/addXP" method="POST"> <div class="modal-footer">
<div> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<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>
</div>
<div>
<p>Minimum: 1</p>
<p>Maximum: 50</p>
</div>
<div class="form-group">
<label for="amount">Amount</label>
<input
id="amount"
name="amount"
type="number"
min="1"
max="50"
value=""
class="form-control"
>
</div>
<button type="submit" class="btn btn-primary">
Add XP
</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
<script> <!-- Create Quest Modal -->
// Creates unique ID <div class="modal fade" id="createQuest" tabindex="-1" role="dialog" aria-labelledby="createQuestLabel" 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="createQuestLabel"</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">&times;</span>
} </button>
return result; </div>
<div class="modal-body">
<form action="/users/createQuest" method="POST">
<div>
<label for="title">Title</label>
<input
id="title"
name="title"
type="text"
value=""
class="form-control"
required
>
</div>
<div class="form-group">
<label for="amount">Amount</label>
<input
id="amount"
name="amount"
type="number"
min="1"
max="50"
value=""
class="form-control"
required
>
</div>
<div>
<label for="instructions">Instructions</label>
<textarea
id="instructions"
name="instructions"
value=""
class="form-control"
required
></textarea>
</div>
<div>
<label for="campaign">Campaign</label>
<select required name="campaign" id="campaign">
<option value="">--Please choose an option--</option>
<option value="HTML">HTML</option>
<option value="CSS">CSS</option>
<option value="JS">JavaScript</option>
</select>
</div>
<button type="submit" class="btn btn-primary">
Create Quest
</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script>
// 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;
}
// Create Div // Create Div
function createDiv(type, message) { function createDiv(type, message) {
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;" 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">&times;</span>';
document.getElementById('new-div-'+id).style.display = "block";
} }
if (type == 'message') {
// // Check amount document.getElementById('div-container').innerHTML += '<div id="new-div-'+id+'" style="display: none;" class="alert alert-info alert-dismissible fade show" role="alert">';
// function amountCheck(_id) {
// const amount = document.getElementById("amount").value;
// if (amount > 50) {
// createDiv('error', "Can't add more than 50 XP");
// }
// if (amount == 0 || amount < 0) {
// createDiv('error', "XP Must be more than 0");
// }
//
// if (amount > 0 && amount < 50) {
//
// createDiv('message', "Succesfully added XP");
// }
// }
// 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);
}
} }
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">&times;</span>';
document.getElementById('new-div-'+id).style.display = "block";
}
// Catching url Parameters // Pass name to Modal
window.onload = function () { function passName(name, xp, member_id) {
const queryString = window.location.search; if (xp < 800) {
const urlParams = new URLSearchParams(queryString); document.getElementById("exampleModalLabel").innerHTML = "Give " + name + " XP";
const successRate = urlParams.get('successRate') document.getElementById("_id_add").value = member_id;
if(successRate == 'addXP > 50') { document.getElementById("current_xp").value = xp;
createDiv('error', "Can't add more than 50 XP") $("#exampleModal").modal()
}
if(successRate == 'addXP <= 0') {
createDiv('error', "XP Must be Greater than 0");
}
if(parseInt(successRate) > 0 && parseInt(successRate) < 50 || parseInt(successRate) == 50) {
createDiv('message', "Gave " + successRate + "XP to a Student");
}
} }
</script> if (xp >= 800) {
// Construct and show Max XP Alert
message = name + ' has reached max XP!';
createDiv('message', message);
}
}
// 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 && parseInt(successRate) < 50 || parseInt(successRate) == 50) {
createDiv('message', "Gave " + successRate + "XP to a Student");
}
if(successRate == 'createdQuest') {
createDiv('message', "Successfully Created Quest");
}
}
</script>
<div class="members-container">
<!-- List of all site students (not teachers) --> <!-- List of all site students (not teachers) -->
<h2>Studen Members</h2> <h2>Studen Members</h2>
<div class='members'> <div class='members'>
@@ -342,6 +427,15 @@
</div> </div>
</div> </div>
<div class="quests-container">
<!-- List of Quests -->
<div class='quest-content'>
<h2>All Quests</h2>
<% quests.forEach(function (quest) { %>
<p class='quest'><%= quest.title %></p>
<% }) %>
</div>
<!-- Script for show/hide user profile data --> <!-- Script for show/hide user profile data -->
<script> <script>
function openProfile(id) { function openProfile(id) {