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
+111 -35

No files matched your search

+20 -10
View File
@@ -1,20 +1,22 @@
# 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.
To create a teacher, it must be done by a site admin. You'll need to create the site admin in the
database in a collection called `users` and set insert a document formatted as shown:
`
{
"_id": your generated id,
To create a teacher, it must be done by a site admin.
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:
`{
"role": "Admin",
"name": your name,
"email": your email,
"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 :
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. 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
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.
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
router.post('/edit', upload.single('image'), (req, res, next) => {
// Passes image path to defaultImage Model
imagePath = __dirname + '/uploads/default-image';
let imagePath = __dirname + '/uploads/default-image';
module.exports = {
defaultPath: imagePath
}
@@ -426,7 +426,7 @@ router.post('/edit', upload.single('image'), (req, res, next) => {
// Register Teacher
router.post('/registerTeacher', upload.single('image'), (req, res, next) => {
// Passes image path to defaultImage Model
imagePath = __dirname + '/uploads/default-image';
let imagePath = __dirname + '/uploads/default-image';
module.exports = {
defaultPath: imagePath
}
@@ -565,7 +565,7 @@ router.post('/registerTeacher', upload.single('image'), (req, res, next) => {
// Register
router.post('/register', upload.single('image'), (req, res, next) => {
// Passes image path to defaultImage Model
imagePath = __dirname + '/uploads/default-image';
let imagePath = __dirname + '/uploads/default-image';
module.exports = {
defaultPath: imagePath
}
+1
View File
@@ -1,3 +1,4 @@
<!-- Shows user specific Dashboard -->
<% if (user.role == "Admin") { %>
<% include admin %>
+5 -1
View File
@@ -17,6 +17,9 @@
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
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) { %>
if('<%= quest._id %>' == id) {
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 += '<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>';
document.getElementById('quest').innerHTML += `<h3 class="info">Instructions: <%= quest.instruction %></h3>`;
}
<% }) %>
<% } %>
}
</script>
+28 -20
View File
@@ -1,4 +1,4 @@
<!-- Simple Syling for layout -->
<!-- Simple Styling for layout -->
<style>
.quests-container {
position: absolute;
@@ -166,7 +166,7 @@
<h1 id="quest-title">Courses</h1>
<div class='quests-container'>
<div class='quest-buttons'>
<% if(courses.length == 0) {%>
<% if(courses.length == 0) { %>
<h2 id="error-noClass"">There are no classes yet :(</h2>
<% } else if(courses.length > 0) { %>
<select id="classes" onchange="showQuest()" class="form-control" style="margin-right: 5px;">
@@ -186,7 +186,7 @@
let socket = io.connect('http://localhost:5000');
socket.on("added:xp", function(data) {
if(data.userID == '<%=user._id%>') {
if(data.userID == '<%= user._id %>') {
reCalculate(data.addXP);
}
});
@@ -201,19 +201,25 @@
let percent;
let indexes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12]
window.onload = function() {
calculate();
}
let xp = <%= user.xp %>;
window.onload = function() {
calculate()
}
// Passing user _id to edit page script
function passData() {
let url = '/users/edit?name=' + encodeURIComponent('<%= user._id %>');
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 questObj;
<% quests.forEach(function (quest) { %>
@@ -222,23 +228,25 @@
title: "<%= quest.title %>",
expiry: "<%= quest.expiry %>",
xp: <%= quest.xp %>,
instruction: "<%= quest.instruction %>",
instruction: `<%= quest.instruction %>`,
referenceClass: "<%= quest.referenceClass %>",
campaign: "<%= quest.campaign %>",
};
allQuests.push(questObj);
<% }) %>
// Shows quests only related to selected class
function showQuest() {
document.getElementById('class-quests').innerHTML = "";
let className = document.getElementById('classes').value;
for(let i = 0; i < allQuests.length; i++) {
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 = [
{"Digital Noob": 0}, // index 0
{"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
document.getElementById('percent').innerHTML = '800|800';
currRank = "Master Digital Crafter";
@@ -306,17 +315,19 @@
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) {
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];
// Gets rank after current rank
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]) {
// Sets new temporary variables
let newCurrRank = rank;
let newCurrRankXP = ranks[i][rank]
// Calculate xp till next Rank
@@ -324,6 +335,7 @@
i++;
let newNextRank = ranks[i];
for (let r in newNextRank) {
// Initialize new temporary variables
let newRankUp = r;
let newPercent;
let diff = addXP;
@@ -337,6 +349,7 @@
let diffPercent=(diff/total)*100;
newRemain = remain - diff;
newTotal = total;
// Update Progress Bar
let elem = document.getElementById("myBar");
newPercent = percent + diffPercent;
elem.style.height = newPercent + "%";
@@ -356,7 +369,7 @@
let elem = document.getElementById("myBar");
newPercent = Math.round((newProgress/newTotal)*100);
elem.style.height = newPercent + "%";
// Adds 1 to progress till progress == total
// Sets progress to new Progress
let progressDiff = total-progress;
document.getElementById('percent').innerHTML = newProgress + "|" + newTotal;
// Update Display with new Data
@@ -381,6 +394,7 @@
}
}
} else {
console.log('You are a coding master!')
// Display data for max level
document.getElementById('percent').innerHTML = '800|800';
currRank = "Master Digital Crafter";
@@ -396,10 +410,4 @@
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>
+41 -1
View File
@@ -380,6 +380,33 @@
</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">
<!-- List of all site students (not teachers) -->
<h2>Studen Members</h2>
@@ -462,11 +489,13 @@
<!-- List of Courses -->
<div class='course-content'>
<h2>All Courses</h2>
<ul>
<% courses.forEach(function (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>
<% }) %>
</ul>
</div>
</div>
@@ -474,6 +503,17 @@
<script>
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
function makeid(length) {
var result = '';