457 lines
15 KiB
HTML
Executable File
457 lines
15 KiB
HTML
Executable File
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{% block title %}Admin{% endblock %} - {{ branding.company_name }} Admin</title>
|
|
{% if branding.favicon_url %}
|
|
<link rel="icon" href="{{ branding.favicon_url }}" type="image/x-icon">
|
|
{% endif %}
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
|
|
<style>
|
|
:root {
|
|
--admin-primary: #dc3545;
|
|
--admin-primary-hover: #bb2d3b;
|
|
--sidebar-bg: {{ branding.colors.sidebar_bg }};
|
|
--sidebar-border: {{ branding.colors.border }};
|
|
--text-light: {{ branding.colors.text }};
|
|
--text-muted: {{ branding.colors.muted }};
|
|
--portal-bg: {{ branding.colors.background }};
|
|
}
|
|
|
|
body {
|
|
background: var(--portal-bg);
|
|
color: var(--text-light);
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.admin-sidebar {
|
|
position: fixed;
|
|
left: 0;
|
|
top: 0;
|
|
width: 240px;
|
|
height: 100vh;
|
|
background: var(--sidebar-bg);
|
|
border-right: 1px solid var(--sidebar-border);
|
|
display: flex;
|
|
flex-direction: column;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.admin-sidebar-header {
|
|
padding: 1.25rem;
|
|
border-bottom: 1px solid var(--sidebar-border);
|
|
}
|
|
|
|
.admin-logo {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
color: var(--text-light);
|
|
text-decoration: none;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.admin-logo i {
|
|
color: var(--admin-primary);
|
|
font-size: 1.5rem;
|
|
}
|
|
|
|
.admin-nav-wrapper {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
.admin-nav-wrapper::-webkit-scrollbar {
|
|
width: 6px;
|
|
}
|
|
|
|
.admin-nav-wrapper::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
.admin-nav-wrapper::-webkit-scrollbar-thumb {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.admin-nav-wrapper::-webkit-scrollbar-thumb:hover {
|
|
background: rgba(255, 255, 255, 0.2);
|
|
}
|
|
|
|
.admin-nav {
|
|
list-style: none;
|
|
padding: 1rem 0.75rem;
|
|
margin: 0;
|
|
}
|
|
|
|
.admin-nav .nav-item {
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.admin-nav .nav-link {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.75rem;
|
|
padding: 0.75rem 1rem;
|
|
color: var(--text-muted);
|
|
text-decoration: none;
|
|
border-radius: 0.5rem;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.admin-nav .nav-link:hover {
|
|
color: var(--text-light);
|
|
background: rgba(255, 255, 255, 0.05);
|
|
}
|
|
|
|
.admin-nav .nav-link.active {
|
|
color: var(--text-light);
|
|
background: var(--admin-primary);
|
|
}
|
|
|
|
.admin-sidebar-footer {
|
|
padding: 1rem;
|
|
border-top: 1px solid var(--sidebar-border);
|
|
}
|
|
|
|
.admin-main {
|
|
margin-left: 240px;
|
|
min-height: 100vh;
|
|
padding: 2rem;
|
|
}
|
|
|
|
.card {
|
|
background: var(--sidebar-bg);
|
|
border-color: var(--sidebar-border);
|
|
}
|
|
|
|
.table {
|
|
--bs-table-bg: transparent;
|
|
--bs-table-color: var(--text-light);
|
|
--bs-table-border-color: var(--sidebar-border);
|
|
}
|
|
|
|
.form-control, .form-select {
|
|
background: #0d0f12;
|
|
border-color: var(--sidebar-border);
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.form-control:focus, .form-select:focus {
|
|
background: #0d0f12;
|
|
border-color: var(--admin-primary);
|
|
color: var(--text-light);
|
|
box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
|
|
}
|
|
|
|
.form-label {
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.form-text {
|
|
color: var(--text-muted) !important;
|
|
}
|
|
|
|
.form-check-label {
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.card-header {
|
|
color: var(--text-light);
|
|
background: rgba(255, 255, 255, 0.03);
|
|
border-color: var(--sidebar-border);
|
|
}
|
|
|
|
.card-body {
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.breadcrumb-item {
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.breadcrumb-item.active {
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.breadcrumb-item + .breadcrumb-item::before {
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
h1, h2, h3, h4, h5, h6 {
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.modal-content {
|
|
background: var(--sidebar-bg);
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.modal-header, .modal-footer {
|
|
border-color: var(--sidebar-border);
|
|
}
|
|
|
|
.btn-close {
|
|
filter: invert(1);
|
|
}
|
|
|
|
/* Text colors - ensure visibility on dark background */
|
|
.text-muted {
|
|
color: var(--text-muted) !important;
|
|
}
|
|
|
|
p, li, td, th, span, strong, label {
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.card .small, .card small {
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.card ul {
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.alert {
|
|
color: var(--text-light);
|
|
}
|
|
|
|
.alert-info {
|
|
background: rgba(13, 202, 240, 0.15);
|
|
border-color: rgba(13, 202, 240, 0.3);
|
|
}
|
|
|
|
.alert-warning {
|
|
background: rgba(255, 193, 7, 0.15);
|
|
border-color: rgba(255, 193, 7, 0.3);
|
|
}
|
|
|
|
.alert-danger {
|
|
background: rgba(220, 53, 69, 0.15);
|
|
border-color: rgba(220, 53, 69, 0.3);
|
|
}
|
|
|
|
.alert-success {
|
|
background: rgba(25, 135, 84, 0.15);
|
|
border-color: rgba(25, 135, 84, 0.3);
|
|
}
|
|
|
|
code {
|
|
color: #17a2b8;
|
|
}
|
|
|
|
.form-text {
|
|
color: var(--text-muted) !important;
|
|
}
|
|
|
|
.table-dark {
|
|
--bs-table-color: var(--text-light);
|
|
--bs-table-bg: transparent;
|
|
}
|
|
|
|
.table-dark th {
|
|
color: var(--text-light) !important;
|
|
}
|
|
|
|
.table-dark td {
|
|
color: var(--text-light) !important;
|
|
}
|
|
|
|
.btn-danger {
|
|
background: var(--admin-primary);
|
|
border-color: var(--admin-primary);
|
|
}
|
|
|
|
.btn-danger:hover {
|
|
background: var(--admin-primary-hover);
|
|
border-color: var(--admin-primary-hover);
|
|
}
|
|
|
|
@media (max-width: 991px) {
|
|
.admin-sidebar {
|
|
transform: translateX(-100%);
|
|
transition: transform 0.3s;
|
|
}
|
|
.admin-sidebar.show {
|
|
transform: translateX(0);
|
|
}
|
|
.admin-main {
|
|
margin-left: 0;
|
|
}
|
|
}
|
|
</style>
|
|
{% block extra_css %}{% endblock %}
|
|
</head>
|
|
<body>
|
|
<nav class="admin-sidebar">
|
|
<div class="admin-sidebar-header">
|
|
<a href="{{ url_for('admin.index') }}" class="admin-logo">
|
|
{% if branding.logo_url %}
|
|
<img src="{{ branding.logo_url }}" alt="{{ branding.company_name }}" style="max-height: 30px;">
|
|
{% else %}
|
|
<i class="bi bi-shield-lock"></i>
|
|
{% endif %}
|
|
<span>Admin</span>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="admin-nav-wrapper">
|
|
<ul class="admin-nav">
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.index' %}active{% endif %}"
|
|
href="{{ url_for('admin.index') }}">
|
|
<i class="bi bi-speedometer2"></i>
|
|
<span>Dashboard</span>
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Benutzer -->
|
|
<li class="nav-item mt-3">
|
|
<span class="nav-label text-muted small px-3">BENUTZER</span>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.customers' %}active{% endif %}"
|
|
href="{{ url_for('admin.customers') }}">
|
|
<i class="bi bi-people"></i>
|
|
<span>Kunden</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if 'admins' in request.endpoint %}active{% endif %}"
|
|
href="{{ url_for('admin.admins') }}">
|
|
<i class="bi bi-shield-check"></i>
|
|
<span>Administratoren</span>
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Buchungen -->
|
|
<li class="nav-item mt-3">
|
|
<span class="nav-label text-muted small px-3">BUCHUNGEN</span>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.bookings' %}active{% endif %}"
|
|
href="{{ url_for('admin.bookings') }}">
|
|
<i class="bi bi-calendar-check"></i>
|
|
<span>Buchungen</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.bookings_sync' %}active{% endif %}"
|
|
href="{{ url_for('admin.bookings_sync') }}">
|
|
<i class="bi bi-arrow-repeat"></i>
|
|
<span>Sync</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.bookings_import' %}active{% endif %}"
|
|
href="{{ url_for('admin.bookings_import') }}">
|
|
<i class="bi bi-upload"></i>
|
|
<span>Import</span>
|
|
</a>
|
|
</li>
|
|
|
|
<!-- Einstellungen -->
|
|
<li class="nav-item mt-3">
|
|
<span class="nav-label text-muted small px-3">EINSTELLUNGEN</span>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.field_config' %}active{% endif %}"
|
|
href="{{ url_for('admin.field_config') }}">
|
|
<i class="bi bi-sliders"></i>
|
|
<span>Profil-Felder</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.settings_customer_view' %}active{% endif %}"
|
|
href="{{ url_for('admin.settings_customer_view') }}">
|
|
<i class="bi bi-layout-text-sidebar"></i>
|
|
<span>Kundenansicht</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.settings_mail' %}active{% endif %}"
|
|
href="{{ url_for('admin.settings_mail') }}">
|
|
<i class="bi bi-envelope"></i>
|
|
<span>Mail-Server</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.settings_otp' %}active{% endif %}"
|
|
href="{{ url_for('admin.settings_otp') }}">
|
|
<i class="bi bi-key"></i>
|
|
<span>OTP & Sicherheit</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.settings_wordpress' %}active{% endif %}"
|
|
href="{{ url_for('admin.settings_wordpress') }}">
|
|
<i class="bi bi-wordpress"></i>
|
|
<span>WordPress</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.settings_csv' %}active{% endif %}"
|
|
href="{{ url_for('admin.settings_csv') }}">
|
|
<i class="bi bi-filetype-csv"></i>
|
|
<span>CSV Export/Import</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.settings_customer_defaults' %}active{% endif %}"
|
|
href="{{ url_for('admin.settings_customer_defaults') }}">
|
|
<i class="bi bi-person-plus"></i>
|
|
<span>Kunden-Standards</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.settings_field_mapping' %}active{% endif %}"
|
|
href="{{ url_for('admin.settings_field_mapping') }}">
|
|
<i class="bi bi-arrow-left-right"></i>
|
|
<span>Feld-Mapping</span>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link {% if request.endpoint == 'admin.settings_branding' %}active{% endif %}"
|
|
href="{{ url_for('admin.settings_branding') }}">
|
|
<i class="bi bi-palette"></i>
|
|
<span>Branding</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="admin-sidebar-footer">
|
|
<div class="d-flex align-items-center gap-2 mb-2 text-muted small">
|
|
<i class="bi bi-person-circle"></i>
|
|
<span>{{ g.admin_user.name }}</span>
|
|
</div>
|
|
<a href="{{ url_for('admin.logout') }}" class="btn btn-outline-danger btn-sm w-100">
|
|
<i class="bi bi-box-arrow-right me-1"></i>
|
|
Abmelden
|
|
</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<main class="admin-main">
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
{% if messages %}
|
|
{% for category, message in messages %}
|
|
<div class="alert alert-{{ 'danger' if category == 'error' else category }} alert-dismissible fade show">
|
|
{{ message }}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endwith %}
|
|
|
|
{% block content %}{% endblock %}
|
|
</main>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
{% block extra_js %}{% endblock %}
|
|
</body>
|
|
</html>
|