v1.0.0 #8

Merged
DrMaxNix merged 9 commits from dev into main 2024-03-01 17:00:11 +01:00
8 changed files with 606 additions and 0 deletions
Showing only changes of commit e974aa49c8 - Show all commits

View File

@ -24,5 +24,12 @@
* @var Lang_Dict $dict Dict object for current client.
*/
public static Lang_Dict $dict;
/**
* @var array $alternate Urls for this page in alternate language.
*/
public static array $alternate = [];
}
?>

View File

@ -9,6 +9,8 @@
static::$ext[] = "lang";
static::$ext[] = "request";
static::$ext[] = "url";
static::$ext[] = "page";
static::$ext[] = "file";
// ROUTES //

34
page/footer.php Normal file
View File

@ -0,0 +1,34 @@
<?php
declare(strict_types = 1);
namespace Kimendisch\Thi_Hub;
use Flake\File;
use Flake\Project;
?>
<div class="footer">
<div class="brand">
<img src="<?= File::file("./asset/logo-256.png") ?>" alt="logo" />
<span>THI-Hub.de</span>
<a href="https://git.tjdev.de/kimendisch/thi-hub.de" target="_blank"><?= Data::$dict->get("text_sourcecode") ?> <i class="ti ti-external-link"></i></a>
<span class="version">v<?= Project::version() ?></span>
</div>
<div class="lang">
<span><i class="ti ti-world"></i></span>
<a <?= (Data::$lang === "de" ? "class=\"selected\"" : "") ?> href="<?= Data::$alternate["de"] ?>">DE</a>
<span class="delimiter">|</span>
<a <?= (Data::$lang === "en" ? "class=\"selected\"" : "") ?> href="<?= Data::$alternate["en"] ?>">EN</a>
</div>
<div class="legal">
<span>&copy; 2024 Kim Endisch</span>
<span class="delimiter">|</span>
<a href="<?= Data::$dict->get("link_imprint") ?>" target="_blank"><?= Data::$dict->get("text_imprint") ?> <i class="ti ti-external-link"></i></a>
<span class="delimiter">|</span>
<a href="<?= Data::$dict->get("link_privacy_policy") ?>" target="_blank"><?= Data::$dict->get("text_privacy_policy") ?> <i class="ti ti-external-link"></i></a>
</div>
</div>

View File

@ -5,6 +5,7 @@
use Flake\Lang;
use Flake\Lang_Dict;
use Flake\Request;
use Flake\Url;
use Flake\Url_redirect;
// MAYBE REDIRECT //
@ -38,4 +39,17 @@
// 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));
}
?>

21
page/page_base.php Normal file
View File

@ -0,0 +1,21 @@
<?php
declare(strict_types = 1);
namespace Kimendisch\Thi_Hub;
use Flake\Page;
// PAGE INIT //
Page::start();
Page::icon("./asset/logo-256.png");
Page::lang(Data::$lang);
Page::viewport(scale: 1, zoom: true);
Page::$head["alternate_de"] = '<link rel="alternate" hreflang="de" href="' . Data::$alternate["de"] . '" />';
Page::$head["alternate_en"] = '<link rel="alternate" hreflang="en" href="' . Data::$alternate["en"] . '" />';
Page::author("Kim Endisch");
Page::$head["analytics"] = '<script defer data-domain="thi-hub.de" src="https://analytics.tjdev.de/js/script.js"></script>';
Page::css("./page/style.css");
Page::font("ubuntu");
Page::font("tabler");
?>

View File

@ -1,7 +1,61 @@
<?php
declare(strict_types = 1);
namespace Kimendisch\Thi_Hub;
use Flake\Page;
// AUTOSELECT LANGUAGE //
require("./page/lang_autoselect.php");
// PAGE INIT //
require("./page/page_base.php");
Page::title(Data::$dict->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");
?>
<div class="page-container">
<div class="page">
<div class="section quicklinks">
<div class="content">
<div class="button-list">
<?php foreach(["red", "orange", "yellow", "green", "cyan", "blue", "purple"] as $color){ ?>
<a href="#" target="_blank" class="button <?= $color ?>">
<span class="icon big ti ti-circle-off"></span>
<div class="text">
<span>Lorem Ipsum</span>
<span class="gray-dark">Lorem Ipsum</span>
</div>
<span class="icon ti ti-external-link"></span>
</a>
<?php } ?>
</div>
</div>
</div>
<div class="section about">
<div class="header">
<span class="icon ti ti-circle-off"></span>
<span class="text">About Title</span>
</div>
<div class="content">
<div class="box">
<span>Lorem ipsum dolor sit amet, consectetur adipisicing 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.</span>
</div>
</div>
</div>
</div>
</div>
<?php
require("./page/footer.php");
?>

View File

@ -3,6 +3,40 @@
namespace Kimendisch\Thi_Hub;
Data::$dict->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",
],
"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&shy;erklärung",
"en" => "Privacy Policy"
],
"link_privacy_policy" => [
"de" => "https://www.tjdev.de/datenschutz",
"en" => "https://www.tjdev.de/privacy"
],
]);
?>

440
page/style.css Normal file
View File

@ -0,0 +1,440 @@
: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.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: 2rem;
}
.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;
}