Use top menu structure

This commit is contained in:
Tobias Kunze 2025-04-07 22:46:13 +02:00
parent 5aae477a17
commit 8b49d05e1d
4 changed files with 221 additions and 195 deletions

View file

@ -1,4 +1,4 @@
{% load static %}
{% load i18n static %}
<!DOCTYPE html>
<html lang="en">
<head>
@ -20,49 +20,48 @@
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
<script src="{% static 'mazer/static/js/initTheme.js' %}"></script>
<div id="app">
{% include 'includes/sidebar.html' %}
<div id="main">
<header class="mb-3">
<a href="#" class="burger-btn d-block d-xl-none">
<i class="bi bi-justify fs-3"></i>
</a>
</header>
<div class="page-heading">
<h3>
{% block page_title %}
Dashboard
{% endblock page_title %}
</h3>
</div>
<div class="page-content">
{% for message in messages %}
{% include "includes/message.html" %}
{% endfor %}
{% block content %}
<section class="section">
<div class="card">
{% block card_header %}{% endblock %}
<div class="card-content">
<div class="card-body">
{% block card_content %}
{% endblock card_content %}
<div id="main" class="layout-horizontal">
{% include 'includes/header.html' %}
<div class="content-wrapper container">
<div class="page-heading">
<h3>
{% block page_title %}
Dashboard
{% endblock page_title %}
</h3>
</div>
<div class="page-content">
{% for message in messages %}
{% include "includes/message.html" %}
{% endfor %}
{% block content %}
<section class="section">
<div class="card">
{% block card_header %}{% endblock %}
<div class="card-content">
<div class="card-body">
{% block card_content %}
{% endblock card_content %}
</div>
</div>
</div>
</div>
</section>
{% endblock content %}
</section>
{% endblock content %}
</div>
</div>
<footer>
<div class="footer clearfix mb-0 text-muted">
<div class="float-start">
<p>
&copy; 2025 <a href="https://www.vshn.ch/en/">VSHN AG</a>, Neugasse 10, CH-8005 Zürich, Switzerland
</p>
</div>
<div class="float-end">
<p>
Crafted with <span class="text-danger"><i class="bi bi-heart-fill icon-mid"></i></span> in Zurich
</p>
<div class="container">
<div class="footer clearfix mb-0 text-muted">
<div class="float-start">
<p>
&copy; 2025 <a href="https://www.vshn.ch/en/">VSHN AG</a>, Neugasse 10, CH-8005 Zürich, Switzerland
</p>
</div>
<div class="float-end">
<p>
Crafted with <span class="text-danger"><i class="bi bi-heart-fill icon-mid"></i></span> in Zurich
</p>
</div>
</div>
</div>
</footer>

View file

