This commit is contained in:
Turtle committed 2025-12-22 13:26:45 +01:00
1 parent e49ce13dc7
commit 322c62ec80
7 files changed
+387 -23

No files matched your search

+6 -3
View File
@@ -34,6 +34,7 @@ test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>test<br>
<script src="../auth.js"></script>
<script src="../lib/basic.js"></script>
<script src="../help/data_xample.js"></script>
<script>
showOverlay("overlay1");
@@ -42,16 +43,18 @@ showOverlay("overlay1");
async function main() {
const couchDB = new CouchDB();
await couchDB.set("login", {
"username": "bla",
"password": "bla"
await couchDB.set("xample", {
"my_data": 1,
"more_data": "bla"
});
const data = await couchDB.get("login");
console.log(JSON.stringify(data));
//Gibt { "username": "bla", "password": "bla" } wieder
}
main();
createTemp();
</script>
+82
View File
@@ -0,0 +1,82 @@
async function createTemp() {
const couchDB = new CouchDB();
await couchDB.set("users", {
"turtle": {
"password": "1234",
"level": 1,
"avatar": null,
"abilities": [],
"role": "student",
"courses": [
"weiche_ware",
"bucket"
]
},
"dumble-door": {
"password": "bla",
"level": 10,
"avatar": "https://static.turtle-coding-gbr.de/profile-pic.png",
"abilities": [],
"role": "professor",
"courses": [
"weiche_ware"
]
},
"narrator": {
"password": "stanley",
"level": 100,
"avatar": "https://static.turtle-coding-gbr.de/st",
"abilities": [],
"role": "professor",
"courses": [
"bucket"
]
}
});
await couchDB.set("course:bucket", {
"title": "Bucket",
"description": "The end is never the end is never the end is never",
"owner": "narrator",
"questions": [
{
"title": "What is comedic timing?",
"type": "text"
},
{
"title": "How does it work?",
"type": "text"
},
{
"title": "How long should it last?",
"type": "scala"
},
{
"title": "How can it be used to effectively silence your political enemies?",
"type": "emoji"
}
],
"result": [
["YES", "YES", 5, 2],
["YES", "YES", 1, 3]
]
});
await couchDB.set("course:weiche_ware", {
"title": "Weiche Ware",
"description": "blabering",
"owner": "dumble-door",
"questions": [
{
"title": "Wie fanden Sie die Vorlesung?",
"type": "text"
},
{
"title": "Finden Sie, dass man Zauberei an lebendigen Schülern praktizieren sollte?",
"type": "scala"
}
],
"result": [
["Gut, aber ...", 5],
["Schlecht", 1]
]
});
}
+24 -8
View File
@@ -7,11 +7,15 @@
##Overlays
```
//Erstelle ein element mit <overlay></overla> in html und vergebe eine id. Um das overlay anzuzeigen, rufe showOverlay mit der id auf
function showOverlay(string id);
//Erstelle ein element mit <overlay></overlay> in html und vergebe eine id. Um das overlay anzuzeigen, rufe showOverlay mit der id auf
function showOverlay(string id) -> void;
//Schließe das overlay mit der id
function hideOverlay(string id);
function hideOverlay(string id) -> void;
//Rufe das overlay auf
function getOverlay(string id) -> div;
```
##CouchDB
@@ -21,15 +25,17 @@ function hideOverlay(string id);
//Erstelle eine neue CouchDB-Klasse mit new CouchDB();
class CouchDB {
//Überprüfe, ob CouchDB online ist. (Wird sowieso automatisch gemacht, wenn get, set oder createDB verwendet wird)
async checkOnlineStatus();
async checkOnlineStatus() -> bool;
//Erstellt die Datenbank. (Wird auch automatisch gemacht, wenn man get oder set verwendet)
async createDB();
async createDB() -> void;
//Bekomme das Objekt, was in der Datenbank unter der id gespeichert wurde
async get(string id);
//Bekomme das Objekt, was in der Datenbank unter der id gespeichert wurde (Gibt null zurück, wenn nicht vorhanden)
async get(string id) -> Map|null;
//Setze ein Objekt, was in der Datenbank gespeichert wird (Bedenke: Du musst ein Objekt angeben, alles andere (string, array) wird nicht genommen)
async set(string id, object content, boolean replace = true);
async set(string id, object content, boolean replace = true) -> Map;
//Lösche ein Objekt, was in der Datenbank gespeichert ist
async delete(string id) -> Map;
}
```
@@ -54,3 +60,13 @@ async function main() {
}
main();
```
##User
```
//Gebe dir den Nutzer wieder
async function getUserData(couchDB) -> Map?;
//Setze den Nutzer, welcher unter der Variable userData verfügbar sein wird
async function setUserData(couchDB) -> bool;
```
+17 -1
View File
@@ -77,7 +77,7 @@ overlay {
backdrop-filter: blur(10px);
border-radius: var(--border-radius);
padding: 15px;
text-align: center;
text-align: left;
overflow-x: hidden;
overflow-y: auto;
box-shadow: var(--def-shadow);
@@ -169,3 +169,19 @@ content {
border-radius: 0;
}
}
/* ----------- custom ----------- */
.add_button {
width: 45px;
height: 45px;
border-radius: 50%;
padding: 0;
font-size: 25px;
background-color: white;
border: 1px solid black;
}
.add_button:hover {
border: 2px solid grey;
background-color: lightgray;
}
+98 -1
View File
@@ -1,18 +1,48 @@
const getId = (id) => document.getElementById(id);
function getOverlay(id) {
const elms = document.getElementsByName(id);
if (elms.length == 0) return null;
return elms[0];
}
function showOverlay(id) {
const elm = getId(id);
if (!elm) return;
const overlay = document.createElement("div");
const computedStyles = getComputedStyle(elm);
const defaultStyles = getDefaultComputedStyle(elm);
let styleString = "";
for (let style of computedStyles) {
if (style == "display") continue;
const computedValue = computedStyles.getPropertyValue(style);
const defaultValue = defaultStyles.getPropertyValue(style);
if (computedValue == defaultValue) continue;
styleString += `${style}: ${computedValue}; `;
}
overlay.classList.add("overlay");
overlay.setAttribute("name", id);
overlay.innerHTML = `
<div onclick="_onOverlayDestroy(this.parentElement);"></div>
<div>
<div class="${id}" style="${styleString}">
<button class="close" onclick="_onOverlayDestroy(this.parentElement.parentElement);">x</button>
${elm.innerHTML}
</div>
`;
document.body.appendChild(overlay);
const cb = elm.getAttribute("onopen");
if (typeof cb == "string") {
try {
eval(
`const overlay = document.getElementsByClassName("${id}")[0]; ` +
cb
);
} catch (err) {
console.error(err);
}
}
}
function _onOverlayDestroy(elm) {
const ori_elm = getId(elm.getAttribute("name"));
@@ -253,4 +283,71 @@ class CouchDB {
};
}
}
async delete(id) {
try {
var existingDoc = null;
try {
existingDoc = await this._get_db_data(id);
} catch (err) {}
if (!existingDoc) return {
type: "error",
message: "Not found!",
};
const res = await this._send_db_request(
"DELETE",
`${id}?rev=${existingDoc._rev}`
);
return {
type: "success",
message: res,
};
} catch (err) {
console.error(err);
return {
type: "error",
message: err,
};
}
}
}
//getuser
function getURLArgsMap() {
let spl = location.href.split("?");
if (spl.length != 2) return {};
let _1 = spl[1].split(",");
const res = {};
for (var i of _1) {
let _2 = i.split("=");
if (_2.length == 2) {
res[_2[0]] = _2[1];
} else {
res[i] = null;
}
}
return res;
}
async function getUserData(couchDB) {
const username = getURLArgsMap()["user"];
if (!username) return null;
const res = await couchDB.get("users");
if (!res) return null;
const data = res[username];
return !data ? null : {
...data,
"name": username
};
}
var userData = null;
async function setUserData(couchDB) {
const res = await getUserData(couchDB);
if (res == null) {
location.href = "../login.html";
return false;
}
userData = res;
return true;
}
+2 -10
View File
@@ -25,7 +25,7 @@ async function getData() {
async function login() {
const data = await getData();
const username = getId("username").value;
const username = getId("username").value.toLowerCase();
const password = getId("password").value;
const user = data[username];
@@ -39,17 +39,9 @@ async function login() {
return;
}
location.href = "/uebersicht.html";
location.href = "./prof/uebersicht.html?user=" + username;
}
couchDB.set("users", {
turtle: {
password: "password",
level: 1,
isProf: true
}
});
</script>
</body>
+158
View File
@@ -0,0 +1,158 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../lib/basic.css">
<script src="../auth.js"></script>
<script src="../lib/basic.js"></script>
<script>
const couchDB = new CouchDB();
setUserData(couchDB);
</script>
<title>Übersicht</title>
</head>
<body>
<!--Implementiere hier dein Zeugs-->
<style>
.edit_course {
min-width: 70% !important;
}
.edit_course input {
width: 100%;
font-size: 18px;
padding: 4px;
background: none;
border: 1px solid black;
border-radius: var(--border-radius);
}
.edit_course textarea {
width: 100%;
font-size: 18px;
resize: none;
padding: 4px;
background: none;
border: 1px solid black;
height: 100px;
border-radius: var(--border-radius);
}
.edit_course .evaluations {
overflow-y: auto;
text-align: center;
max-height: 400px;
border: 2px solid grey;
padding: 10px;
border-radius: var(--border-radius);
}
.edit_course .evaluations .evaluation {
display: inline-block;
width: 100%;
border-radius: var(--border-radius);
border: 1px solid black;
padding: 10px;
text-align: center;
margin-bottom: 10px;
position: relative;
}
.edit_course .evaluation span {
display: inline-block;
font-size: 20px !important;
width: calc(100% - 80px);
}
.edit_course .evaluation > select {
width: 90%;
font-size: 18px;
margin-top: 15px;
}
.edit_course .evaluation > button {
width: 40px;
height: 40px;
font-size: 28px;
position: absolute;
top: 5px;
right: 5px;
overflow: hidden;
}
.edit_course > button {
width: 100%;
font-size: 18px;
border-radius: var(--border-radius);
padding: 4px;
font-weight: normal;
}
</style>
<button onclick="showEditCourse('bucket')">Open Course:Bucket</button>
<overlay id="edit_course">
<input placeholder="Kursname" style="width: calc(100% - 50px);"><br><br>
<textarea placeholder="Beschreibung"></textarea><br><br>
<div class="evaluations">
<div></div>
<button class="add_button">+</button>
</div><br>
<button onclick="saveEditCourse()">Speichern</button>
</overlay>
<script>
async function showEditCourse(name) {
const data = await couchDB.get("course:" + name);
if (data.owner != userData.name) return;
showOverlay("edit_course");
const elm = getOverlay("edit_course");
const title = elm.getElementsByTagName("input")[0];
const description = elm.getElementsByTagName("textarea")[0];
title.value = data.title;
title.setAttribute("oldID", name);
description.value = data.description;
const evaluations = elm.querySelector(".evaluations > div");
for (var i of data.questions) {
evaluations.innerHTML += createEvaluation(i);
}
}
function createEvaluation(question) {
return `
<div class="evaluation">
<button>🗑</button>
<span>${question.title}</span>
<select>
<option value="text" ${question.type == "text" ? "selected": ""}>Text</option>
<option value="scala" ${question.type == "scala" ? "selected": ""}>Scala</option>
<option value="emoji" ${question.type == "emoji" ? "selected": ""}>Emoji</option>
</select>
</div>
`;
}
async function saveEditCourse() {
const elm = getOverlay("edit_course");
const title = elm.getElementsByTagName("input")[0];
const description = elm.getElementsByTagName("textarea")[0];
const oldID = title.getAttribute("oldID");
const data = await couchDB.get("course:" + oldID);
data["title"] = title.value;
data["description"] = description.value;
await couchDB.delete("course:" + oldID);
await couchDB.set("course:" + title.value.toLowerCase(), data);
hideOverlay("edit_course");
}
</script>
</body>
</html>