first commit

This commit is contained in:
schmieders
2022-12-10 12:25:13 +01:00
commit 06cedbd790
36 changed files with 3550 additions and 0 deletions
+414
View File
@@ -0,0 +1,414 @@
/***********/
/* GENERAL */
/***********/
:root {
/* Override Bootstrap colors */
--bs-primary: #e2001a;
--bs-secondary: #5c6971;
/* Other colors */
--primary-hover: #fe1530;
--secondary-hover: #222;
--light-grey: #f1f3f3;
--darker-grey: #d4dada;
}
body {
background-color: #eee;
}
a {
color: var(--secondary-hover);
text-decoration-color: var(--bs-primary);
}
a:hover {
color: var(--primary-hover);
}
/*************/
/* BOOTSTRAP */
/*************/
/* Colors*/
.bg-primary {
background-color: var(--bs-primary) !important;
}
.bg-secondary {
background-color: var(--bs-secondary) !important;
}
/* Buttons */
.btn-primary {
--bs-btn-color: #fff;
--bs-btn-bg: var(--bs-primary);
--bs-btn-border-color: var(--bs-primary);
--bs-btn-hover-color: #fff;
--bs-btn-hover-bg: var(--primary-hover);
--bs-btn-hover-border-color: var(--primary-hover);
--bs-btn-focus-shadow-rgb: 49, 132, 253;
--bs-btn-active-color: #fff;
--bs-btn-active-bg: var(--bs-primary);
--bs-btn-active-border-color: var(--bs-primary);
--bs-btn-active-shadow: inset 0 3px 5px #00000020;
}
.btn-secondary {
--bs-btn-color: #fff;
--bs-btn-bg: var(--bs-secondary);
--bs-btn-border-color: var(--bs-secondary);
--bs-btn-hover-color: #fff;
--bs-btn-hover-bg: var(--secondary-hover);
--bs-btn-hover-border-color: var(--secondary-hover);
--bs-btn-focus-shadow-rgb: 130, 138, 145;
--bs-btn-active-color: #fff;
--bs-btn-active-bg: var(--bs-secondary);
--bs-btn-active-border-color: var(--bs-secondary);
--bs-btn-active-shadow: inset 0 3px 5px #00000020;
}
.btn-primary:focus,
.btn-secondary:focus {
box-shadow: 0 0 0 0.25rem #5c69714a;
}
.form-control:focus,
.form-select:focus,
.btn-close:focus {
color: #212529;
background-color: #fff;
border-color: #5c6971;
outline: 0;
box-shadow: 0 0 0 0.25rem #5c69714a;
}
/* Navbar */
.navbar-dark {
--bs-navbar-color: #fffc;
--bs-navbar-hover-color: #fffe;
--bs-navbar-active-color: #fff;
}
.dropdown-item.active,
.dropdown-item:active {
background-color: var(--bs-primary) !important;
}
/* Modals */
.modal-body form {
padding: 10px 20px;
}
/**********/
/* HEADER */
/**********/
header nav {
font-weight: 500;
}
.dash-item {
display: flex;
align-items: center;
vertical-align: middle;
}
/***********/
/* CONTENT */
/***********/
h5 {
font-size: 18px;
}
/* Main Page */
.section-title {
margin-bottom: 15px;
}
.content-section:first-of-type {
padding-top: 62px;
}
.content-section {
padding-top: 70px;
}
/* Management */
main.content {
margin-top: 62px;
margin-bottom: 66px;
padding: 20px;
min-height: calc(100vh - 194px);
}
/* Tables */
.table-heading {
margin: 20px 0;
display: flex;
align-items: center;
}
.content table tbody td,
.content table tbody th {
vertical-align: middle;
}
.content table thead th.text-center {
width: 78px;
}
/* Custom Buttons */
.add-button {
margin-left: auto;
background-color: var(--bs-secondary);
border-radius: 100%;
color: white;
height: 32px;
width: 32px;
display: flex;
align-items: center;
text-align: center;
justify-content: center;
}
.add-button:hover {
background-color: var(--secondary-hover);
}
.action-row {
justify-content: center;
display: flex;
gap: 10px;
}
.action-button {
border: none;
border-radius: 100%;
height: 34px;
width: 34px;
display: flex;
align-items: center;
text-align: center;
justify-content: center;
}
.action-button.edit {
color: white;
background-color: var(--bs-secondary);
}
.action-button.edit:not(.placeholder):hover {
background-color: var(--secondary-hover);
}
.action-button.delete {
color: white;
background-color: var(--bs-primary);
}
.action-button.delete:hover {
background-color: var(--bs-secondary);
}
/* Media Queries */
@media (min-width: 992px) {
.container,
.content > section {
padding-left: 80px;
padding-right: 80px;
}
}
@media (max-width: 992px) {
aside {
display: none;
}
}
/* SIDEBAR */
.sidebar {
-webkit-box-shadow: 5px 0 5px rgba(196, 194, 196, 0.72);
-moz-box-shadow: 5px 0 5px rgba(196, 194, 196, 0.72);
box-shadow: 5px 0 5px rgba(196, 194, 196, 0.72);
position: absolute;
top: 62px;
left: 0;
width: 80px;
background-color: white;
min-height: calc(100vh - 62px - 66px);
}
.sidebar li {
border-bottom: 1px solid #c5c5c5;
}
.sidebar li a {
display: block;
height: 65px;
width: 80px;
text-align: center;
}
.sidebar .nav-link {
color: var(--bs-secondary);
}
.sidebar .nav-link:not(.active):hover {
color: var(--secondary-hover);
}
.sidebar .nav-link.active {
color: var(--bs-primary);
}
.sidebar .nav-link svg {
vertical-align: -1.4em;
}
/* Carousel */
.carousel-item {
height: calc(100vh - 62px);
}
.carousel-item > img {
position: absolute;
object-fit: cover;
top: 0;
left: 0;
min-width: 100%;
min-height: 100%;
}
.carousel-caption {
text-align: left;
max-width: 400px;
z-index: 10;
color: white;
background-color: #00000090;
padding: 20px;
}
/* Custom Cards */
.name {
color: var(--bs-primary);
}
.work {
font-weight: bold;
font-size: 15px;
}
.work a {
text-decoration: none;
}
.about {
font-size: 13px;
}
.box {
-webkit-box-shadow: 13px 12px 5px -10px rgba(196, 194, 196, 0.72);
-moz-box-shadow: 13px 12px 5px -10px rgba(196, 194, 196, 0.72);
box-shadow: 13px 12px 5px -10px rgba(196, 194, 196, 0.72);
min-height: 300px;
}
/*************/
/* DASHBOARD */
/*************/
.dash-select {
border: none;
background-color: transparent;
font-size: 24px;
}
.dashboard .row.full,
.dashboard .section {
min-height: calc(100vh - 330px);
}
.dashboard .row.gap {
gap: 10px;
justify-content: center;
}
.dashboard .person {
vertical-align: middle;
margin: auto 0;
}
.dashboard .details svg {
color: var(--bs-primary)
}
#lecturerOther {
font-size: 16px;
text-overflow: ellipsis;
max-height: 580px;
}
.dashboard .details {
padding: 20px;
font-size: 18px;
vertical-align: middle;
}
.dashboard .row .card-cust {
height: 100%;
width: 100%;
}
/* Lecture List */
.lectureList {
list-style-type: none;
padding-left: 0;
overflow-y: scroll;
max-height: 580px;
}
.lectureList li {
padding: 10px;
}
.lectureList li:not(:last-of-type) {
border-bottom: 0.5px solid var(--darker-grey);
}
.lectureList li:nth-child(even) {
background-color: var(--light-grey);
}
.lectureList li:hover {
background-color: var(--darker-grey);
}
.lectureList .lecture {
font-size: 16px;
vertical-align: middle;
}
/* Misc */
.error {
display: none;
color: red;
padding: 0 20px;
}
.error.show {
display: block;
}
/**********/
/* FOOTER */
/**********/
footer {
bottom: 0;
text-align: center;
font-weight: 600;
color: var(--light-grey);
background-color: var(--bs-secondary);
padding: 20px 0;
margin-top: 20px;
border-top: 2px solid var(--bs-primary);
z-index: 2;
width: 100%;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="#e2001a" viewBox="0 0 640 512">
<!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<path d="M320 32c-8.1 0-16.1 1.4-23.7 4.1L15.8 137.4C6.3 140.9 0 149.9 0 160s6.3 19.1 15.8 22.6l57.9 20.9C57.3 229.3 48 259.8 48 291.9v28.1c0 28.4-10.8 57.7-22.3 80.8c-6.5 13-13.9 25.8-22.5 37.6C0 442.7-.9 448.3 .9 453.4s6 8.9 11.2 10.2l64 16c4.2 1.1 8.7 .3 12.4-2s6.3-6.1 7.1-10.4c8.6-42.8 4.3-81.2-2.1-108.7C90.3 344.3 86 329.8 80 316.5V291.9c0-30.2 10.2-58.7 27.9-81.5c12.9-15.5 29.6-28 49.2-35.7l157-61.7c8.2-3.2 17.5 .8 20.7 9s-.8 17.5-9 20.7l-157 61.7c-12.4 4.9-23.3 12.4-32.2 21.6l159.6 57.6c7.6 2.7 15.6 4.1 23.7 4.1s16.1-1.4 23.7-4.1L624.2 182.6c9.5-3.4 15.8-12.5 15.8-22.6s-6.3-19.1-15.8-22.6L343.7 36.1C336.1 33.4 328.1 32 320 32zM128 408c0 35.3 86 72 192 72s192-36.7 192-72L496.7 262.6 354.5 314c-11.1 4-22.8 6-34.5 6s-23.5-2-34.5-6L143.3 262.6 128 408z" />
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

@@ -0,0 +1,42 @@
let logicHandler = new LogicHandler()
window.addEventListener('load', function () {
let dropdown = this.document.getElementById("dropdown")
logicHandler.getItems("lecturers").forEach(lecturer => {
dropdown.innerHTML += `<li><a class="dropdown-item" onclick="selectLecturer('${lecturer.id}')">${lecturer.firstName} ${lecturer.lastName}</a></li>`
})
})
function selectLecturer(id) {
let lecturer = logicHandler.getItem("lecturers", id)
document.getElementById("dropdown-button").innerText = `${lecturer.firstName} ${lecturer.lastName}`
document.getElementById("lecturerName").innerText = `${lecturer.firstName} ${lecturer.lastName}`
document.getElementById("lecturerTitle").innerText = "Prof. Dr."
document.getElementById("lecturerMail").innerHTML = `<a href="mailto:${lecturer.email}">${lecturer.email}</a>`
document.getElementById("lecturerProgram").innerText = logicHandler.getItem("studyPrograms", lecturer.studyProgram).name
document.getElementById("lecturerOther").innerText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
let btn = document.getElementById("lecturerEditButton")
btn.classList.remove("disabled", "placeholder")
btn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="bi bi-pencil" viewBox = "0 0 16 16" ><path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" /></svg>`
btn.onclick = () => window.location.href = window.location.href.replace("dashboard", "lecturers") + `?id=${id}`
let html = ""
let lectures = logicHandler.getItems("lectures")
lectures.forEach(lecture => {
lecture.lectureDates.forEach(lectureDate => {
let date = logicHandler.getItem("lectureDates", lectureDate)
if (lecture.lecturers.includes(id)) {
html = html + `
<li class="lecture">${lecture.lectureName} - ${logicHandler.getItem("studyClasses", lecture.studyClass).name} (${logicHandler.formatDateTime(date.startDate)} - ${logicHandler.formatDateTime(date.endDate)})</li>
`
}
})
})
document.querySelector(".lectureList").innerHTML = html
document.getElementsByClassName("sidebar")[0].style.minHeight = `${document.body.offsetHeight - 66}px`
}
+149
View File
@@ -0,0 +1,149 @@
function loadDummyData() {
window.localStorage.setItem("studyPrograms", JSON.stringify([
{
id: 0,
name: "Informatik",
short: "TIF"
},
{
id: 1,
name: "Wirtschaftsinformatik",
short: "WIF"
},
{
id: 2,
name: "Betriebswirtschaftslehre",
short: "BWL"
},
]))
window.localStorage.setItem("lectureDates", JSON.stringify([
{
id: 0,
startDate: "2022-01-01T00:00",
endDate: "2022-01-01T23:59"
},
{
id: 1,
startDate: "2022-02-02T00:00",
endDate: "2022-02-02T23:59"
},
{
id: 2,
startDate: "2022-03-03T00:00",
endDate: "2022-03-03T23:59"
},
]))
window.localStorage.setItem("semesters", JSON.stringify([
{
id: 0,
name: "1. Semester",
startDate: 0,
endDate: 2,
number: 1,
studyProgram: 1
}, {
id: 1,
name: "2. Semester",
startDate: 1,
endDate: 2,
number: 2,
studyProgram: 2
}, {
id: 2,
name: "3. Semester",
startDate: 0,
endDate: 1,
number: 3,
studyProgram: 0
},
]))
window.localStorage.setItem("studyClasses", JSON.stringify([
{
id: 0,
name: "TIF22A",
startDate: 0,
endDate: 0,
semester: 0,
studyProgram: 0
}, {
id: 1,
name: "WIF21B",
startDate: 1,
endDate: 1,
semester: 1,
studyProgram: 1
}, {
id: 2,
name: "BWL20A",
startDate: 2,
endDate: 2,
semester: 2,
studyProgram: 2
},
]))
window.localStorage.setItem("lecturers", JSON.stringify([
{
id: 0,
firstName: "Max",
lastName: "Mustermann",
email: "max.mustermann@uniplanner.de",
studyProgram: 0
}, {
id: 1,
firstName: "Erika",
lastName: "Musterfrau",
email: "erika.musterfrau@uniplanner.de",
studyProgram: 1
}, {
id: 2,
firstName: "Max",
lastName: "Musterfrau",
email: "max.musterfrau@uniplanner.de",
studyProgram: 2
},
]))
window.localStorage.setItem("lectures", JSON.stringify([
{
id: 0,
lectureName: "Technische Informatik",
moduleName: "Digitaltechnik I",
duration: 48,
lectureDates: ["0", "2"],
lecturers: ["0"],
studyClass: 0
}, {
id: 1,
lectureName: "Mathematik I",
moduleName: "Analysis",
duration: 50,
lectureDates: ["1", "2"],
lecturers: ["1", "2"],
studyClass: 1
}, {
id: 2,
lectureName: "Betriebswirtschaftslehre",
moduleName: "Projektmanagement",
duration: 35,
lectureDates: ["0", "2"],
lecturers: ["0", "1", "2"],
studyClass: 2
},
]))
window.localStorage.setItem("currentIds", JSON.stringify({
lectureDate: 3,
lecturer: 3,
lecture: 3,
semester: 3,
studyClass: 3,
studyProgram: 3
}))
}
@@ -0,0 +1,35 @@
let logicHandler = new LogicHandler()
let modalHandler = new LectureDateModalHandler()
function renderLectureDateModal(id) {
id = typeof id == "undefined" ? "Create" : id
let lectureDate = id == "Create" ? getEmptyLectureDate() : logicHandler.getItem("lectureDates", id)
document.body.append(modalHandler.getLectureDateModal(lectureDate))
document.body.append(modalHandler.getLectureDateModalButton(id))
let htmlButton = document.getElementById("modalButton" + id)
htmlButton.click()
htmlButton.remove()
}
function cancelLectureDateModal(id) {
document.getElementById("lectureDateModal" + id).remove()
}
function saveLectureDate(id) {
logicHandler.saveItem("lectureDate", id)
}
function removeLectureDate(id) {
logicHandler.removeItem("lectureDates", id)
document.getElementById("row" + id).remove()
}
function getEmptyLectureDate() {
return {
id: "Create",
startDate: "",
endDate: ""
}
}
@@ -0,0 +1,49 @@
class LectureDateModalHandler {
getLectureDateModal(lectureDate) {
let heading = lectureDate.id == "Create" ? "Neuen Termin erstellen" : `Termin #${lectureDate.id} bearbeiten`
let modal = `
<div class="modal modal-lg fade" id="lectureDateModal${lectureDate.id}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="lectureDateModalLabel${lectureDate.id}" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="lectureDateModalLabel${lectureDate.id}">${heading}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Abbrechen" onclick="cancelLectureDateModal('${lectureDate.id}')"></button>
</div>
<div class="modal-body">
<p class="error"><i class="bi bi-exclamation-circle"></i> Bitte alle Felder ausfüllen.</p>
<form id="lectureDateForm${lectureDate.id}">
<div class="mb-3">
<label for="startDateInput" class="form-label">Startdatum</label>
<input type="datetime-local" class="form-control modalInput" id="startDateInput" name="startDate" value="${lectureDate.startDate}" >
</div>
<div class="mb-3">
<label for="endDateInput" class="form-label">Enddatum</label>
<input type="datetime-local" class="form-control modalInput" id="endDateInput" name="endDate" value="${lectureDate.endDate}" >
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" onclick="cancelLectureDateModal('${lectureDate.id}')">Abbrechen</button>
<button type="button" class="btn btn-secondary" onclick="saveLectureDate('${lectureDate.id}')">Speichern</button>
</div>
</div>
</div>
</div>
`
let htmlModal = document.createElement("div")
htmlModal.innerHTML = modal
return htmlModal
}
getLectureDateModalButton(id) {
let button = `
<button type="button" data-bs-toggle="modal" data-bs-target="#lectureDateModal${id}" id="modalButton${id}" style="display: none;"></button>
`
let htmlButton = document.createElement("div")
htmlButton.innerHTML = button
return htmlButton
}
}
@@ -0,0 +1,43 @@
window.addEventListener("load", function () {
var logicHandler = new LogicHandler()
let lectureDates = logicHandler.getItems("lectureDates")
if (lectureDates != null) {
lectureDates.forEach(lectureDate => {
let content = `
<th scope="row">${lectureDate.id}</th>
<td>${logicHandler.formatDateTime(lectureDate.startDate)}</td>
<td>${logicHandler.formatDateTime(lectureDate.endDate)}</td>
<td>
<div class="action-row">
<button class="action-button edit" onclick="renderLectureDateModal(${lectureDate.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-pencil" viewBox="0 0 16 16">
<path
d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" />
</svg>
</button>
<button class="action-button delete" onclick="removeLectureDate(${lectureDate.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-trash" viewBox="0 0 16 16">
<path
d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
<path fill-rule="evenodd"
d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
</svg>
</button>
</div>
</td>
`
let row = document.createElement("tr")
row.id = "row" + lectureDate.id
row.innerHTML = content
document.getElementById("lectureDateTable").appendChild(row)
document.getElementsByClassName("sidebar")[0].style.minHeight = `${document.body.offsetHeight - 66}px`
})
}
})
@@ -0,0 +1,46 @@
let logicHandler = new LogicHandler()
let modalHandler = new LecturerModalHandler()
window.addEventListener('load', function () {
if (this.window.location.search.includes("id=")) {
renderLecturerModal(window.location.search.replace("?id=", ""))
}
})
function renderLecturerModal(id) {
id = typeof id == "undefined" ? "Create" : id
let lecturer = id == "Create" ? getEmptyLecturer() : logicHandler.getItem("lecturers", id)
let studyProgramList = logicHandler.getAsDataList("studyPrograms", "name", [lecturer.studyProgram])
document.body.append(modalHandler.getLecturerModal(lecturer, studyProgramList))
document.body.append(modalHandler.getLecturerModalButton(id))
let htmlButton = document.getElementById("lecturerButton" + id)
htmlButton.click()
htmlButton.remove()
}
function cancelLecturerModal(id) {
document.getElementById("lecturerModal" + id).remove()
window.location.href = window.location.href.replace(window.location.search, "")
}
function saveLecturer(id) {
logicHandler.saveItem("lecturer", id)
}
function removeLecturer(id) {
logicHandler.removeItem("lecturers", id)
document.getElementById("row" + id).remove()
}
function getEmptyLecturer() {
return {
id: "Create",
firstName: "",
lastName: "",
email: "",
studyProgram: ""
}
}
@@ -0,0 +1,60 @@
class LecturerModalHandler {
getLecturerModal(lecturer, studyProgramList) {
let heading = lecturer.id == "Create" ? "Neuen Dozent erstellen" : `Dozent #${lecturer.id} bearbeiten`
let modal = `
<div class="modal modal-lg fade" id="lecturerModal${lecturer.id}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="lecturerModalLabel${lecturer.id}" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="lecturerModalLabel${lecturer.id}">${heading}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Abbrechen" onclick="cancelLecturerModal('${lecturer.id}')"></button>
</div>
<div class="modal-body">
<p class="error"><i class="bi bi-exclamation-circle"></i> Bitte alle Felder ausfüllen.</p>
<form id="lecturerForm${lecturer.id}">
<div class="mb-3">
<label for="firstNameInput" class="form-label">Vorname</label>
<input type="text" class="form-control modalInput" id="firstNameInput" name="firstName" value="${lecturer.firstName}" >
</div>
<div class="mb-3">
<label for="lastNameInput" class="form-label">Nachname</label>
<input type="text" class="form-control modalInput" id="lastNameInput" name="lastName" value="${lecturer.lastName}" >
</div>
<div class="mb-3">
<label for="emailInput" class="form-label">Email</label>
<input type="email" class="form-control modalInput" id="emailInput" name="email" value="${lecturer.email}" >
</div>
<div class="mb-3">
<label for="studyProgramInput" class="form-label">Studiengang</label>
<select class="form-select modalInput" id="studyProgramInput" name="studyProgram" >
<option selected disabled hidden>Bitte wählen</option>
${studyProgramList}
</select>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" onclick="cancelLecturerModal('${lecturer.id}')">Abbrechen</button>
<button type="button" class="btn btn-secondary" onclick="saveLecturer('${lecturer.id}')">Speichern</button>
</div>
</div>
</div>
</div>
`
let htmlModal = document.createElement("div")
htmlModal.innerHTML = modal
return htmlModal
}
getLecturerModalButton(id) {
let button = `
<button type="button" data-bs-toggle="modal" data-bs-target="#lecturerModal${id}" id="lecturerButton${id}" style="display: none;"></button>
`
let htmlButton = document.createElement("div")
htmlButton.innerHTML = button
return htmlButton
}
}
@@ -0,0 +1,48 @@
window.addEventListener("load", function () {
let logicHandler = new LogicHandler()
let lecturers = logicHandler.getItems("lecturers")
if (lecturers != null) {
lecturers.forEach(lecturer => {
let studyProgram = logicHandler.getItem("studyPrograms", lecturer.studyProgram)
studyProgram = typeof studyProgram == "undefined" ? "" : studyProgram.name
let content = `
<th scope="row">${lecturer.id}</th>
<td>${lecturer.firstName}</td>
<td>${lecturer.lastName}</td>
<td>${lecturer.email}</td>
<td>${studyProgram}</td>
<td>
<div class="action-row">
<button class="action-button edit" onclick="renderLecturerModal(${lecturer.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-pencil" viewBox="0 0 16 16">
<path
d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" />
</svg>
</button>
<button class="action-button delete" onclick="removeLecturer(${lecturer.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-trash" viewBox="0 0 16 16">
<path
d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
<path fill-rule="evenodd"
d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
</svg>
</button>
</div>
</td>
`
let row = document.createElement("tr")
row.id = "row" + lecturer.id
row.innerHTML = content
document.getElementById("lecturersTable").appendChild(row)
document.getElementsByClassName("sidebar")[0].style.minHeight = `${document.body.offsetHeight - 66}px`
})
}
})
+43
View File
@@ -0,0 +1,43 @@
let logicHandler = new LogicHandler()
let modalHandler = new LectureModalHandler()
function renderLectureModal(id) {
id = typeof id == "undefined" ? "Create" : id
let lecture = id == "Create" ? getEmptyLecture() : logicHandler.getItem("lectures", id)
let lectureDateList = logicHandler.getAsDataListWithRange("lectureDates", "startDate", "endDate", lecture.lectureDates)
let lecturerList = logicHandler.getAsDataList("lecturers", "lastName", lecture.lecturers)
let studyClassList = logicHandler.getAsDataList("studyClasses", "name", [lecture.studyClass])
document.body.append(modalHandler.getLectureModal(lecture, lectureDateList, lecturerList, studyClassList))
document.body.append(modalHandler.getLectureModalButton(id))
let htmlButton = document.getElementById("lectureButton" + id)
htmlButton.click()
htmlButton.remove()
}
function cancelLectureModal(id) {
document.getElementById("lectureModal" + id).remove()
}
function saveLecture(id) {
logicHandler.saveItem("lecture", id)
}
function removeLecture(id) {
logicHandler.removeItem("lectures", id)
document.getElementById("row" + id).remove()
}
function getEmptyLecture() {
return {
id: "Create",
lectureName: "",
moduleName: "",
duration: "",
lectureDates: [],
lecturers: [],
studyClass: ""
}
}
+72
View File
@@ -0,0 +1,72 @@
class LectureModalHandler {
getLectureModal(lecture, lectureDateList, lecturerList, studyClassList) {
let heading = lecture.id == "Create" ? "Neue Vorlesung erstellen" : `Vorlesung #${lecture.id} bearbeiten`
let modal = `
<div class="modal modal-lg fade" id="lectureModal${lecture.id}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="lectureModalLabel${lecture.id}" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="lectureModalLabel${lecture.id}">${heading}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Abbrechen" onclick="cancelLectureModal('${lecture.id}')"></button>
</div>
<div class="modal-body">
<p class="error"><i class="bi bi-exclamation-circle"></i> Bitte alle Felder ausfüllen.</p>
<form id="lectureForm${lecture.id}">
<div class="mb-3">
<label for="lectureNameInput" class="form-label">Vorlesungs-Name</label>
<input type="text" class="form-control modalInput" id="lectureNameInput" name="lectureName" value="${lecture.lectureName}" >
</div>
<div class="mb-3">
<label for="moduleNameInput" class="form-label">Modul-Name</label>
<input type="text" class="form-control modalInput" id="moduleNameInput" name="moduleName" value="${lecture.moduleName}" >
</div>
<div class="mb-3">
<label for="durationInput" class="form-label">Dauer</label>
<input type="number" min="0" class="form-control modalInput" id="durationInput" name="duration" value="${lecture.duration}" >
</div>
<div class="mb-3">
<label for="lectureDatesInput" class="form-label">Termine</label>
<select class="form-select modalInput" id="lectureDatesInput" name="lectureDates" multiple >
${lectureDateList}
</select>
</div>
<div class="mb-3">
<label for="lecturersInput" class="form-label">Dozenten</label>
<select class="form-select modalInput" id="lecturersInput" name="lecturers" multiple >
${lecturerList}
</select>
</div>
<div class="mb-3">
<label for="studyClassInput" class="form-label">Jahrgang</label>
<select class="form-select modalInput" id="studyClassInput" name="studyClass" >
<option selected disabled hidden>Bitte wählen</option>
${studyClassList}
</select>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" onclick="cancelLectureModal('${lecture.id}')">Abbrechen</button>
<button type="button" class="btn btn-secondary" onclick="saveLecture('${lecture.id}')">Speichern</button>
</div>
</div>
</div>
</div>
`
let htmlModal = document.createElement("div")
htmlModal.innerHTML = modal
return htmlModal
}
getLectureModalButton(id) {
let button = `
<button type="button" data-bs-toggle="modal" data-bs-target="#lectureModal${id}" id="lectureButton${id}" style="display: none;"></button>
`
let htmlButton = document.createElement("div")
htmlButton.innerHTML = button
return htmlButton
}
}
+55
View File
@@ -0,0 +1,55 @@
window.addEventListener("load", function () {
let logicHandler = new LogicHandler()
let lectures = logicHandler.getItems("lectures")
if (lectures != null) {
lectures.forEach(lecture => {
let lecturers = logicHandler.getItems("lecturers").filter(lecturer => { return lecture.lecturers.indexOf(lecturer.id.toString()) > -1 })
lecturers.forEach((lecturer, idx) => lecturers[idx] = " " + lecturer.lastName)
let lectureDates = logicHandler.getItems("lectureDates").filter(lectureDate => { return lecture.lectureDates.indexOf(lectureDate.id.toString()) > -1 })
lectureDates.forEach((lectureDate, idx) => lectureDates[idx] = ` ${logicHandler.formatDateTime(lectureDate.startDate)} - ${logicHandler.formatDateTime(lectureDate.endDate)}`)
let studyClass = logicHandler.getItem("studyClasses", lecture.studyClass)
studyClass = typeof studyClass == "undefined" ? "" : studyClass.name
let content = `
<th scope="row">${lecture.id}</th>
<td>${lecture.lectureName}</td>
<td>${lecture.moduleName}</td>
<td>${lecture.duration}</td>
<td>${lectureDates}</td>
<td>${lecturers}</td>
<td>${studyClass}</td>
<td>
<div class="action-row">
<button class="action-button edit" onclick="renderLectureModal(${lecture.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-pencil" viewBox="0 0 16 16">
<path
d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" />
</svg>
</button>
<button class="action-button delete" onclick="removeLecture(${lecture.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-trash" viewBox="0 0 16 16">
<path
d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
<path fill-rule="evenodd"
d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
</svg>
</button>
</div>
</td>
`
let row = document.createElement("tr")
row.id = "row" + lecture.id
row.innerHTML = content
document.getElementById("lecturesTable").appendChild(row)
document.getElementsByClassName("sidebar")[0].style.minHeight = `${document.body.offsetHeight - 66}px`
})
}
})
+152
View File
@@ -0,0 +1,152 @@
class LogicHandler {
getItems(type) {
let items = JSON.parse(window.localStorage.getItem(type))
return items == null ? [] : items
}
getItem(type, id) {
let item = JSON.parse(window.localStorage.getItem(type))
return item == null ? {} : item.filter(item => {
return item.id == id
})[0]
}
addItem(type, item) {
let items = this.getItems(type)
items[items.length] = item
window.localStorage.setItem(type, JSON.stringify(items))
}
updateItem(type, data) {
let items = this.getItems(type)
items.forEach((item, idx) => {
if (item.id == data.id)
items[idx] = data
})
window.localStorage.setItem(type, JSON.stringify(items))
}
removeItem(type, id) {
let items = this.getItems(type).filter(item => {
return item.id != id
})
window.localStorage.setItem(type, JSON.stringify(items))
}
saveItem(type, id, multiple = "s") {
let json = this.getFormData(type + "Form" + id)
if (!json) {
document.getElementById(type + "Modal" + id).querySelector("p.error").classList.add("show")
return
}
json.id = id == "Create" ? this.getId(type) : id
if (id == "Create")
this.addItem(type + multiple, json)
else
this.updateItem(type + multiple, json)
window.location.href = window.location.href.replace(window.location.search, "")
}
getId(type) {
var values = JSON.parse(window.localStorage.getItem("currentIds"))
if (values == null)
values = {}
if (values[type] == null)
values[type] = 0
let id = values[type]
values[type] = parseInt(values[type]) + 1
window.localStorage.setItem("currentIds", JSON.stringify(values))
return id
}
getAsDataList(type, field, selected) {
let datalist = ""
Array.from(this.getItems(type)).forEach(item => {
if (selected.length > 0 && selected.filter(select => { return parseInt(select) == item['id'] }).length > 0)
datalist += `<option value="${item['id']}" selected>${item[field]}</option>`
else
datalist += `<option value="${item['id']}">${item[field]}</option>`
})
return datalist
}
getAsDataListWithRange(type, rangeStart, rangeEnd, selected) {
let datalist = ""
Array.from(this.getItems(type)).forEach(item => {
if (selected.length > 0 && selected.filter(select => { return parseInt(select) == item['id'] }).length > 0)
datalist += `<option value="${item['id']}" selected>${this.formatDateTime(item[rangeStart])} - ${this.formatDateTime(item[rangeEnd])}</option>`
else
datalist += `<option value="${item['id']}">${this.formatDateTime(item[rangeStart])} - ${this.formatDateTime(item[rangeEnd])}</option>`
})
return datalist
}
getAsDateList(type, field, selected) {
let datalist = ""
Array.from(this.getItems(type)).forEach(item => {
if (selected.length > 0 && selected.filter(select => { return parseInt(select) == item['id'] }).length > 0)
datalist += `<option value="${item['id']}" selected>${this.formatDateTimeToDate(item[field])}</option>`
else
datalist += `<option value="${item['id']}">${this.formatDateTimeToDate(item[field])}</option>`
})
return datalist
}
getFormData(form) {
let fields = Array.from(document.getElementById(form).querySelectorAll(".modalInput"))
let json = {}
let valid = true
fields.forEach(element => {
if (typeof element.options != "undefined") {
let values = []
Array.from(element.options).forEach(option => {
if (option.selected && !option.disabled)
values.push(option.value)
})
if (values.length == 0)
valid = false
json[element.name] = values
} else {
if (element.value.trim().length == 0)
valid = false
json[element.name] = element.value
}
})
if (!valid)
return false
return json
}
formatDateTime(dateTime) {
let split = dateTime.split("T")
let dateSplit = split[0].split("-")
return dateSplit[2] + "." + dateSplit[1] + "." + dateSplit[0] + " " + split[1]
}
formatDateTimeToDate(dateTime) {
let split = dateTime.split("T")
let dateSplit = split[0].split("-")
return dateSplit[2] + "." + dateSplit[1] + "." + dateSplit[0]
}
}
window.addEventListener('load', function () {
document.getElementsByClassName("sidebar")[0].style.minHeight = `${document.body.offsetHeight - 66}px`
})
window.addEventListener('resize', function () {
document.getElementsByClassName("sidebar")[0].style.minHeight = `${document.body.offsetHeight - 66}px`
})
@@ -0,0 +1,43 @@
let logicHandler = new LogicHandler()
let modalHandler = new SemesterModalHandler()
function renderSemesterModal(id) {
id = typeof id == "undefined" ? "Create" : id
let semester = id == "Create" ? getEmptySemester() : logicHandler.getItem("semesters", id)
let startDateList = logicHandler.getAsDateList("lectureDates", "startDate", [semester.startDate])
let endDateList = logicHandler.getAsDateList("lectureDates", "endDate", [semester.endDate])
let studyProgramList = logicHandler.getAsDataList("studyPrograms", "name", [semester.studyProgram])
document.body.append(modalHandler.getSemesterModal(semester, startDateList, endDateList, studyProgramList))
document.body.append(modalHandler.getSemesterModalButton(id))
let htmlButton = document.getElementById("modalButton" + id)
htmlButton.click()
htmlButton.remove()
}
function cancelSemesterModal(id) {
document.getElementById("semesterModal" + id).remove()
}
function saveSemester(id) {
logicHandler.saveItem("semester", id)
}
function removeSemester(id) {
logicHandler.removeItem("semesters", id)
document.getElementById("row" + id).remove()
}
function getEmptySemester() {
return {
id: "Create",
name: "",
startDate: "",
endDate: "",
number: "",
studyProgram: ""
}
}
@@ -0,0 +1,68 @@
class SemesterModalHandler {
getSemesterModal(semester, startDateList, endDateList, studyProgramList) {
let heading = semester.id == "Create" ? "Neues Semester erstellen" : `Semester #${semester.id} bearbeiten`
let modal = `
<div class="modal modal-lg fade" id="semesterModal${semester.id}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="semesterModalLabel${semester.id}" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="semesterModalLabel${semester.id}">${heading}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Abbrechen" onclick="cancelSemesterModal('${semester.id}')"></button>
</div>
<div class="modal-body">
<p class="error"><i class="bi bi-exclamation-circle"></i> Bitte alle Felder ausfüllen.</p>
<form id="semesterForm${semester.id}">
<div class="mb-3">
<label for="semesterNameInput" class="form-label">Semester-Name</label>
<input type="text" class="form-control modalInput" id="semesterNameInput" name="name" value="${semester.name}" >
</div>
<div class="mb-3">
<label for="startDateInput" class="form-label">Startdatum</label>
<select class="form-select modalInput" id="startDateInput" name="startDate">
<option selected hidden disabled>Bitte wählen</option>
${startDateList}
</select>
</div>
<div class="mb-3">
<label for="endDateInput" class="form-label">Enddatum</label>
<select class="form-select modalInput" id="endDateInput" name="endDate">
<option selected hidden disabled>Bitte wählen</option>
${endDateList}
</select>
</div>
<div class="mb-3">
<label for="semesterNumberInput" class="form-label">Semester (Nummer)</label>
<input type="number" min="0" class="form-control modalInput" id="semesterNumberInput" name="number" value="${semester.number}" >
</div>
<div class="mb-3">
<label for="studyProgramInput" class="form-label">Studiengang</label>
<select class="form-select modalInput" id="studyProgramInput" name="studyProgram" >
<option selected disabled hidden>Bitte wählen</option>
${studyProgramList}
</select>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" onclick="cancelSemesterModal('${semester.id}')">Abbrechen</button>
<button type="button" class="btn btn-secondary" onclick="saveSemester('${semester.id}')">Speichern</button>
</div>
</div>
</div>
</div>
`
let htmlModal = document.createElement("div")
htmlModal.innerHTML = modal
return htmlModal
}
getSemesterModalButton(id) {
let button = `
<button type="button" data-bs-toggle="modal" data-bs-target="#semesterModal${id}" id="modalButton${id}" style="display: none;"></button>
`
let htmlButton = document.createElement("div")
htmlButton.innerHTML = button
return htmlButton
}
}
@@ -0,0 +1,49 @@
window.addEventListener("load", function () {
var logicHandler = new LogicHandler()
let semesters = logicHandler.getItems("semesters")
if (semesters != null) {
semesters.forEach(semester => {
let studyProgram = logicHandler.getItem("studyPrograms", semester.studyProgram)
studyProgram = typeof studyProgram == "undefined" ? "" : studyProgram.name
let content = `
<th scope="row">${semester.id}</th>
<td>${semester.name}</td>
<td>${logicHandler.formatDateTimeToDate(logicHandler.getItem("lectureDates", semester.startDate).startDate)}</td>
<td>${logicHandler.formatDateTimeToDate(logicHandler.getItem("lectureDates", semester.endDate).endDate)}</td>
<td>${semester.number}</td>
<td>${studyProgram}</td>
<td>
<div class="action-row">
<button class="action-button edit" onclick="renderSemesterModal(${semester.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-pencil" viewBox="0 0 16 16">
<path
d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" />
</svg>
</button>
<button class="action-button delete" onclick="removeSemester(${semester.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-trash" viewBox="0 0 16 16">
<path
d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
<path fill-rule="evenodd"
d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
</svg>
</button>
</div>
</td>
`
let row = document.createElement("tr")
row.id = "row" + semester.id
row.innerHTML = content
document.getElementById("semestersTable").appendChild(row)
document.getElementsByClassName("sidebar")[0].style.minHeight = `${document.body.offsetHeight - 66}px`
})
}
})
@@ -0,0 +1,43 @@
let logicHandler = new LogicHandler()
let modalHandler = new StudyClassModalHandler()
function renderStudyClassModal(id) {
id = typeof id == "undefined" ? "Create" : id
let studyClass = id == "Create" ? getEmptyStudyClass() : logicHandler.getItem("studyClasses", id)
let startDateList = logicHandler.getAsDateList("lectureDates", "startDate", [studyClass.startDate])
let endDateList = logicHandler.getAsDateList("lectureDates", "endDate", [studyClass.endDate])
let semesterList = logicHandler.getAsDataList("semesters", "name", [studyClass.semester])
let studyProgramList = logicHandler.getAsDataList("studyPrograms", "name", [studyClass.studyProgram])
document.body.append(modalHandler.getStudyClassModal(studyClass, semesterList, startDateList, endDateList, studyProgramList))
document.body.append(modalHandler.getStudyClassModalButton(id))
let htmlButton = document.getElementById("studyClassButton" + id)
htmlButton.click()
htmlButton.remove()
}
function cancelStudyClassModal(id) {
document.getElementById("studyClassModal" + id).remove()
}
function saveStudyClass(id) {
logicHandler.saveItem("studyClass", id, "es")
}
function removeStudyClass(id) {
logicHandler.removeItem("studyClasses", id)
document.getElementById("row" + id).remove()
}
function getEmptyStudyClass() {
return {
id: "Create",
name: "",
startDate: "",
endDate: "",
semester: "",
studyProgram: ""
}
}
@@ -0,0 +1,73 @@
class StudyClassModalHandler {
getStudyClassModal(studyClass, semesterList, startDateList, endDateList, studyProgramList) {
let heading = studyClass.id == "Create" ? "Neuen Jahrgang erstellen" : `Jahrgang #${studyClass.id} bearbeiten`
let modal = `
<div class="modal modal-lg fade" id="studyClassModal${studyClass.id}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="lecturerModalLabel${studyClass.id}" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="studyClassModalLabel${studyClass.id}">${heading}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Abbrechen" onclick="cancelStudyClassModal('${studyClass.id}')"></button>
</div>
<div class="modal-body">
<p class="error"><i class="bi bi-exclamation-circle"></i> Bitte alle Felder ausfüllen.</p>
<form id="studyClassForm${studyClass.id}">
<div class="mb-3">
<label for="studyClassNameInput" class="form-label">Name</label>
<input type="text" class="form-control modalInput" id="studyClassNameInput" name="name" value="${studyClass.name}" >
</div>
<div class="mb-3">
<label for="startDateInput" class="form-label">Startdatum</label>
<select class="form-select modalInput" id="startDateInput" name="startDate" >
<option selected disabled hidden>Bitte wählen</option>
${startDateList}
</select>
</div>
<div class="mb-3">
<label for="endDateInput" class="form-label">Enddatum</label>
<select class="form-select modalInput" id="endDateInput" name="endDate" >
<option selected disabled hidden>Bitte wählen</option>
${endDateList}
</select>
</div>
<div class="mb-3">
<label for="semesterInput" class="form-label">Semester</label>
<select class="form-select modalInput" id="semesterInput" name="semester">
<option selected disabled hidden>Bitte wählen</option>
${semesterList}
</select>
</div>
<div class="mb-3">
<label for="studyProgramInput" class="form-label">Studiengang</label>
<select class="form-select modalInput" id="studyProgramInput" name="studyProgram" >
<option selected disabled hidden>Bitte wählen</option>
${studyProgramList}
</select>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" onclick="cancelStudyClassModal('${studyClass.id}')">Abbrechen</button>
<button type="button" class="btn btn-secondary" onclick="saveStudyClass('${studyClass.id}')">Speichern</button>
</div>
</div>
</div>
</div>
`
let htmlModal = document.createElement("div")
htmlModal.innerHTML = modal
return htmlModal
}
getStudyClassModalButton(id) {
let button = `
<button type="button" data-bs-toggle="modal" data-bs-target="#studyClassModal${id}" id="studyClassButton${id}" style="display: none;"></button>
`
let htmlButton = document.createElement("div")
htmlButton.innerHTML = button
return htmlButton
}
}
@@ -0,0 +1,49 @@
window.addEventListener("load", function () {
let logicHandler = new LogicHandler()
let studyClasses = logicHandler.getItems("studyClasses")
if (studyClasses != null) {
studyClasses.forEach(studyClass => {
let studyProgram = logicHandler.getItem("studyPrograms", studyClass.studyProgram)
studyProgram = typeof studyProgram == "undefined" ? "" : studyProgram.name
let content = `
<th scope="row">${studyClass.id}</th>
<td>${studyClass.name}</td>
<td>${logicHandler.formatDateTimeToDate(logicHandler.getItem("lectureDates", studyClass.startDate).startDate)}</td>
<td>${logicHandler.formatDateTimeToDate(logicHandler.getItem("lectureDates", studyClass.endDate).endDate)}</td>
<td>${logicHandler.getItem("semesters", studyClass.semester).name}</td>
<td>${studyProgram}</td>
<td>
<div class="action-row">
<button class="action-button edit" onclick="renderStudyClassModal(${studyClass.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-pencil" viewBox="0 0 16 16">
<path
d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" />
</svg>
</button>
<button class="action-button delete" onclick="removeStudyClass(${studyClass.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-trash" viewBox="0 0 16 16">
<path
d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
<path fill-rule="evenodd"
d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
</svg>
</button>
</div>
</td>
`
let row = document.createElement("tr")
row.id = "row" + studyClass.id
row.innerHTML = content
document.getElementById("studyClassTable").appendChild(row)
document.getElementsByClassName("sidebar")[0].style.minHeight = `${document.body.offsetHeight - 66}px`
})
}
})
@@ -0,0 +1,35 @@
let logicHandler = new LogicHandler()
let modalHandler = new StudyProgramModalHandler()
function renderStudyProgramModal(id) {
id = typeof id == "undefined" ? "Create" : id
let studyProgram = id == "Create" ? getEmptyStudyProgram() : logicHandler.getItem("studyPrograms", id)
document.body.append(modalHandler.getStudyProgramModal(studyProgram))
document.body.append(modalHandler.getStudyProgramModalButton(id))
let htmlButton = document.getElementById("modalButton" + id)
htmlButton.click()
htmlButton.remove()
}
function cancelStudyProgramModal(id) {
document.getElementById("studyProgramModal" + id).remove()
}
function saveStudyProgram(id) {
logicHandler.saveItem("studyProgram", id)
}
function removeStudyProgram(id) {
logicHandler.removeItem("studyPrograms", id)
document.getElementById("row" + id).remove()
}
function getEmptyStudyProgram() {
return {
id: "Create",
name: "",
short: ""
}
}
@@ -0,0 +1,49 @@
class StudyProgramModalHandler {
getStudyProgramModal(studyProgram) {
let heading = studyProgram.id == "Create" ? "Neuen Studiengang erstellen" : `Studiengang #${studyProgram.id} bearbeiten`
let modal = `
<div class="modal modal-lg fade" id="studyProgramModal${studyProgram.id}" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="studyProgramModalLabel${studyProgram.id}" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="studyProgramModalLabel${studyProgram.id}">${heading}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Abbrechen" onclick="cancelStudyProgramModal('${studyProgram.id}')"></button>
</div>
<div class="modal-body">
<p class="error"><i class="bi bi-exclamation-circle"></i> Bitte alle Felder ausfüllen.</p>
<form id="studyProgramForm${studyProgram.id}">
<div class="mb-3">
<label for="nameInput" class="form-label">Name</label>
<input type="text" class="form-control modalInput" id="nameInput" name="name" value="${studyProgram.name}" >
</div>
<div class="mb-3">
<label for="shortInput" class="form-label">Kürzel</label>
<input type="text" class="form-control modalInput" id="shortInput" name="short" value="${studyProgram.short}" >
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" onclick="cancelStudyProgramModal('${studyProgram.id}')">Abbrechen</button>
<button type="button" class="btn btn-secondary" onclick="saveStudyProgram('${studyProgram.id}')">Speichern</button>
</div>
</div>
</div>
</div>
`
let htmlModal = document.createElement("div")
htmlModal.innerHTML = modal
return htmlModal
}
getStudyProgramModalButton(id) {
let button = `
<button type="button" data-bs-toggle="modal" data-bs-target="#studyProgramModal${id}" id="modalButton${id}" style="display: none;"></button>
`
let htmlButton = document.createElement("div")
htmlButton.innerHTML = button
return htmlButton
}
}
@@ -0,0 +1,43 @@
window.addEventListener("load", function () {
let logicHandler = new LogicHandler()
let studyPrograms = logicHandler.getItems("studyPrograms")
if (studyPrograms != null) {
studyPrograms.forEach(studyProgram => {
let content = `
<th scope="row">${studyProgram.id}</th>
<td>${studyProgram.name}</td>
<td>${studyProgram.short}</td>
<td>
<div class="action-row">
<button class="action-button edit" onclick="renderStudyProgramModal(${studyProgram.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-pencil" viewBox="0 0 16 16">
<path
d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z" />
</svg>
</button>
<button class="action-button delete" onclick="removeStudyProgram(${studyProgram.id})">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor"
class="bi bi-trash" viewBox="0 0 16 16">
<path
d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z" />
<path fill-rule="evenodd"
d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z" />
</svg>
</button>
</div>
</td>
`
let row = document.createElement("tr")
row.id = "row" + studyProgram.id
row.innerHTML = content
document.getElementById("studyProgramTable").appendChild(row)
document.getElementsByClassName("sidebar")[0].style.minHeight = `${document.body.offsetHeight - 66}px`
})
}
})