616 lines
13 KiB
HTML
616 lines
13 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=0.5">
|
|
<link rel="stylesheet" href="../lib/basic.css">
|
|
<script src="../auth.js"></script>
|
|
<script src="../lib/basic.js"></script>
|
|
<script src="../other/skills.js"></script>
|
|
<script src="../other/skilltree.js"></script>
|
|
<script>
|
|
const couchDB = new CouchDB();
|
|
setUserData(couchDB);
|
|
</script>
|
|
<title>Übersicht</title>
|
|
</head>
|
|
<body>
|
|
<div class="header_bar_1">
|
|
<div style="font-weight: bold;">
|
|
Meine Kurse
|
|
</div>
|
|
<div>
|
|
<button class="auswertung" onclick='location.href = "./auswertung.html?user=" + userData.name'>
|
|
Auswertungen
|
|
</button>
|
|
</div>
|
|
<div>
|
|
<button class="profile" onclick='showOverlay("miniProfile")'>
|
|
<overlay id="miniProfile">
|
|
hello
|
|
</overlay>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="header_bar_1_placeholder"></div>
|
|
|
|
<content>
|
|
<div id="course-list"></div>
|
|
|
|
<button class="new" id="newButton" onclick="showCourseCreation()">+</button>
|
|
|
|
<overlay id="createCourse" class="createCourse">
|
|
<input placeholder="Kursname" style="width: calc(100% - 50px);"><br><br>
|
|
Beschreibung:
|
|
<textarea placeholder="Beschreibung"></textarea><br><br>
|
|
Feedback-Fragen:
|
|
<div class="evaluations">
|
|
<div></div>
|
|
<button class="add_button" onclick="createCourseNewEvaluation()">+</button>
|
|
</div><br>
|
|
Start-Termin: <input type="date" style="margin-bottom: 5px;"><br>
|
|
Abgabe-Termin: <input type="date"><br><br>
|
|
<button onclick="saveCreateCourse()">Kurs erstellen</button>
|
|
</overlay>
|
|
|
|
<overlay id="deletionConfirmation">
|
|
<p style="padding: 15px;"> Wollen sie wirklich diesen Kurs löschen?</p>
|
|
<div style="display: flex; gap: 15px; justify-content: center;">
|
|
<button class="confirmation" onclick="confirmNo()">Abbrechen</button>
|
|
<button class="confirmation" onclick="confirmYes()">OK</button>
|
|
</div>
|
|
</overlay>
|
|
</content>
|
|
|
|
<style>
|
|
button.confirmation {
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
padding: 10px;
|
|
border: none;
|
|
border-radius: var(--border-radius);
|
|
background-color: var(--accent_color_fg);
|
|
cursor: pointer;
|
|
}
|
|
|
|
button.confirmation:hover {
|
|
background-color: var(--accent_color_fg_o);
|
|
}
|
|
|
|
button.new {
|
|
display: block;
|
|
margin: 20px auto;
|
|
font-size: 30px;
|
|
font-weight: bold;
|
|
border: none;
|
|
width: 60px;
|
|
height: 60px;
|
|
border-radius: 50%;
|
|
background-color: var(--accent_color_bg);
|
|
cursor: pointer;
|
|
}
|
|
|
|
button.new:hover {
|
|
background-color: var(--accent_color_bg_o);
|
|
}
|
|
|
|
button.auswertung {
|
|
font-size: 20px;
|
|
padding: 15px;
|
|
padding-left: 40px;
|
|
padding-right: 40px;
|
|
background-color: var(--accent_color_bg);
|
|
border: none;
|
|
border-radius: var(--border-radius);
|
|
cursor: pointer;
|
|
}
|
|
|
|
button.auswertung:focus-visible {
|
|
outline: 2px var(--accent_color_fg_o);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
button.auswertung:hover {
|
|
background: var(--accent_color_bg_o);
|
|
border-radius: var(--border-radius);
|
|
}
|
|
|
|
.course-card {
|
|
position: relative;
|
|
width: 80%;
|
|
min-height: 300px;
|
|
padding: 16px;
|
|
background: var(--accent_color_bg_o);
|
|
border-radius: 12px;
|
|
box-shadow: var(--def-shadow);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.course-title {
|
|
margin: 0;
|
|
padding: 10px;
|
|
font-size: 25px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.course-description {
|
|
margin: 0;
|
|
font-size: 20px;
|
|
padding: 10px;
|
|
}
|
|
|
|
.course-actions {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-top: auto;
|
|
}
|
|
|
|
.action {
|
|
padding: 8px;
|
|
border: none;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
font-size: 20px;
|
|
}
|
|
|
|
.action.start {
|
|
position: absolute;
|
|
top: 16px;
|
|
right: 70px;
|
|
font-size: 20px;
|
|
border-radius: var(--border-radius);
|
|
background-color: var(--accent_color_bg);
|
|
}
|
|
|
|
.action.start:hover {
|
|
background: var(--accent_color_bg_o);
|
|
border-radius: var(--border-radius);
|
|
}
|
|
|
|
.action.delete {
|
|
position: absolute;
|
|
top: 16px;
|
|
right: 16px;
|
|
font-size: 20px;
|
|
padding-left: 12px;
|
|
padding-right: 12px;
|
|
max-height: 40px;
|
|
border-radius: var(--border-radius);
|
|
background-color: var(--accent_color_bg);
|
|
}
|
|
|
|
.action.delete:hover {
|
|
background: var(--accent_color_bg_o);
|
|
border-radius: var(--border-radius);
|
|
}
|
|
|
|
.action.edit {
|
|
position: absolute;
|
|
bottom: 16px;
|
|
right: 16px;
|
|
font-size: 25px;
|
|
padding-left: 12px;
|
|
padding-right: 12px;
|
|
border-radius: var(--border-radius);
|
|
background-color: var(--accent_color_bg);
|
|
}
|
|
|
|
.action.edit:hover {
|
|
background: var(--accent_color_bg_o);
|
|
border-radius: var(--border-radius);
|
|
}
|
|
|
|
#course-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 15px;
|
|
align-items: center;
|
|
}
|
|
|
|
.createCourse {
|
|
min-width: 70% !important;
|
|
}
|
|
.createCourse input {
|
|
width: 100%;
|
|
font-size: 18px;
|
|
padding: 4px;
|
|
background: none;
|
|
border: 1px solid black;
|
|
border-radius: var(--border-radius);
|
|
}
|
|
.createCourse textarea {
|
|
width: 100%;
|
|
font-size: 18px;
|
|
resize: none;
|
|
padding: 4px;
|
|
background: none;
|
|
border: 1px solid black;
|
|
height: 100px;
|
|
border-radius: var(--border-radius);
|
|
}
|
|
.createCourse .evaluations {
|
|
overflow-y: auto;
|
|
text-align: center;
|
|
max-height: 300px;
|
|
border: 2px solid grey;
|
|
padding: 10px;
|
|
border-radius: var(--border-radius);
|
|
}
|
|
.createCourse .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;
|
|
}
|
|
.createCourse .evaluation input {
|
|
display: inline-block;
|
|
font-size: 20px !important;
|
|
width: calc(100% - 80px);
|
|
}
|
|
.createCourse .evaluation > select {
|
|
width: 90%;
|
|
font-size: 18px;
|
|
margin-top: 15px;
|
|
}
|
|
.createCourse .evaluation > button {
|
|
width: 40px;
|
|
height: 40px;
|
|
font-size: 23px;
|
|
position: absolute;
|
|
top: 5px;
|
|
right: 5px;
|
|
overflow: hidden;
|
|
}
|
|
.createCourse > button {
|
|
width: 100%;
|
|
font-size: 18px;
|
|
border-radius: var(--border-radius);
|
|
padding: 4px;
|
|
font-weight: normal;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
(async () => {
|
|
await setUserData(couchDB);
|
|
await setCourseView();
|
|
})();
|
|
|
|
async function setCourseView() {
|
|
const courseList = document.getElementById("course-list");
|
|
courseList.innerHTML = "";
|
|
|
|
for(const courseId of userData.courses) {
|
|
const course = await couchDB.get("course:" + courseId);
|
|
|
|
const card = document.createElement("div");
|
|
card.className = "course-card";
|
|
|
|
card.innerHTML = `
|
|
<div class="course-title">${course.title}</div>
|
|
|
|
<div class="course-description">
|
|
${course.description}
|
|
</div>
|
|
|
|
<button class="action start" onclick='location.href = "./kursAnzeige.html?user=${userData.name},course=${courseId}";'>
|
|
Umfrage Starten
|
|
</button>
|
|
|
|
<button class="action edit" onclick="showEditCourse('${courseId}')">
|
|
✎
|
|
</button>
|
|
|
|
<button class="action delete" onclick="deleteCourse('${courseId}')">
|
|
🗑
|
|
</button>
|
|
`;
|
|
courseList.appendChild(card);
|
|
}
|
|
}
|
|
|
|
function createCourseNewEvaluation() {
|
|
const elm = getOverlay("createCourse");
|
|
if (elm == null) return;
|
|
|
|
const evaluations = elm.querySelector(".evaluations > div");
|
|
evaluations.appendChild(createEvaluation({
|
|
"title": "", "type": "text"
|
|
}));
|
|
}
|
|
|
|
async function saveCreateCourse() {
|
|
const elm = getOverlay("createCourse");
|
|
const inputs = elm.getElementsByTagName("input");
|
|
const description = elm.getElementsByTagName("textarea")[0];
|
|
|
|
const title = inputs[0].value.toLowerCase().trim();
|
|
if (title.length == 0) {
|
|
alert("Kursname darf nicht leer sein");
|
|
return;
|
|
}
|
|
|
|
const courseId = title.replace(/\s+/g, "_");
|
|
|
|
const sDateInp = inputs[inputs.length-2];
|
|
const eDateInp = inputs[inputs.length-1];
|
|
|
|
const data = {
|
|
"title": title,
|
|
"description": description.value,
|
|
"owner": userData.name,
|
|
"questions": [],
|
|
"result": [],
|
|
"result_history": [],
|
|
"start_date": sDateInp.value || "",
|
|
"expire_date": eDateInp.value || ""
|
|
};
|
|
|
|
const evaluations = elm.querySelector(".evaluations > div");
|
|
const questions = [];
|
|
for (var i of evaluations.getElementsByClassName("evaluation")) {
|
|
const inpE = i.querySelector("input");
|
|
const selE = i.querySelector("select");
|
|
if (inpE.value.length == 0) continue;
|
|
|
|
questions.push({
|
|
"title": inpE.value,
|
|
"type": selE.value
|
|
});
|
|
}
|
|
data.questions = questions;
|
|
evaluations.remove();
|
|
|
|
await couchDB.set("course:" + courseId, data);
|
|
|
|
const users = await couchDB.get("users");
|
|
users[userData.name].courses.push(courseId);
|
|
await couchDB.set("users", users);
|
|
|
|
hideOverlay("createCourse");
|
|
location.reload();
|
|
}
|
|
|
|
async function showCourseCreation() {
|
|
showOverlay("createCourse");
|
|
}
|
|
|
|
let confirmReturn = null;
|
|
|
|
function showConfirm(onYes) {
|
|
confirmReturn = onYes;
|
|
showOverlay("deletionConfirmation")
|
|
}
|
|
|
|
function confirmYes() {
|
|
hideOverlay("deletionConfirmation")
|
|
if (confirmReturn) {
|
|
confirmReturn()
|
|
}
|
|
confirmReturn = null;
|
|
}
|
|
|
|
function confirmNo() {
|
|
hideOverlay("deletionConfirmation")
|
|
confirmReturn = null;
|
|
}
|
|
|
|
async function deleteCourse(courseId) {
|
|
showConfirm(
|
|
async() => {
|
|
await couchDB.delete("course:" + courseId);
|
|
|
|
const users = await couchDB.get("users");
|
|
users[userData.name].courses = users[userData.name].courses.filter(id => id !== courseId);
|
|
await couchDB.set("users", users);
|
|
|
|
location.reload();
|
|
}
|
|
)
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
<!--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: 300px;
|
|
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 input {
|
|
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: 23px;
|
|
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>
|
|
|
|
<overlay id="edit_course">
|
|
<input placeholder="Kursname" style="width: calc(100% - 50px);"><br><br>
|
|
Beschreibung:
|
|
<textarea placeholder="Beschreibung"></textarea><br><br>
|
|
Feedback-Fragen:
|
|
<div class="evaluations">
|
|
<div></div>
|
|
<button class="add_button" onclick="createNewEvaluation()">+</button>
|
|
</div><br>
|
|
Start-Termin: <input type="date" style="margin-bottom: 5px;"><br>
|
|
Abgabe-Termin: <input type="date"><br><br>
|
|
<button onclick="saveEditCourse()">Speichern</button>
|
|
</overlay>
|
|
|
|
<script>
|
|
|
|
async function showEditCourse(name) { //
|
|
const data = await couchDB.get("course:" + name);
|
|
/*if (data.owner != userData.name) {
|
|
console.error("User is not author");
|
|
return;
|
|
}*/
|
|
|
|
showOverlay("edit_course");
|
|
|
|
const elm = getOverlay("edit_course");
|
|
|
|
const inputs = elm.getElementsByTagName("input");
|
|
const description = elm.getElementsByTagName("textarea")[0];
|
|
|
|
inputs[0].value = data.title;
|
|
inputs[0].setAttribute("oldID", name);
|
|
description.value = data.description;
|
|
|
|
const sDateInp = inputs[inputs.length-2];
|
|
const eDateInp = inputs[inputs.length-1];
|
|
|
|
sDateInp.value = data["start_date"] ?? "";
|
|
eDateInp.value = data["expire_date"] ?? "";
|
|
|
|
const evaluations = elm.querySelector(".evaluations > div");
|
|
|
|
for (var i of data.questions) {
|
|
evaluations.appendChild(createEvaluation(i));
|
|
}
|
|
}
|
|
function createNewEvaluation() {
|
|
const elm = getOverlay("edit_course");
|
|
if (elm == null) return;
|
|
|
|
const evaluations = elm.querySelector(".evaluations > div");
|
|
evaluations.appendChild(
|
|
createEvaluation({
|
|
"title": "", "type": "text"
|
|
})
|
|
);
|
|
}
|
|
function createEvaluation(question) {
|
|
const div = document.createElement("div");
|
|
div.classList.add("evaluation");
|
|
div.innerHTML = `
|
|
<button onclick="this.parentElement.remove();">🗑</button>
|
|
<input value="${question.title}">
|
|
<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>
|
|
`;
|
|
return div;
|
|
}
|
|
async function saveEditCourse() {
|
|
const elm = getOverlay("edit_course");
|
|
const inputs = elm.getElementsByTagName("input");
|
|
const description = elm.getElementsByTagName("textarea")[0];
|
|
|
|
const oldID = inputs[0].getAttribute("oldID");
|
|
const data = await couchDB.get("course:" + oldID);
|
|
|
|
data["title"] = inputs[0].value;
|
|
data["description"] = description.value;
|
|
|
|
const evaluations = elm.querySelector(".evaluations > div");
|
|
const questions = [];
|
|
for (var i of evaluations.getElementsByClassName("evaluation")) {
|
|
const inpE = i.querySelector("input");
|
|
const selE = i.querySelector("select");
|
|
if (inpE.value.length == 0) continue;
|
|
|
|
questions.push({
|
|
"title": inpE.value,
|
|
"type": selE.value
|
|
});
|
|
}
|
|
data["questions"] = questions;
|
|
evaluations.remove();
|
|
|
|
const sDateInp = inputs[inputs.length-2];
|
|
const eDateInp = inputs[inputs.length-1];
|
|
|
|
if (sDateInp.value.length > 0) {
|
|
let dateObject = new Date(sDateInp.value);
|
|
let dateString = dateObject.toISOString().split('T')[0];
|
|
data["start_date"] = dateString;
|
|
} if (eDateInp.value.length > 0) {
|
|
let dateObject = new Date(eDateInp.value);
|
|
let dateString = dateObject.toISOString().split('T')[0];
|
|
data["expire_date"] = dateString;
|
|
}
|
|
|
|
|
|
await couchDB.set("course:" + oldID, data);
|
|
|
|
hideOverlay("edit_course");
|
|
setCourseView();
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
</body>
|
|
</html> |