Merge pull request #4 from Braeden57/final-update

Final update
This commit is contained in:
Braeden Sowinski authored and GitHub committed 2021-01-25 08:59:22 -08:00
commit bb4c558dc3
7 files changed
+109 -33

No files matched your search

+20 -10
View File
@@ -1,20 +1,22 @@
# XP-System # XP-System
School Project This school project is for my teacher to have students log in and check out their XP and assignments.
This school project is for my teacher to have students
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. This website application is not available online, this is just a locally run website at our school.
To create a teacher, it must be done by a site admin. You'll need to create the site admin in the To create a teacher, it must be done by a site admin.
database in a collection called `users` and set insert a document formatted as shown:
` You'll need to create the site admin in the database in a collection called users,
{ and insert a document via MongoDB Compass. Format the document as shown:
"_id": your generated id, `{
"role": "Admin", "role": "Admin",
"name": your name, "name": your name,
"email": your email, "email": your email,
"password": your encrypted password "password": your encrypted password
} }`
`
Replace `your name` with the name you specify, `your email` with the email you would like to use to login,
and replace `your encrypted password` with your [Encrypted Password](#Encrypting Your Password)
The ID for your admin document should be auto generated by MongoDB Compass when you `insert` the document.
### Requirements : ### Requirements :
1. [Node.js](https://nodejs.org/en/) 1. [Node.js](https://nodejs.org/en/)
@@ -28,7 +30,15 @@ database in a collection called `users` and set insert a document formatted as s
1. Run `npm start` to boot up server. 1. Run `npm start` to boot up server.
1. Go to http://localhost:8080. 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.
### Setting up MongoDB
1. Install mongodb and follow the setup steps.
1. [Step by step instructions](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows)
### 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.
1. You can use MongoDB compass app to view the db and edit any information stored. 1. You can use MongoDB compass app to view the db and edit any information stored.
2. Or connect it to an external db by changing the DB_URI in the `.env` to your db key. 2. Or connect it to an external db by changing the DB_URI in the `.env` to your db key.
### Encrypting Your Password
1. To encrypt your password while creating the admin account. Go into the `config` folder,
1. follow the instructions in encrypt.js and run encrypt.js via node `node encrypt.js`
+13
View File
@@ -0,0 +1,13 @@
const bcrypt = require('bcryptjs');
// Set `password` as the password you will use
// Then Run this script and copy the output as it is your encrypted password
let password = "APPLEZ57";
// Encrypts password and returns encrypted password
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(password, salt, (err, hash) => {
if (err) throw err;
console.log(hash);
});
});
+3 -3
View File
@@ -224,7 +224,7 @@ router.post('/addXP', (req, res, next) => {
// Edit // Edit
router.post('/edit', upload.single('image'), (req, res, next) => { router.post('/edit', upload.single('image'), (req, res, next) => {
// Passes image path to defaultImage Model // Passes image path to defaultImage Model
imagePath = __dirname + '/uploads/default-image'; let imagePath = __dirname + '/uploads/default-image';
module.exports = { module.exports = {
defaultPath: imagePath defaultPath: imagePath
} }
@@ -426,7 +426,7 @@ router.post('/edit', upload.single('image'), (req, res, next) => {
// Register Teacher // Register Teacher
router.post('/registerTeacher', upload.single('image'), (req, res, next) => { router.post('/registerTeacher', upload.single('image'), (req, res, next) => {
// Passes image path to defaultImage Model // Passes image path to defaultImage Model
imagePath = __dirname + '/uploads/default-image'; let imagePath = __dirname + '/uploads/default-image';
module.exports = { module.exports = {
defaultPath: imagePath defaultPath: imagePath
} }
@@ -565,7 +565,7 @@ router.post('/registerTeacher', upload.single('image'), (req, res, next) => {
// Register // Register
router.post('/register', upload.single('image'), (req, res, next) => { router.post('/register', upload.single('image'), (req, res, next) => {
// Passes image path to defaultImage Model // Passes image path to defaultImage Model
imagePath = __dirname + '/uploads/default-image'; let imagePath = __dirname + '/uploads/default-image';
module.exports = { module.exports = {
defaultPath: imagePath defaultPath: imagePath
} }
+1
View File
@@ -1,3 +1,4 @@
<!-- Shows user specific Dashboard --> <!-- Shows user specific Dashboard -->
<% if (user.role == "Admin") { %> <% if (user.role == "Admin") { %>
<% include admin %> <% include admin %>
+5 -1
View File
@@ -17,6 +17,9 @@
const queryString = window.location.search; const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString); const urlParams = new URLSearchParams(queryString);
const id = urlParams.get('id'); const id = urlParams.get('id');
<% if(quests.length == 0) { %>
document.getElementById('div-container').innerHTML = "<h2>Uh oh, theres no quests :(</h2>";
<% } else if(quests.length > 0) { %>
<% quests.forEach(function (quest) { %> <% quests.forEach(function (quest) { %>
if('<%= quest._id %>' == id) { if('<%= quest._id %>' == id) {
document.getElementById('div-container').innerHTML += '<div id="quest">'; document.getElementById('div-container').innerHTML += '<div id="quest">';
@@ -24,9 +27,10 @@
document.getElementById('quest').innerHTML += '<h2 class="title">Campaign: <%= quest.campaign %></h2>' 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">XP: <%= quest.xp %></p>';
document.getElementById('quest').innerHTML += '<p class="info">Expires: <%= quest.expiry %></p>'; document.getElementById('quest').innerHTML += '<p class="info">Expires: <%= quest.expiry %></p>';
document.getElementById('quest').innerHTML += '<h3 class="info">Instructions: <%= quest.instruction %></h3>'; document.getElementById('quest').innerHTML += `<h3 class="info">Instructions: <%= quest.instruction %></h3>`;
} }
<% }) %> <% }) %>
<% } %>
} }
</script> </script>
+26 -18
View File
@@ -1,4 +1,4 @@
<!-- Simple Syling for layout --> <!-- Simple Styling for layout -->
<style> <style>
.quests-container { .quests-container {
position: absolute; position: absolute;
@@ -201,19 +201,25 @@
let percent; 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]
window.onload = function() {
calculate();
}
let xp = <%= user.xp %>; let xp = <%= user.xp %>;
window.onload = function() {
calculate()
}
// Passing user _id to edit page script // Passing user _id to edit page script
function passData() { function passData() {
let url = '/users/edit?name=' + encodeURIComponent('<%= user._id %>'); let url = '/users/edit?name=' + encodeURIComponent('<%= user._id %>');
document.location.href = url; document.location.href = url;
} }
// Redirects to quest page to see quest
function redirect(id) {
let url = '/users/quests?id=' + encodeURIComponent(id);
document.location.href = url;
}
// Creates a list of Quest Objects
let allQuests = []; let allQuests = [];
let questObj; let questObj;
<% quests.forEach(function (quest) { %> <% quests.forEach(function (quest) { %>
@@ -222,23 +228,25 @@
title: "<%= quest.title %>", title: "<%= quest.title %>",
expiry: "<%= quest.expiry %>", expiry: "<%= quest.expiry %>",
xp: <%= quest.xp %>, xp: <%= quest.xp %>,
instruction: "<%= quest.instruction %>", instruction: `<%= quest.instruction %>`,
referenceClass: "<%= quest.referenceClass %>", referenceClass: "<%= quest.referenceClass %>",
campaign: "<%= quest.campaign %>", campaign: "<%= quest.campaign %>",
}; };
allQuests.push(questObj); allQuests.push(questObj);
<% }) %> <% }) %>
// Shows quests only related to selected class
function showQuest() { function showQuest() {
document.getElementById('class-quests').innerHTML = ""; document.getElementById('class-quests').innerHTML = "";
let className = document.getElementById('classes').value; let className = document.getElementById('classes').value;
for(let i = 0; i < allQuests.length; i++) { for(let i = 0; i < allQuests.length; i++) {
if (allQuests[i]["referenceClass"] == className) { if (allQuests[i]["referenceClass"] == className) {
document.getElementById('class-quests').innerHTML += `<li><button class='list-button btn btn-outline-success mt-2' onclick="redirect(${allQuests[i]["_id"]})">${allQuests[i]["title"]}</button></li>`; document.getElementById('class-quests').innerHTML += `<li><button class="list-button btn btn-outline-success mt-2" onclick="redirect('${allQuests[i]["_id"]}')">${allQuests[i]["title"]}</button></li>`;
} }
} }
} }
// Global Ranks + RankXP
let ranks = [ let ranks = [
{"Digital Noob": 0}, // index 0 {"Digital Noob": 0}, // index 0
{"Digital Novice": 48}, // index 1 {"Digital Novice": 48}, // index 1
@@ -290,7 +298,8 @@
} }
} }
} }
} else { } else if(xp == 800 || xp > 800) {
console.log('You are a coding master!');
// Display data for max level // Display data for max level
document.getElementById('percent').innerHTML = '800|800'; document.getElementById('percent').innerHTML = '800|800';
currRank = "Master Digital Crafter"; currRank = "Master Digital Crafter";
@@ -306,17 +315,19 @@
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 // reCalculate function recaculates all the data with oldXP + addxp to newxp
function reCalculate(addXP) { function reCalculate(addXP) {
let newXP = xp + parseInt(addXP); let newXP = xp + parseInt(addXP);
console.log(newXP);
// Get current rank // Get current rank
if (newXP < 800) { if (newXP < 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 (newXP >= ranks[i][rank] && newXP < ranks[nextIndex][nextRank]) { if (newXP >= ranks[i][rank] && newXP < ranks[nextIndex][nextRank]) {
// Sets new temporary variables
let newCurrRank = rank; let newCurrRank = rank;
let newCurrRankXP = ranks[i][rank] let newCurrRankXP = ranks[i][rank]
// Calculate xp till next Rank // Calculate xp till next Rank
@@ -324,6 +335,7 @@
i++; i++;
let newNextRank = ranks[i]; let newNextRank = ranks[i];
for (let r in newNextRank) { for (let r in newNextRank) {
// Initialize new temporary variables
let newRankUp = r; let newRankUp = r;
let newPercent; let newPercent;
let diff = addXP; let diff = addXP;
@@ -337,6 +349,7 @@
let diffPercent=(diff/total)*100; let diffPercent=(diff/total)*100;
newRemain = remain - diff; newRemain = remain - diff;
newTotal = total; newTotal = total;
// Update Progress Bar
let elem = document.getElementById("myBar"); let elem = document.getElementById("myBar");
newPercent = percent + diffPercent; newPercent = percent + diffPercent;
elem.style.height = newPercent + "%"; elem.style.height = newPercent + "%";
@@ -356,7 +369,7 @@
let elem = document.getElementById("myBar"); let elem = document.getElementById("myBar");
newPercent = Math.round((newProgress/newTotal)*100); newPercent = Math.round((newProgress/newTotal)*100);
elem.style.height = newPercent + "%"; elem.style.height = newPercent + "%";
// Adds 1 to progress till progress == total // Sets progress to new Progress
let progressDiff = total-progress; let progressDiff = total-progress;
document.getElementById('percent').innerHTML = newProgress + "|" + newTotal; document.getElementById('percent').innerHTML = newProgress + "|" + newTotal;
// Update Display with new Data // Update Display with new Data
@@ -381,6 +394,7 @@
} }
} }
} else { } else {
console.log('You are a coding master!')
// Display data for max level // Display data for max level
document.getElementById('percent').innerHTML = '800|800'; document.getElementById('percent').innerHTML = '800|800';
currRank = "Master Digital Crafter"; currRank = "Master Digital Crafter";
@@ -396,10 +410,4 @@
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>
+41 -1
View File
@@ -380,6 +380,33 @@
</div> </div>
</div> </div>
<!-- Class Details Modal -->
<div class="modal fade" id="classDetails" tabindex="-1" role="dialog" aria-labelledby="classDetailsLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="classDetailsLabel">Class Details</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<label>Name:</label>
<h2 id="classDetailName"></h2>
<br>
<label>Grade:</label>
<h3 id="classDetailGrade"></h3>
<br>
<label>Description:</label>
<p id="classDetailDesc"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="members-container"> <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>
@@ -462,11 +489,13 @@
<!-- List of Courses --> <!-- List of Courses -->
<div class='course-content'> <div class='course-content'>
<h2>All Courses</h2> <h2>All Courses</h2>
<ul>
<% courses.forEach(function (course) { %> <% courses.forEach(function (course) { %>
<div class='course'> <div class='course'>
<p><%= course.name %>: Grade <%= course.grade %></p> <li><button class="btn btn-outline-success mt-2" onclick="showDetails('<%= course._id %>')"><%= course.name %>: <%= course.grade %></button></li>
</div> </div>
<% }) %> <% }) %>
</ul>
</div> </div>
</div> </div>
@@ -474,6 +503,17 @@
<script> <script>
let socket = io.connect('http://localhost:5000'); let socket = io.connect('http://localhost:5000');
function showDetails(id) {
<% courses.forEach(function(course) { %>
if('<%=course._id%>' == id) {
document.getElementById('classDetailName').innerHTML = '<%= course.name %>';
document.getElementById('classDetailGrade').innerHTML = '<%= course.grade %>';
document.getElementById('classDetailDesc').innerHTML = '<%= course.description %>';
$("#classDetails").modal();
}
<% }) %>
}
// Creates unique ID // Creates unique ID
function makeid(length) { function makeid(length) {
var result = ''; var result = '';