@ -0,0 +1,143 @@
{% load i18n static %}
<header class="mb-5">
<div class="header-top">
<div class="container">
<div class="header-top-left">
<div class="logo me-3">
<a href="{% if request.organization %}{{ request.organization.urls.base }}{% else %}/{% endif %}">
<img id="logo-light"
src="{% static 'img/Servala-1.png' %}"
alt="{% translate 'Logo' %}">
<img id="logo-dark"
src="{% static 'img/Servala-2.png' %}"
alt="{% translate 'Logo' %}">
</a>
</div>
{% if request.user.is_authenticated %}
{# request.user.is_authenticated #}
{% if user_organizations.count %}
<button class="btn btn-outline-primary dropdown-toggle btn-sm"
type="button"
id="organizationDropdown"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
{% if request.organization %}
{{ request.organization.name }}
{% else %}
{% translate "Organizations" %}
{% endif %}
</button>
<div class="dropdown-menu shadow"
aria-labelledby="organizationDropdown"
id="organization-dropdown">
{% for organization in user_organizations %}
<a class="dropdown-item{% if organization == request.organization %} active{% endif %}"
href="{{ organization.urls.base }}">
<i class="bi bi-building-fill me-1"></i>
{{ organization.name }}
</a>
{% endfor %}
<a href="{% url 'frontend:organization.create' %}" class="dropdown-item">
<i class="bi bi-building-add me-1"></i>
<span>{% translate "Create organization" %}</span>
</a>
</div>
{% else %}
<a href="{% url 'frontend:organization.create' %}"
class="btn btn-outline-primary btn-sm">
<i class="bi bi-plus-square"></i>
<span>{% translate "Create organization" %}</span>
</a>
{% endif %}
{% endif %}
</div>
<div class="header-top-right">
<div class="theme-toggle d-flex gap-2 align-items-center me-3">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--system-uicons"
width="20"
height="20"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 21 21">
<g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path d="M10.5 14.5c2.219 0 4-1.763 4-3.982a4.003 4.003 0 0 0-4-4.018c-2.219 0-4 1.781-4 4c0 2.219 1.781 4 4 4zM4.136 4.136L5.55 5.55m9.9 9.9l1.414 1.414M1.5 10.5h2m14 0h2M4.135 16.863L5.55 15.45m9.899-9.9l1.414-1.415M10.5 19.5v-2m0-14v-2" opacity=".3">
</path>
<g transform="translate(-210 -1)">
<path d="M220.5 2.5v2m6.5.5l-1.5 1.5"></path>
<circle cx="220.5" cy="11.5" r="4"></circle>
<path d="m214 5l1.5 1.5m5 14v-2m6.5-.5l-1.5-1.5M214 18l1.5-1.5m-4-5h2m14 0h2"></path>
</g>
</g>
</svg>
<div class="form-check form-switch fs-6">
<input class="form-check-input me-0"
type="checkbox"
id="toggle-dark"
style="cursor: pointer">
<label class="form-check-label"></label>
</div>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--mdi"
width="20"
height="20"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24">
<path fill="currentColor" d="m17.75 4.09l-2.53 1.94l.91 3.06l-2.63-1.81l-2.63 1.81l.91-3.06l-2.53-1.94L12.44 4l1.06-3l1.06 3l3.19.09m3.5 6.91l-1.64 1.25l.59 1.98l-1.7-1.17l-1.7 1.17l.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95l2.06.05m-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85c-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14c.4-.4.82-.76 1.27-1.08c.75-.53 1.93.36 1.85 1.19c-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82c-2.81 3.14-2.7 7.96.31 10.98c3.02 3.01 7.84 3.12 10.98.31Z">
</path>
</svg>
</div>
{% if request.user and request.user.is_authenticated %}
<div class="dropdown">
<a href="#"
id="topbarUserDropdown"
class="user-dropdown d-flex align-items-center dropend dropdown-toggle"
data-bs-toggle="dropdown"
aria-expanded="false">
{# <div class="avatar avatar-md2"> #}
{# <img src="" alt="Avatar"> #}
{# </div>#}
<div class="text">
<h6 class="user-dropdown-name">{{ request.user }}</h6>
{% if request.organization %}<p class="user-dropdown-status text-sm text-muted">{{ request.user_role }}</p>{% endif %}
</div>
</a>
<ul class="dropdown-menu dropdown-menu-end shadow-lg"
aria-labelledby="topbarUserDropdown"
style="">
<li>
<a class="dropdown-item" href="{% url 'frontend:profile' %}">{% translate "My Account" %}</a>
</li>
<li>
<hr class="dropdown-divider">
</li>
<li>
<form action="{% url 'frontend:logout' %}"
method="post"
class="dropdown-item">
{% csrf_token %}
<button type="submit" class='sidebar-link btn'>{% translate 'Logout' %}</button>
</form>
</li>
</ul>
</div>
{% else %}
<a href="{% url 'account_login' %}" class="sidebar-link">
<i class="bi bi-person-badge-fill"></i>
<span>{% translate 'Login' %}</span>
</a>
{% endif %}
<a href="#" class="burger-btn d-block d-xl-none">
<i class="bi bi-justify fs-3"></i>
</a>
</div>
</div>
</div>
{% include 'includes/menu.html' %}
</header>

View file

@ -0,0 +1,39 @@
{% load i18n static %}
{% if request.user.is_authenticated and request.organization %}
<nav class="main-navbar">
<div class="container">
<ul>
<li class="menu-item">
<a href="{{ request.organization.urls.base }}" class='menu-link'>
<span>
<i class="bi bi-grid-fill"></i>
{% translate 'Dashboard' %}</span>
</a>
</li>
<li class="menu-item">
<a href="{{ request.organization.urls.details }}" class='menu-link'>
<span>
<i class="bi bi-building-gear"></i>
{% translate 'Organization' %}</span>
</a>
</li>
<li class="menu-item">
<a href="{{ request.organization.urls.services }}" class='menu-link'>
<span>
<i class="bi bi-card-list"></i>
{% translate 'Services' %}</span>
</a>
</li>
<li class="menu-item">
<a href="{{ request.organization.urls.instances }}" class='menu-link'>
<span>
<i class="bi bi-server"></i>
{% translate 'Instances' %}</span>
</span>
</a>
</li>
</ul>
</div>
</nav>
{% endif %}
<script src="{% static 'js/sidebar.js' %}" defer></script>

View file

@ -1,155 +0,0 @@
{% load i18n static %}
<div id="sidebar">
<div id="sidebar">
<div class="sidebar-wrapper active">
<div class="sidebar-header position-relative">
<div class="d-flex justify-content-between align-items-center">
<div class="logo">
<a href="{% if request.organization %}{{ request.organization.urls.base }}{% else %}/{% endif %}">
<img src="" alt="{% translate 'Logo' %}" srcset="">
</a>
</div>
<div class="theme-toggle d-flex gap-2 align-items-center mt-2">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--system-uicons"
width="20"
height="20"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 21 21">
<g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round">
<path d="M10.5 14.5c2.219 0 4-1.763 4-3.982a4.003 4.003 0 0 0-4-4.018c-2.219 0-4 1.781-4 4c0 2.219 1.781 4 4 4zM4.136 4.136L5.55 5.55m9.9 9.9l1.414 1.414M1.5 10.5h2m14 0h2M4.135 16.863L5.55 15.45m9.899-9.9l1.414-1.415M10.5 19.5v-2m0-14v-2" opacity=".3">
</path>
<g transform="translate(-210 -1)">
<path d="M220.5 2.5v2m6.5.5l-1.5 1.5"></path>
<circle cx="220.5" cy="11.5" r="4"></circle>
<path d="m214 5l1.5 1.5m5 14v-2m6.5-.5l-1.5-1.5M214 18l1.5-1.5m-4-5h2m14 0h2"></path>
</g>
</g>
</svg>
<div class="form-check form-switch fs-6">
<input class="form-check-input me-0"
type="checkbox"
id="toggle-dark"
style="cursor: pointer">
<label class="form-check-label"></label>
</div>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
class="iconify iconify--mdi"
width="20"
height="20"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24">
<path fill="currentColor" d="m17.75 4.09l-2.53 1.94l.91 3.06l-2.63-1.81l-2.63 1.81l.91-3.06l-2.53-1.94L12.44 4l1.06-3l1.06 3l3.19.09m3.5 6.91l-1.64 1.25l.59 1.98l-1.7-1.17l-1.7 1.17l.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95l2.06.05m-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85c-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14c.4-.4.82-.76 1.27-1.08c.75-.53 1.93.36 1.85 1.19c-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82c-2.81 3.14-2.7 7.96.31 10.98c3.02 3.01 7.84 3.12 10.98.31Z">
</path>
</svg>
</div>
<div class="sidebar-toggler x">
<a href="#" class="sidebar-hide d-xl-none d-block"><i class="bi bi-x bi-middle"></i></a>
</div>
</div>
{% if request.user.is_authenticated %}
{# request.user.is_authenticated #}
{% if user_organizations.count %}
<button class="btn btn-outline-primary dropdown-toggle w-100"
type="button"
id="organizationDropdown"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
{% if request.organization %}
{{ request.organization.name }}
{% else %}
{% translate "Organizations" %}
{% endif %}
</button>
<div class="dropdown-menu shadow"
aria-labelledby="organizationDropdown"
id="organization-dropdown">
{% for organization in user_organizations %}
<a class="dropdown-item{% if organization == request.organization %} active{% endif %}"
href="{{ organization.urls.base }}">
<i class="bi bi-building-fill me-1"></i>
{{ organization.name }}
</a>
{% endfor %}
<a href="{% url 'frontend:organization.create' %}" class="dropdown-item">
<i class="bi bi-building-add me-1"></i>
<span>{% translate "Create organization" %}</span>
</a>
</div>
{% else %}
<a href="{% url 'frontend:organization.create' %}"
class="btn btn-outline-primary w-100">
<i class="bi bi-plus-square"></i>
<span>{% translate "Create organization" %}</span>
</a>
{% endif %}
{% endif %}
</div>
<div class="sidebar-menu">
<ul class="menu">
{% if not request.user.is_authenticated %}
<li class="sidebar-item">
<a href="{% url 'account_login' %}" class="sidebar-link">
<i class="bi bi-person-badge-fill"></i>
<span>{% translate 'Login' %}</span>
</a>
</li>
{% else %}
{% if request.organization %}
<li class="sidebar-item">
<a href="{{ request.organization.urls.base }}" class='sidebar-link'>
<i class="bi bi-grid-fill"></i>
<span>{% translate 'Dashboard' %}</span>
</a>
</li>
<li class="sidebar-title">{% translate 'Organization' %}</li>
<li class="sidebar-item">
<a href="{{ request.organization.urls.details }}" class='sidebar-link'>
<i class="bi bi-building-gear"></i>
<span>{% translate 'Details' %}</span>
</a>
</li>
<li class="sidebar-title">{% translate 'Services' %}</li>
<li class="sidebar-item">
<a href="{{ request.organization.urls.services }}" class='sidebar-link'>
<i class="bi bi-card-list"></i>
<span>{% translate 'Available Services' %}</span>
</a>
</li>
<li class="sidebar-item">
<a href="{{ request.organization.urls.instances }}" class='sidebar-link'>
<i class="bi bi-server"></i>
<span>{% translate 'Instances' %}</span>
</a>
</li>
{% endif %}
<li class="sidebar-title">{% translate 'Account' %}</li>
<li class="sidebar-item">
<a href="{% url 'frontend:profile' %}" class='sidebar-link'>
<i class="bi bi-file-person"></i>
<span>{% translate 'Profile' %}</span>
</a>
</li>
<li class="sidebar-item">
<form action="{% url 'frontend:logout' %}" method="post">
{% csrf_token %}
<button type="submit" class='sidebar-link btn'>
<i class="bi bi-box-arrow-right"></i>
<span>{% translate 'Log out' %}</span>
</button>
</form>
</li>
{% endif %}
{# request.user.is_authenticated #}
</ul>
</div>
</div>
</div>
<script src="{% static 'js/sidebar.js' %}" defer></script>