Files

309 lines
20 KiB
HTML

{% extends "base.html" %}
{% block title %}Wochenansicht | Nouri{% endblock %}
{% block content %}
<section class="page-intro">
<div>
<p class="eyebrow">Wochenansicht</p>
<h1>Die nächsten sieben Tage auf einen Blick</h1>
<p class="lead">Du kannst Einträge zwischen Tagen und Tageszeiten verschieben, Vorlagen anwenden und sehen, was erst später für den Einkauf wichtig wird.</p>
</div>
<div class="week-nav">
<a class="ghost-button" href="{{ url_for('main.planner', week=prev_week.isoformat()) }}">Vorige Woche</a>
<span>{{ week_start.strftime('%d.%m.%Y') }} bis {{ week_end.strftime('%d.%m.%Y') }}</span>
<details class="export-menu">
<summary class="ghost-button export-menu-trigger">PDF exportieren</summary>
<div class="export-menu-panel">
<a href="{{ url_for('main.planner_export_pdf', week=week_start.isoformat(), mode='mine') }}">Meinen Essensplan</a>
<a href="{{ url_for('main.planner_export_pdf', week=week_start.isoformat(), mode='household') }}">Unseren Essensplan</a>
</div>
</details>
<a class="ghost-button" href="{{ url_for('main.planner', week=next_week.isoformat()) }}">Nächste Woche</a>
</div>
</section>
<section class="two-column">
<article class="panel">
<div class="panel-head">
<h2>Wochenvorlagen</h2>
<a href="{{ url_for('main.week_template_create', source_week=week_start.isoformat()) }}">Als Vorlage speichern</a>
</div>
{% if week_templates %}
<div class="stack-sections">
{% for template in week_templates %}
<form method="post" action="{{ url_for('main.week_template_apply', template_id=template.id) }}" class="inline-form template-apply-form">
{{ csrf_input() }}
<input type="hidden" name="target_week" value="{{ week_start.isoformat() }}">
<div class="template-card">
<strong>{{ template.name }}</strong>
<small>{{ template.visibility_label }} · {{ template.owner_label }}</small>
</div>
<button type="submit">Vorlage anwenden</button>
</form>
{% endfor %}
</div>
{% else %}
<p class="empty-state">Wenn eine Woche sich bewährt hat, kannst du sie hier später als Wochenvorlage wiederverwenden.</p>
{% endif %}
</article>
{% if week_hints %}
<article class="panel">
<div class="panel-head">
<h2>Für diese Woche</h2>
</div>
<div class="hint-list">
{% for hint in week_hints %}
<p class="hint-chip">{{ hint }}</p>
{% endfor %}
</div>
</article>
{% endif %}
</section>
{% if upcoming_entries %}
<section class="panel">
<div class="panel-head">
<h2>Kommt später zum Einkauf dazu</h2>
<small>{{ household_settings.shopping_prep_days }} Tag{% if household_settings.shopping_prep_days != 1 %}e{% endif %} Vorlauf</small>
</div>
<div class="chip-row">
{% for entry in upcoming_entries %}
<span class="chip">{{ entry.item_name }} · ab {{ entry.activation_label }}</span>
{% endfor %}
</div>
</section>
{% endif %}
<section class="week-overview-grid week-board" data-csrf-token="{{ csrf_token_value }}">
{% for card in week_cards %}
<article class="week-card">
<div class="week-card-head">
<div>
<p class="eyebrow">{{ weekday_name(card.date) }}</p>
<h2>{{ card.date.strftime('%d.%m.%Y') }}</h2>
</div>
{% if card.date == today %}
<span class="status-pill status-home">heute</span>
{% endif %}
</div>
{% if not card.filled_dayparts %}
<p class="empty-state week-card-empty-copy">Noch offen. Du kannst den Tag nach und nach füllen.</p>
{% endif %}
{% if card.hidden_snack_slots %}
<div class="week-card-snack-actions" data-week-snack-actions>
<div>
<p class="eyebrow">Snacks ergänzen</p>
</div>
<div class="chip-row snack-reveal-actions">
{% for hidden_slot in card.hidden_snack_slots %}
<button
class="ghost-button snack-reveal-button"
type="button"
data-week-snack-slot-open
data-target="#week-slot-{{ card.date.isoformat() }}-{{ hidden_slot.id }}"
>
{% if hidden_slot.name == 'Vormittagssnack' %}
Vormittag
{% elif hidden_slot.name == 'Nachmittagssnack' %}
Nachmittag
{% elif hidden_slot.name == 'Später Snack' %}
Abend
{% else %}
{{ hidden_slot.name }}
{% endif %}
</button>
{% endfor %}
</div>
</div>
{% endif %}
<div class="week-slot-stack">
{% for slot in card.slots %}
<div
class="week-slot drop-slot{% if slot.entries %} has-entries{% endif %}{% if slot.is_snack_daypart %} week-slot-snack{% endif %}"
id="week-slot-{{ card.date.isoformat() }}-{{ slot.daypart.id }}"
data-target-date="{{ card.date.isoformat() }}"
data-target-daypart-id="{{ slot.daypart.id }}"
{% if slot.is_snack_daypart and not slot.visible_by_default %}hidden data-week-snack-slot{% endif %}
>
<div class="week-slot-head">
<div class="week-slot-title">
<span class="ui-icon {{ daypart_icon_class(slot.daypart.slug) }}"></span>
<strong>{{ slot.daypart.name }}</strong>
</div>
<div class="week-slot-head-meta">
<span class="week-slot-count{% if slot.entries %} status-home{% endif %}">{{ slot.entries|length }}</span>
<button class="week-slot-add" type="button" data-week-slot-picker-open aria-label="{{ slot.daypart.name }} an {{ weekday_name(card.date) }} direkt ergänzen">+</button>
</div>
</div>
<div class="week-slot-picker" hidden>
<div class="week-slot-picker-head">
<strong>{{ slot.daypart.name }} ergänzen</strong>
<button class="ghost-button week-slot-picker-close" type="button" data-week-slot-picker-close>Schließen</button>
</div>
<label class="planner-search week-slot-picker-search">
<span>Suche</span>
<input type="text" placeholder="Mahlzeiten oder Ideen suchen" data-filter-input data-filter-target="#week-slot-picker-list-{{ card.date.isoformat() }}-{{ slot.daypart.id }}">
</label>
<div id="week-slot-picker-list-{{ card.date.isoformat() }}-{{ slot.daypart.id }}">
{% if slot.picker.meal_candidates %}
<div class="planner-subsection">
<h3>Mahlzeitenideen</h3>
<div class="quick-add-row compact-quick-row">
{% for item in slot.picker.meal_candidates %}
<form method="post" action="{{ url_for('main.planner_day', date=card.date.isoformat()) }}" class="js-week-slot-submit" data-filter-label="{{ item.name|lower }}">
{{ csrf_input() }}
<input type="hidden" name="plan_date" value="{{ card.date.isoformat() }}">
<input type="hidden" name="daypart_id" value="{{ slot.daypart.id }}">
<input type="hidden" name="item_id" value="{{ item.id }}">
<input type="hidden" name="visibility" value="{{ item.visibility }}">
<button class="quick-add-button compact-button" type="submit">
<span>{{ item.name }}</span>
{% if item.is_home %}<small>Zuhause vorhanden</small>{% endif %}
</button>
</form>
{% endfor %}
</div>
</div>
{% endif %}
{% if slot.picker.recipe_suggestions %}
<div class="planner-subsection">
<h3>Passt gut dazu</h3>
<div class="quick-add-row compact-quick-row">
{% for suggestion in slot.picker.recipe_suggestions %}
{% if suggestion.existing_item_id %}
<form method="post" action="{{ url_for('main.planner_day', date=card.date.isoformat()) }}" class="js-week-slot-submit" data-filter-label="{{ suggestion.title|lower }} {{ suggestion.reason|lower }}">
{{ csrf_input() }}
<input type="hidden" name="plan_date" value="{{ card.date.isoformat() }}">
<input type="hidden" name="daypart_id" value="{{ slot.daypart.id }}">
<input type="hidden" name="item_id" value="{{ suggestion.existing_item_id }}">
<input type="hidden" name="visibility" value="{{ suggestion.visibility or 'shared' }}">
<button class="quick-add-button compact-button" type="submit">
<span>{{ suggestion.title }}</span>
<small>{{ suggestion.reason }}</small>
</button>
</form>
{% else %}
<form method="post" action="{{ url_for('main.planner_generated_meal') }}" class="js-week-slot-submit" data-filter-label="{{ suggestion.title|lower }} {{ suggestion.reason|lower }}">
{{ csrf_input() }}
<input type="hidden" name="plan_date" value="{{ card.date.isoformat() }}">
<input type="hidden" name="daypart_id" value="{{ slot.daypart.id }}">
<input type="hidden" name="meal_name" value="{{ suggestion.title }}">
<input type="hidden" name="visibility" value="{{ suggestion.visibility or 'shared' }}">
{% for component_id in suggestion.component_ids %}
<input type="hidden" name="component_ids" value="{{ component_id }}">
{% endfor %}
<button class="quick-add-button compact-button" type="submit">
<span>{{ suggestion.title }}</span>
<small>{{ suggestion.reason }}</small>
</button>
</form>
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{% if not slot.picker.meal_candidates and not slot.picker.recipe_suggestions %}
<p class="empty-state">Hier ist gerade noch nichts vorbereitet. Im Tagesplan kannst du jederzeit etwas Neues anlegen.</p>
{% endif %}
</div>
</div>
{% if slot.entries %}
<div class="week-entry-stack">
{% for entry in slot.entries %}
<article
class="plan-chip draggable-plan-entry{% if entry.can_edit %} is-editable{% endif %}"
draggable="{{ 'true' if entry.can_edit else 'false' }}"
data-entry-id="{{ entry.id }}"
data-move-url="{{ url_for('main.planner_move', entry_id=entry.id) }}"
{% if entry.can_edit %}
data-week-entry-open
data-week-entry-dialog-id="week-entry-dialog-{{ entry.id }}"
tabindex="0"
role="button"
aria-label="{{ entry.item_name }} bearbeiten"
{% endif %}
>
<strong>{{ entry.item_name }}</strong>
<small>{{ entry.visibility_label }} · {{ entry.for_label }}</small>
</article>
{% if entry.can_edit %}
<dialog class="week-entry-dialog" id="week-entry-dialog-{{ entry.id }}">
<div class="week-entry-dialog-card">
<div class="week-entry-dialog-head">
<div>
<h3>{{ entry.item_name }}</h3>
<p>{{ slot.daypart.name }} · {{ weekday_name(card.date) }}, {{ card.date.strftime('%d.%m.%Y') }}</p>
</div>
<button class="ghost-button" type="button" data-week-entry-close>Schließen</button>
</div>
<form method="post" action="{{ url_for('main.planner_update', entry_id=entry.id) }}" class="planner-entry-inline-form js-week-entry-submit">
{{ csrf_input() }}
<input type="hidden" name="plan_date" value="{{ card.date.isoformat() }}">
<input type="hidden" name="return_week" value="{{ week_start.isoformat() }}">
<label>
Für wen?
<select name="visibility">
{% for value, label in visibility_options %}
<option value="{{ value }}" {% if entry.visibility == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</label>
<label class="wide">
Notiz
<input type="text" name="note" value="{{ entry.note or '' }}" placeholder="Optional">
</label>
<div class="week-entry-dialog-actions">
<button type="submit">Speichern</button>
</div>
</form>
<form method="post" action="{{ url_for('main.planner_remove', entry_id=entry.id) }}" class="week-entry-remove-form js-week-entry-submit">
{{ csrf_input() }}
<input type="hidden" name="plan_date" value="{{ card.date.isoformat() }}">
<input type="hidden" name="return_week" value="{{ week_start.isoformat() }}">
<button class="ghost-button" type="submit">Eintrag entfernen</button>
</form>
</div>
</dialog>
{% endif %}
{% endfor %}
</div>
<div class="week-slot-actions">
{% if slot.copy_allowed %}
<form method="post" action="{{ url_for('main.planner_slot_copy_forward') }}" class="js-copy-forward-form">
{{ csrf_input() }}
<input type="hidden" name="source_date" value="{{ card.date.isoformat() }}">
<input type="hidden" name="daypart_id" value="{{ slot.daypart.id }}">
<button class="ghost-button week-slot-copy" type="submit">Zum nächsten Tag kopieren</button>
</form>
{% endif %}
</div>
{% else %}
<div class="week-slot-empty">
<p>Hierher ziehen</p>
{% if slot.is_snack_daypart %}
<button
class="ghost-button week-slot-hide"
type="button"
data-week-snack-slot-hide
data-target="#week-slot-{{ card.date.isoformat() }}-{{ slot.daypart.id }}"
>
Wieder ausblenden
</button>
{% endif %}
</div>
{% endif %}
</div>
{% endfor %}
</div>
<div class="week-card-actions">
<a class="button" href="{{ url_for('main.planner_day', date=card.date.isoformat()) }}">Tagesplan öffnen</a>
</div>
</article>
{% endfor %}
</section>
{% endblock %}