Files
linkvault/app/templates/index.html
Erik Thiele b6a236527e Add a "needs review" flag with a sidebar filter
Links can be bookmarked for a later look via a toggle button on the
card (🏷️/🔖), shown with a yellow border while flagged. A new
sidebar section "Merkliste" links to /?review=1, filtering to just
the flagged links; the count updates live via the existing facets
query.

Since the project has no migration framework, add a minimal
startup check that ALTER TABLEs in the needs_review column for
existing SQLite databases (create_all only creates missing tables).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 22:41:40 +02:00

119 lines
4.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}Meine Links · LinkVault{% endblock %}
{% block body %}
<header class="topbar">
<div class="brand">Link<span>Vault</span></div>
<div class="user-info">
{% if not ai_enabled %}
<span title="Kein OPENAI_API_KEY gesetzt Auto-Kategorisierung deaktiviert">
⚠️ KI aus
</span>
{% endif %}
<span>{{ user.email }}</span>
<form method="post" action="/logout" style="margin:0;">
<button class="ghost" type="submit">Abmelden</button>
</form>
</div>
</header>
<div class="layout">
<aside class="sidebar">
<div class="panel">
<a href="/?sort={{ sort }}" class="facet {% if not active_category and not active_manufacturer and not review_only %}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 }}&amp;sort={{ sort }}"
class="facet {% if active_category == name and not review_only %}active{% endif %}">
<span>{{ name }}</span><span class="count">{{ count }}</span>
</a>
{% else %}
<div class="muted" style="font-size:.85rem; padding:4px 8px;">noch keine</div>
{% endfor %}
</div>
<div class="facet-group">
<h3>Hersteller / Quellen</h3>
{% for name, count in facets.manufacturers %}
<a href="/?manufacturer={{ name | urlencode }}&amp;sort={{ sort }}"
class="facet {% if active_manufacturer == name and not review_only %}active{% endif %}">
<span>{{ name }}</span><span class="count">{{ count }}</span>
</a>
{% else %}
<div class="muted" style="font-size:.85rem; padding:4px 8px;">noch keine</div>
{% endfor %}
</div>
<div class="facet-group">
<h3>Merkliste</h3>
<a href="/?review=1&amp;sort={{ sort }}" class="facet {% if review_only %}active{% endif %}">
<span>🔖 Zur Durchsicht</span><span class="count">{{ facets.review_count }}</span>
</a>
</div>
</div>
</aside>
<main class="main">
<div class="panel">
<form hx-post="/links" hx-target="#links" hx-swap="afterbegin"
hx-disabled-elt="button"
hx-on::after-request="if(event.detail.successful){this.reset(); var e=document.getElementById('empty-state'); if(e) e.remove();}">
<div style="display:flex; gap:8px; flex-wrap:wrap;">
<input type="url" name="url" placeholder="Link einfügen, z.B. https://hersteller.de/produkt" required
style="flex:1 1 220px; width:auto;">
<button type="submit" style="white-space:nowrap;">
<span class="htmx-indicator"></span> Hinzufügen
</button>
</div>
<div class="muted" style="font-size:.8rem; margin-top:6px;">
Der Link wird automatisch geladen, zusammengefasst und einsortiert.
</div>
</form>
</div>
<div class="panel">
<form id="searchform" onsubmit="return false;" style="margin:0;">
<input type="hidden" name="category" value="{{ active_category }}">
<input type="hidden" name="manufacturer" value="{{ active_manufacturer }}">
<input type="hidden" name="review" value="{{ '1' if review_only else '' }}">
<input type="text" name="q" value="{{ q }}"
placeholder="🔍 Suche in Titel, Zusammenfassung, Tags..."
hx-get="/search" hx-target="#links" hx-swap="innerHTML"
hx-trigger="keyup changed delay:400ms, search"
hx-include="#searchform">
<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>
<div id="links">
{% include "_links_list.html" %}
</div>
</main>
</div>
{% endblock %}