small performance and security changes

This commit is contained in:
2026-02-19 18:18:15 +01:00
parent 2885a23544
commit 91d9fa3a21
5 changed files with 244 additions and 9 deletions

View File

@@ -0,0 +1,118 @@
{% extends "base.html" %}
{% block title %}Post-Archiv - LinkedIn Posts{% endblock %}
{% block content %}
<div class="mb-6 flex items-center justify-between">
<div>
<div class="flex items-center gap-3 mb-1">
<a href="/posts" class="text-gray-400 hover:text-white transition-colors flex items-center gap-1 text-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/></svg>
Zurück
</a>
<h1 class="text-2xl font-bold text-white">Post-Archiv</h1>
</div>
<p class="text-gray-400 text-sm">Veröffentlichte, geplante und abgelehnte Posts ({{ total }} gesamt)</p>
</div>
<a href="/create" class="px-4 py-2.5 btn-primary rounded-lg font-medium flex items-center gap-2">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/></svg>
Neuer Post
</a>
</div>
{% if error %}
<div class="bg-red-900/50 border border-red-500 text-red-200 px-4 py-3 rounded-lg mb-6">
<strong>Error:</strong> {{ error }}
</div>
{% endif %}
{% if not posts and not error %}
<div class="card-bg rounded-xl border p-12 text-center">
<div class="w-20 h-20 bg-brand-bg rounded-2xl flex items-center justify-center mx-auto mb-6">
<svg class="w-10 h-10 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8l1 12a2 2 0 002 2h8a2 2 0 002-2L19 8M10 12v4M14 12v4"/></svg>
</div>
<h3 class="text-xl font-semibold text-white mb-2">Kein Archiv vorhanden</h3>
<p class="text-gray-400 mb-6 max-w-md mx-auto">Noch keine veröffentlichten oder abgelehnten Posts.</p>
<a href="/posts" class="inline-flex items-center gap-2 px-6 py-3 btn-primary font-medium rounded-lg transition-colors">
Zurück zu den Posts
</a>
</div>
{% else %}
<div class="space-y-3">
{% for post in posts %}
<a href="/posts/{{ post.id }}" class="block card-bg rounded-xl border hover:border-gray-500 transition-colors p-4">
<div class="flex items-start justify-between gap-4">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
{% if post.status == 'published' %}
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-green-900/50 text-green-300 border border-green-800">
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
Veröffentlicht
</span>
{% elif post.status == 'scheduled' %}
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-blue-900/50 text-blue-300 border border-blue-800">
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
Geplant
</span>
{% elif post.status == 'rejected' %}
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-red-900/50 text-red-300 border border-red-800">
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
Abgelehnt
</span>
{% endif %}
<h4 class="font-medium text-white truncate">{{ post.topic_title or 'Untitled' }}</h4>
</div>
{% if post.post_content %}
<p class="text-gray-400 text-sm line-clamp-2">{{ post.post_content[:200] }}{% if post.post_content | length > 200 %}...{% endif %}</p>
{% endif %}
</div>
<div class="flex-shrink-0 text-right text-xs text-gray-500 space-y-1">
{% if post.status == 'published' and post.published_at %}
<div>veröffentlicht {{ post.published_at.strftime('%d.%m.%Y') }}</div>
{% elif post.status == 'scheduled' and post.scheduled_at %}
<div>geplant für {{ post.scheduled_at.strftime('%d.%m.%Y %H:%M') }}</div>
{% else %}
<div>erstellt {{ post.created_at.strftime('%d.%m.%Y') if post.created_at else 'N/A' }}</div>
{% endif %}
{% if post.critic_feedback and post.critic_feedback | length > 0 and post.critic_feedback[-1].get('overall_score') is not none %}
{% set score = post.critic_feedback[-1].get('overall_score', 0) %}
<div class="inline-flex items-center px-1.5 py-0.5 rounded-full text-xs font-semibold
{{ 'bg-green-900/50 text-green-300' if score >= 85 else 'bg-yellow-900/50 text-yellow-300' if score >= 70 else 'bg-red-900/50 text-red-300' }}">
{{ score }}
</div>
{% endif %}
</div>
</div>
</a>
{% endfor %}
</div>
{% if total_pages > 1 %}
<div class="flex items-center justify-center gap-2 mt-8">
{% if current_page > 1 %}
<a href="/posts/archive?page={{ current_page - 1 }}" class="px-3 py-2 rounded-lg border border-gray-600 text-gray-300 hover:text-white hover:border-gray-400 transition-colors text-sm">
&larr; Zurück
</a>
{% endif %}
{% for p in range(1, total_pages + 1) %}
{% if p == current_page %}
<span class="px-3 py-2 rounded-lg bg-brand-bg text-white text-sm font-medium border border-yellow-500">{{ p }}</span>
{% elif p <= 2 or p >= total_pages - 1 or (p >= current_page - 2 and p <= current_page + 2) %}
<a href="/posts/archive?page={{ p }}" class="px-3 py-2 rounded-lg border border-gray-600 text-gray-300 hover:text-white hover:border-gray-400 transition-colors text-sm">{{ p }}</a>
{% elif p == 3 or p == total_pages - 2 %}
<span class="text-gray-500 px-1"></span>
{% endif %}
{% endfor %}
{% if current_page < total_pages %}
<a href="/posts/archive?page={{ current_page + 1 }}" class="px-3 py-2 rounded-lg border border-gray-600 text-gray-300 hover:text-white hover:border-gray-400 transition-colors text-sm">
Weiter &rarr;
</a>
{% endif %}
</div>
<p class="text-center text-xs text-gray-500 mt-2">Seite {{ current_page }} von {{ total_pages }} ({{ total }} Posts)</p>
{% endif %}
{% endif %}
{% endblock %}