Add sorting by date or name

Adds a sort dropdown offering newest/oldest first and name A-Z/Z-A.
Sorting applies to plain listings, text search, and semantic search
results, and the sidebar facet links preserve the current choice.
Invalid sort values fall back to the default.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Erik Thiele
2026-07-19 22:05:22 +02:00
parent 6a35769943
commit 148074e24c
3 changed files with 69 additions and 17 deletions

View File

@@ -38,7 +38,12 @@
background: var(--panel2); border: 1px solid var(--border); color: var(--text);
border-radius: 8px; padding: 10px 12px; font-size: .95rem; width: 100%;
}
input:focus { outline: none; border-color: var(--accent); }
input:focus, select:focus { outline: none; border-color: var(--accent); }
select {
background: var(--panel2); border: 1px solid var(--border); color: var(--text);
border-radius: 8px; padding: 6px 10px; font-size: .85rem; font-family: inherit;
cursor: pointer;
}
.layout { display: flex; gap: 24px; max-width: 1200px; margin: 24px auto; padding: 0 24px; }
.sidebar { width: 240px; flex-shrink: 0; }
.main { flex: 1; min-width: 0; }

View File

@@ -19,14 +19,14 @@
<div class="layout">
<aside class="sidebar">
<div class="panel">
<a href="/" class="facet {% if not active_category and not active_manufacturer %}active{% endif %}">
<a href="/?sort={{ sort }}" class="facet {% if not active_category and not active_manufacturer %}active{% endif %}">
<span>📚 Alle Links</span>
</a>
<div class="facet-group">
<h3>Kategorien</h3>
{% for name, count in facets.categories %}
<a href="/?category={{ name | urlencode }}"
<a href="/?category={{ name | urlencode }}&amp;sort={{ sort }}"
class="facet {% if active_category == name %}active{% endif %}">
<span>{{ name }}</span><span class="count">{{ count }}</span>
</a>
@@ -38,7 +38,7 @@
<div class="facet-group">
<h3>Hersteller / Quellen</h3>
{% for name, count in facets.manufacturers %}
<a href="/?manufacturer={{ name | urlencode }}"
<a href="/?manufacturer={{ name | urlencode }}&amp;sort={{ sort }}"
class="facet {% if active_manufacturer == name %}active{% endif %}">
<span>{{ name }}</span><span class="count">{{ count }}</span>
</a>
@@ -75,14 +75,29 @@
hx-get="/search" hx-target="#links" hx-swap="innerHTML"
hx-trigger="keyup changed delay:400ms, search"
hx-include="#searchform">
{% if ai_enabled %}
<label class="muted" style="display:inline-flex; align-items:center; gap:6px; font-size:.85rem; margin-top:10px;">
<input type="checkbox" name="semantic" value="1" {% if semantic %}checked{% endif %}
hx-get="/search" hx-target="#links" hx-swap="innerHTML"
hx-trigger="change" hx-include="#searchform" style="width:auto;">
KI-Suche (findet auch sinnverwandte Treffer)
</label>
{% endif %}
<div style="display:flex; justify-content:space-between; align-items:center; gap:12px; margin-top:10px; flex-wrap:wrap;">
{% if ai_enabled %}
<label class="muted" style="display:inline-flex; align-items:center; gap:6px; font-size:.85rem;">
<input type="checkbox" name="semantic" value="1" {% if semantic %}checked{% endif %}
hx-get="/search" hx-target="#links" hx-swap="innerHTML"
hx-trigger="change" hx-include="#searchform" style="width:auto;">
KI-Suche (findet auch sinnverwandte Treffer)
</label>
{% else %}
<span></span>
{% endif %}
<label class="muted" style="display:inline-flex; align-items:center; gap:6px; font-size:.85rem;">
Sortierung:
<select name="sort"
hx-get="/search" hx-target="#links" hx-swap="innerHTML"
hx-trigger="change" hx-include="#searchform">
{% for value, label in sort_options.items() %}
<option value="{{ value }}" {% if sort == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</label>
</div>
</form>
</div>