From 06cedbd790a48995b5889960f9e30b1e8e39c319 Mon Sep 17 00:00:00 2001 From: schmieders <80328887+schmieders@users.noreply.github.com> Date: Sat, 10 Dec 2022 12:25:13 +0100 Subject: [PATCH] first commit --- assets/css/styles.css | 414 ++++++++++++++++++ assets/img/AliFistik.jpg | Bin 0 -> 7747 bytes assets/img/JonasBraus.jpg | Bin 0 -> 7365 bytes assets/img/SimonSchmieder.jpg | Bin 0 -> 7562 bytes assets/img/favicon.svg | 4 + assets/img/uniplanner.png | Bin 0 -> 51432 bytes assets/js/dashboard/dashboardLogicHandler.js | 42 ++ assets/js/dummyDataHandler.js | 149 +++++++ .../lectureDates/lectureDateLogicHandler.js | 35 ++ .../lectureDates/lectureDateModalHandler.js | 49 +++ .../lectureDates/lectureDateTableHandler.js | 43 ++ assets/js/lecturers/lecturerLogicHandler.js | 46 ++ assets/js/lecturers/lecturerModalHandler.js | 60 +++ assets/js/lecturers/lecturerTableHandler.js | 48 ++ assets/js/lectures/lectureLogicHandler.js | 43 ++ assets/js/lectures/lectureModalHandler.js | 72 +++ assets/js/lectures/lectureTableHandler.js | 55 +++ assets/js/logicHandler.js | 152 +++++++ assets/js/semesters/semesterLogicHandler.js | 43 ++ assets/js/semesters/semesterModalHandler.js | 68 +++ assets/js/semesters/semesterTableHandler.js | 49 +++ .../js/studyClasses/studyClassLogicHandler.js | 43 ++ .../js/studyClasses/studyClassModalHandler.js | 73 +++ .../js/studyClasses/studyClassTableHandler.js | 49 +++ .../studyProgram/studyProgramLogicHandler.js | 35 ++ .../studyProgram/studyProgramModalHandler.js | 49 +++ .../studyProgram/studyProgramTableHandler.js | 43 ++ dashboard/index.html | 279 ++++++++++++ index.html | 332 ++++++++++++++ lectureDates/index.html | 195 +++++++++ lecturers/index.html | 197 +++++++++ lectures/index.html | 201 +++++++++ readme.md | 94 ++++ semesters/index.html | 197 +++++++++ studyClasses/index.html | 197 +++++++++ studyProgram/index.html | 194 ++++++++ 36 files changed, 3550 insertions(+) create mode 100644 assets/css/styles.css create mode 100644 assets/img/AliFistik.jpg create mode 100644 assets/img/JonasBraus.jpg create mode 100644 assets/img/SimonSchmieder.jpg create mode 100644 assets/img/favicon.svg create mode 100644 assets/img/uniplanner.png create mode 100644 assets/js/dashboard/dashboardLogicHandler.js create mode 100644 assets/js/dummyDataHandler.js create mode 100644 assets/js/lectureDates/lectureDateLogicHandler.js create mode 100644 assets/js/lectureDates/lectureDateModalHandler.js create mode 100644 assets/js/lectureDates/lectureDateTableHandler.js create mode 100644 assets/js/lecturers/lecturerLogicHandler.js create mode 100644 assets/js/lecturers/lecturerModalHandler.js create mode 100644 assets/js/lecturers/lecturerTableHandler.js create mode 100644 assets/js/lectures/lectureLogicHandler.js create mode 100644 assets/js/lectures/lectureModalHandler.js create mode 100644 assets/js/lectures/lectureTableHandler.js create mode 100644 assets/js/logicHandler.js create mode 100644 assets/js/semesters/semesterLogicHandler.js create mode 100644 assets/js/semesters/semesterModalHandler.js create mode 100644 assets/js/semesters/semesterTableHandler.js create mode 100644 assets/js/studyClasses/studyClassLogicHandler.js create mode 100644 assets/js/studyClasses/studyClassModalHandler.js create mode 100644 assets/js/studyClasses/studyClassTableHandler.js create mode 100644 assets/js/studyProgram/studyProgramLogicHandler.js create mode 100644 assets/js/studyProgram/studyProgramModalHandler.js create mode 100644 assets/js/studyProgram/studyProgramTableHandler.js create mode 100644 dashboard/index.html create mode 100644 index.html create mode 100644 lectureDates/index.html create mode 100644 lecturers/index.html create mode 100644 lectures/index.html create mode 100644 readme.md create mode 100644 semesters/index.html create mode 100644 studyClasses/index.html create mode 100644 studyProgram/index.html diff --git a/assets/css/styles.css b/assets/css/styles.css new file mode 100644 index 0000000..b533985 --- /dev/null +++ b/assets/css/styles.css @@ -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%; +} \ No newline at end of file diff --git a/assets/img/AliFistik.jpg b/assets/img/AliFistik.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eefb7f4aaa283005ff06f07a518b605535986bd5 GIT binary patch literal 7747 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 literal 0 HcmV?d00001 diff --git a/assets/img/JonasBraus.jpg b/assets/img/JonasBraus.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c1ad0bcd92fbb9e7b1dbbb3b27d14373ec38543f GIT binary patch literal 7365 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 X%7#=WhGL7+eN*6{7Frv>d|UiKH439p literal 0 HcmV?d00001 diff --git a/assets/img/favicon.svg b/assets/img/favicon.svg new file mode 100644 index 0000000..e164827 --- /dev/null +++ b/assets/img/favicon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/assets/img/uniplanner.png b/assets/img/uniplanner.png new file mode 100644 index 0000000000000000000000000000000000000000..ca832cf87c9afd4f81f37f3b31524f91372cebc2 GIT binary patch literal 51432 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

