232 lines
12 KiB
HTML
232 lines
12 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}Einkaufsliste | Nouri{% endblock %}
|
||
{% block content %}
|
||
<section class="page-intro">
|
||
<div>
|
||
<p class="eyebrow">Einkaufsliste</p>
|
||
<h1>Was noch mitkommen soll</h1>
|
||
<p class="lead">Hier erscheint, was für den nächsten Einkauf wirklich relevant ist. Spätere Bedarfe bleiben erstmal ruhig vorgemerkt.</p>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="panel compact-form-panel">
|
||
<div class="stack-sections">
|
||
<label>
|
||
Lebensmittel suchen
|
||
<input
|
||
type="text"
|
||
placeholder="Nach Lebensmitteln suchen"
|
||
data-filter-input
|
||
data-filter-target="#shopping-add-list"
|
||
data-filter-limit="8"
|
||
>
|
||
</label>
|
||
<div class="shopping-add-grid" id="shopping-add-list">
|
||
{% for item in addable_items %}
|
||
{% set item_icon_class = {
|
||
'protein': 'icon-component-protein',
|
||
'carb': 'icon-component-carb',
|
||
'veg': 'icon-component-veg',
|
||
'fruit': 'icon-component-fruit',
|
||
'dairy': 'icon-component-dairy',
|
||
'nuts': 'icon-component-nuts',
|
||
'seeds': 'icon-component-seeds',
|
||
'neutral': 'icon-component-neutral',
|
||
}.get(item.primary_builder_key or item.base_type, 'icon-component-neutral') %}
|
||
<form method="post" data-filter-label="{{ item.name|lower }} {{ item.base_type_label|lower }} {{ item.for_label|lower }}">
|
||
{{ csrf_input() }}
|
||
<input type="hidden" name="item_id" value="{{ item.id }}">
|
||
<button class="shopping-add-card" type="submit">
|
||
<span class="shopping-add-card-visual">
|
||
{% if item.photo_filename %}
|
||
<img
|
||
src="{{ image_url(item.photo_filename, 'md') }}"
|
||
srcset="{{ image_srcset(item.photo_filename) }}"
|
||
sizes="{{ image_sizes('grid') }}"
|
||
alt=""
|
||
loading="lazy">
|
||
{% else %}
|
||
<span class="shopping-add-card-fallback">
|
||
<span class="ui-icon {{ item_icon_class }}"></span>
|
||
</span>
|
||
{% endif %}
|
||
</span>
|
||
<span class="shopping-add-card-copy">
|
||
<strong>{{ item.name }}</strong>
|
||
<small>
|
||
{% if item.is_archived %}
|
||
Archiviert
|
||
{% elif item.is_quick_added %}
|
||
Unsortiert
|
||
{% elif item.is_home %}
|
||
Zuhause · trotzdem ergänzen
|
||
{% else %}
|
||
Gerade nicht da
|
||
{% endif %}
|
||
</small>
|
||
</span>
|
||
</button>
|
||
</form>
|
||
{% else %}
|
||
<p class="shopping-add-empty muted">Gerade ist nichts zusätzlich offen.</p>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{% if entries %}
|
||
<section class="panel compact-form-panel">
|
||
<div class="panel-head">
|
||
<h2>Für den nächsten Einkauf</h2>
|
||
<span>{{ entries|length }} Einträge</span>
|
||
</div>
|
||
</section>
|
||
<section class="stack-list">
|
||
{% for entry in entries %}
|
||
{% set entry_icon_class = {
|
||
'protein': 'icon-component-protein',
|
||
'carb': 'icon-component-carb',
|
||
'veg': 'icon-component-veg',
|
||
'fruit': 'icon-component-fruit',
|
||
'dairy': 'icon-component-dairy',
|
||
'nuts': 'icon-component-nuts',
|
||
'seeds': 'icon-component-seeds',
|
||
'neutral': 'icon-component-neutral',
|
||
}.get(entry.primary_builder_key or entry.base_type, 'icon-component-neutral') %}
|
||
<article class="shopping-entry-card">
|
||
<div class="shopping-entry-row">
|
||
<div
|
||
class="shopping-entry-open"
|
||
data-dialog-open="shopping-entry-dialog-{{ entry.id }}"
|
||
tabindex="0"
|
||
role="button"
|
||
aria-label="{{ entry.item_name }} öffnen"
|
||
>
|
||
<div class="shopping-entry-main">
|
||
<div class="shopping-entry-visual">
|
||
{% if entry.photo_filename %}
|
||
<img
|
||
src="{{ image_url(entry.photo_filename, 'md') }}"
|
||
srcset="{{ image_srcset(entry.photo_filename) }}"
|
||
sizes="{{ image_sizes('grid') }}"
|
||
alt=""
|
||
loading="lazy">
|
||
{% else %}
|
||
<span class="shopping-entry-fallback">
|
||
<span class="ui-icon {{ entry_icon_class }}"></span>
|
||
</span>
|
||
{% endif %}
|
||
</div>
|
||
<div class="shopping-entry-copy">
|
||
<strong>{{ entry.item_name }}</strong>
|
||
{% if entry.needed_for_label %}
|
||
<p class="muted">
|
||
Für {{ entry.needed_for_label }}
|
||
{% if entry.needed_daypart_name %} · {{ entry.needed_daypart_name }}{% endif %}
|
||
</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="shopping-entry-actions">
|
||
<form method="post" action="{{ url_for('main.shopping_check', entry_id=entry.id) }}">
|
||
{{ csrf_input() }}
|
||
<button type="submit">Eingekauft</button>
|
||
</form>
|
||
</div>
|
||
{% if entry.can_edit %}
|
||
<form method="post" action="{{ url_for('main.shopping_remove', entry_id=entry.id) }}" class="shopping-entry-close-form">
|
||
{{ csrf_input() }}
|
||
<button class="shopping-entry-close" type="submit" aria-label="{{ entry.item_name }} entfernen">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
</article>
|
||
<dialog class="shopping-entry-dialog week-entry-dialog" id="shopping-entry-dialog-{{ entry.id }}">
|
||
<div class="shopping-entry-dialog-card week-entry-dialog-card">
|
||
<div class="week-entry-dialog-head">
|
||
<div>
|
||
<h3>{{ entry.item_name }}</h3>
|
||
<p>
|
||
{% if entry.needed_for_label %}
|
||
Für {{ entry.needed_for_label }}
|
||
{% if entry.needed_daypart_name %} · {{ entry.needed_daypart_name }}{% endif %}
|
||
{% elif entry.is_home %}
|
||
Zuhause vorhanden
|
||
{% else %}
|
||
Gerade nicht da
|
||
{% endif %}
|
||
</p>
|
||
</div>
|
||
<button class="ghost-button" type="button" data-dialog-close>Schließen</button>
|
||
</div>
|
||
<div class="shopping-entry-dialog-actions">
|
||
{% if entry.can_edit %}
|
||
<a class="ghost-button" href="{{ url_for('main.item_edit', item_id=entry.item_id) }}">Bearbeiten</a>
|
||
{% endif %}
|
||
<form method="post" action="{{ url_for('main.shopping_check', entry_id=entry.id) }}">
|
||
{{ csrf_input() }}
|
||
<button type="submit">Eingekauft</button>
|
||
</form>
|
||
{% if entry.can_edit %}
|
||
<form method="post" action="{{ url_for('main.shopping_remove', entry_id=entry.id) }}">
|
||
{{ csrf_input() }}
|
||
<button class="ghost-button" type="submit">Von Einkaufsliste nehmen</button>
|
||
</form>
|
||
{% if entry.is_home %}
|
||
<form method="post" action="{{ url_for('main.item_set_not_home', item_id=entry.item_id) }}">
|
||
{{ csrf_input() }}
|
||
<button class="ghost-button" type="submit">Nicht mehr da</button>
|
||
</form>
|
||
{% else %}
|
||
<form method="post" action="{{ url_for('main.item_set_home', item_id=entry.item_id) }}">
|
||
{{ csrf_input() }}
|
||
<button class="ghost-button" type="submit">Als zuhause markieren</button>
|
||
</form>
|
||
{% endif %}
|
||
<form method="post" action="{{ url_for('main.item_archive', item_id=entry.item_id) }}">
|
||
{{ csrf_input() }}
|
||
<button class="ghost-button" type="submit">Archivieren</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</dialog>
|
||
{% endfor %}
|
||
</section>
|
||
{% else %}
|
||
<section class="panel empty-panel">
|
||
<h2>Die Liste ist gerade frei</h2>
|
||
<p>Einträge aus Lebensmitteln, Vorlagen oder kleinen Paketen lassen sich jederzeit wieder hinzufügen.</p>
|
||
</section>
|
||
{% endif %}
|
||
|
||
{% if upcoming_entries %}
|
||
<section class="panel">
|
||
<div class="panel-head">
|
||
<h2>Später gebraucht</h2>
|
||
<small>Einkaufstag: {{ shopping_weekday_label }}</small>
|
||
</div>
|
||
<div class="stack-list">
|
||
{% for entry in upcoming_entries %}
|
||
<article class="list-row stacked-mobile roomy-row">
|
||
<div>
|
||
<strong>{{ entry.item_name }}</strong>
|
||
<p class="muted">Wird ab {{ entry.activation_label }} in die Einkaufsliste übernommen</p>
|
||
<div class="chip-row">
|
||
<span class="chip">{{ entry.for_label }}</span>
|
||
<span class="chip">{{ entry.needed_for_label }}</span>
|
||
{% if entry.needed_daypart_name %}
|
||
<span class="chip status-soft">{{ entry.needed_daypart_name }}</span>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</article>
|
||
{% endfor %}
|
||
</div>
|
||
</section>
|
||
{% endif %}
|
||
{% endblock %}
|