diff options
author | LarsVomMars | 2020-10-19 19:40:35 +0200 |
---|---|---|
committer | LarsVomMars | 2020-10-19 19:40:46 +0200 |
commit | e2c8fea877c156863dbf84f5593acf02894f56b5 (patch) | |
tree | 7e7b2da5ecd3abf984e41b5e44dc2c6a3197bf48 /profile | |
parent | 8d540e4d9aaa951b9031b38eb55bf181e04a8ab1 (diff) |
User comments frontend
Diffstat (limited to 'profile')
-rw-r--r-- | profile/index.js | 42 | ||||
-rw-r--r-- | profile/public/style.css | 55 | ||||
-rw-r--r-- | profile/public/user.html | 12 | ||||
-rw-r--r-- | profile/public/user.js | 148 | ||||
-rw-r--r-- | profile/public/users.html | 17 | ||||
-rw-r--r-- | profile/public/users.js | 11 |
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, "<").replace(/>/g, ">"), ]); } 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)); |