aboutsummaryrefslogtreecommitdiff
path: root/profile/public
diff options
context:
space:
mode:
authorMarvin Borner2021-01-29 14:10:45 +0100
committerMarvin Borner2021-01-29 14:10:45 +0100
commitaec1e8f2cd4c0fdedd200fc30094587c0834d372 (patch)
tree407946fbe687b252d4133067aa770e0ee24851b1 /profile/public
parent2eff2deb98280aa61241e06163c87155911bbfae (diff)
parent8637186a9f835972a5a0b96e4df1665d6d42557a (diff)
Merge branch 'crop'
Diffstat (limited to 'profile/public')
-rw-r--r--profile/public/index.html30
-rw-r--r--profile/public/script.js100
-rw-r--r--profile/public/style.css18
-rw-r--r--profile/public/user.js6
-rw-r--r--profile/public/users.html10
-rw-r--r--profile/public/users.js2
6 files changed, 148 insertions, 18 deletions
diff --git a/profile/public/index.html b/profile/public/index.html
index 672f409..91cb545 100644
--- a/profile/public/index.html
+++ b/profile/public/index.html
@@ -10,6 +10,12 @@
crossorigin="anonymous"
/>
<link rel="stylesheet" href="style.css" type="text/css" media="all" />
+ <link
+ rel="stylesheet"
+ href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.9/cropper.min.css"
+ integrity="sha512-w+u2vZqMNUVngx+0GVZYM21Qm093kAexjueWOv9e9nIeYJb1iEfiHC7Y+VvmP/tviQyA5IR32mwN/5hTEJx6Ng=="
+ crossorigin="anonymous"
+ />
<title>Steckbrief</title>
</head>
@@ -20,13 +26,33 @@
</div>
<main>
<h2 id="username"></h2>
+ <p>
+ Bitte fülle diese Seite nur mit korrekten Daten aus, da diese direkt in der Abizeitung dargestellt
+ werden. Auf dem Kinderbild solltest du gut sichtbar und nicht älter als 8 Jahre sein.
+ </p>
<form class="pure-form pure-form-stacked">
<fieldset>
- <!-- TODO: Consider autosave -->
- <button type="submit" class="pure-button pure-button-primary">Wohooo</button>
+ <button type="submit" class="pure-button pure-button-primary">Senden</button>
</fieldset>
</form>
</main>
+ <div class="popup">
+ <img id="popup-img" src="https://fengyuanchen.github.io/cropperjs/images/picture.jpg" alt="Picture" />
+ <button class="pure-button pure-button-primary" id="save-btn">Übernehmen</button>
+ <label for="rotation-slider">Drehen</label>
+ <input id="rotation-slider" type="range" min="-180" max="180" value="0" />
+ <div class="control-btns">
+ <button class="pure-button pure-button-primary" id="rot45" data-value="-45" data-rot="true">45</button>
+ <button class="pure-button pure-button-primary" id="nrot45" data-value="45" data-rot="true">-45</button>
+ <button class="pure-button pure-button-primary" id="norm" data-value="0" data-rot="false">0</button>
+ </div>
+ </div>
+
+ <script
+ src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.9/cropper.min.js"
+ integrity="sha512-9pGiHYK23sqK5Zm0oF45sNBAX/JqbZEP7bSDHyt+nT3GddF+VFIcYNqREt0GDpmFVZI3LZ17Zu9nMMc9iktkCw=="
+ crossorigin="anonymous"
+ ></script>
<script src="script.js"></script>
</body>
</html>
diff --git a/profile/public/script.js b/profile/public/script.js
index b927f9f..db9a277 100644
--- a/profile/public/script.js
+++ b/profile/public/script.js
@@ -1,9 +1,42 @@
const fs = document.querySelector("fieldset");
const form = document.querySelector("form");
let init = true;
+let imageInit = true;
+let imageID = -1;
+
+const popup = document.querySelector(".popup");
+const popupImage = document.querySelector("#popup-img");
+const saveBtn = document.querySelector("#save-btn");
+const slider = document.querySelector("#rotation-slider");
+const controlButtons = document.querySelectorAll(".control-btns button");
+let cropper = undefined;
+
+const crop = () => {
+ cropper = new Cropper(document.getElementById("popup-img"), {
+ // Consider dataset id
+ //dragMode: "move",
+ aspectRatio: 10 / 13,
+ //autoCropArea: 0.65,
+ //restore: false,
+ //guides: false,
+ //center: false,
+ //highlight: false,
+ //cropBoxMovable: false,
+ //cropBoxResizable: false,
+ //toggleDragModeOnDblclick: false,
+ });
+};
+
+NodeList.prototype.on = function (listener, event) {
+ for (const node of this) {
+ node.addEventListener(listener, event);
+ }
+};
function updateHeading(user) {
- document.getElementById("username").textContent = `Steckbrief: ${user.name} ${user.middlename || ""} ${user.surname}`;
+ document.getElementById("username").textContent = `Steckbrief: ${user.name} ${user.middlename || ""} ${
+ user.surname
+ }`;
}
function appendQuestions(question) {
@@ -19,6 +52,7 @@ function appendQuestions(question) {
img.src = "uploads/" + question.answer;
img.alt = "Image";
div.appendChild(img);
+ imageInit = false;
}
const field = document.createElement("input");
@@ -28,7 +62,21 @@ function appendQuestions(question) {
field.value = question.answer || "";
field.placeholder = question.question;
field.type = question.type;
- if (question.type === "file") field.accept = "image/*";
+ if (question.type === "file") {
+ imageID = question.id;
+ field.accept = "image/*";
+ field.addEventListener("input", (e) => {
+ const file = e.target.files[0];
+ popupImage.file = file;
+ const reader = new FileReader();
+ reader.addEventListener("load", (e) => {
+ popupImage.src = e.target.result;
+ popup.style.display = "block";
+ crop();
+ });
+ reader.readAsDataURL(file);
+ });
+ }
div.appendChild(field);
fs.insertBefore(div, fs.querySelector("button"));
@@ -36,20 +84,52 @@ function appendQuestions(question) {
form.addEventListener("submit", async (evt) => {
evt.preventDefault();
- const url = init ? "api/add" : "api/update";
const method = init ? "POST" : "PUT";
const inputs = form.querySelectorAll("input");
- const body = new FormData();
+ const rawBody = {};
for (const input of inputs) {
- if (input.type !== "file") body.append(input.name, input.value);
- else body.append(input.name, input.files[0] ?? "dbg-image");
+ if (input.type !== "file") rawBody[input.name] = input.value;
}
+ const body = JSON.stringify(rawBody);
+
+ const resp = await fetch("api/answer", { method, body, headers: { "Content-Type": "application/json" } });
+ const res = await resp.json();
+ if (!res.success) alert("An error occurred");
+ else init = false;
+});
+
+saveBtn.addEventListener("click", (e) => {
+ cropper.getCroppedCanvas().toBlob(async (blob) => {
+ const url = "api/answerImage";
+ const method = imageInit ? "POST" : "PUT";
+ const body = new FormData();
+ if (imageID === -1) {
+ return;
+ }
+ body.append(imageID, blob);
+ const resp = await fetch(url, { method, body });
+ const res = await resp.json();
+ if (!res.success) {
+ alert("An error occurred");
+ } else {
+ imageInit = false;
+ popup.style.display = "none";
+ cropper.destroy();
+ document.querySelectorAll("img").forEach((elem) => {
+ if (elem.src.startsWith("http")) elem.src += "#" + new Date().getTime();
+ });
+ }
+ }, "image/jpeg");
+});
+
+slider.addEventListener("input", (e) => {
+ cropper.rotateTo(-e.target.value);
+});
- const resp = await fetch(url, { method, body });
- const res = await resp.text();
- if (res !== "ok") alert("AHHHH");
- else location.reload();
+controlButtons.on("click", (e) => {
+ if (e.target.dataset.rot === "true") cropper.rotate(+e.target.dataset.value);
+ else cropper.rotateTo(+e.target.dataset.value);
});
fetch("/auth/api/self")
diff --git a/profile/public/style.css b/profile/public/style.css
index 106e590..becb428 100644
--- a/profile/public/style.css
+++ b/profile/public/style.css
@@ -54,12 +54,14 @@ img {
}
#user h1,
-#comments h2 {
+#comments h2,
+#char h2 {
cursor: pointer;
}
#user h1:hover,
-#comments h2:hover {
+#comments h2:hover,
+#char h2:hover {
opacity: 0.8;
}
@@ -132,3 +134,15 @@ img {
height: 80%;
margin-bottom: 12px;
}
+
+.popup {
+ z-index: 10;
+ position: absolute;
+ display: none;
+ max-height: 600px;
+ max-width: 600px;
+ left: 50%;
+ top: 50%;
+ transform: translateX(-50%) translateY(-50%);
+ border: 1px solid black;
+}
diff --git a/profile/public/user.js b/profile/public/user.js
index 39d6713..963904c 100644
--- a/profile/public/user.js
+++ b/profile/public/user.js
@@ -10,10 +10,12 @@ function addUser(userData) {
const questions = userData.questions;
const user = userData.user;
for (const questionID in questions) {
- if (!questions.hasOwnProperty(questionID)) continue;
+ if (!questions.hasOwnProperty(questionID) || questions[questionID].type === "file") continue;
const question = questions[questionID];
const div = document.createElement("div");
- div.innerHTML = `<b>${question.question}</b> <span>${question.answer || ""}</span>`;
+ div.innerHTML = `<b>${question.question.replace(/</g, "&lt;").replace(/>/g, "&gt;")}</b> <span>${
+ (question.answer || "nichts").replace(/</g, "&lt;").replace(/>/g, "&gt;") || ""
+ }</span>`;
divs.push(div);
}
const h1 = document.createElement("h1");
diff --git a/profile/public/users.html b/profile/public/users.html
index ebca429..f7bd346 100644
--- a/profile/public/users.html
+++ b/profile/public/users.html
@@ -19,12 +19,20 @@
</div>
<main>
- <p>Nutzerliste</p>
+ <p>
+ Hier kannst du andere Schüler kommentieren und Erkennungsmerkmale schreiben. Diese werden dann auf dem
+ Steckbrief der jeweiligen Person in der Abizeitung dargestellt.
+ </p>
<div id="student-list">
+ TGM13.1
<ul id="class_1"></ul>
+ TGM13.2
<ul id="class_2"></ul>
+ TGTM13.1
<ul id="class_3"></ul>
+ TGI13.1
<ul id="class_4"></ul>
+ TGI13.2
<ul id="class_5"></ul>
</div>
</main>
diff --git a/profile/public/users.js b/profile/public/users.js
index 77bc85c..73f0e4a 100644
--- a/profile/public/users.js
+++ b/profile/public/users.js
@@ -2,7 +2,7 @@ function addUser(user) {
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);
+ if (user.class_id < 6) document.getElementById("class_" + user.class_id).appendChild(li);
}
fetch("/auth/api/list?class=all")