Merge pull request 'First branding integration' (#40) from 20-styling-branding into main
Reviewed-on: #40
This commit is contained in:
commit
d53804b8d0
11 changed files with 315 additions and 218 deletions
|
@ -16,10 +16,10 @@
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ redirect_field }}
|
{{ redirect_field }}
|
||||||
<button href="{{ href }}"
|
<button href="{{ href }}"
|
||||||
class="btn btn-warning btn-lg icon icon-left"
|
class="btn btn-warning btn-lg icon icon-left btn-keycloak"
|
||||||
title="{{ provider.name }}">
|
title="{{ provider.name }}">
|
||||||
<img src="{% static 'img/keycloak.svg' %}" style="height: 30px">
|
<img src="{% static 'img/keycloak.svg' %}" style="height: 30px">
|
||||||
<span class="mx-1">{% translate "Sign in with your" %} {{ provider.name }}</span>
|
<span class="ms-2">{% translate "Sign In" %}</span>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% load static %}
|
{% load i18n static %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
@ -20,49 +20,48 @@
|
||||||
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
|
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
|
||||||
<script src="{% static 'mazer/static/js/initTheme.js' %}"></script>
|
<script src="{% static 'mazer/static/js/initTheme.js' %}"></script>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
{% include 'includes/sidebar.html' %}
|
<div id="main" class="layout-horizontal">
|
||||||
<div id="main">
|
{% include 'includes/header.html' %}
|
||||||
<header class="mb-3">
|
<div class="content-wrapper container">
|
||||||
<a href="#" class="burger-btn d-block d-xl-none">
|
<div class="page-heading">
|
||||||
<i class="bi bi-justify fs-3"></i>
|
<h3>
|
||||||
</a>
|
{% block page_title %}
|
||||||
</header>
|
Dashboard
|
||||||
<div class="page-heading">
|
{% endblock page_title %}
|
||||||
<h3>
|
</h3>
|
||||||
{% block page_title %}
|
</div>
|
||||||
Dashboard
|
<div class="page-content">
|
||||||
{% endblock page_title %}
|
{% for message in messages %}
|
||||||
</h3>
|
{% include "includes/message.html" %}
|
||||||
</div>
|
{% endfor %}
|
||||||
<div class="page-content">
|
{% block content %}
|
||||||
{% for message in messages %}
|
<section class="section">
|
||||||
{% include "includes/message.html" %}
|
<div class="card">
|
||||||
{% endfor %}
|
{% block card_header %}{% endblock %}
|
||||||
{% block content %}
|
<div class="card-content">
|
||||||
<section class="section">
|
<div class="card-body">
|
||||||
<div class="card">
|
{% block card_content %}
|
||||||
{% block card_header %}{% endblock %}
|
{% endblock card_content %}
|
||||||
<div class="card-content">
|
</div>
|
||||||
<div class="card-body">
|
|
||||||
{% block card_content %}
|
|
||||||
{% endblock card_content %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
{% endblock content %}
|
||||||
{% endblock content %}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<div class="footer clearfix mb-0 text-muted">
|
<div class="container">
|
||||||
<div class="float-start">
|
<div class="footer clearfix mb-0 text-muted">
|
||||||
<p>
|
<div class="float-start">
|
||||||
© 2025 <a href="https://www.vshn.ch/en/">VSHN AG</a>, Neugasse 10, CH-8005 Zürich, Switzerland
|
<p>
|
||||||
</p>
|
© 2025 <a href="https://www.vshn.ch/en/">VSHN AG</a>, Neugasse 10, CH-8005 Zürich, Switzerland
|
||||||
</div>
|
</p>
|
||||||
<div class="float-end">
|
</div>
|
||||||
<p>
|
<div class="float-end">
|
||||||
Crafted with <span class="text-danger"><i class="bi bi-heart-fill icon-mid"></i></span> in Zurich
|
<p>
|
||||||
</p>
|
Crafted with <span class="text-danger"><i class="bi bi-heart-fill icon-mid"></i></span> in Zurich
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -115,15 +115,16 @@
|
||||||
You are logged in with your VSHN user account. Change your password and other account data here:
|
You are logged in with your VSHN user account. Change your password and other account data here:
|
||||||
{% endblocktranslate %}
|
{% endblocktranslate %}
|
||||||
</p>
|
</p>
|
||||||
<a href="{{ account_href }}"
|
<div>
|
||||||
class="btn btn-warning btn-lg icon icon-left">
|
<a href="{{ account_href }}"
|
||||||
<img src="{% static 'img/keycloak.svg' %}" style="height: 30px">
|
class="btn btn-warning btn-lg icon icon-left btn-keycloak">
|
||||||
<span class="mx-1">{% translate "VSHN Account" %}</span>
|
<img src="{% static 'img/keycloak.svg' %}" style="height: 30px">
|
||||||
</a>
|
<span class="mx-1">{% translate "Account" %}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
{% endblock content %}
|
||||||
{% endblock content %}
|
|
||||||
|
|
143
src/servala/frontend/templates/includes/header.html
Normal file
143
src/servala/frontend/templates/includes/header.html
Normal 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>
|
39
src/servala/frontend/templates/includes/menu.html
Normal file
39
src/servala/frontend/templates/includes/menu.html
Normal 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>
|
|
@ -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>
|
|
|
@ -1,3 +1,55 @@
|
||||||
|
:root, html[data-bs-theme="dark"]:root {
|
||||||
|
--bs-primary: #9A63EC;
|
||||||
|
--bs-link-color: var(--bs-primary);
|
||||||
|
--bs-link-color-rgb: 154, 99, 236;
|
||||||
|
--bs-link-hover-color-rgb: 154, 99, 236;
|
||||||
|
--brand-black: #333333;
|
||||||
|
--brand-mid: #C4ACE0;
|
||||||
|
--brand-light: #FCEAFF;
|
||||||
|
--brand-success: #64BAAA;
|
||||||
|
}
|
||||||
|
.dropdown-menu, html[data-bs-theme="dark"] .dropdown-menu {
|
||||||
|
--bs-dropdown-link-active-bg: var(--bs-primary);
|
||||||
|
}
|
||||||
|
.layout-horizontal .main-navbar {
|
||||||
|
background-color: var(--bs-primary);
|
||||||
|
}
|
||||||
|
html[data-bs-theme="dark"] .btn-primary, .btn-primary {
|
||||||
|
--bs-btn-bg: var(--bs-primary);
|
||||||
|
--bs-btn-border-color: var(--bs-primary);
|
||||||
|
--bs-btn-hover-bg: var(--bs-primary);
|
||||||
|
--bs-btn-hover-border-color: var(--bs-primary);
|
||||||
|
--bs-btn-active-bg: var(--bs-primary);
|
||||||
|
--bs-btn-active-border-color: var(--bs-primary);
|
||||||
|
--bs-btn-disabled-bg: var(--bs-primary);
|
||||||
|
--bs-btn-disabled-border-color: var(--bs-primary);
|
||||||
|
}
|
||||||
|
.btn.btn-light-primary {
|
||||||
|
background-color: var(--brand-light);
|
||||||
|
color: var(--bs-primary);
|
||||||
|
}
|
||||||
|
html[data-bs-theme="dark"] .btn.btn-light-primary {
|
||||||
|
background-color: var(--brand-light);
|
||||||
|
}
|
||||||
|
html[data-bs-theme="dark"] .btn-outline-primary, .btn-outline-primary {
|
||||||
|
--bs-btn-color: var(--bs-primary);
|
||||||
|
--bs-btn-border-color: var(--bs-primary);
|
||||||
|
--bs-btn-hover-bg: var(--bs-primary);
|
||||||
|
--bs-hover-border-color: var(--bs-primary);
|
||||||
|
--bs-btn-active-bg: var(--bs-primary);
|
||||||
|
--bs-btn-active-border-color: var(--bs-primary);
|
||||||
|
--bs-btn-disabled-color: var(--bs-primary);
|
||||||
|
--bs-btn-disabled-color: var(--bs-primary);
|
||||||
|
--bs-btn-disabled-border-color: var(--bs-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-top-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
#main .header-top .logo img {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
.form-group.d-inline {
|
.form-group.d-inline {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
@ -9,3 +61,27 @@
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-bs-theme="light"] {
|
||||||
|
header #logo-dark {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
header #logo-light {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[data-bs-theme="dark"] {
|
||||||
|
header #logo-light {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
header #logo-dark {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.btn-keycloak {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
a.btn-keycloak {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
BIN
src/servala/static/img/Servala-1.png
Normal file
BIN
src/servala/static/img/Servala-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
src/servala/static/img/Servala-2.png
Normal file
BIN
src/servala/static/img/Servala-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
|
@ -1,6 +1 @@
|
||||||
<svg width="107" height="60" fill="none" xmlns="http://www.w3.org/2000/svg" class="image" aria-hidden="true">
|
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1271.63 301.28"><defs><style>.cls-1{fill:#444;}.cls-2{fill:#4081cb;}</style></defs><polyline class="cls-1" points="164.16 264.17 0 169.29 0 128.63 163.16 33.24 162.55 75.49 34.64 149.71 164.34 222.5 164.16 264.17"/><path class="cls-2" d="M469.84,75.53v38.41s-40.79-30-90.18-30C326.23,83.89,266.52,123,266.52,123V80.84c41.3-22.09,77.94-33.31,113.59-33.31,43.55,0,89.73,28,89.73,28" transform="translate(-103.97 -47.53)"/><path class="cls-2" d="M381,295.1A99.55,99.55,0,1,0,381,96c-55.12,0-99.81,44.57-99.81,99.54A99.68,99.68,0,0,0,381,295.1" transform="translate(-103.97 -47.53)"/><polyline class="cls-1" points="389.91 36.82 554.07 131.7 554.07 172.36 390.91 267.75 391.51 225.5 519.43 151.28 389.73 78.49 389.91 36.82"/><path class="cls-2" d="M292.1,320.8V282.39s40.8,30.05,90.19,30.05c53.43,0,113.13-39.13,113.13-39.13v42.18c-41.29,22.09-77.94,33.31-113.58,33.31-43.55,0-89.74-28-89.74-28" transform="translate(-103.97 -47.53)"/><path class="cls-1" d="M727.16,119.64h44.32l39.38,114.07,39.6-114.07h42.3L831.11,277.37H788.36Z" transform="translate(-103.97 -47.53)"/><path class="cls-1" d="M989.39,155q-14.28-4.72-24-4.73-7.65,0-12,2.81a9.17,9.17,0,0,0-4.38,8.22,11.24,11.24,0,0,0,3.82,8.66,29.27,29.27,0,0,0,9.45,5.62q5.63,2.14,16.65,5.52a216.24,216.24,0,0,1,27.11,9.45A47.34,47.34,0,0,1,1024.38,205q7.65,9.78,7.65,25.54t-8.32,26.88q-8.33,11.15-22.84,16.76a88.72,88.72,0,0,1-32.29,5.63,116.87,116.87,0,0,1-39-6.86,107,107,0,0,1-33.63-18.79l16-32.17a99.35,99.35,0,0,0,28.24,17.32q16.3,6.75,28.91,6.75,9.22,0,14.51-3.38a11,11,0,0,0,5.29-9.89,11.66,11.66,0,0,0-3.94-9,28.76,28.76,0,0,0-9.9-5.74q-6-2.15-16.76-5.06a205.9,205.9,0,0,1-26.77-9.12,47.28,47.28,0,0,1-18.12-14q-7.53-9.33-7.53-24.86a43.39,43.39,0,0,1,7.76-25.65q7.75-11,22-17t33.19-6a120.31,120.31,0,0,1,33.75,4.84,111.4,111.4,0,0,1,29.25,12.94l-15.53,32.85A138.22,138.22,0,0,0,989.39,155Z" transform="translate(-103.97 -47.53)"/><path class="cls-1" d="M1053,119.64h41.17V184h63.68V119.64H1199V277.37h-41.17V216.84h-63.68v60.53H1053Z" transform="translate(-103.97 -47.53)"/><path class="cls-1" d="M1337.35,119.64h38.25V277.37h-36l-71.55-94.28v94.28h-38.47V119.64h36.22l71.78,95Z" transform="translate(-103.97 -47.53)"/></svg>
|
||||||
<circle cx="53.002" cy="30" r="19" fill="#4CC3FF"></circle>
|
|
||||||
<path opacity="0.25" d="M67.833 41.874A18.92 18.92 0 0071.999 30c0-10.493-8.506-19-19-19a18.932 18.932 0 00-12.868 5.021c14.446.554 26.182 11.675 27.702 25.853z" fill="#000D1A"></path>
|
|
||||||
<path d="M31.594 6.491v8.571l5.217-3.173a31.165 31.165 0 0132.426 0l.622.378v.006l.14.078v-8.39l-.137-.07a38.382 38.382 0 00-36.807 1.712l-1.461.888zM74.436 53.508v-8.57l-5.218 3.173a31.165 31.165 0 01-32.425 0l-.625-.38v-.005L36 47.64v8.39l.168.079a38.382 38.382 0 0036.807-1.712l1.461-.889z" fill="#4CC3FF"></path>
|
|
||||||
<path d="M31.571 15.063v-8.57L0 25.694v8.614L31.571 53.51v-8.57L7.011 30l24.56-14.938zM74.432 53.511l31.571-19.202v-8.614L74.432 6.492v8.571l24.56 14.939-24.56 14.938v8.571z" fill="#000D1A"></path>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 893 B After Width: | Height: | Size: 2.2 KiB |
|
@ -1,13 +1,12 @@
|
||||||
/**
|
/**
|
||||||
* This script marks the current path as active in the sidebar.
|
* This script marks the current path as active in the menu.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const markActive = (link) => {
|
const markActive = (link) => {
|
||||||
const parentItem = link.closest('.sidebar-item');
|
const parentItem = link.closest('.menu-item');
|
||||||
|
link.classList.add('active');
|
||||||
if (parentItem) {
|
if (parentItem) {
|
||||||
parentItem.classList.add('active');
|
parentItem.classList.add('active');
|
||||||
} else {
|
|
||||||
link.classList.add('active');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,13 +15,13 @@ const checkLink = (fuzzy) => {
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const currentPath = window.location.pathname;
|
const currentPath = window.location.pathname;
|
||||||
const sidebarLinks = [...document.querySelectorAll('a.sidebar-link')]
|
const menuLinks = [...document.querySelectorAll('a.menu-link')]
|
||||||
|
|
||||||
const exactMatches = sidebarLinks.filter(link => link.getAttribute('href') === currentPath)
|
const exactMatches = menuLinks.filter(link => link.getAttribute('href') === currentPath)
|
||||||
if (exactMatches.length > 0) {
|
if (exactMatches.length > 0) {
|
||||||
markActive(exactMatches[0])
|
markActive(exactMatches[0])
|
||||||
} else {
|
} else {
|
||||||
fuzzyMatches = sidebarLinks.filter(link => currentPath.startsWith(link.getAttribute('href')))
|
fuzzyMatches = menuLinks.filter(link => currentPath.startsWith(link.getAttribute('href')))
|
||||||
if (fuzzyMatches.length > 0) {
|
if (fuzzyMatches.length > 0) {
|
||||||
const longestMatch = fuzzyMatches.sort((a, b) => b.href.length - a.href.length)[0]
|
const longestMatch = fuzzyMatches.sort((a, b) => b.href.length - a.href.length)[0]
|
||||||
markActive(longestMatch)
|
markActive(longestMatch)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue