158 lines
11 KiB
HTML
158 lines
11 KiB
HTML
<!doctype html>
|
|
<html lang="de" data-theme="auto">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">
|
|
<title>{% block title %}Nouri{% endblock %}</title>
|
|
<meta name="theme-color" content="#de9862">
|
|
<meta name="mobile-web-app-capable" content="yes">
|
|
<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="Nouri">
|
|
<meta name="application-name" content="Nouri">
|
|
<meta name="csrf-token" content="{{ csrf_token_value }}">
|
|
<meta name="nouri-push-public-key" content="{{ push_public_key }}">
|
|
<link rel="icon" type="image/svg+xml" href="{{ asset_url('brand/favicon.svg') }}">
|
|
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset_url('brand/pwa-180.png') }}">
|
|
<link rel="manifest" href="{{ url_for('webmanifest') }}">
|
|
<link rel="stylesheet" href="{{ asset_url('css/styles.css') }}">
|
|
<script defer src="{{ asset_url('js/theme.js') }}"></script>
|
|
<script defer src="{{ asset_url('js/planner.js') }}"></script>
|
|
<script defer src="{{ asset_url('js/ui.js') }}"></script>
|
|
<script defer src="{{ asset_url('js/pwa.js') }}"></script>
|
|
</head>
|
|
<body class="{% if g.user %}has-mobile-nav{% endif %}">
|
|
<div class="page-shell">
|
|
<header class="site-header">
|
|
<div class="desktop-header-main">
|
|
<a class="brand" href="{{ url_for('main.dashboard') }}">
|
|
<span class="brand-mark">
|
|
<img src="{{ asset_url('brand/nouri-icon.svg') }}" alt="">
|
|
</span>
|
|
<span class="brand-copy">
|
|
<strong>Nouri</strong>
|
|
<small>einfach essen planen</small>
|
|
</span>
|
|
</a>
|
|
|
|
{% if g.user %}
|
|
<nav class="site-nav desktop-nav">
|
|
<a href="{{ url_for('main.dashboard') }}" class="{{ 'active' if request.endpoint == 'main.dashboard' else '' }}"><span class="nav-link-inner"><span class="ui-icon icon-sparkles"></span><span>Heute</span></span></a>
|
|
<a href="{{ url_for('main.shopping_list') }}" class="{{ 'active' if request.endpoint == 'main.shopping_list' else '' }}"><span class="nav-link-inner"><span class="ui-icon icon-cart-shopping"></span><span>Einkauf</span></span></a>
|
|
<a href="{{ url_for('main.planner_day', date=today.isoformat()) }}" class="{{ 'active' if request.endpoint == 'main.planner_day' else '' }}"><span class="nav-link-inner"><span class="ui-icon icon-calendar"></span><span>Plan</span></span></a>
|
|
<a href="{{ url_for('main.planner') }}" class="{{ 'active' if request.endpoint == 'main.planner' else '' }}"><span class="nav-link-inner"><span class="ui-icon icon-calendar-days"></span><span>Woche</span></span></a>
|
|
<a href="{{ url_for('main.home_view') }}" class="{{ 'active' if request.endpoint == 'main.home_view' else '' }}"><span class="nav-link-inner"><span class="ui-icon icon-house"></span><span>Zuhause</span></span></a>
|
|
<a href="{{ url_for('main.item_list', kind='food') }}" class="{{ 'active' if request.endpoint == 'main.item_list' and request.view_args and request.view_args.get('kind') == 'food' else '' }}"><span class="nav-link-inner"><span class="ui-icon icon-utensils"></span><span>Lebensmittel</span></span></a>
|
|
<a href="{{ url_for('main.item_list', kind='meal') }}" class="{{ 'active' if request.endpoint == 'main.item_list' and request.view_args and request.view_args.get('kind') == 'meal' else '' }}"><span class="nav-link-inner"><span class="ui-icon icon-bowl-food"></span><span>Mahlzeiten</span></span></a>
|
|
<a href="{{ url_for('main.template_library') }}" class="{{ 'active' if (request.endpoint or '').startswith('main.day_template') or (request.endpoint or '').startswith('main.week_template') or (request.endpoint or '').startswith('main.item_set') or request.endpoint == 'main.template_library' else '' }}"><span class="nav-link-inner"><span class="ui-icon icon-leaf"></span><span>Vorlagen</span></span></a>
|
|
<a href="{{ url_for('main.archive_view') }}" class="{{ 'active' if request.endpoint == 'main.archive_view' else '' }}"><span class="nav-link-inner"><span class="ui-icon icon-archive"></span><span>Archiv</span></span></a>
|
|
</nav>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if g.user %}
|
|
<div class="desktop-header-sub">
|
|
<div class="header-actions desktop-actions">
|
|
<button class="theme-toggle ghost-button" type="button" data-theme-toggle aria-label="Darstellung wechseln">
|
|
<span class="ui-icon icon-sun-theme" data-theme-icon></span>
|
|
<span data-theme-label>Hell</span>
|
|
</button>
|
|
<a class="ghost-button" href="{{ url_for('main.settings_view') }}">Optionen</a>
|
|
<a class="user-chip" href="{{ url_for('auth.profile') }}">
|
|
<span class="user-chip-title">{{ g.user.display_name or g.user.username }}</span>
|
|
<small>{{ role_labels[g.user.role] }}</small>
|
|
</a>
|
|
{% if g.user.role == 'admin' %}
|
|
<a class="ghost-button" href="{{ url_for('admin.user_list') }}">Nutzer</a>
|
|
{% endif %}
|
|
<form method="post" action="{{ url_for('auth.logout') }}">
|
|
{{ csrf_input() }}
|
|
<button class="ghost-button" type="submit">Abmelden</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<button class="mobile-profile-link ghost-button" type="button" data-mobile-sheet-open aria-label="Mehr öffnen">
|
|
<span class="mobile-profile-avatar">{{ (g.user.display_name or g.user.username or 'N')[:1]|upper }}</span>
|
|
</button>
|
|
{% endif %}
|
|
</header>
|
|
|
|
<main class="content">
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
{% if messages %}
|
|
<section class="flash-stack" aria-label="Hinweise">
|
|
{% for category, message in messages %}
|
|
<div class="flash flash-{{ category }}">{{ message }}</div>
|
|
{% endfor %}
|
|
</section>
|
|
{% endif %}
|
|
{% endwith %}
|
|
|
|
{% block content %}{% endblock %}
|
|
</main>
|
|
|
|
<footer class="site-footer">
|
|
<div class="footer-copy">
|
|
<a href="{{ app_release_url }}" target="_blank" rel="noreferrer">Version {{ app_version }}</a>
|
|
<span>Made with <span class="ui-icon icon-heart"></span> in Göttingen</span>
|
|
</div>
|
|
<div class="footer-copy">
|
|
<span>© 2026 <a href="https://hnz.io" target="_blank" rel="noreferrer">@ hnz.io</a></span>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
|
|
{% if g.user %}
|
|
<div class="mobile-nav-stack" data-mobile-nav-stack>
|
|
<nav class="mobile-nav-extension" data-mobile-sheet hidden aria-label="Mehr Navigation">
|
|
<a class="mobile-extra-link" href="{{ url_for('main.item_list', kind='food') }}"><span class="ui-icon icon-utensils"></span><span>Lebensmittel</span></a>
|
|
<a class="mobile-extra-link" href="{{ url_for('main.item_list', kind='meal') }}"><span class="ui-icon icon-bowl-food"></span><span>Mahlzeiten</span></a>
|
|
<a class="mobile-extra-link" href="{{ url_for('main.home_view') }}"><span class="ui-icon icon-house"></span><span>Zuhause</span></a>
|
|
<a class="mobile-extra-link" href="{{ url_for('main.archive_view') }}"><span class="ui-icon icon-archive"></span><span>Archiv</span></a>
|
|
<a class="mobile-extra-link" href="{{ url_for('main.template_library') }}"><span class="ui-icon icon-leaf"></span><span>Vorlagen</span></a>
|
|
<a class="mobile-extra-link" href="{{ url_for('main.settings_view') }}"><span class="ui-icon icon-sliders"></span><span>Optionen</span></a>
|
|
<a class="mobile-extra-link" href="{{ url_for('auth.profile') }}"><span class="ui-icon icon-heart"></span><span>Profil</span></a>
|
|
{% if g.user.role == 'admin' %}
|
|
<a class="mobile-extra-link" href="{{ url_for('admin.user_list') }}"><span class="ui-icon icon-sparkles"></span><span>Nutzer</span></a>
|
|
{% endif %}
|
|
<button class="mobile-extra-link mobile-extra-button" type="button" data-theme-toggle aria-label="Darstellung wechseln">
|
|
<span class="ui-icon icon-sun-theme" data-theme-icon></span>
|
|
<span data-theme-label>Hell</span>
|
|
</button>
|
|
<form method="post" action="{{ url_for('auth.logout') }}" class="mobile-extra-form">
|
|
{{ csrf_input() }}
|
|
<button class="mobile-extra-link mobile-extra-button" type="submit">
|
|
<span class="ui-icon icon-ellipsis"></span>
|
|
<span>Abmelden</span>
|
|
</button>
|
|
</form>
|
|
</nav>
|
|
|
|
<nav class="mobile-bottom-nav" aria-label="Mobile Navigation">
|
|
<a href="{{ url_for('main.dashboard') }}" class="{{ 'active' if request.endpoint == 'main.dashboard' else '' }}">
|
|
<span class="ui-icon icon-sparkles"></span>
|
|
<span>Heute</span>
|
|
</a>
|
|
<a href="{{ url_for('main.shopping_list') }}" class="{{ 'active' if request.endpoint == 'main.shopping_list' else '' }}">
|
|
<span class="ui-icon icon-cart-shopping"></span>
|
|
<span>Einkauf</span>
|
|
</a>
|
|
<a href="{{ url_for('main.planner_day', date=today.isoformat()) }}" class="{{ 'active' if request.endpoint == 'main.planner_day' else '' }}">
|
|
<span class="ui-icon icon-calendar"></span>
|
|
<span>Plan</span>
|
|
</a>
|
|
<a href="{{ url_for('main.planner') }}" class="{{ 'active' if request.endpoint == 'main.planner' else '' }}">
|
|
<span class="ui-icon icon-calendar-days"></span>
|
|
<span>Woche</span>
|
|
</a>
|
|
<button type="button" class="mobile-nav-button" data-mobile-sheet-open>
|
|
<span class="ui-icon icon-ellipsis"></span>
|
|
<span>Mehr</span>
|
|
</button>
|
|
</nav>
|
|
</div>
|
|
{% endif %}
|
|
</body>
|
|
</html>
|