diff --git a/auth.js b/auth.js index 3b022be..706829c 100644 --- a/auth.js +++ b/auth.js @@ -3,4 +3,6 @@ const couchdb_password = "admin"; const couchdb_name = "sassy"; +const debug_username = "dumble-door"; //set a default user when not logged in + //http://127.0.0.1:5984/_utils/#_config/couchdb@127.0.0.1 diff --git a/help/Example.html b/help/Example.html index 27f3748..f926d9c 100644 --- a/help/Example.html +++ b/help/Example.html @@ -39,22 +39,23 @@ test
test
test
test
test
test
test
test
test
test
showOverlay("overlay1"); -//setTimeout(() => hideOverlay("overlay1"), 3000); +const couchDB = new CouchDB(); async function main() { - const couchDB = new CouchDB(); await couchDB.set("xample", { "my_data": 1, "more_data": "bla" }); - const data = await couchDB.get("login"); + const data = await couchDB.get("xample"); console.log(JSON.stringify(data)); - //Gibt { "username": "bla", "password": "bla" } wieder + //Gibt { "my_data": 1, "more_data": "bla" } wieder } main(); -createTemp(); +createTemp().then((v) => { + setUserData(couchDB); +}); diff --git a/help/data_xample.js b/help/data_xample.js index 301ee14..a93be73 100644 --- a/help/data_xample.js +++ b/help/data_xample.js @@ -58,7 +58,22 @@ async function createTemp() { "result": [ ["YES", "YES", 5, 2], ["YES", "YES", 1, 3] - ] + ], + "result_history": [ + { + "date": "2025-12-27", + "questions": [ + { "title": "1", "type": "text" }, + { "title": "2", "type": "scala" } + ], + "result": [ + ["Gut, aber ...", 5], + ["Schlecht", 1] + ] + } + ], + "start_date": "2025-12-23", + "expire_date": "2025-12-27" }); await couchDB.set("course:weiche_ware", { "title": "Weiche Ware", @@ -77,6 +92,21 @@ async function createTemp() { "result": [ ["Gut, aber ...", 5], ["Schlecht", 1] - ] + ], + "result_history": [ + { + "date": "2025-12-27", + "questions": [ + { "title": "1", "type": "text" }, + { "title": "2", "type": "scala" } + ], + "result": [ + ["Gut, aber ...", 5], + ["Schlecht", 1] + ] + } + ], + "start_date": "2025-12-23", + "expire_date": "2025-12-27" }); } \ No newline at end of file diff --git a/help/documentation.md b/help/documentation.md index 49163f6..a600f9c 100644 --- a/help/documentation.md +++ b/help/documentation.md @@ -70,3 +70,10 @@ async function getUserData(couchDB) -> Map?; //Setze den Nutzer, welcher unter der Variable userData verfügbar sein wird async function setUserData(couchDB) -> bool; ``` + +##Nützliche CSS-Klassen +- .profile = Runde Profilbox +- overlay = Overlay +- .header_bar_1 = Headerbar +- .header_bar_1_placeholder = Platzhalter für Headerbar +- .add_button = Runder "Hinzufügen"-Knopf \ No newline at end of file diff --git a/lib/basic.css b/lib/basic.css index db5e77b..ad237af 100644 --- a/lib/basic.css +++ b/lib/basic.css @@ -1,11 +1,14 @@ :root { - --accent_color_fg: #007bff; + --accent_color_fg: rgba(0, 123, 255, 1); + --accent_color_fg_o: rgba(0, 123, 255, 0.5); --accent_color_bg: rgba(137, 197, 221, 1); --accent_color_bg_o: rgba(137, 197, 221, 0.5); + --accent_color_bg_o2: rgba(137, 197, 221, 0.25); --main_color_fg: white; --main_color_bg: black; --border-radius: 10px; --def-shadow: 10px 20px 20px rgb(128, 128, 128, 0.5); + --reversed_def_shadow: inset 1px 2.5px 2.5px rgb(128, 128, 128, 0.5); } * { box-sizing: border-box; @@ -24,10 +27,10 @@ body, html { font-size: 20px; } ::selection { - background-color: var(--accent_color_fg); + background-color: var(--accent_color_fg_o); color: black; } -selectable { +.selectable { -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; @@ -42,6 +45,14 @@ selectable { border-radius: 50%; background: var(--accent_color_bg); border: none; + background-size: 58px 58px; +} +input { + font-size: 18px; + background: none; + border: 1px solid black; + border-radius: var(--border-radius); + padding: 4px; } /* ----------- overlay ----------- */ @@ -72,6 +83,8 @@ overlay { left: 50%; min-width: 250px; min-height: 150px; + max-height: 95%; + max-width: 95%; transform: translate(-50%, -50%); background: var(--accent_color_bg_o); backdrop-filter: blur(10px); @@ -117,6 +130,7 @@ overlay { } .header_bar_1 > div:nth-child(1) { text-align: left; + width: 100%; } .header_bar_1 > div:nth-child(2) { text-align: center; @@ -124,6 +138,7 @@ overlay { } .header_bar_1 > div:nth-child(3) { text-align: right; + width: 100%; } .header_bar_1_placeholder { @@ -184,4 +199,64 @@ content { .add_button:hover { border: 2px solid grey; background-color: lightgray; +} + + + +dropdown { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: none; + z-index: 300; +} +dropdown > div:first-child { + width: 100%; + height: 100%; + background: none; +} +dropdown > div:last-child { + position: absolute; + background: var(--accent_color_bg_o); + backdrop-filter: blur(10px); + border-radius: var(--border-radius); + transform: translate(calc(-100% + 50px), 5px); + width: 200px; + display: flex; + flex-direction:column; + box-shadow: var(--def-shadow); +} +dropdown > div:last-child label { + background: none; + font-size: 20px; + border: none; + border-bottom: 1px solid black; + padding-top: 8px; + padding-bottom: 8px; + font-weight: normal; + text-align: center; +} +dropdown > div:last-child button { + background: none; + font-size: 20px; + border: none; + border-bottom: 1px solid black; + padding-top: 8px; + padding-bottom: 8px; + font-weight: normal; + text-align: center; +} +dropdown > div:last-child button:hover { + background: var(--accent_color_fg_o); +} +dropdown > div:last-child button:first-child { + border-top-left-radius: var(--border-radius); + border-top-right-radius: var(--border-radius); +} +dropdown > div:last-child button:last-child { + border-bottom: none; + border-bottom-left-radius: var(--border-radius); + border-bottom-right-radius: var(--border-radius); } \ No newline at end of file diff --git a/lib/basic.js b/lib/basic.js index c1b8faf..020a4e4 100644 --- a/lib/basic.js +++ b/lib/basic.js @@ -330,9 +330,23 @@ function getURLArgsMap() { } return res; } + + +function form1(string) { + if (!string) return string; + return string.charAt(0).toUpperCase() + string.slice(1); +} + + async function getUserData(couchDB) { - const username = getURLArgsMap()["user"]; - if (!username) return null; + let username = getURLArgsMap()["user"]; + if (!username) { + if (typeof (debug_username) == "string") { + username = debug_username; + } else { + return null; + } + } const res = await couchDB.get("users"); if (!res) return null; const data = res[username]; @@ -341,6 +355,7 @@ async function getUserData(couchDB) { "name": username }; } + var userData = null; async function setUserData(couchDB) { const res = await getUserData(couchDB); @@ -349,5 +364,92 @@ async function setUserData(couchDB) { return false; } userData = res; + updateAllProfiles(res); return true; +} + +function updateAllProfiles(user) { + const profiles = document.getElementsByClassName("profile"); + for (var i of profiles) { + i.style.backgroundImage = `url("${user.avatar}")`; + i.onclick = _onProfileClick; + } +} +function _onProfileClick(event) { + var buttonRect = this.getBoundingClientRect(); + + var dropdown = document.createElement("dropdown"); + dropdown.addEventListener("click", dropdown.remove); + + var bg = document.createElement("div"); + dropdown.appendChild(bg); + + var div = document.createElement("div"); + + const _1 = window.innerHeight - buttonRect.y - 200; + if (_1 < 0) { + div.style.transform = "translate(calc(-100% + 58px), calc(-100% - 30px))"; + } + + div.style.top = (buttonRect.bottom) + 'px'; + div.style.left = (buttonRect.left) + 'px'; + div.innerHTML = ` + + + + `; + dropdown.appendChild(div); + + document.body.appendChild(dropdown); +} +function _onProfilClickOnProfil() { + if (typeof(showProfile) == "function") { + showProfile(userData); + } else { + _showProfile(userData); + } +} +function _showProfile(user) { + let elm = getId("profile_overlay"); + if (!elm) { + elm = document.createElement("overlay"); + elm.setAttribute("id", "profile_overlay"); + document.body.appendChild(elm); + } + elm.innerHTML = ` +
Profil-Übersicht
+ +
+
+${!user.title ? "": user.title+" "}${form1(user.name)} +

