aboutsummaryrefslogtreecommitdiff
path: root/profile
diff options
context:
space:
mode:
authorLarsVomMars2020-10-19 19:40:35 +0200
committerLarsVomMars2020-10-19 19:40:46 +0200
commite2c8fea877c156863dbf84f5593acf02894f56b5 (patch)
tree7e7b2da5ecd3abf984e41b5e44dc2c6a3197bf48 /profile
parent8d540e4d9aaa951b9031b38eb55bf181e04a8ab1 (diff)
User comments frontend
Diffstat (limited to 'profile')
-rw-r--r--profile/index.js42
-rw-r--r--profile/public/style.css55
-rw-r--r--profile/public/user.html12
-rw-r--r--profile/public/user.js148
-rw-r--r--profile/public/users.html17
-rw-r--r--profile/public/users.js11
6 files changed, 265 insertions, 20 deletions
diff --git a/profile/index.js b/profile/index.js
index e6627d6..1a46fc1 100644
--- a/profile/index.js
+++ b/profile/index.js
@@ -7,12 +7,22 @@ app.use(fileupload({}));
app.use("/", express.static(__dirname + "/public/"));
-// Basic API
-app.get("/api/user", async (req, res) => {
- const user = (await db.query("SELECT name, surname FROM users WHERE id = ?", [req.session.uid]))[0];
- res.json(user);
+app.get("/api/user/:uid", async (req, res) => {
+ const uid = req.params.uid;
+ const user = await db.query("SELECT name, middlename, surname FROM users WHERE id = ?", [uid]);
+ const questions = await db.query(
+ "SELECT q.id, q.question, t.type FROM profile_questions q INNER JOIN profile_input_types t ON t.id = q.question_type",
+ );
+ const answers = await db.query("SELECT answer, question_id FROM profile_answers WHERE user_id = ?", [uid]);
+
+ for (const answer of answers) {
+ const qid = questions.findIndex((question) => question.id === answer.question_id);
+ if (qid !== undefined) questions[qid].answer = answer.answer;
+ }
+ res.json({ user: user[0], questions });
});
+// Basic API
app.get("/api/questions", async (req, res) => {
const questions = await db.query(
"SELECT q.id, q.question, t.type FROM profile_questions q INNER JOIN profile_input_types t ON t.id = q.question_type",
@@ -36,7 +46,7 @@ app.post("/api/add", async (req, res) => {
await db.query("INSERT INTO profile_answers (question_id, user_id, answer) VALUES (?, ?, ?)", [
qid,
req.session.uid,
- answer,
+ answer.replace(/</g, "&lt;").replace(/>/g, "&gt;"),
]);
}
for (let fid in req.files) {
@@ -49,7 +59,7 @@ app.post("/api/add", async (req, res) => {
imageName = `${req.session.uid}_${new Date().getTime()}.${imageType}`;
image.mv(__dirname + "/public/uploads/" + imageName);
await db.query("INSERT INTO profile_answers (question_id, user_id, answer) VALUES (?, ?, ?)", [
- qid,
+ fid,
req.session.uid,
imageName,
]);
@@ -97,28 +107,32 @@ app.put("/api/update", async (req, res) => {
// Comments API
app.get("/api/comments/:uid", async (req, res) => {
const uid = req.params.uid;
- const comments = await db.query("SELECT * FROM profile_comments WHERE profile_id = ?", [uid]);
+ const comments = await db.query(
+ "SELECT *, (user_id = ? OR ?) AS owner FROM profile_comments WHERE profile_id = ?",
+ [req.session.uid, req.session.isAdmin, uid],
+ );
res.json(comments);
});
app.post("/api/comment", async (req, res) => {
const { pid, comment } = req.body;
- if (!pid || !comment) return res.send("error");
+ if (!pid || !comment) return res.json({ success: false });
try {
await db.query("INSERT INTO profile_comments (user_id, profile_id, comment) VALUES (?,?,?)", [
req.session.uid,
pid,
comment,
]);
+ res.json({ success: true });
} catch (e) {
console.error(e);
- return res.send("error");
+ return res.json({ success: false });
}
});
app.put("/api/comment", async (req, res) => {
const { pid, cid, comment } = req.body;
- if (!pid || !comment || !cid) return res.send("error");
+ if (!pid || !comment || !cid) return res.json({ success: false });
try {
await db.query("UPDATE profile_comments SET comment = ? WHERE user_id = ? AND profile_id = ? AND id = ?", [
comment,
@@ -126,24 +140,26 @@ app.put("/api/comment", async (req, res) => {
pid,
cid,
]);
+ res.json({ success: true });
} catch (e) {
console.error(e);
- return res.send("error");
+ return res.json({ success: false });
}
});
app.delete("/api/comment", async (req, res) => {
const { pid, cid } = req.body;
- if (!pid || !cid) return res.send("error");
+ if (!pid || !cid) return res.json({ success: false });
try {
await db.query("DELETE FROM profile_comments WHERE user_id = ? AND profile_id = ? AND id = ?", [
req.session.uid,
pid,
cid,
]);
+ res.json({ success: true });
} catch (e) {
console.error(e);
- return res.send("error");
+ return res.json({ success: false });
}
});
diff --git a/profile/public/style.css b/profile/public/style.css
index 825cf24..600c2b5 100644
--- a/profile/public/style.css
+++ b/profile/public/style.css
@@ -44,3 +44,58 @@ img {
width: calc(100% - 20%);
}
}
+
+#student-list li {
+ cursor: pointer;
+}
+
+#student-list li:hover {
+ opacity: 0.8;
+}
+
+#user h1 {
+ cursor: pointer;
+}
+
+#user h1:hover {
+ opacity: 0.8;
+}
+
+#comments div {
+ display: flex;
+ flex-flow: row wrap;
+ justify-content: space-between;
+}
+
+#comments h1 {
+ cursor: pointer;
+}
+
+#comments h1:hover {
+ opacity: 0.8;
+}
+
+#comments .edit-btn,
+#comments .delete-btn,
+#comments .add-btn {
+ cursor: pointer;
+}
+
+#comments .edit-btn:hover,
+#comments .delete-btn:hover,
+#comments .add-btn:hover {
+ opacity: 0.8;
+}
+
+#comments #add-div {
+ justify-content: center;
+}
+
+#comments #add-div div {
+ width: 100%;
+}
+
+#comments #add-div div textarea {
+ width: 100%;
+ height: 80%;
+}
diff --git a/profile/public/user.html b/profile/public/user.html
index 85c186e..8a3e980 100644
--- a/profile/public/user.html
+++ b/profile/public/user.html
@@ -4,6 +4,13 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title></title>
+ <link
+ rel="stylesheet"
+ href="https://unpkg.com/purecss@2.0.3/build/pure-min.css"
+ integrity="sha384-cg6SkqEOCV1NbJoCu11+bm0NvBRc8IYLRGXkmNrqUBfTjmMYwNKPWBTIKyw9mHNJ"
+ crossorigin="anonymous"
+ />
+ <link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="pure-menu pure-menu-horizontal">
@@ -11,7 +18,10 @@
<a href="/auth/api/logout" class="pure-menu-item pure-menu-link">Logout</a>
</div>
- <main></main>
+ <main>
+ <div id="user"></div>
+ <div id="comments"></div>
+ </main>
<script src="user.js" charset="utf-8"></script>
</body>
diff --git a/profile/public/user.js b/profile/public/user.js
index e69de29..96215e7 100644
--- a/profile/public/user.js
+++ b/profile/public/user.js
@@ -0,0 +1,148 @@
+const uid = new URL(window.location.href).searchParams.get("uid");
+const userDiv = document.getElementById("user");
+const commentsDiv = document.getElementById("comments");
+
+if (uid < 1 || uid > 119) window.location.assign("./users.html"); // Well
+
+function addUser(userData) {
+ const divs = [];
+ const questions = userData.questions;
+ const user = userData.user;
+ for (const questionID in questions) {
+ if (!questions.hasOwnProperty(questionID)) continue;
+ const question = questions[questionID];
+ const div = document.createElement("div");
+ div.innerHTML = `<b>${question.question}</b>: <span>${question.answer || ""}</span>`;
+ divs.push(div);
+ }
+ const h1 = document.createElement("h1");
+ h1.textContent = `${user.name} ${user.middlename || ""} ${user.surname}`;
+ h1.addEventListener("click", (evt) => {
+ const qDivs = evt.target.parentElement.querySelectorAll("div");
+ qDivs.forEach(
+ (div) => (div.style.display = !div.style.display || div.style.display === "block" ? "none" : "block"),
+ );
+ });
+ userDiv.append(h1, ...divs);
+}
+
+async function addComments(comments) {
+ const h1 = document.createElement("h1");
+ h1.textContent = "Kommentare";
+ h1.addEventListener("click", (evt) => {
+ const qDivs = evt.target.parentElement.querySelectorAll("div");
+ qDivs.forEach(
+ (div) => (div.style.display = !div.style.display || div.style.display === "flex" ? "none" : "flex"),
+ );
+ });
+ const divs = [];
+ for (const comment of comments) {
+ const div = document.createElement("div");
+ div.dataset.id = comment.id;
+ const span = document.createElement("span");
+ span.textContent = comment.comment;
+ div.append(span);
+
+ if (comment.owner) {
+ const buttons = document.createElement("div");
+ buttons.classList.add("control-buttons");
+
+ const del = document.createElement("span");
+ del.classList.add("delete-btn");
+ del.textContent = "[Löschen]";
+ del.addEventListener("click", async (evt) => {
+ const body = JSON.stringify({
+ pid: uid,
+ cid: evt.target.parentElement.parentElement.dataset.id,
+ });
+ const resp = await fetch("api/comment", {
+ method: "DELETE",
+ headers: { "Content-Type": "application/json" },
+ body,
+ });
+ const res = await resp.json();
+ if (res.success) window.location.reload();
+ });
+
+ const edit = document.createElement("span");
+ edit.classList.add("edit-btn");
+ edit.textContent = "[Bearbeiten]";
+ edit.addEventListener("click", (evt) => {
+ const updateDiv = document.createElement("div");
+
+ const input = document.createElement("input");
+ input.value = comment.comment;
+ const submit = document.createElement("input");
+ submit.type = "submit";
+ submit.value = "Speichern";
+ submit.classList.add("pure-button", "pure-button-primary");
+
+ submit.addEventListener("click", async () => {
+ const body = JSON.stringify({
+ pid: uid,
+ cid: evt.target.parentElement.parentElement.dataset.id,
+ comment: input.value,
+ });
+ const resp = await fetch("api/comment", {
+ method: "PUT",
+ headers: { "Content-Type": "application/json" },
+ body,
+ });
+ const res = await resp.json();
+ if (res.success) window.location.reload();
+ });
+
+ updateDiv.append(input, submit);
+ div.insertAdjacentElement("beforebegin", updateDiv);
+ commentsDiv.removeChild(div);
+ });
+
+ buttons.append(edit, del);
+ div.append(buttons);
+ }
+ divs.push(div);
+ }
+
+ commentsDiv.append(h1, ...divs);
+
+ const addDiv = document.createElement("div");
+ addDiv.id = "add-div";
+ const add = document.createElement("span");
+ add.classList.add("add-btn");
+ add.textContent = "[Neuen Kommentar hinzufügen]";
+ add.addEventListener("click", (evt) => {
+ const div = document.createElement("div");
+ const input = document.createElement("textarea");
+ const submit = document.createElement("input");
+ submit.type = "submit";
+ submit.value = "Hinzufügen";
+ submit.classList.add("pure-button", "pure-button-primary");
+
+ submit.addEventListener("click", async (evt) => {
+ const comment = input.value;
+ console.log(comment);
+ const body = JSON.stringify({ comment, pid: uid });
+ const resp = await fetch("api/comment", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body,
+ });
+ const res = await resp.json();
+ console.log(res);
+ if (res.success) window.location.reload();
+ });
+ div.append(input, submit);
+ addDiv.removeChild(add);
+ addDiv.append(div);
+ });
+ addDiv.append(add);
+ commentsDiv.append(addDiv);
+}
+
+fetch(`api/user/${uid}`)
+ .then((response) => response.json())
+ .then(addUser);
+
+fetch(`api/comments/${uid}`)
+ .then((response) => response.json())
+ .then(addComments);
diff --git a/profile/public/users.html b/profile/public/users.html
index 550ff4b..ebca429 100644
--- a/profile/public/users.html
+++ b/profile/public/users.html
@@ -5,6 +5,12 @@
<meta name="viewport" content="width=device-width" />
<title>Benutzer</title>
<link rel="stylesheet" href="style.css" type="text/css" media="screen" charset="utf-8" />
+ <link
+ rel="stylesheet"
+ href="https://unpkg.com/purecss@2.0.3/build/pure-min.css"
+ integrity="sha384-cg6SkqEOCV1NbJoCu11+bm0NvBRc8IYLRGXkmNrqUBfTjmMYwNKPWBTIKyw9mHNJ"
+ crossorigin="anonymous"
+ />
</head>
<body>
<div class="pure-menu pure-menu-horizontal">
@@ -12,7 +18,16 @@
<a href="/auth/api/logout" class="pure-menu-item pure-menu-link">Logout</a>
</div>
- <main></main>
+ <main>
+ <p>Nutzerliste</p>
+ <div id="student-list">
+ <ul id="class_1"></ul>
+ <ul id="class_2"></ul>
+ <ul id="class_3"></ul>
+ <ul id="class_4"></ul>
+ <ul id="class_5"></ul>
+ </div>
+ </main>
<script src="users.js" charset="utf-8"></script>
</body>
diff --git a/profile/public/users.js b/profile/public/users.js
index 0f3700a..77bc85c 100644
--- a/profile/public/users.js
+++ b/profile/public/users.js
@@ -1,9 +1,10 @@
function addUser(user) {
- const div = document.createElement("div");
- // Idk what to do lel
+ const li = document.createElement("li");
+ li.textContent = `${user.name} ${user.middlename || ""} ${user.surname}`;
+ li.addEventListener("click", () => window.location.assign(`./user.html?uid=${user.id}`));
+ document.getElementById("class_" + user.class_id).appendChild(li);
}
-fetch("api/users")
+fetch("/auth/api/list?class=all")
.then((response) => response.json())
- .then((response) => response.forEach(addUser))
- .catch(console.error);
+ .then((response) => response.forEach(addUser));