nav (fix #103)

This commit is contained in:
DrMaxNix 2024-07-24 16:56:25 +02:00
parent 8582996df9
commit 6dbf54e35b
13 changed files with 359 additions and 23 deletions

View File

@ -4,4 +4,11 @@
// LOAD ENV CONFIG //
require_once("./.env.php");
// PREPARE CLASSES FOR STATE STORAGE //
// nav
class Nav {
public static ?string $active = null;
}
?>

View File

@ -10,7 +10,7 @@
<div class="footer">
<div id="footer" class="footer">
<div class="brand">
<img src="<?= File::file("./asset/logo-256.png") ?>" alt="logo" />
<span>SBGG.jetzt</span>

View File

@ -59,8 +59,12 @@
<?php require("./page/nav.php"); ?>
<?php if(!Cookieaccept::is_accepted()){ ?>
<div class="cookie-notice-required">
<div id="cookie-notice-required" class="cookie-notice-required">
<div class="box important">
<span class="title"><i class="ti ti-cookie"></i>Cookies</span>
@ -82,8 +86,8 @@
<div class="page-container">
<div class="page">
<div class="page-container has-nav">
<div id="page" class="page">
<div class="section">
<div class="content rows">
<div id="login" class="box">

View File

@ -83,8 +83,12 @@
<div class="page-container full-page">
<div class="page">
<?php require("./page/nav.php"); ?>
<div class="page-container has-nav full-page">
<div id="page" class="page">
<div class="section">
<div class="content">
<div class="button-list align-left">

View File

@ -46,8 +46,12 @@
<div class="page-container">
<div class="page">
<?php require("./page/nav.php"); ?>
<div class="page-container has-nav">
<div id="page" class="page">
<div class="section">
<div class="content">
<div class="button-list align-left">

View File

@ -45,8 +45,12 @@
<div class="page-container">
<div class="page">
<?php require("./page/nav.php"); ?>
<div class="page-container has-nav">
<div id="page" class="page">
<div class="title">
<h1><?= $dict->get("page_title_h1") ?></h1>
<h2>Admin Area</h2>

View File

@ -50,8 +50,12 @@
<div class="page-container">
<div class="page">
<?php require("./page/nav.php"); ?>
<div class="page-container has-nav">
<div id="page" class="page">
<div class="title">
<h1><?= $dict->get("page_title_h1") ?></h1>
<h2><?= $dict->get("legal_imprint_title") ?></h2>
@ -68,7 +72,7 @@
<div class="footer">
<div id="footer" class="footer">
<div class="brand">
<img src="<?= File::file("./asset/logo-256.png") ?>" alt="logo" />
<span>SBGG.jetzt</span>

85
page/nav.js Normal file
View File

@ -0,0 +1,85 @@
"use strict";
/**
* Global element references.
*/
let nav_menu_mobile_button;
let nav_menu_mobile_button_icon;
let nav_menu;
let nav_menu_mobile;
let nav_menu_mobile_page_overlay;
let nav_ref_page;
let nav_ref_cookie_notice;
let nav_ref_footer;
/**
* Global states.
*/
let nav_menu_mobile_opened = false;
/**
* CALLBACK: Initialize.
*/
window.addEventListener("load", function(event){
// COLLECT ELEMENTS //
nav_menu_mobile_button = document.getElementById("nav-menu-mobile-button");
nav_menu_mobile_button_icon = nav_menu_mobile_button.getElementsByClassName("icon")[0];
nav_menu = document.getElementById("nav-menu");
nav_menu_mobile = document.getElementById("nav-menu-mobile");
nav_menu_mobile_page_overlay = document.getElementById("nav-menu-mobile-page-overlay");
nav_ref_page = document.getElementById("page");
nav_ref_cookie_notice = document.getElementById("cookie-notice-required");
nav_ref_footer = document.getElementById("footer");
// REGISTER ONCLICK HANDLERS //
nav_menu_mobile_button.onclick = nav_menu_mobile_toggle;
nav_menu_mobile_page_overlay.onclick = nav_menu_mobile_toggle;
// COPY MENU CONTENT TO MOBILE MENU //
nav_menu_mobile.innerHTML = nav_menu.innerHTML;
});
/**
* CALLBACK: Mobile nav menu button or page overlay was clicked, toggle mobile menu.
*/
async function nav_menu_mobile_toggle(){
// SET NEW STATE //
nav_menu_mobile_opened = !nav_menu_mobile_opened;
// CHANGE BUTTON ICON //
nav_menu_mobile_button_icon.classList.remove("ti-menu-2", "ti-x");
if(nav_menu_mobile_opened) nav_menu_mobile_button_icon.classList.add("ti-x");
else nav_menu_mobile_button_icon.classList.add("ti-menu-2");
// MAYBE DISPLAY MOBILE MENU //
nav_menu_mobile.classList.add("gone");
if(nav_menu_mobile_opened) nav_menu_mobile.classList.remove("gone");
// SET PAGE, COOKIE NOTICE AND FOOTER FOCUS //
nav_ref_page.classList.remove("focus-remove-on-mobile");
if(nav_menu_mobile_opened) nav_ref_page.classList.add("focus-remove-on-mobile");
if(nav_ref_cookie_notice !== null){
nav_ref_cookie_notice.classList.remove("focus-remove-on-mobile");
if(nav_menu_mobile_opened) nav_ref_cookie_notice.classList.add("focus-remove-on-mobile");
}
nav_ref_footer.classList.remove("focus-remove-on-mobile");
if(nav_menu_mobile_opened) nav_ref_footer.classList.add("focus-remove-on-mobile");
// MAYBE DISPLAY PAGE OVERLAY //
nav_menu_mobile_page_overlay.classList.add("gone");
if(nav_menu_mobile_opened) nav_menu_mobile_page_overlay.classList.remove("gone");
}

56
page/nav.php Normal file
View File

@ -0,0 +1,56 @@
<?php
declare(strict_types = 1);
namespace Kimendisch\Sbgg_Jetzt;
use Flake\Page;
use Flake\File;
Page::js("./page/nav.js");
?>
<nav>
<div class="nav-container">
<div class="width-governor">
<div class="branding">
<div class="button-list">
<a href="/" class="button tertiary">
<img src="<?= File::file("./asset/logo-256.png") ?>" alt="Logo" />
<span><?= $dict->get("nav_branding_name") ?></span>
</a>
</div>
</div>
<div class="menu-container">
<div class="button-list">
<button id="nav-menu-mobile-button" class="menu-mobile-button button secondary">
<span class="icon ti ti-menu-2"></span>
<span class="text">Menu</span>
</button>
</div>
<div id="nav-menu" class="menu button-list">
<a href="#" class="button tertiary <?= (Nav::$active === "button_1" ? "active" : "") ?>">
<span class="icon ti ti-circle-off"></span>
<span class="text"><?= $dict->get("nav_button_1") ?></span>
</a>
<a href="#" class="button tertiary <?= (Nav::$active === "button_2" ? "active" : "") ?>">
<span class="icon ti ti-circle-off"></span>
<span class="text"><?= $dict->get("nav_button_2") ?></span>
</a>
<a href="#" class="button tertiary <?= (Nav::$active === "button_3" ? "active" : "") ?>">
<span class="icon ti ti-circle-off"></span>
<span class="text"><?= $dict->get("nav_button_3") ?></span>
</a>
</div>
</div>
</div>
</div>
<div id="nav-menu-mobile" class="menu-mobile button-list gone"></div>
<div id="nav-menu-mobile-page-overlay" class="menu-mobile-page-overlay gone"></div>
</nav>

View File

@ -50,8 +50,12 @@
<div class="page-container">
<div class="page">
<?php require("./page/nav.php"); ?>
<div class="page-container has-nav">
<div id="page" class="page">
<div class="title">
<h1><?= $dict->get("page_title_h1") ?></h1>
<h2><?= $dict->get("legal_privacy_title") ?></h2>
@ -68,7 +72,7 @@
<div class="footer">
<div id="footer" class="footer">
<div class="brand">
<img src="<?= File::file("./asset/logo-256.png") ?>" alt="logo" />
<span>SBGG.jetzt</span>

View File

@ -85,8 +85,15 @@
<div class="page-container">
<div class="page">
<?php
Nav::$active = "button_1";
require("./page/nav.php");
?>
<div class="page-container has-nav">
<div id="page" class="page">
<div class="title">
<h1><?= $dict->get("page_title_h1") ?></h1>
<h2><?= $dict->get("page_title_h2") ?></h2>
@ -636,7 +643,7 @@
<div class="footer">
<div id="footer" class="footer">
<div class="brand">
<img src="<?= File::file("./asset/logo-256.png") ?>" alt="logo" />
<span>SBGG.jetzt</span>

View File

@ -138,6 +138,120 @@ span.align-left {
.rounded {
border-radius: 50%;
}
@media only screen and (max-width: 600px) {
.focus-remove-on-mobile { filter: blur(4px) }
}
/* NAV */
nav {
position: fixed;
top: 0;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
flex-wrap: nowrap;
z-index: 1024;
box-shadow: #0004 0px 2px 4px;
background-color: var(--color-bg-light);
}
nav .nav-container {
height: 4.3rem; /* NOTE: This is tied to `.page-container` and `nav .menu-mobile` */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
background-color: inherit;
z-index: 1025;
}
nav .width-governor {
width: 50vw; /* NOTE: This is tied to `.page` */
padding: 0 4rem; /* NOTE: This is tied to `.page` and many more */
display: flex;
flex-direction: row;
align-items: stretch;
justify-content: space-between;
flex-wrap: nowrap;
gap: 1rem;
}
@media only screen and (max-width: 1600px) {
nav .width-governor {
width: 70vw; /* NOTE: This is tied to `.page` */
}
}
@media only screen and (max-width: 1300px) {
nav .width-governor {
width: 80vw; /* NOTE: This is tied to `.page` */
}
}
@media only screen and (max-width: 1000px) {
nav .width-governor {
width: 100vw; /* NOTE: This is tied to `.page` */
padding: 0 3rem; /* NOTE: This is tied to `.page` and many more */
}
}
nav .width-governor > * {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
text-align: center;
}
nav .button-list { height: 100%; }
nav .branding { justify-content: flex-start !important; }
nav .branding img { height: 2rem; }
nav .branding span { font-weight: bold; }
nav .menu-container { justify-content: flex-end !important; }
nav .menu { gap: 2rem; }
nav .menu-mobile {
display: none;
flex-direction: column;
justify-content: flex-start;
align-items: center;
flex-wrap: wrap;
max-height: calc(100vh - 4.3rem); /* NOTE: This is tied to `.nav-container` and `.page-container` */
max-height: calc(100dvh - 4.3rem); /* NOTE: This is tied to `.nav-container` and `.page-container` */
padding: 2rem;
overflow-y: auto;
}
nav .menu-mobile-button { display: none; }
nav .menu-mobile-page-overlay {
position: absolute;
top: 100%;
width: 100vw;
height: 100vh;
display: none;
background-color: #0004;
}
@media only screen and (max-width: 600px) {
nav .menu { display: none; }
nav .menu-mobile { display: flex; }
nav .menu-mobile-button { display: inline-flex; }
nav .menu-mobile-page-overlay { display: block; }
}
@ -152,11 +266,14 @@ span.align-left {
align-items: center;
justify-content: flex-start;
}
.page-container.has-nav {
padding-top: 4.3rem; /* NOTE: This is tied to `.nav-container` and `nav .menu-mobile` */
}
.page-container.full-page {
width: 100%;
}
.page {
max-width: 50vw;
max-width: 50vw; /* NOTE: This is tied to `nav .width-governor` */
padding: 6rem 2rem;
@ -171,17 +288,17 @@ span.align-left {
}
@media only screen and (max-width: 1600px) {
.page {
max-width: 70vw;
max-width: 70vw; /* NOTE: This is tied to `nav .width-governor` */
}
}
@media only screen and (max-width: 1300px) {
.page {
max-width: 80vw;
max-width: 80vw; /* NOTE: This is tied to `nav .width-governor` */
}
}
@media only screen and (max-width: 1000px) {
.page {
max-width: 100vw;
max-width: 100vw; /* NOTE: This is tied to `nav .width-governor` */
padding: 6rem 1rem;
}
}
@ -486,6 +603,7 @@ a.box:hover {
align-items: center;
display: inline-flex;
flex-direction: row;
gap: 0.5rem;
width: fit-content;
padding: 1rem 1.5rem;
@ -523,6 +641,18 @@ a.box:hover {
background-color: var(--theme-dark);
}
.button.tertiary, .button.tertiary.disabled:hover {
padding: 0.5rem 1rem;
margin: 0 -1rem; /* NOTE: Fix to increase hitbox without messing up the button-list gap */
color: var(--color-white);
background: none;
}
.button.tertiary:hover, .button.tertiary.active {
color: var(--theme);
background: none;
}
.button .icon.big {
font-size: 2rem;
}
@ -841,6 +971,11 @@ input::placeholder {
padding: 1rem;
background-color: var(--color-bg-light);
/* NOTE: This fixes the partial edges when blur is active */
-webkit-box-shadow: 0 2rem 0 2rem var(--color-bg-light);
-moz-box-shadow: 0 2rem 0 2rem var(--color-bg-light);
box-shadow: 0 2rem 0 2rem var(--color-bg-light);
}
.footer > div {
flex-grow: 1;

View File

@ -17,6 +17,28 @@
"nav_branding_name" => [
"de" => "SBGG.jetzt",
"en" => "SBGG.jetzt"
],
"nav_button_1" => [
"de" => "Knopf 1",
"en" => "Button 1"
],
"nav_button_2" => [
"de" => "Knopf 2",
"en" => "Button 2"
],
"nav_button_3" => [
"de" => "Knopf 3",
"en" => "Button 3"
],
"page_title_h1" => [
"de" => "SBGG.jetzt",
"en" => "SBGG.jetzt"