diff --git a/LICENSE b/LICENSE index 11664aa..78bde0c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Kim Endisch +Copyright (c) 2024 Kim Endisch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/asset/logo-1024.png b/asset/logo-1024.png new file mode 100644 index 0000000..77b9fea Binary files /dev/null and b/asset/logo-1024.png differ diff --git a/asset/logo-2048.png b/asset/logo-2048.png new file mode 100644 index 0000000..b146c4c Binary files /dev/null and b/asset/logo-2048.png differ diff --git a/asset/logo-256.png b/asset/logo-256.png new file mode 100644 index 0000000..85053e6 Binary files /dev/null and b/asset/logo-256.png differ diff --git a/asset/logo-512.png b/asset/logo-512.png new file mode 100644 index 0000000..5da2bcc Binary files /dev/null and b/asset/logo-512.png differ diff --git a/asset/logo-bg-1024.png b/asset/logo-bg-1024.png new file mode 100644 index 0000000..dc109e2 Binary files /dev/null and b/asset/logo-bg-1024.png differ diff --git a/asset/logo-bg-2048.png b/asset/logo-bg-2048.png new file mode 100644 index 0000000..7a3cdf3 Binary files /dev/null and b/asset/logo-bg-2048.png differ diff --git a/asset/logo-bg-256.png b/asset/logo-bg-256.png new file mode 100644 index 0000000..addad82 Binary files /dev/null and b/asset/logo-bg-256.png differ diff --git a/asset/logo-bg-512.png b/asset/logo-bg-512.png new file mode 100644 index 0000000..d733d2e Binary files /dev/null and b/asset/logo-bg-512.png differ diff --git a/asset/logo.svg b/asset/logo.svg new file mode 100644 index 0000000..e479d35 --- /dev/null +++ b/asset/logo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/init.php b/init.php new file mode 100644 index 0000000..fa24e8f --- /dev/null +++ b/init.php @@ -0,0 +1,35 @@ + diff --git a/meta.php b/meta.php index 5b24977..3138396 100644 --- a/meta.php +++ b/meta.php @@ -1,11 +1,16 @@ "", "target" => "page/start"] + ["path" => "", "target" => "page/start"], + ["path" => ":lang", "target" => "page/start"], ]; ?> diff --git a/page/footer.php b/page/footer.php new file mode 100644 index 0000000..609a249 --- /dev/null +++ b/page/footer.php @@ -0,0 +1,34 @@ + + + + + + + diff --git a/page/lang_autoselect.php b/page/lang_autoselect.php new file mode 100644 index 0000000..71bbdeb --- /dev/null +++ b/page/lang_autoselect.php @@ -0,0 +1,55 @@ +get()); + $path_raw_full = implode("/", $path_raw); + Url_redirect::path_modify($path_raw_full); + } + + + // LANGUAGE MANAGER // + // hack: fake get param from url path + $_GET["lang"] = $param_lang; + + // initialize + Data::$lang_object = new Lang(list: ["de", "en"], default: "de"); + Data::$lang = Data::$lang_object->get(); + + // load dict + Data::$dict = new Lang_Dict(Data::$lang_object); + require("./page/strings.php"); + + + // BUILD ALTERNATE LANGUAGE URLS // + // get content path + $content_path_raw = Request::path_raw(); + $content_path_raw = array_splice($content_path_raw, 1); + + // prepend lang codes + foreach(["de", "en"] as $one_lang_code){ + $path_raw = $content_path_raw; + array_unshift($path_raw, $one_lang_code); + Data::$alternate[$one_lang_code] = Url::path_modify(implode("/", $path_raw)); + } +?> diff --git a/page/page_base.php b/page/page_base.php new file mode 100644 index 0000000..97cc502 --- /dev/null +++ b/page/page_base.php @@ -0,0 +1,21 @@ +'; + Page::$head["alternate_en"] = ''; + + Page::author("Kim Endisch"); + Page::$head["analytics"] = ''; + + Page::css("./page/style.css"); + Page::font("ubuntu"); + Page::font("tabler"); +?> diff --git a/page/start/index.php b/page/start/index.php index 578ed9e..48f1ec0 100644 --- a/page/start/index.php +++ b/page/start/index.php @@ -1,7 +1,65 @@ get("title")); + Page::description(Data::$dict->get("description")); + + Page::robots(index: true, follow: true); + Page::keywords("thi", "thi hub", "thi links", "hochschule", "ingolstadt", "hochschule ingolstadt"); +?> + + + + + +
+
+ + +
+
+ + get("about_title") ?> +
+
+
+ get("about_text"); + foreach($about_text as $one_about_text_line){ + echo("" . $one_about_text_line . ""); + } + ?> +
+
+
+
+
+ + + + diff --git a/page/strings.php b/page/strings.php new file mode 100644 index 0000000..c9febae --- /dev/null +++ b/page/strings.php @@ -0,0 +1,136 @@ +define([ + "title" => [ + "de" => "THI-Hub.de", + "en" => "THI-Hub.de", + ], + "description" => [ + "de" => "Ein übersichtlicher Hub für Student*innen der THI", + "en" => "A simple hub for THI students", + ], + + + + + + "quicklink_list" => [ + "de" => [ + [ + "color" => "blue", + "icon" => "school", + "name" => "Moodle", + "extra" => "", + "url" => "https://moodle.thi.de/my", + ],[ + "color" => "red", + "icon" => "settings", + "name" => "Primuss", + "extra" => "Für Studierende", + "url" => "https://www3.primuss.de/cgi-bin/login/index.pl?FH=fhin", + ],[ + "color" => "green", + "icon" => "calendar-time", + "name" => "Stundenplan", + "extra" => "", + "url" => "https://www3.primuss.de/stpl/index.php?FH=fhin", + ],[ + "color" => "yellow", + "icon" => "books", + "name" => "Bücherei", + "extra" => "OPAC", + "url" => "https://thi.idm.oclc.org/login?url=https://opac.ku.de/index-hi.html", + ],[ + "color" => "orange", + "icon" => "mail", + "name" => "Webmail", + "extra" => "Outlook", + "url" => "https://outlook.thi.de", + ], + ], + "en" => [ + [ + "color" => "blue", + "icon" => "school", + "name" => "Moodle", + "extra" => "", + "url" => "https://moodle.thi.de/my", + ],[ + "color" => "red", + "icon" => "settings", + "name" => "Primuss", + "extra" => "For Students", + "url" => "https://www3.primuss.de/cgi-bin/login/index.pl?FH=fhin", + ],[ + "color" => "green", + "icon" => "calendar-time", + "name" => "Timetable", + "extra" => "", + "url" => "https://www3.primuss.de/stpl/index.php?FH=fhin", + ],[ + "color" => "yellow", + "icon" => "books", + "name" => "Library", + "extra" => "OPAC", + "url" => "https://thi.idm.oclc.org/login?url=https://opac.ku.de/index-hi.html", + ],[ + "color" => "orange", + "icon" => "mail", + "name" => "Webmail", + "extra" => "Outlook", + "url" => "https://outlook.thi.de", + ], + ], + ], + + + + + + "about_title" => [ + "de" => "Über diese Seite", + "en" => "About this Page", + ], + "about_text" => [ + "de" => [ + "Eine Webseite nur für THI-Links? Im Ernst? – Ja, im Ernst!", + "Die Onlineangebote der Technischen Hochschule Ingolstadt sind über eine Vielzahl von Seiten verteilt; Um diese zu erreichen musst Du dich jedes Mal durch komplexe Untermenüs klicken – Das muss nicht sein!", + "Auf THI-Hub.de hast Du alle wichtigen Links für Dein Studium immer griffbereit! Die großen farbigen Buttons mit Icons helfen Dir dabei, den Richtigen Link blitzschnell zu finden; Ohne Untermenüs oder schreckliche Ladezeiten. Ganz einfach.", + ], + "en" => [ + "A website just for THI links? Seriously? – Yes, seriously!", + "The online portals of the Ingolstadt Technical University are distributed over a variety of pages; To reach them, you have to click through complex sub menus every time – This should not be necessary!", + "On THI-Hub.de you always have all the important links for your studies at hand! The large colored buttons with icons help you to find the right link at lightning speed; Without sub menus or terrible loading times. Very easy.", + ], + ], + + + + + + "text_sourcecode" => [ + "de" => "Quellcode", + "en" => "Source Code", + ], + + "text_imprint" => [ + "de" => "Impressum", + "en" => "Imprint", + ], + "link_imprint" => [ + "de" => "https://www.tjdev.de/impressum", + "en" => "https://www.tjdev.de/imprint", + ], + + "text_privacy_policy" => [ + "de" => "Datenschutz­erklärung", + "en" => "Privacy Policy", + ], + "link_privacy_policy" => [ + "de" => "https://www.tjdev.de/datenschutz", + "en" => "https://www.tjdev.de/privacy", + ], + ]); +?> diff --git a/page/style.css b/page/style.css new file mode 100644 index 0000000..6ea50fa --- /dev/null +++ b/page/style.css @@ -0,0 +1,443 @@ +:root { + --color-bg: #21252b; + --color-bg-light: #2c313a; + + --color-white: #c5cad3; + + --color-gray-light: #acb0b9; + --color-gray: #828997; + --color-gray-dark: #5c6370; + --color-gray-dark-dark: #454b54; + + --color-red: #e06c75; + --color-red-light: #e9969d; + --color-red-dark: #cb4d58; + + --color-orange: #d19a66; + --color-orange-light: #ddb48d; + --color-orange-dark: #b9804b; + + --color-yellow: #dace71; + --color-yellow-light: #e5dc9a; + --color-yellow-dark: #c4b754; + + --color-green: #98c379; + --color-green-light: #b3d39c; + --color-green-dark: #7fa762; + + --color-cyan: #71d6bc; + --color-cyan-light: #98e1cf; + --color-cyan-dark: #55bea4; + + --color-blue: #61afef; + --color-blue-light: #90c7f4; + --color-blue-dark: #3e97e0; + + --color-purple: #c678dd; + --color-purple-light: #d7a1e8; + --color-purple-dark: #af5bc8; + + + + --theme: var(--color-cyan); + --theme-light: var(--color-cyan-light); + --theme-dark: var(--color-cyan-dark); +} +* { + box-sizing: border-box; +} + + + +html, body { + margin: 0; + padding: 0; + overflow-x: hidden; + + color: var(--color-white); + background-color: var(--color-bg); +} +html { + font-size: 16px; +} +@media only screen and (max-width: 1000px) { + html { + font-size: 14px; + } +} +body { + min-height: 100vh; + min-height: 100dvh; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + + font-size: 0; + font-family: "Ubuntu", sans-serif; +} +span { + display: block; + font-size: 1rem; +} +a { + text-decoration: none; +} +span a { + color: var(--theme); +} +span a:hover { + text-decoration: underline; + cursor: pointer; +} +span.gray a { + color: var(--color-gray); + text-decoration: underline; + text-decoration-style: dotted; +} +span.gray a:hover { + text-decoration-style: solid; +} +button { + all: unset; +} +button:focus { + outline: revert; +} + +.colored { + color: var(--theme); +} +.gray { + color: var(--color-gray); +} +.gray-dark { + color: var(--color-gray-dark-dark); +} +.white { + color: var(--color-white); +} + +.hidden { + visibility: hidden !important; +} +.gone { + display: none !important; +} + +.select-none { + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} + + + + + +/* PAGE LAYOUT */ +.page-container { + flex-grow: 1; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; +} +.page { + max-width: 60vw; + + padding: 6rem 2rem; + + display: flex; + flex-direction: column; + gap: 6rem; + + text-align: center; +} +@media only screen and (max-width: 1600px) { + .page { + max-width: 75vw; + } +} +@media only screen and (max-width: 1300px) { + .page { + max-width: 85vw; + } +} +@media only screen and (max-width: 1000px) { + .page { + max-width: 100vw; + padding: 6rem 1rem; + } +} + + + + + +/* PAGE TITLE */ +.page > .title { + display: flex; + flex-direction: column; + gap: 1rem; + + margin: 2rem 0; +} +@media only screen and (max-width: 1000px) { + .page > .title { + margin: 0 0; + } +} +.page > .title h1, .page > .title h2 { + align-self: center; + margin: 0; +} + +.page > .title h1 { + font-size: 3rem; + + background-image: linear-gradient(to right, var(--color-red), var(--color-orange), var(--color-yellow), var(--color-green), var(--color-blue), var(--color-purple)); + -webkit-background-clip: text; + color: transparent; +} +.page > .title h2 { + font-size: 1.5rem; +} + + + + + +/* SECTIONS */ +.section { + display: flex; + flex-direction: column; + + width: 100%; +} + +.section > .header { + align-self: flex-start; + + position: relative; + padding-right: 0.5rem; + + display: inline-flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + gap: 0.5rem; + + color: var(--theme); +} +.section > .header .extra { + color: var(--color-gray); +} + +.section > .content { + display: flex; + flex-direction: column; + gap: 1rem; + + padding: 1rem 2rem; +} +.section > .content.rows { + flex-direction: row; + flex-wrap: wrap; + align-items: flex-start; + justify-content: center; +} + + + + + +/* BOX */ +.box { + display: flex; + flex-direction: column; + align-items: center; + gap: 1rem; + + padding: 2rem; + + border-radius: 2rem; + background-color: var(--color-bg-light); +} +.box.shrink { + display: inline-flex; +} + +.box .title, .box .extra { + display: inline-flex; + flex-direction: row; + justify-content: center; + align-items: baseline; + gap: 0.5rem; +} +.box .title { + position: relative; + left: -0.5rem; + padding-left: 0.5rem; + + color: var(--theme); + font-size: 1.5rem; +} +.box .extra { + color: var(--color-gray); +} + + + + + +/* BUTTONS */ +.button-list { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 1rem; +} + +.button, .button.disabled:hover { + align-items: center; + + display: inline-flex; + gap: 0.5rem; + width: fit-content; + padding: 1rem 1.5rem; + + color: var(--color-white); + border-radius: 1rem; + background-color: var(--color-gray-dark-dark); + + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} +.button.big { + gap: 1rem; +} +.button.on-bg { + background-color: var(--color-bg-light); +} +.button:hover { + cursor: pointer; +} +.button:hover { + background-color: var(--color-gray-dark); +} +.button.on-bg:hover { + background-color: var(--color-gray-dark-dark); +} +.button.disabled { + opacity: 0.3; +} +.button.disabled:hover { + cursor: not-allowed; +} + +.button.primary, .button.primary.disabled:hover { + color: var(--color-bg); + background-color: var(--theme); +} +.button.primary:hover { + background-color: var(--theme-dark); +} + +.button .icon.big { + font-size: 1.75rem; +} +.button .text { + display: inline-flex; + flex-flow: column; + align-items: flex-start; +} + +.button.red, .button.red.disabled:hover, .button.orange, .button.orange.disabled:hover, .button.yellow, .button.yellow.disabled:hover, .button.green, .button.green.disabled:hover, .button.cyan, .button.cyan.disabled:hover, .button.blue, .button.blue.disabled:hover, .button.purple, .button.purple.disabled:hover { + color: var(--color-bg); +} +.button.red, .button.red.disabled:hover { background-color: var(--color-red); } +.button.red:hover { background-color: var(--color-red-dark); } +.button.orange, .button.orange.disabled:hover { background-color: var(--color-orange); } +.button.orange:hover { background-color: var(--color-orange-dark); } +.button.yellow, .button.yellow.disabled:hover { background-color: var(--color-yellow); } +.button.yellow:hover { background-color: var(--color-yellow-dark); } +.button.green, .button.green.disabled:hover { background-color: var(--color-green); } +.button.green:hover { background-color: var(--color-green-dark); } +.button.cyan, .button.cyan.disabled:hover { background-color: var(--color-cyan); } +.button.cyan:hover { background-color: var(--color-cyan-dark); } +.button.blue, .button.blue.disabled:hover { background-color: var(--color-blue); } +.button.blue:hover { background-color: var(--color-blue-dark); } +.button.purple, .button.purple.disabled:hover { background-color: var(--color-purple); } +.button.purple:hover { background-color: var(--color-purple-dark); } + + + + + +/* FOOTER */ +.footer { + width: 100%; + + display: flex; + flex-direction: row; + justify-content: space-between; + flex-wrap: wrap; + gap: 1rem; + + padding: 1rem; + + background-color: var(--color-bg-light); +} +.footer > div { + flex-grow: 1; + flex-shrink: 1; + flex-basis: 0px; + + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + gap: 0.5rem; + + text-align: center; +} +@media only screen and (max-width: 1000px) { + .footer > div { + flex-basis: 100%; + justify-content: center !important; + } +} + +.footer > div a { + font-size: 1rem; + color: var(--theme); +} +.footer > div a:hover { + text-decoration: underline; +} + +.footer .delimiter { + color: var(--color-gray); +} +.footer .brand { + justify-content: flex-start; +} +.footer .legal { + justify-content: flex-end; +} + +.footer .brand img { + height: 2rem; +} +.footer .brand .version { + color: var(--color-gray); +} + +.footer .lang .selected { + font-weight: bold; + color: inherit; +}