Refine planner filters and compact selection cards

This commit is contained in:
2026-04-14 09:15:46 +02:00
parent c5dea16c53
commit 6f6269c66d
13 changed files with 451 additions and 108 deletions
+28 -4
View File
@@ -210,15 +210,39 @@
<p class="helper-text">Schon ausgewählt</p>
<div class="selected-components-grid">
{% for component in selected_components %}
{% set component_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(component.primary_builder_key or component.base_type, 'icon-component-neutral') %}
<article class="selected-component-card">
<input type="hidden" name="component_ids" value="{{ component.id }}">
<button class="selected-component-remove" type="submit" name="remove_component_id" value="{{ component.id }}">
<span aria-hidden="true">×</span>
<span class="sr-only">{{ component.name }} entfernen</span>
</button>
<div class="selected-component-visual">
{% if component.photo_filename %}
<img
src="{{ image_url(component.photo_filename, 'md') }}"
srcset="{{ image_srcset(component.photo_filename) }}"
sizes="{{ image_sizes('grid') }}"
alt="{{ component.name }}"
loading="lazy">
{% else %}
<span class="selected-component-fallback">
<span class="ui-icon {{ component_icon_class }}"></span>
</span>
{% endif %}
</div>
<div class="selected-component-main">
<strong>{{ component.name }}</strong>
<small>{{ component.base_type_label }} · {{ component.visibility_label }}</small>
</div>
<button class="ghost-button selected-component-remove" type="submit" name="remove_component_id" value="{{ component.id }}">
Entfernen
</button>
</article>
{% endfor %}
</div>
+38 -3
View File
@@ -51,11 +51,46 @@
<h3>{{ group["title"] }}</h3>
<span>{{ group["items"]|length }} Einträge</span>
</div>
<div class="checkbox-grid">
<div class="checkbox-grid package-option-grid">
{% for item in group["items"] %}
<label class="check-option" data-filter-label="{{ item.name|lower }} {{ item.category|default('', true)|lower }}">
{% if item.kind == 'meal' %}
{% set item_icon_class = {
'breakfast': 'icon-daypart-breakfast',
'lunch': 'icon-daypart-lunch',
'dinner': 'icon-daypart-dinner',
'snack': 'icon-daypart-afternoon-snack',
}.get(item.meal_type, 'icon-utensils') %}
{% else %}
{% 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') %}
{% endif %}
<label class="set-item-option" data-filter-label="{{ item.name|lower }} {{ item.category|default('', true)|lower }}">
<input type="checkbox" name="item_ids" value="{{ item.id }}" {% if item.id in form_data.item_ids %}checked{% endif %}>
<span>{{ item.name }} · {{ item_kind_labels[item.kind] }} · {{ item.visibility_label }} · {{ item.for_label }}</span>
<span class="set-item-option-card">
<span class="set-item-option-visual">
{% if item.photo_filename %}
<img
src="{{ image_url(item.photo_filename, 'md') }}"
srcset="{{ image_srcset(item.photo_filename) }}"
sizes="{{ image_sizes('grid') }}"
alt="{{ item.name }}"
loading="lazy">
{% else %}
<span class="set-item-option-fallback">
<span class="ui-icon {{ item_icon_class }}"></span>
</span>
{% endif %}
</span>
<span class="set-item-option-label">{{ item.name }}</span>
</span>
</label>
{% endfor %}
</div>
+88 -84
View File
@@ -14,90 +14,53 @@
</div>
</section>
<section class="two-column">
<article class="panel">
<div class="panel-head">
<h2>Tagesvorlagen</h2>
<a href="{{ url_for('main.day_template_create', source_date=selected_date.isoformat()) }}">Als Vorlage speichern</a>
</div>
{% if day_templates %}
<div class="stack-sections">
{% for template in day_templates %}
<form method="post" action="{{ url_for('main.day_template_apply', template_id=template.id) }}" class="inline-form template-apply-form">
{{ csrf_input() }}
<input type="hidden" name="target_date" value="{{ selected_date.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 du einen Tag öfter wiederverwenden möchtest, kannst du ihn hier als Tagesvorlage speichern.</p>
{% endif %}
</article>
{% if day_hints %}
<article class="panel">
<div class="panel-head">
<h2>Heute im Blick</h2>
</div>
<div class="hint-list">
{% for hint in day_hints %}
<p class="hint-chip">{{ hint }}</p>
{% endfor %}
</div>
</article>
{% endif %}
</section>
<section class="planner-day-stack">
{% set hidden_snack_sections = sections | selectattr('is_snack_daypart') | rejectattr('visible_by_default') | list %}
{% if hidden_snack_sections %}
<section class="panel compact-form-panel snack-reveal-panel" data-day-snack-actions>
<div class="panel-head">
<h2>Zwischenmahlzeit hinzufügen</h2>
</div>
<div class="chip-row snack-reveal-actions">
{% for section in hidden_snack_sections %}
<button
class="ghost-button snack-reveal-button"
type="button"
data-day-snack-open
data-target="#daypart-{{ section.daypart.id }}"
>
{{ section.daypart.name }}
</button>
{% endfor %}
</div>
</section>
{% endif %}
{% for section in sections %}
<details
class="day-tile{% if section.entries %} has-entries{% endif %}{% if section.selected_quick_action %} has-selection{% endif %}"
id="daypart-{{ section.daypart.id }}"
{% if section.is_snack_daypart and not section.visible_by_default %}hidden data-day-snack-tile{% endif %}
{% if section.is_open %}open{% endif %}
>
<summary class="day-tile-summary">
<div class="day-tile-summary-main">
<div class="day-tile-icon"><span class="ui-icon {{ daypart_icon_class(section.daypart.slug) }}"></span></div>
<div>
<h2>{{ section.daypart.name }}</h2>
{% if section.summary_items %}
<p class="day-tile-summary-text">{{ section.summary_items|join(', ') }}</p>
{% else %}
<p class="muted">Noch offen. Öffnen, wenn du etwas eintragen möchtest.</p>
{% endif %}
<section class="planner-day-layout">
<div class="planner-day-main">
<section class="planner-day-stack">
{% set hidden_snack_sections = sections | selectattr('is_snack_daypart') | rejectattr('visible_by_default') | list %}
{% if hidden_snack_sections %}
<section class="panel compact-form-panel snack-reveal-panel" data-day-snack-actions>
<div class="panel-head">
<h2>Zwischenmahlzeit hinzufügen</h2>
</div>
</div>
<span class="status-pill{% if section.entries %} status-home{% endif %}">{{ section.entries|length }} geplant</span>
</summary>
<div class="chip-row snack-reveal-actions">
{% for section in hidden_snack_sections %}
<button
class="ghost-button snack-reveal-button"
type="button"
data-day-snack-open
data-target="#daypart-{{ section.daypart.id }}"
>
{{ section.daypart.name }}
</button>
{% endfor %}
</div>
</section>
{% endif %}
<div class="day-tile-body">
{% for section in sections %}
<details
class="day-tile{% if section.entries %} has-entries{% endif %}{% if section.selected_quick_action %} has-selection{% endif %}"
id="daypart-{{ section.daypart.id }}"
{% if section.is_snack_daypart and not section.visible_by_default %}hidden data-day-snack-tile{% endif %}
{% if section.is_open %}open{% endif %}
>
<summary class="day-tile-summary">
<div class="day-tile-summary-main">
<div class="day-tile-icon"><span class="ui-icon {{ daypart_icon_class(section.daypart.slug) }}"></span></div>
<div>
<h2>{{ section.daypart.name }}</h2>
{% if section.summary_items %}
<p class="day-tile-summary-text">{{ section.summary_items|join(', ') }}</p>
{% else %}
<p class="muted">Noch offen. Öffnen, wenn du etwas eintragen möchtest.</p>
{% endif %}
</div>
</div>
<span class="status-pill{% if section.entries %} status-home{% endif %}">{{ section.entries|length }} geplant</span>
</summary>
<div class="day-tile-body">
{% if section.selected_quick_action %}
<div class="suggestion-card selected-quick-action">
<span class="status-pill status-home">Schon ausgewählt</span>
@@ -301,8 +264,49 @@
</div>
{% endif %}
{% endif %}
</div>
</details>
{% endfor %}
</section>
</div>
<aside class="planner-day-sidebar">
<article class="panel">
<div class="panel-head">
<h2>Tagesvorlagen</h2>
<a href="{{ url_for('main.day_template_create', source_date=selected_date.isoformat()) }}">Als Vorlage speichern</a>
</div>
</details>
{% endfor %}
{% if day_templates %}
<div class="stack-sections">
{% for template in day_templates %}
<form method="post" action="{{ url_for('main.day_template_apply', template_id=template.id) }}" class="inline-form template-apply-form">
{{ csrf_input() }}
<input type="hidden" name="target_date" value="{{ selected_date.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 du einen Tag öfter wiederverwenden möchtest, kannst du ihn hier als Tagesvorlage speichern.</p>
{% endif %}
</article>
{% if day_hints %}
<article class="panel">
<div class="panel-head">
<h2>Heute im Blick</h2>
</div>
<div class="hint-list">
{% for hint in day_hints %}
<p class="hint-chip">{{ hint }}</p>
{% endfor %}
</div>
</article>
{% endif %}
</aside>
</section>
{% endblock %}