156 lines
7.3 KiB
HTML
156 lines
7.3 KiB
HTML
<!doctype html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#f5f7ff">
|
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#101826">
|
|
<meta name="color-scheme" content="light dark">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
|
<meta name="apple-mobile-web-app-title" content="{{ app_name }}">
|
|
<meta name="description" content="Putzliga macht Haushaltsaufgaben leichter, motivierender und fair verteilt.">
|
|
<title>{% block title %}{{ app_name }}{% endblock %}</title>
|
|
<link rel="manifest" href="{{ url_for('main.manifest') }}">
|
|
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='images/favicon.svg') }}">
|
|
<link rel="apple-touch-icon" href="{{ url_for('static', filename='images/apple-touch-icon.png') }}">
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css', v=asset_version('css/style.css')) }}">
|
|
</head>
|
|
<body data-push-key="{{ config['VAPID_PUBLIC_KEY'] if current_user.is_authenticated else '' }}">
|
|
{% from "partials/macros.html" import nav_icon %}
|
|
<div class="app-shell {% if not current_user.is_authenticated %}app-shell--auth{% endif %}">
|
|
{% if current_user.is_authenticated %}
|
|
<aside class="sidebar">
|
|
<a class="brand" href="{{ url_for('tasks.my_tasks') }}">
|
|
<img src="{{ url_for('static', filename='images/logo.svg') }}" alt="Putzliga Logo" class="brand__logo">
|
|
<div>
|
|
<strong>Putzliga</strong>
|
|
<span>Haushalt mit Punktestand</span>
|
|
</div>
|
|
</a>
|
|
|
|
<nav class="sidebar-nav" aria-label="Hauptnavigation">
|
|
{% for endpoint, label, icon in nav_items %}
|
|
<a href="{{ url_for(endpoint) }}" class="nav-link {% if request.endpoint == endpoint %}is-active{% endif %}">
|
|
{{ nav_icon(icon) }}
|
|
<span>{{ label }}</span>
|
|
</a>
|
|
{% endfor %}
|
|
</nav>
|
|
|
|
<section class="sidebar-card">
|
|
<div class="sidebar-card__row">
|
|
<img class="avatar avatar--lg" src="{% if current_user.avatar_path and current_user.avatar_path.startswith('avatars/') %}{{ url_for('main.uploads', filename=current_user.avatar_path) }}{% else %}{{ url_for('static', filename=current_user.display_avatar) }}{% endif %}" alt="Avatar von {{ current_user.name }}">
|
|
<div>
|
|
<strong>{{ current_user.name }}</strong>
|
|
<p>{{ current_user.email }}</p>
|
|
</div>
|
|
</div>
|
|
<a class="text-link" href="{{ url_for('auth.logout') }}">Abmelden</a>
|
|
</section>
|
|
</aside>
|
|
{% endif %}
|
|
|
|
<div class="page-shell">
|
|
<header class="topbar">
|
|
{% if current_user.is_authenticated %}
|
|
<div>
|
|
<p class="eyebrow">Spielerisch sauber bleiben</p>
|
|
<h1>{% block page_title %}{{ app_name }}{% endblock %}</h1>
|
|
</div>
|
|
<a class="topbar-user" href="{{ url_for('settings.index') }}">
|
|
<span>{{ current_user.name }}</span>
|
|
<img class="avatar" src="{% if current_user.avatar_path and current_user.avatar_path.startswith('avatars/') %}{{ url_for('main.uploads', filename=current_user.avatar_path) }}{% else %}{{ url_for('static', filename=current_user.display_avatar) }}{% endif %}" alt="">
|
|
</a>
|
|
{% else %}
|
|
<a class="brand brand--public" href="{{ url_for('auth.login') }}">
|
|
<img src="{{ url_for('static', filename='images/logo.svg') }}" alt="Putzliga Logo" class="brand__logo">
|
|
<div>
|
|
<strong>Putzliga</strong>
|
|
<span>Haushaltsaufgaben mit Liga-Gefühl</span>
|
|
</div>
|
|
</a>
|
|
{% endif %}
|
|
</header>
|
|
|
|
<main class="content">
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
{% if messages %}
|
|
<div class="flash-stack">
|
|
{% for category, message in messages %}
|
|
<div class="flash flash--{{ category }}">{{ message }}</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
{% endwith %}
|
|
|
|
{% block content %}{% endblock %}
|
|
</main>
|
|
|
|
<footer class="app-footer">
|
|
<a href="https://git.hnz.io/hnzio/putzliga/releases" target="_blank" rel="noreferrer">Version {{ app_version }}</a>
|
|
<span>·</span>
|
|
<a href="https://hnz.io" target="_blank" rel="noreferrer">(c) 2026 @hnz.io</a>
|
|
</footer>
|
|
</div>
|
|
</div>
|
|
|
|
{% if current_user.is_authenticated %}
|
|
<nav class="bottom-nav" aria-label="Mobile Navigation">
|
|
{% for endpoint, label, icon in mobile_nav_items %}
|
|
<a href="{{ url_for(endpoint) }}" class="bottom-nav__item {% if request.endpoint == endpoint %}is-active{% endif %}">
|
|
{{ nav_icon(icon) }}
|
|
<span>{{ label }}</span>
|
|
</a>
|
|
{% endfor %}
|
|
</nav>
|
|
|
|
<button type="button" class="fab-quick-task" id="quickTaskOpen" aria-label="Schnellaufgabe anlegen">
|
|
{{ nav_icon('plus') }}
|
|
</button>
|
|
|
|
<dialog class="complete-dialog" id="completeDialog">
|
|
<form method="dialog" class="complete-dialog__surface">
|
|
<p class="eyebrow">Punkte fair verbuchen</p>
|
|
<h2>Wer hat diese Aufgabe erledigt?</h2>
|
|
<p id="completeDialogText">Bitte wähle aus, wem die Punkte gutgeschrieben werden sollen.</p>
|
|
<div class="choice-grid">
|
|
<button type="button" class="button button--secondary" data-complete-choice="assigned">Zugewiesene Person</button>
|
|
<button type="button" class="button" data-complete-choice="me">Ich</button>
|
|
</div>
|
|
<button type="button" class="button button--ghost" id="completeDialogClose">Abbrechen</button>
|
|
</form>
|
|
</dialog>
|
|
|
|
<dialog class="complete-dialog" id="quickTaskDialog">
|
|
<form method="post" action="{{ url_for('tasks.quick_create') }}" class="complete-dialog__surface complete-dialog__surface--task">
|
|
{{ quick_task_form.hidden_tag() }}
|
|
<p class="eyebrow">Schnellaufgabe</p>
|
|
<h2>Direkt etwas für dich anlegen</h2>
|
|
<p class="muted">Titel und Aufwand reichen. Die Aufgabe wird automatisch dir zugewiesen und auf heute gesetzt.</p>
|
|
<div class="field">
|
|
{{ quick_task_form.title.label }}
|
|
{{ quick_task_form.title(placeholder="Zum Beispiel: Küche kurz aufräumen") }}
|
|
</div>
|
|
<div class="field">
|
|
{{ quick_task_form.effort.label }}
|
|
{{ quick_task_form.effort() }}
|
|
</div>
|
|
<div class="dialog-actions">
|
|
<button type="submit" class="button" name="quick_action" value="save">Aufgabe speichern</button>
|
|
<button type="submit" class="button button--secondary" name="quick_action" value="complete">Aufgabe als erledigt speichern</button>
|
|
<button type="button" class="button button--ghost" id="quickTaskClose">Abbrechen</button>
|
|
</div>
|
|
</form>
|
|
</dialog>
|
|
|
|
<form method="post" class="sr-only" id="completeDialogForm">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
<input type="hidden" name="completed_for" value="me" id="completeDialogChoice">
|
|
</form>
|
|
{% endif %}
|
|
|
|
<script src="{{ url_for('static', filename='js/app.js', v=asset_version('js/app.js')) }}" defer></script>
|
|
</body>
|
|
</html>
|