+
+ +Level: ${user.level ?? 0}
+Rolle: ${form1(user.role ?? "Student")} +

+Avatar:

+ + `; + showOverlay("profile_overlay"); +} +async function _showProfileSave(elm) { + if (!userData) return; + + let couchDB = new CouchDB(); + const res = await couchDB.get("users"); + + const avatar = elm.parentElement.querySelector("input"); + + userData.avatar = avatar.value; + + const user = {...userData}; + delete user["name"]; + res[userData.name] = user; + + await couchDB.set("users", res); + + updateAllProfiles(userData); + + hideOverlay("profile_overlay"); } \ No newline at end of file diff --git a/login.html b/login.html index f5d7dde..7d50240 100644 --- a/login.html +++ b/login.html @@ -1,6 +1,8 @@ + + Login diff --git a/prof/auswertung.html b/prof/auswertung.html new file mode 100644 index 0000000..3a3508f --- /dev/null +++ b/prof/auswertung.html @@ -0,0 +1,225 @@ + + + + + + + + + + + + +
+
+
+
⇦
+   Meine Kurse +
+
+
Auswertungen
+
+ +
+
+
+ + + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/prof/uebersicht.html b/prof/uebersicht.html index c966df6..3e13154 100644 --- a/prof/uebersicht.html +++ b/prof/uebersicht.html @@ -2,13 +2,13 @@ + Übersicht @@ -62,7 +62,7 @@ setUserData(couchDB); .edit_course .evaluations { overflow-y: auto; text-align: center; - max-height: 400px; + max-height: 300px; border: 2px solid grey; padding: 10px; border-radius: var(--border-radius); @@ -109,11 +109,15 @@ setUserData(couchDB);

+Beschreibung:

+Feedback-Fragen:

+Start-Termin:
+Abgabe-Termin:

@@ -121,21 +125,23 @@ setUserData(couchDB); async function showEditCourse(name) { // const data = await couchDB.get("course:" + name); - if (data.owner != userData.name) { + /*if (data.owner != userData.name) { console.error("User is not author"); return; - } + }*/ showOverlay("edit_course"); const elm = getOverlay("edit_course"); - const title = elm.getElementsByTagName("input")[0]; + const inputs = elm.getElementsByTagName("input"); const description = elm.getElementsByTagName("textarea")[0]; - title.value = data.title; - title.setAttribute("oldID", name); + inputs[0].value = data.title; + inputs[0].setAttribute("oldID", name); description.value = data.description; + inputs[1].value = data["start_date"] ?? ""; + inputs[2].value = data["expire_date"] ?? ""; const evaluations = elm.querySelector(".evaluations > div"); @@ -167,13 +173,13 @@ function createEvaluation(question) { } async function saveEditCourse() { const elm = getOverlay("edit_course"); - const title = elm.getElementsByTagName("input")[0]; + const inputs = elm.getElementsByTagName("input"); const description = elm.getElementsByTagName("textarea")[0]; - const oldID = title.getAttribute("oldID"); + const oldID = inputs[0].getAttribute("oldID"); const data = await couchDB.get("course:" + oldID); - data["title"] = title.value; + data["title"] = inputs[0].value; data["description"] = description.value; const evaluations = elm.querySelector(".evaluations > div"); @@ -189,9 +195,20 @@ async function saveEditCourse() { }); } data["questions"] = questions; + evaluations.remove(); + + if (inputs[1].value.length > 0) { + let dateObject = new Date(inputs[1].value); + let dateString = dateObject.toISOString().split('T')[0]; + data["start_date"] = dateString; + } if (inputs[2].value.length > 0) { + let dateObject = new Date(inputs[2].value); + let dateString = dateObject.toISOString().split('T')[0]; + data["expire_date"] = dateString; + } await couchDB.delete("course:" + oldID); - await couchDB.set("course:" + title.value.toLowerCase(), data); + await couchDB.set("course:" + inputs[0].value.toLowerCase(), data); hideOverlay("edit_course"); }