v1.0
This commit is contained in:
commit
d9f266b720
19
.gitignore
vendored
Normal file
19
.gitignore
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
node_modules/**/*
|
||||
.expo/*
|
||||
npm-debug.*
|
||||
*.jks
|
||||
*.p8
|
||||
*.p12
|
||||
*.key
|
||||
*.mobileprovision
|
||||
*.orig.*
|
||||
web-build/
|
||||
web-report/
|
||||
.idea/*
|
||||
lettalk-release-key.keystore
|
||||
*.iml
|
||||
*.pem
|
||||
trash
|
||||
*.env
|
||||
# macOS
|
||||
.DS_Store
|
0
db/posts.db
Normal file
0
db/posts.db
Normal file
0
db/sessions.db
Normal file
0
db/sessions.db
Normal file
1
db/users.db
Normal file
1
db/users.db
Normal file
@ -0,0 +1 @@
|
||||
{"email":"admin@ghd.de","username":"admin","password":"$2b$10$30zu4TwSjMdjmnGQ.Nr6C./Tu71kEhlUHkHso2bnkKkn7Pm2q.u3e","role":"admin","_id":"VxsdGrHioVlUga4q"}
|
66
init.setup
Normal file
66
init.setup
Normal file
@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
|
||||
#update sytem
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y upgrade
|
||||
|
||||
#enable and start ssh
|
||||
sudo systemctl enable ssh
|
||||
sudo systemctl start ssh
|
||||
|
||||
#install remote desktop
|
||||
sudo apt-get -y install xrdp
|
||||
|
||||
#install nodejs
|
||||
sudo apt-get -y install nodejs
|
||||
|
||||
#install npm
|
||||
sudo apt-get -y install npm
|
||||
|
||||
#install firefox
|
||||
sudo apt-get -y install firefox-esr
|
||||
|
||||
cd `dirname $0`
|
||||
echo "`dirname $0`"
|
||||
#get correct node modules
|
||||
|
||||
rm -rf node_modules
|
||||
npm install express
|
||||
npm install bcrypt
|
||||
npm install nedb
|
||||
npm install express-session
|
||||
npm install nedb-session-store
|
||||
|
||||
|
||||
#add server.start to autostart if not found
|
||||
find="`grep server.start /etc/rc.local`"
|
||||
if [ "$find" = "" ]
|
||||
then
|
||||
echo "adding server startup to /etc/rc.local"
|
||||
cp /etc/rc.local "`pwd`"
|
||||
sed -i '$d' rc.local
|
||||
echo "`pwd`/server.start" >> rc.local
|
||||
echo "exit 0" >> rc.local
|
||||
sudo mv rc.local /etc/rc.local
|
||||
else
|
||||
echo "server startup already in /etc/rc.local"
|
||||
fi
|
||||
|
||||
#add firefox start in kiosk mode after logged in
|
||||
find="`grep firefox ~/.profile`"
|
||||
if [ "$find" = "" ]
|
||||
then
|
||||
echo "adding firefox start to ~/.profile"
|
||||
echo "firefox --kiosk http://localhost:8080/info &" >> ~/.profile
|
||||
else
|
||||
echo "firefox start already found in ~/.profile"
|
||||
fi
|
||||
|
||||
sudo chmod +x server.start
|
||||
|
||||
echo "network/mac adress:`hostname -I`"
|
||||
|
||||
#system restart
|
||||
echo "System will restart in 10s. ^C to cancel"
|
||||
sleep 10
|
||||
sudo reboot -h now
|
1010
package-lock.json
generated
Normal file
1010
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
package.json
Normal file
14
package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "NodeHelp",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.19.0",
|
||||
"express": "^4.17.1",
|
||||
"nedb": "^1.8.0",
|
||||
"nedb-session-store": "^1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bcrypt": "^5.0.0",
|
||||
"express-session": "^1.17.1"
|
||||
}
|
||||
}
|
61
public/admin-login.html
Normal file
61
public/admin-login.html
Normal file
@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Admin-Page</title>
|
||||
<link rel="stylesheet" text="text/css" href="styles.css">
|
||||
|
||||
<script src="admin.js"></script>
|
||||
<!--Font Awesome Icons CDN-->
|
||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class=main>
|
||||
<div class="container user-container">
|
||||
<div class="header">
|
||||
<h1>Adminseite</h1>
|
||||
</div>
|
||||
<div class="ButtonRow">
|
||||
<button class="logoutButton" id="lgoBtn">Logout</button>
|
||||
<div class="rightButtons">
|
||||
<button class="manageButton" id="mngBtn">Manage Posts</button>
|
||||
|
||||
<button data-popup-target="#addPopup" id="addBtn">+</button>
|
||||
<div class="popup" id="addPopup">
|
||||
<div class="popup-header">
|
||||
<div class="title">Registration Form</div>
|
||||
<button data-close-btn class="close-btn">×</button>
|
||||
</div>
|
||||
<div class="popup-body">
|
||||
<form class="" id="formNewUser" method="POST">
|
||||
<div class="regSection">
|
||||
<input type="email" id="email" required placeholder="e-Mail">
|
||||
</div>
|
||||
<div class="regSection">
|
||||
<input type="text" id="username" required placeholder="Username">
|
||||
</div>
|
||||
<div class="ButtonRow">
|
||||
<button type="submit" value="Create" id="submit">
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="" id="overlay"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table" id="table">
|
||||
</div>
|
||||
<div class="ButtonRow">
|
||||
<button class="logoutButton" id="changePwBtn">Change Password</button>
|
||||
<div class="rightButtons">
|
||||
<button class="icon-backward , backButton" id="pageDown"></button>
|
||||
<button class="icon-forward , nextButton" id="pageUp"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
189
public/admin.js
Normal file
189
public/admin.js
Normal file
@ -0,0 +1,189 @@
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
var form = document.getElementById("formNewUser");
|
||||
form.addEventListener("submit", function(e){
|
||||
e.preventDefault();
|
||||
console.log("Sending Formular")
|
||||
async function register(){
|
||||
var email = document.getElementById("email").value;
|
||||
var username = document.getElementById("username").value;
|
||||
var bodyContent = {email:email, username:username};
|
||||
var response = await fetch("/newmod", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify(bodyContent)
|
||||
});
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
loadMods();
|
||||
}
|
||||
register();
|
||||
});
|
||||
|
||||
document.getElementById("changePwBtn").onclick = function(){
|
||||
window.location = "/new-password";
|
||||
}
|
||||
|
||||
/*changin page*/
|
||||
var pageUp = document.getElementById("pageUp");
|
||||
var pageDown = document.getElementById("pageDown");
|
||||
|
||||
pageUp.addEventListener("click", () => {
|
||||
if(maxPages > currentPage+1) {
|
||||
currentPage++;
|
||||
loadMods();
|
||||
}
|
||||
});
|
||||
|
||||
pageDown.addEventListener("click", () => {
|
||||
if(currentPage > 0){
|
||||
currentPage--;
|
||||
|
||||
loadMods();
|
||||
}
|
||||
});
|
||||
|
||||
/*logout*/
|
||||
var lgoBtn = document.getElementById("lgoBtn");
|
||||
lgoBtn.addEventListener("click", () => {
|
||||
window.location = "/logout";
|
||||
});
|
||||
|
||||
var maxPages;
|
||||
var currentPage = 0;
|
||||
var maxDisplayed = 8;
|
||||
async function loadMods(){
|
||||
var response = await fetch("/getmods", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
}
|
||||
})
|
||||
var data = await response.json();
|
||||
try{
|
||||
showMods(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed)));
|
||||
console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed)));
|
||||
maxPages = data.users.length / 8;
|
||||
console.log(maxPages, currentPage+1)
|
||||
}catch(error){
|
||||
document.getElementById("table").innerHTML = ""; //empty table
|
||||
}
|
||||
};
|
||||
loadMods();
|
||||
|
||||
function showMods(pdata){
|
||||
document.getElementById("table").innerHTML = ""; //empty table
|
||||
var container = document.getElementById("table"); //insert in table
|
||||
pdata.forEach(element => {
|
||||
var row = document.createElement("div");
|
||||
var status;
|
||||
var susbuttonstate;
|
||||
if(element.suspended) {
|
||||
status = "suspended"
|
||||
susbuttonstate = "icon-pause"
|
||||
} else {
|
||||
status = "notSuspended"
|
||||
susbuttonstate = "icon-play"
|
||||
}
|
||||
row.classList.add("row");
|
||||
row.innerHTML = `
|
||||
<div class="col-left">
|
||||
<h2>${element.username}</h2>
|
||||
</div>
|
||||
<div class="col-right">
|
||||
<button class="${status} susButton" data-username="${element.username}">
|
||||
<i class="${susbuttonstate} , icon"></i>
|
||||
</button>
|
||||
<button class="remButton" data-username="${element.username}">
|
||||
<i class="icon-trash , icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
container.appendChild(row)
|
||||
});
|
||||
}
|
||||
|
||||
async function toggleSus(pun){
|
||||
var response = await fetch("/toggleSus", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify({username:pun})
|
||||
})
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
if(data.suc || !data.suc){
|
||||
loadMods();
|
||||
}
|
||||
};
|
||||
|
||||
async function deleteMod(username){
|
||||
var response = await fetch("/deleteMod", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify({username:username})
|
||||
})
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
if(data.suc || !data.suc){
|
||||
loadMods();
|
||||
}
|
||||
};
|
||||
|
||||
var mngBtn = document.getElementById("mngBtn");
|
||||
mngBtn.addEventListener("click", () => {
|
||||
window.location = "/manage-posts";
|
||||
});
|
||||
|
||||
|
||||
document.addEventListener("click", function(e){
|
||||
if(e.target && e.target.classList.contains("susButton")){
|
||||
var un = e.target.getAttribute("data-username");
|
||||
toggleSus(un);
|
||||
}else if(e.target && e.target.classList.contains("remButton")){
|
||||
var username = e.target.getAttribute("data-username");
|
||||
deleteMod(username);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
/*-----New User Popup-----*/
|
||||
const openPopupBtns = document.querySelectorAll("[data-popup-target]");
|
||||
const closePopupBtns = document.querySelectorAll("[data-close-btn]");
|
||||
const overlay = document.getElementById("overlay");
|
||||
|
||||
openPopupBtns.forEach(btn => {
|
||||
btn.addEventListener("click", () => {
|
||||
const popup = document.querySelector(btn.dataset.popupTarget);
|
||||
openPopup(popup);
|
||||
})
|
||||
});
|
||||
|
||||
closePopupBtns.forEach(btn => {
|
||||
btn.addEventListener("click", () => {
|
||||
const popup = btn.closest(".popup")
|
||||
closePopup(popup);
|
||||
})
|
||||
});
|
||||
|
||||
function openPopup(popup) {
|
||||
if (popup == null) return
|
||||
popup.classList.add("active");
|
||||
overlay.classList.add("active");
|
||||
}
|
||||
|
||||
function closePopup(popup) {
|
||||
if (popup == null) return
|
||||
popup.classList.remove("active");
|
||||
overlay.classList.remove("active");
|
||||
}
|
||||
|
||||
});
|
37
public/change-pw.html
Normal file
37
public/change-pw.html
Normal file
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=2.0">
|
||||
<title>Change Password</title>
|
||||
<link rel="stylesheet" text="text/css" href="styles.css">
|
||||
<script src="change-pw.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>Change Password</h1>
|
||||
</div>
|
||||
<form name="login" method="post" id="loginform">
|
||||
<div class="datasec">
|
||||
<input class="password" type="password" name="password" id="old_pw" required placeholder="Old Password">
|
||||
</div>
|
||||
<div class="datasec">
|
||||
<input class="password" type="password" name="password" id="new_pw_1" required placeholder="New Password">
|
||||
</div>
|
||||
<div class="datasec">
|
||||
<input class="password" type="password" name="password" id="new_pw_2" required placeholder="Confirm Password">
|
||||
</div>
|
||||
<div class="buttons-container">
|
||||
<button class="button"
|
||||
type="submit"
|
||||
name="submit">
|
||||
<span id="loginText">Change Password</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
30
public/change-pw.js
Normal file
30
public/change-pw.js
Normal file
@ -0,0 +1,30 @@
|
||||
//write code in next section
|
||||
//will run when DOM is loaded
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
var form = document.getElementById("loginform");
|
||||
async function login() {
|
||||
var old_pw = document.getElementById("old_pw").value;
|
||||
var new_pw_1 = document.getElementById("new_pw_1").value;
|
||||
var new_pw_2 = document.getElementById("new_pw_2").value;
|
||||
|
||||
var body = {old_password:old_pw, new_password_1:new_pw_1, new_password_2:new_pw_2};
|
||||
var response = await fetch("/changepw", {
|
||||
method:"POST",
|
||||
headers:{
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify(body)
|
||||
})
|
||||
var data = await response.json();
|
||||
console.log("Data: ");
|
||||
console.log(data);
|
||||
if(data.suc){
|
||||
window.location = "/main"
|
||||
}
|
||||
}
|
||||
form.addEventListener("submit", function(e){
|
||||
e.preventDefault();
|
||||
login();
|
||||
});
|
||||
});
|
37
public/index.html
Normal file
37
public/index.html
Normal file
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=2.0">
|
||||
<title>Login</title>
|
||||
<link rel="stylesheet" text="text/css" href="styles.css">
|
||||
<script src="login.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>Login</h1>
|
||||
</div>
|
||||
<form name="login" method="post" id="loginform">
|
||||
<div class="datasec">
|
||||
<input class="username" type="text" name="username" id="un" required placeholder="Username" autocomplete="off">
|
||||
</div>
|
||||
<div class="datasec">
|
||||
<input class="password" type="password" name="password" id="pw" required placeholder="Password">
|
||||
</div>
|
||||
<div class="buttons-container">
|
||||
<button class="button"
|
||||
type="submit"
|
||||
name="submit">
|
||||
<span id="loginText">Log In</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<button class="button" id="prev">
|
||||
<span>Preview</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
31
public/info-page.html
Normal file
31
public/info-page.html
Normal file
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||
<title>InfoTafel</title>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||
<link rel='stylesheet' type='text/css' media='screen' href='styles.css'>
|
||||
<script src='info-page.js'></script>
|
||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
</head>
|
||||
<body>
|
||||
<div class="TitleRow" id="topper">
|
||||
<div class="titleDiv"></div>
|
||||
<div class="titleDiv">
|
||||
<h1>Infoseite</h1>
|
||||
<h3>Brought to you by Th-Nürnberg</h3>
|
||||
</div>
|
||||
<div class="titleDiv">
|
||||
<h2 id="clock"></h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
</div>
|
||||
<div id="lower">
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
84
public/info-page.js
Normal file
84
public/info-page.js
Normal file
@ -0,0 +1,84 @@
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
var SwitchTime = 10; // in Seconds
|
||||
|
||||
document.getElementById("topper").onclick = function(){
|
||||
window.location = "/main";
|
||||
}
|
||||
|
||||
var maxPages;
|
||||
var currentPage = 0;
|
||||
var maxDisplayed = 6;
|
||||
async function loadPosts(){
|
||||
var response = await fetch("/getliveposts", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
}
|
||||
})
|
||||
|
||||
var data = await response.json();
|
||||
//console.log(data);
|
||||
try{
|
||||
showPosts(data.posts.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed)));
|
||||
//console.log(data.posts.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed)));
|
||||
maxPages = data.posts.length / maxDisplayed;
|
||||
//console.log(maxPages, currentPage+1)
|
||||
}catch(error){
|
||||
document.getElementById("content").innerHTML = ""; //empty content
|
||||
}
|
||||
};
|
||||
loadPosts();
|
||||
|
||||
function showPosts(pdata){
|
||||
var container = document.getElementById("content"); //insert in content
|
||||
container.innerHTML = "" //empty content
|
||||
pdata.forEach(element => {
|
||||
var post = document.createElement("div");
|
||||
post.classList.add("post");
|
||||
post.style.backgroundColor = element.bcolor;
|
||||
post.innerHTML = `
|
||||
<div class="title" style="background-color:${element.bcolor};">
|
||||
<h2 class="preview-title" >${element.title}</h2>
|
||||
</div>
|
||||
<div class="body">
|
||||
${element.text}
|
||||
</div>
|
||||
`
|
||||
container.appendChild(post)
|
||||
});
|
||||
}
|
||||
|
||||
function startTime() {
|
||||
var today = new Date();
|
||||
var h = today.getHours();
|
||||
var m = today.getMinutes();
|
||||
var s = today.getSeconds();
|
||||
h = checkTime(h);
|
||||
m = checkTime(m);
|
||||
s = checkTime(s);
|
||||
document.getElementById('clock').innerHTML =
|
||||
h + ":" + m + ":" + s;
|
||||
var t = setTimeout(startTime, 500);
|
||||
}
|
||||
function checkTime(i) {
|
||||
if (i < 10) {i = "0" + i}; // add zero in front of numbers < 10
|
||||
return i;
|
||||
}
|
||||
startTime();
|
||||
|
||||
function changePage(){
|
||||
if(maxPages > currentPage+1) {
|
||||
currentPage++;
|
||||
}
|
||||
else{
|
||||
currentPage = 0;
|
||||
loadPosts();
|
||||
}
|
||||
|
||||
loadPosts();
|
||||
setTimeout(changePage, SwitchTime*1000);
|
||||
}
|
||||
changePage();
|
||||
});
|
||||
|
50
public/login.js
Normal file
50
public/login.js
Normal file
@ -0,0 +1,50 @@
|
||||
//write code in next section
|
||||
//will run when DOM is loaded
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
var form = document.getElementById("loginform");
|
||||
async function login() {
|
||||
var un = document.getElementById("un").value;
|
||||
var pw = document.getElementById("pw").value;
|
||||
var body = {username:un, password:pw};
|
||||
var response = await fetch("/login", {
|
||||
method:"POST",
|
||||
headers:{
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify(body)
|
||||
})
|
||||
var data = await response.json();
|
||||
console.log("Data: ");
|
||||
console.log(data);
|
||||
if(data.suc){
|
||||
window.location = "/main"
|
||||
} else {
|
||||
var loginText = document.getElementById("loginText");
|
||||
var inputs = document.getElementsByTagName("input")
|
||||
var inputList = Array.prototype.slice.call(inputs);
|
||||
|
||||
loginText.classList.add("fadeout");
|
||||
setTimeout(function() {
|
||||
loginText.innerText = "Try Again";
|
||||
loginText.classList.remove("fadeout");
|
||||
}, 350);
|
||||
console.log(inputs);
|
||||
inputList.forEach(element => {
|
||||
element.style.borderBottom="1px solid #F00";
|
||||
if(element.getAttribute("type") === "password"){
|
||||
element.value = "";
|
||||
element.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
form.addEventListener("submit", function(e){
|
||||
e.preventDefault();
|
||||
login();
|
||||
});
|
||||
var prevBtn = document.getElementById("prev")
|
||||
prevBtn.addEventListener("click", function(){
|
||||
window.location ="/info"
|
||||
})
|
||||
});
|
36
public/manage-post.html
Normal file
36
public/manage-post.html
Normal file
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Manage-Posts</title>
|
||||
<link rel="stylesheet" text="text/css" href="styles.css">
|
||||
<script src="manage-post.js"></script>
|
||||
<!--Font Awesome Icons CDN-->
|
||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class=main>
|
||||
<div class="container user-container">
|
||||
<div class="header">
|
||||
<h1>Manage Posts</h1>
|
||||
</div>
|
||||
<div class="ButtonRow">
|
||||
<button class="logoutButton" id="lgoBtn">Logout</button>
|
||||
<div class="rightButtons">
|
||||
<button class="manageButton" id="mngBtn">Manage Group</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table" id="table">
|
||||
</div>
|
||||
<div class="ButtonRow">
|
||||
<div></div>
|
||||
<div class="rightButtons">
|
||||
<button class="icon-backward , backButton" id="pageDown"></button>
|
||||
<button class="icon-forward , nextButton" id="pageUp"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
161
public/manage-post.js
Normal file
161
public/manage-post.js
Normal file
@ -0,0 +1,161 @@
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
/*changin page*/
|
||||
var pageUp = document.getElementById("pageUp");
|
||||
var pageDown = document.getElementById("pageDown");
|
||||
var reviewButtons = document.getElementsByClassName('editButton');
|
||||
|
||||
pageUp.addEventListener("click", () => {
|
||||
if(maxPages > currentPage+1) {
|
||||
currentPage++;
|
||||
loadPosts();
|
||||
}
|
||||
});
|
||||
|
||||
pageDown.addEventListener("click", () => {
|
||||
if(currentPage > 0){
|
||||
currentPage--;
|
||||
|
||||
loadPosts();
|
||||
}
|
||||
});
|
||||
|
||||
/*logout*/
|
||||
var lgoBtn = document.getElementById("lgoBtn");
|
||||
lgoBtn.addEventListener("click", () => {
|
||||
window.location = "/logout";
|
||||
});
|
||||
|
||||
var mngBtn = document.getElementById("mngBtn");
|
||||
mngBtn.addEventListener("click", () => {
|
||||
window.location = "/main";
|
||||
});
|
||||
|
||||
async function toggleSus(postid){
|
||||
var response = await fetch("/toggleShow", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify({postid:postid})
|
||||
})
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
if(data.suc || !data.suc){
|
||||
loadPosts();
|
||||
}
|
||||
};
|
||||
|
||||
async function deletePost(postid){
|
||||
var response = await fetch("/deletePost", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify({postid:postid})
|
||||
})
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
if(data.suc || !data.suc){
|
||||
loadPosts();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
document.addEventListener("click", function(e){
|
||||
if(e.target && e.target.classList.contains("susButton")){
|
||||
var postid = e.target.getAttribute("data-username");
|
||||
toggleSus(postid);
|
||||
}else if(e.target && e.target.classList.contains("remButton")){
|
||||
var postid = e.target.getAttribute("data-username");
|
||||
deletePost(postid);
|
||||
}
|
||||
})
|
||||
|
||||
/*Show Elements*/
|
||||
var maxPages;
|
||||
var currentPage = 0;
|
||||
var maxDisplayed = 8;
|
||||
async function loadPosts(){
|
||||
var response = await fetch("/getposts", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
}
|
||||
})
|
||||
var data = await response.json();
|
||||
try{
|
||||
showPosts(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed)));
|
||||
console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed)));
|
||||
maxPages = data.users.length / 8;
|
||||
console.log(maxPages, currentPage+1)
|
||||
reviewButtons = document.getElementsByClassName('editButton');
|
||||
console.log(reviewButtons.length);
|
||||
addButtons();
|
||||
}catch(error){
|
||||
document.getElementById("table").innerHTML = ""; //empty table
|
||||
}
|
||||
};
|
||||
loadPosts();
|
||||
|
||||
function showPosts(pdata){
|
||||
document.getElementById("table").innerHTML = ""; //empty table
|
||||
var container = document.getElementById("table"); //insert in table
|
||||
pdata.forEach(element => {
|
||||
var row = document.createElement("div");
|
||||
var status;
|
||||
var susbuttonstate;
|
||||
if(!element.showpost) {
|
||||
status = "hidden"
|
||||
susbuttonstate = "icon-eye-close"
|
||||
} else {
|
||||
status = "shown"
|
||||
susbuttonstate = "icon-eye-open"
|
||||
}
|
||||
row.classList.add("row");
|
||||
row.innerHTML = `
|
||||
<div class="col-left">
|
||||
<h2>${element.title}</h2>
|
||||
</div>
|
||||
<div class="col-right">
|
||||
<button class="editButton" data-username="${element.postid}">
|
||||
<i class="icon-file-text-alt , icon"></i>
|
||||
</button>
|
||||
<button class="${status} susButton" data-username="${element.postid}">
|
||||
<i class="${susbuttonstate} , icon"></i>
|
||||
</button>
|
||||
<button class="remButton" data-username="${element.postid}">
|
||||
<i class="icon-trash , icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
container.appendChild(row)
|
||||
});
|
||||
}
|
||||
|
||||
async function reviewPost(postid){
|
||||
var response = await fetch("/updatePostID", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify({postid:postid})
|
||||
})
|
||||
var data = await response.json();
|
||||
if(data || !data)
|
||||
{
|
||||
window.location = "/post-review";
|
||||
}
|
||||
};
|
||||
|
||||
function addButtons(){
|
||||
for(let i = 0; i < reviewButtons.length; i++){
|
||||
reviewButtons[i].addEventListener('click', function(){
|
||||
reviewPost(this.dataset.username)
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
60
public/mod-login.html
Normal file
60
public/mod-login.html
Normal file
@ -0,0 +1,60 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Mod-Page</title>
|
||||
<link rel="stylesheet" text="text/css" href="styles.css">
|
||||
<script src="mod.js"></script>
|
||||
<!--Font Awesome Icons CDN-->
|
||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class=main>
|
||||
<div class="container user-container">
|
||||
<div class="header">
|
||||
<h1>Modseite</h1>
|
||||
</div>
|
||||
<div class="ButtonRow">
|
||||
<button class="logoutButton" id="lgoBtn">Logout</button>
|
||||
|
||||
<div class="rightButtons">
|
||||
<button class="manageButton" id="mngBtn">Manage Posts</button>
|
||||
<button data-popup-target="#addPopup" id="addBtn">+</button>
|
||||
<div class="popup" id="addPopup">
|
||||
<div class="popup-header">
|
||||
<div class="title">Registration Form</div>
|
||||
<button data-close-btn class="close-btn">×</button>
|
||||
</div>
|
||||
<div class="popup-body">
|
||||
<form class="" id="formNewUser" method="POST">
|
||||
<div class="regSection">
|
||||
<input type="email" id="email" required placeholder="e-Mail">
|
||||
</div>
|
||||
<div class="regSection">
|
||||
<input type="text" id="username" required placeholder="Username">
|
||||
</div>
|
||||
<div class="btn">
|
||||
<button type="submit" value="Create" id="submit">
|
||||
<span>Submit</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="" id="overlay"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table" id="table">
|
||||
</div>
|
||||
<div class="ButtonRow">
|
||||
<button class="logoutButton" id="changePwBtn">Change Password</button>
|
||||
<div class="rightButtons">
|
||||
<button class="icon-backward , backButton" id="pageDown"></button>
|
||||
<button class="icon-forward , nextButton" id="pageUp"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
189
public/mod.js
Normal file
189
public/mod.js
Normal file
@ -0,0 +1,189 @@
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
var form = document.getElementById("formNewUser");
|
||||
form.addEventListener("submit", function(e){
|
||||
e.preventDefault();
|
||||
console.log("Sending Formular")
|
||||
async function register(){
|
||||
var email = document.getElementById("email").value;
|
||||
var username = document.getElementById("username").value;
|
||||
var bodyContent = {email:email, username:username};
|
||||
var response = await fetch("/newuser", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify(bodyContent)
|
||||
});
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
loadUsers();
|
||||
}
|
||||
register();
|
||||
});
|
||||
|
||||
document.getElementById("changePwBtn").onclick = function(){
|
||||
window.location = "/new-password";
|
||||
}
|
||||
|
||||
/*changin page*/
|
||||
var pageUp = document.getElementById("pageUp");
|
||||
var pageDown = document.getElementById("pageDown");
|
||||
|
||||
pageUp.addEventListener("click", () => {
|
||||
if(maxPages > currentPage+1) {
|
||||
currentPage++;
|
||||
loadUsers();
|
||||
}
|
||||
});
|
||||
|
||||
pageDown.addEventListener("click", () => {
|
||||
if(currentPage > 0){
|
||||
currentPage--;
|
||||
|
||||
loadUsers();
|
||||
}
|
||||
});
|
||||
|
||||
/*logout*/
|
||||
var lgoBtn = document.getElementById("lgoBtn");
|
||||
lgoBtn.addEventListener("click", () => {
|
||||
window.location = "/logout";
|
||||
});
|
||||
|
||||
var mngBtn = document.getElementById("mngBtn");
|
||||
mngBtn.addEventListener("click", () => {
|
||||
window.location = "/manage-posts";
|
||||
});
|
||||
|
||||
var maxPages;
|
||||
var currentPage = 0;
|
||||
var maxDisplayed = 8;
|
||||
async function loadUsers(){
|
||||
var response = await fetch("/getusers", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
}
|
||||
})
|
||||
var data = await response.json();
|
||||
try{
|
||||
showUsers(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed)));
|
||||
console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed)));
|
||||
maxPages = data.users.length / 8;
|
||||
console.log(maxPages, currentPage+1)
|
||||
}catch(error){
|
||||
document.getElementById("table").innerHTML = ""; //empty table
|
||||
}
|
||||
};
|
||||
loadUsers();
|
||||
|
||||
function showUsers(pdata){
|
||||
document.getElementById("table").innerHTML = ""; //empty table
|
||||
var container = document.getElementById("table"); //insert in table
|
||||
pdata.forEach(element => {
|
||||
var row = document.createElement("div");
|
||||
var status;
|
||||
var susbuttonstate;
|
||||
if(element.suspended) {
|
||||
status = "suspended"
|
||||
susbuttonstate = "icon-pause"
|
||||
} else {
|
||||
status = "notSuspended"
|
||||
susbuttonstate = "icon-play"
|
||||
}
|
||||
row.classList.add("row");
|
||||
row.innerHTML = `
|
||||
<div class="col-left">
|
||||
<h2>${element.username}</h2>
|
||||
</div>
|
||||
<div class="col-right">
|
||||
<button class="${status} susButton" data-username="${element.username}">
|
||||
<i class="${susbuttonstate} , icon"></i>
|
||||
</button>
|
||||
<button class="remButton" data-username="${element.username}">
|
||||
<i class="icon-trash , icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
container.appendChild(row)
|
||||
});
|
||||
}
|
||||
|
||||
async function toggleSus(pun){
|
||||
var response = await fetch("/toggleSus", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify({username:pun})
|
||||
})
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
if(data.suc || !data.suc){
|
||||
loadUsers();
|
||||
}
|
||||
};
|
||||
|
||||
async function deleteUser(username){
|
||||
var response = await fetch("/deleteUser", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify({username:username})
|
||||
})
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
if(data.suc || !data.suc){
|
||||
loadUsers();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
document.addEventListener("click", function(e){
|
||||
if(e.target && e.target.classList.contains("susButton")){
|
||||
var un = e.target.getAttribute("data-username");
|
||||
toggleSus(un);
|
||||
}else if(e.target && e.target.classList.contains("remButton")){
|
||||
var username = e.target.getAttribute("data-username");
|
||||
deleteUser(username);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
/*-----New User Popup-----*/
|
||||
const openPopupBtns = document.querySelectorAll("[data-popup-target]");
|
||||
const closePopupBtns = document.querySelectorAll("[data-close-btn]");
|
||||
const overlay = document.getElementById("overlay");
|
||||
|
||||
openPopupBtns.forEach(btn => {
|
||||
btn.addEventListener("click", () => {
|
||||
const popup = document.querySelector(btn.dataset.popupTarget);
|
||||
openPopup(popup);
|
||||
})
|
||||
});
|
||||
|
||||
closePopupBtns.forEach(btn => {
|
||||
btn.addEventListener("click", () => {
|
||||
const popup = btn.closest(".popup")
|
||||
closePopup(popup);
|
||||
})
|
||||
});
|
||||
|
||||
function openPopup(popup) {
|
||||
if (popup == null) return
|
||||
popup.classList.add("active");
|
||||
overlay.classList.add("active");
|
||||
}
|
||||
|
||||
function closePopup(popup) {
|
||||
if (popup == null) return
|
||||
popup.classList.remove("active");
|
||||
overlay.classList.remove("active");
|
||||
}
|
||||
|
||||
});
|
75
public/new-Postv2.html
Normal file
75
public/new-Postv2.html
Normal file
@ -0,0 +1,75 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||
<title>Post Editor</title>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||
<link rel='stylesheet' type='text/css' media='screen' href='styles.css'>
|
||||
<script src='new-Postv2.js'></script>
|
||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="container postContainer" id="box">
|
||||
<div class=topper>
|
||||
<button id="cancelBtn" title="Cancel">×</button>
|
||||
</div>
|
||||
<div class="editor">
|
||||
<div class="editor-menubar">
|
||||
<button class="editor-button icon-picture" data-popup-target="#addPopup" data-attribute="insertImage" title="Add Image"></button>
|
||||
<div class="" id="overlay"></div>
|
||||
<div class="popup" id="addPopup">
|
||||
<div class="popup-header">
|
||||
<div class="title">Add Picture</div>
|
||||
<button data-close-btn class="close-btn">×</button>
|
||||
</div>
|
||||
<div class="popup-body">
|
||||
<div class="" id="formNewUser">
|
||||
<div class="regSection">
|
||||
<input type="text" id="url" required placeholder="URL">
|
||||
</div>
|
||||
<div class="btn">
|
||||
<button type="submit" value="Create" id="add">
|
||||
<span>Add</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<button class="editor-button icon-bold" data-attribute="bold" title="Bold"></button>
|
||||
<button class="editor-button icon-italic" data-attribute="italic" title="Italic"></button>
|
||||
<button class="editor-button icon-underline" data-attribute="underline" title="Underline"></button>
|
||||
<button class="editor-button icon-superscript" data-attribute="superscript" title="Superscript"></button>
|
||||
<button class="editor-button icon-subscript" data-attribute="subscript" title="Subscript"></button>
|
||||
<input class="color-select" data-attribute="forecolor" type="color" id="forecolor" title="Text Colour">
|
||||
</div>
|
||||
<div id="title-text">
|
||||
<div class="canvas" id="title-canvas" contenteditable=true data-text="Title"></div>
|
||||
<div class="canvas" id="editor-canvas" contenteditable=true data-text="Content"></div>
|
||||
</div>
|
||||
<div class="editor-menubar">
|
||||
<button class="editor-button icon-undo" data-attribute="undo" title="Undo"></button>
|
||||
<button class="editor-button icon-repeat" data-attribute="redo" title="Redo"></button>
|
||||
<button class="editor-button icon-align-left" data-attribute="justifyleft" title="Justify Left"></button>
|
||||
<button class="editor-button icon-align-center" data-attribute="justifycenter" title="Justify Center"></button>
|
||||
<button class="editor-button icon-align-right" data-attribute="justifyright" title="Justify Right"></button>
|
||||
<input class="color-select" data-attribute="backcolor" type="color" id="backcolor" title="Background Colour" value="#ffffff">
|
||||
</div>
|
||||
</div>
|
||||
<div class="lower">
|
||||
<div class="calendar">
|
||||
<label for="start">Start date:</label>
|
||||
<input class="calendar-element" type="date" id="startDate" value=2020-01-01 min=2020-01-01>
|
||||
</div>
|
||||
<div class="calendar">
|
||||
<label for="start">End date:</label>
|
||||
<input class="calendar-element" type="date" id="endDate" value=2020-01-01 min=2020-01-01>
|
||||
</div>
|
||||
<button id="submit-post">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
118
public/new-Postv2.js
Normal file
118
public/new-Postv2.js
Normal file
@ -0,0 +1,118 @@
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
const editorButtons = document.getElementsByClassName('editor-button');
|
||||
const setAttribute = (element) => {
|
||||
document.execCommand(element.dataset.attribute, false);
|
||||
};
|
||||
|
||||
for(let i = 0; i <editorButtons.length; i++) {
|
||||
editorButtons[i].addEventListener('click', function(){
|
||||
setAttribute(this);
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById("cancelBtn").onclick = function(){
|
||||
window.location = "/main";
|
||||
}
|
||||
|
||||
document.getElementById("add").onclick = function(){
|
||||
document.execCommand("insertImage", false, document.getElementById("url").value);
|
||||
}
|
||||
|
||||
document.getElementById("forecolor").onchange = function(){setColor(this);}
|
||||
const setColor = (element) => {
|
||||
console.log(element);
|
||||
document.execCommand(element.dataset.attribute, false, element.value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
const backColor = document.getElementById("backcolor");
|
||||
const helo = document.getElementsByClassName("canvas");
|
||||
backColor.addEventListener('change', function(){
|
||||
console.log(this);
|
||||
for(let i = 0; i <helo.length; i++) {
|
||||
helo[i].style.backgroundColor = backColor.value;
|
||||
};
|
||||
});
|
||||
|
||||
document.getElementById("submit-post").onclick = function(){
|
||||
if(document.getElementById('title-canvas').innerHTML && document.getElementById('editor-canvas').innerHTML)
|
||||
{
|
||||
const title = document.getElementById('title-canvas').innerHTML;
|
||||
const content = document.getElementById('editor-canvas').innerHTML;
|
||||
const date_begin = document.getElementById('startDate').value;
|
||||
const date_end = document.getElementById('endDate').value;
|
||||
const bcolor = document.getElementById('backcolor').value;
|
||||
var bodyContent = {title:title, text:content, startDate:date_begin, endDate:date_end, bcolor:bcolor};
|
||||
send(bodyContent);
|
||||
}
|
||||
};
|
||||
|
||||
async function send(bodyContent){
|
||||
console.log(bodyContent);
|
||||
var response = await fetch("/newpost", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify(bodyContent)
|
||||
});
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
console.log(helo);
|
||||
window.location = "/main";
|
||||
}
|
||||
|
||||
/*-----New User Popup-----*/
|
||||
const openPopupBtns = document.querySelectorAll("[data-popup-target]");
|
||||
const closePopupBtns = document.querySelectorAll("[data-close-btn]");
|
||||
const overlay = document.getElementById("overlay");
|
||||
|
||||
openPopupBtns.forEach(btn => {
|
||||
btn.addEventListener("click", () => {
|
||||
const popup = document.querySelector(btn.dataset.popupTarget);
|
||||
openPopup(popup);
|
||||
})
|
||||
});
|
||||
|
||||
closePopupBtns.forEach(btn => {
|
||||
btn.addEventListener("click", () => {
|
||||
const popup = btn.closest(".popup")
|
||||
closePopup(popup);
|
||||
})
|
||||
});
|
||||
|
||||
function openPopup(popup) {
|
||||
if (popup == null) return
|
||||
popup.classList.add("active");
|
||||
overlay.classList.add("active");
|
||||
}
|
||||
|
||||
function closePopup(popup) {
|
||||
if (popup == null) return
|
||||
popup.classList.remove("active");
|
||||
overlay.classList.remove("active");
|
||||
}
|
||||
|
||||
document.getElementById("startDate").onchange = function(){
|
||||
document.getElementById("endDate").min = document.getElementById("startDate").value;
|
||||
var end = new Date(document.getElementById("startDate").value);
|
||||
end.setDate(end.getDate() +7);
|
||||
var endDate = end.toISOString().slice(0,10);
|
||||
document.getElementById("endDate").value = endDate;
|
||||
}
|
||||
|
||||
function date(){
|
||||
var today = new Date().toISOString().slice(0,10);
|
||||
var end = new Date();
|
||||
end.setDate(end.getDate() + 7)
|
||||
var endDate = end.toISOString().slice(0,10);
|
||||
|
||||
document.getElementById("startDate").value = today;
|
||||
document.getElementById("startDate").min = today;
|
||||
document.getElementById("endDate").value = endDate;
|
||||
document.getElementById("endDate").min = today;
|
||||
};
|
||||
date()
|
||||
});
|
28
public/post-review.html
Normal file
28
public/post-review.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||
<title>Post Editor</title>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||
<link rel='stylesheet' type='text/css' media='screen' href='styles.css'>
|
||||
<script src='post-review.js'></script>
|
||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<div class="container postContainer" id="box">
|
||||
<div class=topper>
|
||||
<button id="cancelBtn" title="Cancel">×</button>
|
||||
</div>
|
||||
<div id="title-text">
|
||||
<div class="canvas" id="title-canvas" data-text="Title"></div>
|
||||
<div class="canvas" id="editor-canvas" data-text="Content"></div>
|
||||
</div>
|
||||
<div class="lower">
|
||||
<button id="submit-post"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
49
public/post-review.js
Normal file
49
public/post-review.js
Normal file
@ -0,0 +1,49 @@
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
document.getElementById("cancelBtn").onclick = function(){
|
||||
window.location = "/main";
|
||||
}
|
||||
|
||||
var id;
|
||||
async function loadPost(){
|
||||
var response = await fetch("/getReviewPost", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
}
|
||||
})
|
||||
var data = await response.json();
|
||||
id = data.post[0].postid;
|
||||
document.getElementsByClassName("canvas")[0].style.backgroundColor = data.post[0].bcolor;
|
||||
document.getElementsByClassName("canvas")[1].style.backgroundColor = data.post[0].bcolor;
|
||||
document.getElementById("title-canvas").innerHTML = data.post[0].title;
|
||||
document.getElementById("editor-canvas").innerHTML = data.post[0].text;
|
||||
|
||||
if(data.post[0].showpost) {
|
||||
document.getElementById("submit-post").innerHTML = "Suspend Post"
|
||||
} else {
|
||||
document.getElementById("submit-post").innerHTML = "Confirm Post"
|
||||
}
|
||||
};
|
||||
loadPost();
|
||||
|
||||
document.getElementById("submit-post").onclick = function(){
|
||||
toggleShow(id);
|
||||
}
|
||||
|
||||
async function toggleShow(pun){
|
||||
var response = await fetch("/toggleShow", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify({postid:pun})
|
||||
})
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
if(data.suc || !data.suc){
|
||||
window.location = "/main"
|
||||
}
|
||||
};
|
||||
});
|
553
public/styles.css
Normal file
553
public/styles.css
Normal file
@ -0,0 +1,553 @@
|
||||
:root {
|
||||
--border-prop: 0px solid #F2F;
|
||||
--header-height: 10%;
|
||||
--prime-color: rgb(71, 17, 221);
|
||||
--container-bg: rgba(30, 30, 50, 0.644);
|
||||
--text-color: rgba(255,255,255, 1);
|
||||
--row-color: rgba(0, 0, 100, 0.3);
|
||||
--button-prim: rgba(255,255,255,0.1);
|
||||
--button-sec: rgba(255, 255, 255, 0.4);
|
||||
--popup-border: 2px solid rgb(11, 11, 128);
|
||||
--popup-stripe: 3px solid rgba(0,0,50,0.5);
|
||||
--title-size: 60px;
|
||||
--text-size: 30px;
|
||||
--smal-text: 20px;
|
||||
}
|
||||
|
||||
div{
|
||||
border: 0px #F2F;
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--prime-color);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
header{
|
||||
height: var(--header-height);
|
||||
padding-top: 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/*text*/
|
||||
h1, h2, h3, .title, label{
|
||||
font-size: var(--title-size);
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
font-family: Arial;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
h2, label{
|
||||
font-size: var(--text-size);
|
||||
}
|
||||
|
||||
h3{
|
||||
font-size: var(--smal-text);
|
||||
}
|
||||
|
||||
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
font-family: Arial;
|
||||
font-size: 2em;
|
||||
color: rgb(255, 255, 255);
|
||||
padding: 0;
|
||||
padding-bottom: 5px;
|
||||
background: none;
|
||||
border: none;
|
||||
border-bottom: 1px solid #ffffff;
|
||||
margin-bottom: 15px;
|
||||
margin-top: 15px
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.container{
|
||||
width: 400px;
|
||||
border: var(--border-prop);
|
||||
background-color: var(--container-bg);
|
||||
padding: 20px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.user-container{
|
||||
width: 50%;
|
||||
min-height: 35em;
|
||||
}
|
||||
|
||||
.header {
|
||||
border: var(--border-prop);
|
||||
font-size: 25px;
|
||||
text-align: center;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.datasec {
|
||||
border: var(--border-prop);
|
||||
font-family: Arial;
|
||||
font-size: 30px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* buttons */
|
||||
|
||||
.buttons-container {
|
||||
border: var(--border-prop);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
border-radius: 0;
|
||||
background-color: #303030;
|
||||
border: none;
|
||||
/*text*/
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
font-size: var(--text-size);
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
|
||||
.button span{
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
transition: 1s;
|
||||
}
|
||||
|
||||
.button span::after {
|
||||
content: '\00bb';
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
top: 0;
|
||||
right: -20px;
|
||||
transition: .5s;
|
||||
}
|
||||
|
||||
.button:hover span {
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.button:hover span::after{
|
||||
opacity: 1;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.susButton , .remButton, .nextButton, .manageButton, #addBtn{
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.icon{
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* end of buttons*/
|
||||
|
||||
#loginText {
|
||||
transition: 0.35s;
|
||||
}
|
||||
|
||||
.fadeout {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#loginform {
|
||||
border: var(--border-prop);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/*
|
||||
border: 1px #F2F;
|
||||
border-style: dashed;
|
||||
*/
|
||||
|
||||
|
||||
/* User/Mod Table */
|
||||
|
||||
.table{
|
||||
min-height: 32em;
|
||||
}
|
||||
|
||||
.row{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background-color: var(--row-color);
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.col-left , .col-right{
|
||||
display: flex;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* End of Table */
|
||||
|
||||
/* Page Selector */
|
||||
|
||||
.rightButtons{
|
||||
display: flex;
|
||||
margin-left: 10px;
|
||||
|
||||
}
|
||||
|
||||
.ButtonRow{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* End of Page Selector*/
|
||||
|
||||
/*-----POPUP-----*/
|
||||
.popup{
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%) scale(0);
|
||||
transition: 50ms ease-in-out;
|
||||
border: var(--popup-border);
|
||||
z-index: 10; /*lay ontop of everything*/
|
||||
background-color: var(--prime-color);
|
||||
width: 500px;
|
||||
max-width: 80%;
|
||||
min-height: 18em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.popup.active{
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
|
||||
.popup-header{
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: var(--popup-stripe);
|
||||
}
|
||||
|
||||
.popup-header .title{
|
||||
font-size: var(--text-size);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.popup-header .close-btn{
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: none;
|
||||
font-size: var(--title-size);
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.popup-body{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#overlay{
|
||||
position: fixed;
|
||||
opacity: 0;
|
||||
transition: 50ms ease-in-out;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0,0,0,.75);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#overlay.active{
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.popup-body{
|
||||
display: fixed;
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
#formNewUser{
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
font-family: Arial;
|
||||
font-size: var(--text-size);
|
||||
color: white;
|
||||
padding: 0;
|
||||
padding-bottom: 5px;
|
||||
background: none;
|
||||
border: none;
|
||||
border-bottom: 1px solid #ffffff;
|
||||
margin-bottom: 15px;
|
||||
margin-top: 15px
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/*-----POPUP-END-----*/
|
||||
|
||||
/* New Post Section*/
|
||||
|
||||
|
||||
[contentEditable=true]:empty:not(:focus):before{
|
||||
content:attr(data-text);
|
||||
color: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.preview-title{
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.editor{
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.editor-menubar{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
|
||||
button, .color-select{
|
||||
color: #ffffff;
|
||||
font-size: var(--text-size);
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
background-color: var(--button-prim);
|
||||
cursor: pointer;
|
||||
transition: all 250ms;
|
||||
border: none;
|
||||
min-width: 50px;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
button:hover{
|
||||
background-color: var(--button-sec);
|
||||
}
|
||||
|
||||
button:focus{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.regSection{
|
||||
font-size: var(--text-size);
|
||||
}
|
||||
|
||||
.canvas{
|
||||
background-color: rgba(255,255,255,1);
|
||||
width: 46.3rem;
|
||||
height: 30rem;
|
||||
padding: 2.5rem;
|
||||
font-size: var(--text-size);
|
||||
color: #000;
|
||||
font-family: arial;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.canvas:focus{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#title-canvas, #editor-canvas{
|
||||
height: 5rem;
|
||||
font-size: var(--title-size);
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
text-justify: center;
|
||||
padding: 10px;
|
||||
|
||||
border-bottom: .5rem solid #000 ;
|
||||
}
|
||||
|
||||
#editor-canvas{
|
||||
|
||||
text-align: left;
|
||||
text-justify: left;
|
||||
height: 30rem;
|
||||
font-size: var(--smal-text);
|
||||
}
|
||||
|
||||
#box{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#cancelBtn{
|
||||
padding: 0;
|
||||
font-size: var(--title-size);
|
||||
line-height: 1.8rem;
|
||||
}
|
||||
|
||||
.postContainer{
|
||||
width: 60em;
|
||||
}
|
||||
|
||||
.lower{
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.topper{
|
||||
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.calendar{
|
||||
color: #ffffff;
|
||||
font-size: var(--text-size);
|
||||
padding: 1rem;
|
||||
transition: all 250ms;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: .5rem;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.calendar-element{
|
||||
border: none;
|
||||
}
|
||||
|
||||
.calendar-element:focus{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#title-text{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
#submit-post{
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
.color-select{
|
||||
background-color: var(--button-prim);
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.color-select:hover{
|
||||
background-color: var(--button-sec);
|
||||
}
|
||||
|
||||
.editor-button{
|
||||
min-width: 50px;
|
||||
max-width: 50px;
|
||||
min-height: 50px;
|
||||
max-height: 50px;
|
||||
}
|
||||
|
||||
/* End of New Post*/
|
||||
|
||||
/* Preview */
|
||||
|
||||
.TitleRow{
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
background-color: var(--container-bg);
|
||||
padding-right: 10px;
|
||||
padding-bottom: 10px;
|
||||
align-items: center;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.titleDiv{
|
||||
min-width: 25%;
|
||||
}
|
||||
|
||||
#topper{
|
||||
height: 10%;
|
||||
text-align: center;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#content{
|
||||
width: 100%;
|
||||
height: 85%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.post{
|
||||
animation: fadein 2s ease;
|
||||
|
||||
min-width: 30%;
|
||||
max-width: 45%;
|
||||
min-height: 28%;
|
||||
max-height: 45%;
|
||||
padding: 2vh;
|
||||
margin: 5px;
|
||||
border-width: 0px;
|
||||
border-color: var(--prime);
|
||||
color: black;
|
||||
}
|
||||
|
||||
.hidden{
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* End of Preview */
|
||||
|
38
public/user-login.html
Normal file
38
public/user-login.html
Normal file
@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>User-Page</title>
|
||||
<link rel="stylesheet" text="text/css" href="styles.css">
|
||||
<script src="user.js"></script>
|
||||
<!--Font Awesome Icons CDN-->
|
||||
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class=main>
|
||||
<div class="container user-container">
|
||||
<div class="header">
|
||||
<h1>Benutzerseite</h1>
|
||||
</div>
|
||||
<div class="ButtonRow">
|
||||
|
||||
<button class="logoutButton" id="lgoBtn">Logout</button>
|
||||
|
||||
<button onclick="location.href='/newPost'" id="addBtn">+</button>
|
||||
|
||||
<div class="" id="overlay"></div>
|
||||
</div>
|
||||
<div class="table" id="table">
|
||||
</div>
|
||||
<div class="ButtonRow">
|
||||
<button class="logoutButton" id="changePwBtn">Change Password</button>
|
||||
<div class="rightButtons">
|
||||
<button class="icon-backward , backButton" id="pageDown"></button>
|
||||
<button class="icon-forward , nextButton" id="pageUp"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
143
public/user.js
Normal file
143
public/user.js
Normal file
@ -0,0 +1,143 @@
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
/*changin page*/
|
||||
var pageUp = document.getElementById("pageUp");
|
||||
var pageDown = document.getElementById("pageDown");
|
||||
var reviewButtons = document.getElementsByClassName('editButton');
|
||||
|
||||
|
||||
|
||||
document.getElementById("changePwBtn").onclick = function(){
|
||||
window.location = "/new-password";
|
||||
}
|
||||
|
||||
pageUp.addEventListener("click", () => {
|
||||
if(maxPages > currentPage+1) {
|
||||
currentPage++;
|
||||
loadPosts();
|
||||
}
|
||||
});
|
||||
|
||||
pageDown.addEventListener("click", () => {
|
||||
if(currentPage > 0){
|
||||
currentPage--;
|
||||
loadPosts();
|
||||
}
|
||||
});
|
||||
|
||||
async function deletePost(postid){
|
||||
var response = await fetch("/deletePost", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify({postid:postid})
|
||||
})
|
||||
var data = await response.json();
|
||||
console.log(data);
|
||||
if(data.suc || !data.suc){
|
||||
loadPosts();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("click", function(e){
|
||||
if(e.target && e.target.classList.contains("remButton")){
|
||||
var postid = e.target.getAttribute("data-username");
|
||||
deletePost(postid);
|
||||
}
|
||||
})
|
||||
|
||||
/*logout*/
|
||||
var lgoBtn = document.getElementById("lgoBtn");
|
||||
lgoBtn.addEventListener("click", () => {
|
||||
window.location = "/logout";
|
||||
});
|
||||
|
||||
/*NewPost*/
|
||||
var addBtn = document.getElementById("addBtn");
|
||||
addBtn.addEventListener("click", () => {
|
||||
window.location = "/newPost";
|
||||
});
|
||||
|
||||
/*Show Elements*/
|
||||
var maxPages;
|
||||
var currentPage = 0;
|
||||
var maxDisplayed = 8;
|
||||
async function loadPosts(){
|
||||
var response = await fetch("/getposts", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
}
|
||||
})
|
||||
var data = await response.json();
|
||||
try{
|
||||
showPosts(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed)));
|
||||
console.log(data.users.slice(0 + (currentPage * maxDisplayed), maxDisplayed + (currentPage * maxDisplayed)));
|
||||
maxPages = data.users.length / 8;
|
||||
console.log(maxPages, currentPage+1)
|
||||
reviewButtons = document.getElementsByClassName('editButton');
|
||||
console.log(reviewButtons.length);
|
||||
addButtons();
|
||||
}catch(error){
|
||||
document.getElementById("table").innerHTML = ""; //empty table
|
||||
}
|
||||
};
|
||||
loadPosts();
|
||||
|
||||
function showPosts(pdata){
|
||||
document.getElementById("table").innerHTML = ""; //empty table
|
||||
var container = document.getElementById("table"); //insert in table
|
||||
pdata.forEach(element => {
|
||||
var row = document.createElement("div");
|
||||
var status;
|
||||
if(!element.showpost) {
|
||||
status = "hidden icon-eye-close"
|
||||
} else {
|
||||
status = "shown icon-eye-open"
|
||||
}
|
||||
row.classList.add("row");
|
||||
row.innerHTML = `
|
||||
<div class="col-left">
|
||||
<h2>${element.title}</h2>
|
||||
</div>
|
||||
<div class="col-right">
|
||||
<button class="editButton" data-username="${element.postid}">
|
||||
<i class="icon-file-text-alt , icon"></i>
|
||||
</button>
|
||||
<button class="${status} susButton">
|
||||
</button>
|
||||
<button class="remButton" data-username="${element.postid}">
|
||||
<i class="icon-trash , icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
`
|
||||
container.appendChild(row)
|
||||
});
|
||||
}
|
||||
|
||||
async function reviewPost(postid){
|
||||
var response = await fetch("/updatePostID", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Accept":"application/json",
|
||||
"Content-Type":"application/json"
|
||||
},
|
||||
body:JSON.stringify({postid:postid})
|
||||
})
|
||||
var data = await response.json();
|
||||
if(data || !data)
|
||||
{
|
||||
window.location = "/post-review";
|
||||
}
|
||||
};
|
||||
|
||||
function addButtons(){
|
||||
for(let i = 0; i < reviewButtons.length; i++){
|
||||
reviewButtons[i].addEventListener('click', function(){
|
||||
reviewPost(this.dataset.username)
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
573
server.js
Normal file
573
server.js
Normal file
@ -0,0 +1,573 @@
|
||||
const express = require("express");
|
||||
const bodyParser = require("body-parser");
|
||||
const app = express();
|
||||
const bcrypt = require("bcrypt");
|
||||
const Datastore = require("nedb");
|
||||
const session = require("express-session");
|
||||
const NedbSessionStore = require("nedb-session-store")(session);
|
||||
|
||||
app.listen(8080, () => {
|
||||
console.log("Server online on port 8080");
|
||||
})
|
||||
|
||||
app.use(session({
|
||||
secret: process.env.SECRET || 'ENTER YOUR SECRET KEY IN ENV VARIABLES!',
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
unset: "destroy",
|
||||
cookie: {
|
||||
path: '/',
|
||||
httpOnly: true,
|
||||
maxAge: 3600000 //cookie time in ms (=1h)
|
||||
},
|
||||
store: new NedbSessionStore({
|
||||
filename: 'db/sessions.db'
|
||||
})
|
||||
}))
|
||||
|
||||
app.use(express.static("public"));
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------PAGE REQUESTS--------------------------------------------------*/
|
||||
|
||||
app.get("/", (req, res) => {
|
||||
res.send("index.html");
|
||||
});
|
||||
|
||||
app.get("/info", (req, res) => {
|
||||
res.sendFile(__dirname + '/public/info-page.html')
|
||||
});
|
||||
|
||||
app.get("/main", (req, res) => {
|
||||
if(req.session.isLoggedIn && req.session.userRole === "admin"){
|
||||
res.sendFile(__dirname + '/public/admin-login.html')
|
||||
}else if(req.session.isLoggedIn && req.session.userRole === "mod") {
|
||||
res.sendFile(__dirname + '/public/mod-login.html')
|
||||
}else if(req.session.isLoggedIn && req.session.userRole === "user") {
|
||||
res.sendFile(__dirname + '/public/user-login.html')
|
||||
}else {
|
||||
req.session = null;
|
||||
res.redirect("/");
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/newPost", (req, res) => {
|
||||
if(req.session.isLoggedIn && req.session.userRole === "user"){
|
||||
res.sendFile(__dirname + '/public/new-Postv2.html')
|
||||
} else {
|
||||
req.session = null;
|
||||
res.redirect("/");
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/manage-posts", (req, res) => {
|
||||
if(req.session.isLoggedIn && (req.session.userRole === "mod" || req.session.userRole === "admin")){
|
||||
res.sendFile(__dirname + '/public/manage-post.html')
|
||||
} else {
|
||||
req.session = null;
|
||||
res.redirect("/");
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/new-password", (req, res) => {
|
||||
if(req.session.isLoggedIn){
|
||||
res.sendFile(__dirname + '/public/change-pw.html')
|
||||
} else {
|
||||
req.session = null;
|
||||
res.redirect("/");
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/updatePostID", (req, res) => {
|
||||
|
||||
if(req.session.isLoggedIn){
|
||||
req.session.revpost = req.body.postid;
|
||||
res.json({suc:true});
|
||||
//res.sendFile(__dirname + '/public/post-review.html')
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/post-review", (req, res) => {
|
||||
if(req.session.isLoggedIn ){
|
||||
res.sendFile(__dirname + '/public/post-review.html')
|
||||
} else {
|
||||
req.session = null;
|
||||
res.redirect("/");
|
||||
}
|
||||
});
|
||||
|
||||
/*--------------------------------------------------GETTER FUNCTIONS--------------------------------------------------*/
|
||||
|
||||
app.get("/getmods", (req, res) => {
|
||||
if(req.session.isLoggedIn && req.session.userRole === "admin"){
|
||||
const db = new Datastore("db/users.db");
|
||||
db.loadDatabase();
|
||||
db.find({role:"mod"}, (err, docs) => {
|
||||
if(docs.length > 0) {
|
||||
let resArray = [];
|
||||
docs.forEach(element => {
|
||||
resArray.push({
|
||||
username:element.username,
|
||||
suspended:element.suspended
|
||||
})
|
||||
});
|
||||
res.json({suc:true, users:resArray})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/getusers", (req, res) => {
|
||||
if(req.session.isLoggedIn && req.session.userRole === "mod"){
|
||||
const db = new Datastore("db/users.db");
|
||||
db.loadDatabase();
|
||||
db.find({role:"user" , group: req.session.userid }, (err, docs) => {
|
||||
if(docs.length > 0) {
|
||||
let resArray = [];
|
||||
docs.forEach(element => {
|
||||
resArray.push({
|
||||
username:element.username,
|
||||
suspended:element.suspended
|
||||
})
|
||||
});
|
||||
res.json({suc:true, users:resArray})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/getReviewPost", (req, res) => {
|
||||
if(req.session.isLoggedIn){
|
||||
const db = new Datastore("db/posts.db");
|
||||
db.loadDatabase();
|
||||
db.find({_id:req.session.revpost}, (err, docs) => {
|
||||
if(docs.length === 1) {
|
||||
let post = [];
|
||||
post.push({
|
||||
postid:docs[0]._id,
|
||||
username:docs[0].creatorName,
|
||||
showpost:docs[0].showpost,
|
||||
title:docs[0].title,
|
||||
text:docs[0].text,
|
||||
bcolor:docs[0].bcolor,
|
||||
startdate:docs[0].startDate,
|
||||
enddate:docs[0].endDate,
|
||||
})
|
||||
res.json({suc:true, post:post})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/getposts", (req, res) => {
|
||||
if(req.session.isLoggedIn){
|
||||
const db_post = new Datastore("db/posts.db");
|
||||
db_post.loadDatabase();
|
||||
switch(req.session.userRole)
|
||||
{
|
||||
case "admin":
|
||||
db_post.find({}, (err, docs) => {
|
||||
if(docs.length > 0) {
|
||||
let resArray = [];
|
||||
docs.forEach(element => {
|
||||
resArray.push({
|
||||
creator: element.creatorName,
|
||||
postid: element._id,
|
||||
title:element.title,
|
||||
text:element.text,
|
||||
showpost:element.showpost,
|
||||
startDate:element.startDate,
|
||||
endDate:element.endDate,
|
||||
})
|
||||
});
|
||||
res.json({suc:true, users:resArray})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "mod":
|
||||
db_post.find({creatorGroup:req.session.userid}, (err, docs) => {
|
||||
if(docs.length > 0) {
|
||||
let resArray = [];
|
||||
docs.forEach(element => {
|
||||
resArray.push({
|
||||
creator: element.creatorName,
|
||||
postid: element._id,
|
||||
title:element.title,
|
||||
text:element.text,
|
||||
showpost:element.showpost,
|
||||
startDate:element.startDate,
|
||||
endDate:element.endDate,
|
||||
})
|
||||
});
|
||||
res.json({suc:true, users:resArray})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "user":
|
||||
db_post.find({creatorId:req.session.userid}, (err, docs) => {
|
||||
if(docs.length > 0) {
|
||||
let resArray = [];
|
||||
docs.forEach(element => {
|
||||
resArray.push({
|
||||
title:element.title,
|
||||
showpost:element.showpost,
|
||||
postid:element._id
|
||||
})
|
||||
});
|
||||
res.json({suc:true, users:resArray})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/getliveposts", (req, res) => {
|
||||
const now = new Date();
|
||||
const db_post = new Datastore("db/posts.db");
|
||||
db_post.loadDatabase();
|
||||
const db_users = new Datastore("db/users.db");
|
||||
db_users.loadDatabase();
|
||||
db_post.find({}, (err, docs) => {
|
||||
if(docs.length > 0) {
|
||||
let resArray = [];
|
||||
docs.forEach(element => {
|
||||
if(element.showpost){
|
||||
|
||||
var start = new Date(element.startDate) - now;
|
||||
var end = new Date(element.endDate) - now;
|
||||
if(start < 0 && end > 0){
|
||||
db_users.find({_id:element.creatorId}, (err2, docs2) =>{
|
||||
docs2.forEach(element2 => {
|
||||
if(!element2.suspended)
|
||||
{
|
||||
db_users.find({_id:element.creatorGroup}, (err3, docs3) =>{
|
||||
docs3.forEach(element3 => {
|
||||
if(!element3.suspended)
|
||||
{
|
||||
resArray.push({
|
||||
title:element.title,
|
||||
text:element.text,
|
||||
bcolor:element.bcolor
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
setTimeout(function(){ res.json({suc:true, posts:resArray}); }, 100); //delay to resolve timing issue
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/*--------------------------------------------------FUNCTIONS--------------------------------------------------*/
|
||||
|
||||
app.post("/login", (req, res) => {
|
||||
const db = new Datastore("db/users.db");
|
||||
db.loadDatabase();
|
||||
const un = req.body.username;
|
||||
const pw = req.body.password;
|
||||
if(un && pw){
|
||||
db.find({username:un}, (err, docs) => {
|
||||
if(docs.length === 1){
|
||||
const userRole = docs[0].role;
|
||||
bcrypt.compare(pw, docs[0].password, (err2, result) => {
|
||||
if(result){
|
||||
req.session.userRole = userRole;
|
||||
req.session.userid = docs[0]._id;
|
||||
req.session.gr = docs[0].group;
|
||||
req.session.un = docs[0].username;
|
||||
req.session.revpost = 0;
|
||||
req.session.isLoggedIn = true;
|
||||
if(userRole === "admin") {
|
||||
res.json({suc:true, redirect:"admin"}) //login to admin page
|
||||
} else if(userRole === "mod"){
|
||||
res.json({suc:true, redirect:"mod"}) //login to mod page
|
||||
} else if(userRole === "user"){
|
||||
res.json({suc:true, redirect:"user"}) //login to user page
|
||||
}
|
||||
} else { res.json({suc:false}); }
|
||||
})
|
||||
} else { res.json({suc:false}); }
|
||||
})
|
||||
} else { res.json({suc:false}); }
|
||||
});
|
||||
|
||||
app.get("/logout", (req, res) => {
|
||||
req.session = null;
|
||||
res.redirect("/");
|
||||
});
|
||||
|
||||
app.post("/changepw", (req, res) => {
|
||||
const db = new Datastore("db/users.db");
|
||||
db.loadDatabase();
|
||||
const old_pw = req.body.old_password;
|
||||
const new_pw_1 = req.body.new_password_1;
|
||||
const new_pw_2 = req.body.new_password_2;
|
||||
if(old_pw && (new_pw_1 === new_pw_2)){
|
||||
db.find({_id:req.session.userid}, (err, docs) => {
|
||||
if(docs.length === 1){
|
||||
bcrypt.compare(old_pw, docs[0].password, (err2, result) => {
|
||||
if(result){
|
||||
bcrypt.hash(new_pw_1, 10, (err3, hash) => {
|
||||
db.update({_id: docs[0]._id}, {$set: {password: hash}}, (err4, num) =>{
|
||||
res.json({suc:true});
|
||||
});
|
||||
})
|
||||
} else { res.json({suc:false}); }
|
||||
})
|
||||
} else { res.json({suc:false}); }
|
||||
})
|
||||
} else { res.json({suc:false}); }
|
||||
})
|
||||
|
||||
app.post("/newmod", (req, res) => {
|
||||
if(req.session.isLoggedIn && req.session.userRole === "admin"){
|
||||
const nun = req.body.username;
|
||||
const nemail = req.body.email;
|
||||
const db = new Datastore("db/users.db");
|
||||
db.loadDatabase();
|
||||
db.find({username:nun}, (err, docs) => {
|
||||
if(docs.length === 0){
|
||||
db.find({email:nemail}, (err2, docs2) => {
|
||||
if(docs2.length === 0){
|
||||
bcrypt.hash(nun, 10, (err3, hash) => {
|
||||
db.insert({email: nemail,
|
||||
username: nun,
|
||||
password: hash,
|
||||
role: "mod",
|
||||
suspended: false
|
||||
}, (err4, doc) => {
|
||||
res.json({suc:true});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
})
|
||||
|
||||
app.post("/newuser", (req, res) => {
|
||||
if(req.session.isLoggedIn && req.session.userRole === "mod"){
|
||||
const nun = req.body.username;
|
||||
const nemail = req.body.email;
|
||||
const db = new Datastore("db/users.db");
|
||||
db.loadDatabase();
|
||||
db.find({username:nun}, (err, docs) => {
|
||||
if(docs.length === 0){
|
||||
db.find({email:nemail}, (err2, docs2) => {
|
||||
if(docs2.length === 0){
|
||||
bcrypt.hash(nun, 10, (err3, hash) => {
|
||||
db.insert({
|
||||
email: nemail,
|
||||
username: nun,
|
||||
password: hash,
|
||||
role: "user",
|
||||
group: req.session.userid,
|
||||
suspended: false
|
||||
}, (err4, doc) => {
|
||||
res.json({suc:true});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
})
|
||||
|
||||
app.post("/newpost", (req, res) => {
|
||||
if(req.session.isLoggedIn && req.session.userRole === "user"){
|
||||
const db = new Datastore("db/posts.db");
|
||||
db.loadDatabase();
|
||||
db.insert({
|
||||
creatorId:req.session.userid ,
|
||||
creatorName:req.session.un ,
|
||||
creatorGroup:req.session.gr ,
|
||||
showpost:false ,
|
||||
startDate:req.body.startDate ,
|
||||
endDate:req.body.endDate ,
|
||||
title:req.body.title ,
|
||||
text:req.body.text,
|
||||
bcolor:req.body.bcolor
|
||||
}, (err, doc) => {
|
||||
res.json({suc:true});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/toggleSus", (req, res) => {
|
||||
if(req.session.isLoggedIn && (req.session.userRole === "admin" || req.session.userRole === "mod")){
|
||||
const db = new Datastore("db/users.db");
|
||||
db.loadDatabase();
|
||||
db.find({username:req.body.username}, (err, docs) => {
|
||||
if(docs.length === 1) {
|
||||
var now = !docs[0].suspended;
|
||||
db.update({_id: docs[0]._id}, {$set: {suspended: now}}, (err2, num) =>{
|
||||
res.json({suc:true});
|
||||
})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/toggleShow", (req, res) => {
|
||||
if(req.session.isLoggedIn && (req.session.userRole === "mod" || req.session.userRole === "admin")){
|
||||
const db = new Datastore("db/posts.db");
|
||||
db.loadDatabase();
|
||||
db.find({_id:req.body.postid}, (err, docs) => {
|
||||
if(docs.length === 1) {
|
||||
var now = !docs[0].showpost;
|
||||
db.update({_id: docs[0]._id}, {$set: {showpost: now}}, (err2, num) =>{
|
||||
res.json({suc:true});
|
||||
})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/deleteMod", (req, res) => {
|
||||
if(req.session.isLoggedIn && req.session.userRole === "admin") {
|
||||
const db = new Datastore("db/users.db");
|
||||
db.loadDatabase();
|
||||
db.find({username:req.body.username}, (err, docs) => {
|
||||
if(docs.length === 1) {
|
||||
deleteMod(docs[0]._id);
|
||||
setTimeout(function(){ res.json({suc:true}); }, 1000); //delay to resolve timing issue
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/deleteUser", (req, res) => {
|
||||
if(req.session.isLoggedIn && req.session.userRole === "mod"){
|
||||
const db = new Datastore("db/users.db");
|
||||
db.loadDatabase();
|
||||
db.find({username:req.body.username}, (err, docs) => {
|
||||
if(docs.length === 1) {
|
||||
deleteUser(docs[0]._id);
|
||||
setTimeout(function(){ res.json({suc:true}); }, 1000); //delay to resolve timing issue
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/deletePost", (req, res) => {
|
||||
if(req.session.isLoggedIn){
|
||||
const db = new Datastore("db/posts.db");
|
||||
db.loadDatabase();
|
||||
db.find({_id:req.body.postid}, (err, docs) => {
|
||||
if(docs.length === 1) {
|
||||
deletePost(docs[0]._id);
|
||||
setTimeout(function(){ res.json({suc:true}); }, 1000); //delay to resolve timing issue
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
res.json({suc:false});
|
||||
}
|
||||
});
|
||||
|
||||
/*--------------------------------------------------FUNCTIONS--------------------------------------------------*/
|
||||
|
||||
function deleteMod(modID){
|
||||
const db_users = new Datastore("db/users.db");
|
||||
db_users.loadDatabase();
|
||||
db_users.find({group:modID}, (err, docs) => {
|
||||
docs.forEach(element => {
|
||||
deleteUser(element._id);
|
||||
if(docs.indexOf(element) === docs.length-1)
|
||||
db_users.find({_id:modID}, (err2, docs2) => {
|
||||
console.log("deleted mod: ", docs2[0]._id);
|
||||
db_users.remove({_id: docs2[0]._id});
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
function deleteUser(userID){
|
||||
const db_posts = new Datastore("db/posts.db");
|
||||
db_posts.loadDatabase();
|
||||
db_posts.find({creatorId:userID}, (err, docs) => {
|
||||
docs.forEach(element => {
|
||||
deletePost(element._id);
|
||||
});
|
||||
})
|
||||
const db_users = new Datastore("db/users.db");
|
||||
db_users.loadDatabase();
|
||||
db_users.find({_id:userID}, (err, docs) => {
|
||||
console.log("deleted user: ", docs[0]._id);
|
||||
db_users.remove({_id: docs[0]._id})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
function deletePost(postID){
|
||||
const db_posts = new Datastore("db/posts.db");
|
||||
db_posts.loadDatabase();
|
||||
db_posts.find({_id:postID}, (err, docs) => {
|
||||
console.log("deleted post: ", docs[0]._id);
|
||||
db_posts.remove({_id: docs[0]._id});
|
||||
})
|
||||
}
|
4
server.start
Normal file
4
server.start
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd `dirname $0`
|
||||
node server.js
|
Loading…
x
Reference in New Issue
Block a user