Release 1.2.0 with calmer snack planning and PDF exports
This commit is contained in:
@@ -10,6 +10,13 @@
|
||||
<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>
|
||||
@@ -80,24 +87,125 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if card.filled_dayparts %}
|
||||
<p class="week-card-count">{{ card.planned_count }} Einträge</p>
|
||||
<div class="chip-row">
|
||||
{% for slot in card.filled_dayparts %}
|
||||
<span class="chip">{{ slot.name }} · {{ slot.count }}</span>
|
||||
{% endfor %}
|
||||
{% if not card.filled_dayparts %}
|
||||
<p class="empty-state week-card-empty-copy">Noch offen. Du kannst den Tag ganz leicht 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>
|
||||
<p class="muted">{{ card.preview_items | join(', ') }}</p>
|
||||
{% else %}
|
||||
<p class="empty-state">Noch offen. Du kannst den Tag ganz leicht nach und nach füllen.</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="week-slot-stack">
|
||||
{% for slot in card.slots %}
|
||||
<div class="week-slot drop-slot" data-target-date="{{ card.date.isoformat() }}" data-target-daypart-id="{{ slot.daypart.id }}">
|
||||
<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">
|
||||
<strong>{{ slot.daypart.name }}</strong>
|
||||
<span>{{ slot.entries|length }}</span>
|
||||
<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.availability_state == '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">
|
||||
@@ -108,8 +216,30 @@
|
||||
</article>
|
||||
{% 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 %}
|
||||
<p class="week-slot-empty">Hierher ziehen</p>
|
||||
<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 %}
|
||||
|
||||
Reference in New Issue
Block a user