8{zO+$a_)ht?S+UP0-3feD=HL{=Klf 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 { + dropdown.innerHTML += `

  • ${lecturer.firstName} ${lecturer.lastName}
  • ` + }) +}) + +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 = `${lecturer.email}` + 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 = `` + 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 + ` +
  • ${lecture.lectureName} - ${logicHandler.getItem("studyClasses", lecture.studyClass).name} (${logicHandler.formatDateTime(date.startDate)} - ${logicHandler.formatDateTime(date.endDate)})
  • + ` + } + }) + + }) + document.querySelector(".lectureList").innerHTML = html + + document.getElementsByClassName("sidebar")[0].style.minHeight = `${document.body.offsetHeight - 66}px` +} \ No newline at end of file diff --git a/assets/js/dummyDataHandler.js b/assets/js/dummyDataHandler.js new file mode 100644 index 0000000..2cc7c46 --- /dev/null +++ b/assets/js/dummyDataHandler.js @@ -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 + })) + +} \ No newline at end of file diff --git a/assets/js/lectureDates/lectureDateLogicHandler.js b/assets/js/lectureDates/lectureDateLogicHandler.js new file mode 100644 index 0000000..8f0df76 --- /dev/null +++ b/assets/js/lectureDates/lectureDateLogicHandler.js @@ -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: "" + } +} \ No newline at end of file diff --git a/assets/js/lectureDates/lectureDateModalHandler.js b/assets/js/lectureDates/lectureDateModalHandler.js new file mode 100644 index 0000000..02f89bc --- /dev/null +++ b/assets/js/lectureDates/lectureDateModalHandler.js @@ -0,0 +1,49 @@ +class LectureDateModalHandler { + getLectureDateModal(lectureDate) { + let heading = lectureDate.id == "Create" ? "Neuen Termin erstellen" : `Termin #${lectureDate.id} bearbeiten` + + let modal = ` + + ` + + let htmlModal = document.createElement("div") + htmlModal.innerHTML = modal + return htmlModal + } + + getLectureDateModalButton(id) { + let button = ` + + ` + + let htmlButton = document.createElement("div") + htmlButton.innerHTML = button + return htmlButton + } +} \ No newline at end of file diff --git a/assets/js/lectureDates/lectureDateTableHandler.js b/assets/js/lectureDates/lectureDateTableHandler.js new file mode 100644 index 0000000..955d73d --- /dev/null +++ b/assets/js/lectureDates/lectureDateTableHandler.js @@ -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 = ` + ${lectureDate.id} + ${logicHandler.formatDateTime(lectureDate.startDate)} + ${logicHandler.formatDateTime(lectureDate.endDate)} + +
    + + +
    + + ` + + 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` + }) + } +}) \ No newline at end of file diff --git a/assets/js/lecturers/lecturerLogicHandler.js b/assets/js/lecturers/lecturerLogicHandler.js new file mode 100644 index 0000000..88fa466 --- /dev/null +++ b/assets/js/lecturers/lecturerLogicHandler.js @@ -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: "" + } +} \ No newline at end of file diff --git a/assets/js/lecturers/lecturerModalHandler.js b/assets/js/lecturers/lecturerModalHandler.js new file mode 100644 index 0000000..c5be7db --- /dev/null +++ b/assets/js/lecturers/lecturerModalHandler.js @@ -0,0 +1,60 @@ +class LecturerModalHandler { + + getLecturerModal(lecturer, studyProgramList) { + let heading = lecturer.id == "Create" ? "Neuen Dozent erstellen" : `Dozent #${lecturer.id} bearbeiten` + let modal = ` + + ` + + let htmlModal = document.createElement("div") + htmlModal.innerHTML = modal + return htmlModal + } + + getLecturerModalButton(id) { + let button = ` + + ` + + let htmlButton = document.createElement("div") + htmlButton.innerHTML = button + return htmlButton + } +} diff --git a/assets/js/lecturers/lecturerTableHandler.js b/assets/js/lecturers/lecturerTableHandler.js new file mode 100644 index 0000000..89ede3c --- /dev/null +++ b/assets/js/lecturers/lecturerTableHandler.js @@ -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 = ` + ${lecturer.id} + ${lecturer.firstName} + ${lecturer.lastName} + ${lecturer.email} + ${studyProgram} + +
    + + +
    + + ` + 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` + }) + } +}) \ No newline at end of file diff --git a/assets/js/lectures/lectureLogicHandler.js b/assets/js/lectures/lectureLogicHandler.js new file mode 100644 index 0000000..531c1d5 --- /dev/null +++ b/assets/js/lectures/lectureLogicHandler.js @@ -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: "" + } +} \ No newline at end of file diff --git a/assets/js/lectures/lectureModalHandler.js b/assets/js/lectures/lectureModalHandler.js new file mode 100644 index 0000000..d0b9834 --- /dev/null +++ b/assets/js/lectures/lectureModalHandler.js @@ -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 = ` + + ` + + let htmlModal = document.createElement("div") + htmlModal.innerHTML = modal + return htmlModal + } + + getLectureModalButton(id) { + let button = ` + + ` + + let htmlButton = document.createElement("div") + htmlButton.innerHTML = button + return htmlButton + } +} diff --git a/assets/js/lectures/lectureTableHandler.js b/assets/js/lectures/lectureTableHandler.js new file mode 100644 index 0000000..1191138 --- /dev/null +++ b/assets/js/lectures/lectureTableHandler.js @@ -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 = ` + ${lecture.id} + ${lecture.lectureName} + ${lecture.moduleName} + ${lecture.duration} + ${lectureDates} + ${lecturers} + ${studyClass} + +
    + + +
    + + ` + 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` + }) + } +}) \ No newline at end of file diff --git a/assets/js/logicHandler.js b/assets/js/logicHandler.js new file mode 100644 index 0000000..aabe445 --- /dev/null +++ b/assets/js/logicHandler.js @@ -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 += `` + else + datalist += `` + }) + 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 += `` + else + datalist += `` + }) + 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 += `` + else + datalist += `` + }) + 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` +}) diff --git a/assets/js/semesters/semesterLogicHandler.js b/assets/js/semesters/semesterLogicHandler.js new file mode 100644 index 0000000..8f30a1c --- /dev/null +++ b/assets/js/semesters/semesterLogicHandler.js @@ -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: "" + } +} \ No newline at end of file diff --git a/assets/js/semesters/semesterModalHandler.js b/assets/js/semesters/semesterModalHandler.js new file mode 100644 index 0000000..c24d1d6 --- /dev/null +++ b/assets/js/semesters/semesterModalHandler.js @@ -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 = ` + + ` + + let htmlModal = document.createElement("div") + htmlModal.innerHTML = modal + return htmlModal + } + + getSemesterModalButton(id) { + let button = ` + + ` + let htmlButton = document.createElement("div") + htmlButton.innerHTML = button + return htmlButton + } +} \ No newline at end of file diff --git a/assets/js/semesters/semesterTableHandler.js b/assets/js/semesters/semesterTableHandler.js new file mode 100644 index 0000000..47a5efc --- /dev/null +++ b/assets/js/semesters/semesterTableHandler.js @@ -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 = ` + ${semester.id} + ${semester.name} + ${logicHandler.formatDateTimeToDate(logicHandler.getItem("lectureDates", semester.startDate).startDate)} + ${logicHandler.formatDateTimeToDate(logicHandler.getItem("lectureDates", semester.endDate).endDate)} + ${semester.number} + ${studyProgram} + +
    + + +
    + + ` + + 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` + }) + } +}) \ No newline at end of file diff --git a/assets/js/studyClasses/studyClassLogicHandler.js b/assets/js/studyClasses/studyClassLogicHandler.js new file mode 100644 index 0000000..a361e4d --- /dev/null +++ b/assets/js/studyClasses/studyClassLogicHandler.js @@ -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: "" + } +} \ No newline at end of file diff --git a/assets/js/studyClasses/studyClassModalHandler.js b/assets/js/studyClasses/studyClassModalHandler.js new file mode 100644 index 0000000..1a16fef --- /dev/null +++ b/assets/js/studyClasses/studyClassModalHandler.js @@ -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 = ` + + ` + + let htmlModal = document.createElement("div") + htmlModal.innerHTML = modal + return htmlModal + } + + getStudyClassModalButton(id) { + let button = ` + + ` + + let htmlButton = document.createElement("div") + htmlButton.innerHTML = button + return htmlButton + } +} diff --git a/assets/js/studyClasses/studyClassTableHandler.js b/assets/js/studyClasses/studyClassTableHandler.js new file mode 100644 index 0000000..6a7d01c --- /dev/null +++ b/assets/js/studyClasses/studyClassTableHandler.js @@ -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 = ` + ${studyClass.id} + ${studyClass.name} + ${logicHandler.formatDateTimeToDate(logicHandler.getItem("lectureDates", studyClass.startDate).startDate)} + ${logicHandler.formatDateTimeToDate(logicHandler.getItem("lectureDates", studyClass.endDate).endDate)} + ${logicHandler.getItem("semesters", studyClass.semester).name} + ${studyProgram} + +
    + + +
    + + ` + 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` + }) + } +}) \ No newline at end of file diff --git a/assets/js/studyProgram/studyProgramLogicHandler.js b/assets/js/studyProgram/studyProgramLogicHandler.js new file mode 100644 index 0000000..6263192 --- /dev/null +++ b/assets/js/studyProgram/studyProgramLogicHandler.js @@ -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: "" + } +} \ No newline at end of file diff --git a/assets/js/studyProgram/studyProgramModalHandler.js b/assets/js/studyProgram/studyProgramModalHandler.js new file mode 100644 index 0000000..587f602 --- /dev/null +++ b/assets/js/studyProgram/studyProgramModalHandler.js @@ -0,0 +1,49 @@ +class StudyProgramModalHandler { + + getStudyProgramModal(studyProgram) { + let heading = studyProgram.id == "Create" ? "Neuen Studiengang erstellen" : `Studiengang #${studyProgram.id} bearbeiten` + let modal = ` + + ` + + let htmlModal = document.createElement("div") + htmlModal.innerHTML = modal + return htmlModal + } + + getStudyProgramModalButton(id) { + let button = ` + + ` + + let htmlButton = document.createElement("div") + htmlButton.innerHTML = button + return htmlButton + } +} \ No newline at end of file diff --git a/assets/js/studyProgram/studyProgramTableHandler.js b/assets/js/studyProgram/studyProgramTableHandler.js new file mode 100644 index 0000000..caa15ab --- /dev/null +++ b/assets/js/studyProgram/studyProgramTableHandler.js @@ -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 = ` + ${studyProgram.id} + ${studyProgram.name} + ${studyProgram.short} + +
    + + +
    + + ` + + 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` + }) + } +}) \ No newline at end of file diff --git a/dashboard/index.html b/dashboard/index.html new file mode 100644 index 0000000..e7b3f8e --- /dev/null +++ b/dashboard/index.html @@ -0,0 +1,279 @@ + + + + + + + + + UniPlanner + + + + + + + + + +
    + +
    + +
    + + +
    +

    + Dashboard +
    + + +
    +

    + +
    +
    +
    +

    Vorlesungstermine

    +
      +
    • +

      + +

      +
    • +
    • +

      + +

      +
    • +
    • +

      + +

      +
    • +
    • +

      + +

      +
    • +
    • +

      + +

      +
    • +
    +
    +
    +
    +
    +
    +
    + + + + +
    +
    +

    + +

    +

    + +

    +
    +
    + +
    +
    +
    +
    + + + + + + +
    +
    + + + + + + + +
    +
    + + + + + Weiteres +

    + + + + + + + + + +

    +
    +
    +
    +
    +
    +
    +
    + +
    + Copyright © 2022 Ali Fistik, Jonas Braus, Simon Schmieder +
    + + + + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..af1424f --- /dev/null +++ b/index.html @@ -0,0 +1,332 @@ + + + + + + + + + UniPlanner + + + + + + + + + +
    + +
    + +
    +
    + +
    + +
    +
    +
    +

    Über uns

    +
    +
    + +
    +
    +
    +
    + + +
    Ali Fistik
    + Dualer Student + + + + + + + + + + + + +
    + Persistence. Perfection. Prioritize your passion. +
    +
    +
    +
    +
    + + +
    Jonas Braus
    + Dualer Student + + + + + + + + + + + + + +
    + Price is what you pay. Value is what you get. +
    +
    +
    +
    +
    + + +
    Simon Schmieder
    + Dualer Student + + + + + + + + + + + + + +
    + Best way to predict your future is to create IT. +
    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Funktionen

    +
    +
    +

    + Herzlich Willkommen auf uniplanner.de
    + UniPlanner ist DEIN Online-Tool für die Planung sämtlicher studienrelevanten + Themen! +

    + +
    Wie funktionierts?
    + +

    + Mit UniPlanner kannst du kostenlos Einträge für Vorlesungen, Semester, Dozenten und Weiteres + anlegen. Womit du am Besten anfängst + erfährst du in diesem kurzen Guide. +

    +
      +
    • + Über das Dropdownmenü "Verwaltung", gelangst du zu den jeweiligen Seiten für die + Datenerfassung +
    • +
    • + Zu Beginn kannst du einen + Studiengang, sowie einen oder mehrere Termine, bestehend aus einem + Start- und Enddatum, so wie der jeweiligen Uhrzeit, anlegen +
    • +
    • + Hast du das getan, ist es dir bereits möglich Semester und Dozenten mit allen erforderlichen + Daten einzutragen +
    • +
    • + Navigiere nun in den Bereich Jahrgänge und trage die jeweiligen Daten ein +
    • +
    • + Du hast nun alle nötigen Daten um Einträge zu Vorlesungen zu erstellen +
    • +
    • + Nachdem alle Daten ins System eingetragen wurden kannst du über das Dashboard einen Dozenten + auswählen, um dir seine Kontaktdaten, Vorlesungen und einige weiteren Daten anzusehen +
    • +
    +
    +
    +
    + +
    +
    +
    +
    +

    Impressum

    +

    Angaben gemäß § 5 TMG

    +

    Simon Schmieder
    + Musterstraße 1
    + 79576 Weil am Rhein
    +

    +

    Vertreten durch:
    + Ali Fistik, Jonas Braus
    +

    +

    Kontakt:
    + Telefon: 01234-789456
    + Fax: 1234-56789
    + E-Mail: kontakt@uniplanner.de

    +

    Umsatzsteuer-ID:
    + Umsatzsteuer-Identifikationsnummer gemäß §27a Umsatzsteuergesetz: 0123456789

    + Wirtschafts-ID:
    + 0123456789
    +

    +

    Aufsichtsbehörde:
    + Bezirksgericht Freiburg im Breisgau

    +
    +

    + Website Impressum erstellt durch impressum-generator.de von der Kanzlei Hasselbach +

    +
    +
    +
    +
    +
    + +
    + Copyright © 2022 Ali Fistik, Jonas Braus, Simon Schmieder +
    + + + + + + + + \ No newline at end of file diff --git a/lectureDates/index.html b/lectureDates/index.html new file mode 100644 index 0000000..6eab76d --- /dev/null +++ b/lectureDates/index.html @@ -0,0 +1,195 @@ + + + + + + + + + UniPlanner + + + + + + + + + +
    + +
    + +
    + + +
    +

    + Vorlesungstermine + + + + + +

    +
    + + + + + + + + + + +
    #StartdatumEnddatum
    +
    +
    +
    + + + + + + +
    + Copyright © 2022 Ali Fistik, Jonas Braus, Simon Schmieder +
    + + + + + + + + + + \ No newline at end of file diff --git a/lecturers/index.html b/lecturers/index.html new file mode 100644 index 0000000..5d84efa --- /dev/null +++ b/lecturers/index.html @@ -0,0 +1,197 @@ + + + + + + + + + UniPlanner + + + + + + + + + +
    + +
    + +
    + + +
    +

    + Dozenten + + + + + +

    +
    + + + + + + + + + + + + +
    #VornameNachnameEmailStudiengang
    +
    +
    +
    + +
    + Copyright © 2022 Ali Fistik, Jonas Braus, Simon Schmieder +
    + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lectures/index.html b/lectures/index.html new file mode 100644 index 0000000..0125e25 --- /dev/null +++ b/lectures/index.html @@ -0,0 +1,201 @@ + + + + + + + + + UniPlanner + + + + + + + + + +
    + +
    + +
    + + +
    +

    + Vorlesungen + + + + + +

    +
    + + + + + + + + + + + + + + +
    #NameModulDauerTermineDozentenJahrgang
    +
    +
    +
    + +
    + Copyright © 2022 Ali Fistik, Jonas Braus, Simon Schmieder +
    + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..45116e7 --- /dev/null +++ b/readme.md @@ -0,0 +1,94 @@ +# UniPlanner + +## Inhaltsverzeichnis +1. Projektbeschreibung +2. Projektarchitektur + 1. Technologien + 2. Anforderungen +3. Farbschema +4. Anleitung zum starten + +## Projektbeschreibung +Der UniPlanner ist eine WebAnwendung, mit der + - Vorlesungen + - Semester + - Dozenten + - Termine + - Jahrgänge + - Studiengänge + +verwaltet werden können. + +Die Webseite ist dabei aufgeteilt in eine statische Hauptseite und einen Verwaltungsbereich mit Dashboard. + +Die Hauptseite mit Carousel enthält einige Informationen über uns und die Anwendung sowie ein Impressum. + +Im Verwaltungsbereich befinden sich Unterseiten, die per Dropdown oder per Sidebar erreicht werden können. +Auf jeder dieser Unterseiten kann ein "Datentyp" verwaltet werden (Einsehen, Erstellen, Editieren und Löschen). +Die einzelnen Datentypen verweisen dabei teilweise auf andere Datentypen, wodurch eine Reihenfolge der Eingaben vorgegeben ist. +Um Elemente zu erstellen müssen stets alle Felder ausgefüllt werden. + +Über das Dashboard können mithilfe eines Dropdown-Menüs Dozenten einzeln gewählt und angezeigt werden. Hierbei werden Vorlesungen mit Jahrgang und dem ersten Vorlesungstermin angezeigt, außerdem sind einige Informationen über den Dozenten einsehbar. + +## Projektarchitektur +Das Projekt ist in 2 Teile zu unterteilen. +Im Hauptordner befinden sich die einzelnen HTML Dateien, die über eine Ordnerstruktur den Webseitenaufbau abbilden. +Im Assets-Ordner befinden sich alle JavaScript und CSS Dateien, welche in den einzelnen HTML Dateien importiert werden. + +### Technologien + +#### HTML +HTML ist eine Markdownsprache, mit der die Struktur von Webseiten beschrieben werden kann. +Wir haben unsere Webseite mit HTML5 aufgebaut und in Bereiche wie header, main und footer aufgeteilt. + +#### CSS +CSS ist eine Sprache, mit der HTML Elemente gestyled werden können. +In der Datei assets/styles.css befinden sich alle unsere Styledefinitionen (Bootstrap ausgenommen). +Wir haben CSS3 verwendet, um eigene Styles zu definieren und bestehende HTML sowie Bootstrap Styles zu überschreiben. + +#### JavaScript +JavaScript (JS) ist eine Scriptsprache, mit der Webseiten interaktiv aufgebaut werden können. +Wir haben auf unserer Webseite JavaScript verwendet, um Daten im Lokalen Speicher des Browsers abzulegen, HTML Code für Popups und Tabellen zu generieren und styles von HTML Elementen anzupassen (...). + +Unsere JS Dateien verweisen dabei nicht aufeinander, können jedoch Elemente aus anderen Dateien verwenden, da wir sie in einer speziellen Reihenfolge in den HTML Code importiert haben. Die Hauptkomponente stellt hierbei der LogicHandler (assets/logicHandler.js) dar, welcher sich mit der Speicher und Ladelogik sowie einigen weiteren oft verwendeten Operationen befasst. + +Für jeden Datentyp haben wir außerdem einen TableHandler und einen ModalHandler erstellt, welche sich um das generieren von Tabellen und Modals (Popups) mit den jeweiligen Werten kümmern. Diese beiden Handler haben wir dann über einen Datentyp spezifischen LogicHandler mit der Hauptlogik verknüpft. + +Das Dashboard hat ebenfalls einen gesonderten LogicHandler, welcher sich mit der Ladelogik der Dozenten in der Dashboard Ansicht befasst. + +### Anforderungen +Für unser Projekt wird eine stabile Internetanbindung benötigt, da wir Bootstrap v5.2 per URL (CDN) importiert haben. + +Bootstrap ist eine Bibliothek, die Styles, Icons und JavaScript in eine Webseite einbinden kann, um das erstellen von vorgefertigten Komponenten zu ermöglichen. +Im Rahmen unserer Projektarbeit haben wir manche der Standardwerte von Bootstrap überschrieben. + +## Farbschema +Als Farben haben wir uns für ein kräftiges Rot in Kombination mit einem Grauton entschieden. + +In der Farbtheorie wird Rot oft mit Wut und Agressionen, jedoch auch mit Liebe und Harmonie verbunden. Da wir diese Kombination aus Gefühlen als eine recht passende Beschreibung eines Studiums angesehen haben, haben wir die Farbe #e2001a als Primärfarbe gewählt. + +Da die Kombination aus Rot und Grau aus unserer Sicht professionell wirkt und außerdem die Farbkombination der DHBW wiederspiegelt haben wir als Sekundäre Farbe #5c6971 gewählt. + +Als Hintergrundfarbe haben wir zudem nicht ein klares Weiß gewählt, sondern einen sehr hellen grauton. +Durch diese Entscheidung konnten wir einzelne Komponenten der Webseite besser hervorheben und unsere Augen schonen. + +## Anleitung zum starten +Um unsere Webseite zu testen kann die Datei index.html im Hauptverzeichnis im Browser geöffnert werden. + +Unsere Webseite ist alternativ auch über [uniplanner.de](https://uniplanner.de) erreichbar (Stand 12.12.2022) + +Auf der Webseite befindet sich im Bereich Funktionen folgende Kurzanleitung, die veranschaulicht, in welcher Reihenfolge das erstellen von Daten möglich ist. +- Über das Dropdownmenü "Verwaltung", gelangen Sie zu den jeweiligen Seiten für die Datenerfassung +- Zu Beginn können Sie einen Studiengang, sowie einen oder mehrere Termine, bestehend aus einem Start- und Enddatum, so wie der jeweiligen Uhrzeit, anlegen +- Haben Sie das getan, ist es Ihnen bereits möglich Semester und Dozenten mit allen erforderlichen Daten einzutragen +- Navigieren Sie nun in den Bereich Jahrgänge und tragen Sie die jeweiligen Daten ein +- Nun haben Sie alle nötigen Daten um Einträge zu Vorlesungen zu erstellen +- Nachdem Sie alle Daten ins System eingetragen haben, können Sie über das Dashboard einen Dozenten auswählen, um dessen Kontaktdaten, Vorlesungen und einige weiteren Daten anzusehen + +Knöpfe zum erstellen von Daten sind immer durch ein +-Symbol erkennbar + +Knöpfe zum editieren von Daten sind immer durch ein Stift-Symbol erkennbar + +Knöpfe zum löschen von Daten sind immer durch ein Mülleimer-Symbol erkennbar + +Um die manuelle Datenerstellung zu überspringen und die Webseite mit Testdaten zu füllen, kann jedoch auch in der Konsole der JS Befehl loadDummyData() ausgeführt werden. diff --git a/semesters/index.html b/semesters/index.html new file mode 100644 index 0000000..d9e298c --- /dev/null +++ b/semesters/index.html @@ -0,0 +1,197 @@ + + + + + + + + + UniPlanner + + + + + + + + + +
    + +
    + +
    + + +
    +

    + Semester + + + + + +

    +
    + + + + + + + + + + + + + +
    #NameStartEndeNummerStudiengang
    +
    +
    +
    + +
    + Copyright © 2022 Ali Fistik, Jonas Braus, Simon Schmieder +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/studyClasses/index.html b/studyClasses/index.html new file mode 100644 index 0000000..44e8527 --- /dev/null +++ b/studyClasses/index.html @@ -0,0 +1,197 @@ + + + + + + + + + UniPlanner + + + + + + + + + +
    + +
    + +
    + + +
    +

    + Jahrgänge + + + + + +

    +
    + + + + + + + + + + + + + +
    #NameStartEndeSemesterStudiengang
    +
    +
    +
    + +
    + Copyright © 2022 Ali Fistik, Jonas Braus, Simon Schmieder +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/studyProgram/index.html b/studyProgram/index.html new file mode 100644 index 0000000..e357428 --- /dev/null +++ b/studyProgram/index.html @@ -0,0 +1,194 @@ + + + + + + + + + UniPlanner + + + + + + + + + +
    + +
    + +
    + + +
    +

    + Studiengang + + + + + +

    +
    + + + + + + + + + + +
    #NameKürzel
    +
    +
    +
    + +
    + Copyright © 2022 Ali Fistik, Jonas Braus, Simon Schmieder +
    + + + + + + + + + + + + + + \ No newline at end of file