Infrastruktur: - CT 113 auf pve-hetzner erstellt (Docker, Tailscale) - Forgejo-Repo redax-wp angelegt Code (Sprint 2): - docker-compose.yml: wordpress + db + redax-web - .env.example mit allen Variablen - database.py: articles, feeds, feed_items, prompts, settings - wordpress.py: WP REST API Client (create/update post, media upload, Yoast SEO) - rss_fetcher.py: Feed-Import, Blacklist, Teaser-Modus, KI-Rewrite - app.py: Flask Dashboard, Scheduler (publish/rss/briefing), alle API-Routen - templates: base, login, index (Zwei-Spalten-Editor), feeds, history, prompts, settings, hilfe - README.md + .gitignore Made-with: Cursor
78 lines
3.5 KiB
HTML
78 lines
3.5 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Redax-WP — Prompts{% endblock %}
|
|
{% block content %}
|
|
<div class="max-w-4xl mx-auto px-6 py-6">
|
|
<div class="flex items-center justify-between mb-6">
|
|
<h1 class="text-xl font-bold text-white">🧠 Prompt-Bibliothek</h1>
|
|
<button onclick="newPrompt()" class="btn btn-primary text-sm">+ Neuer Prompt</button>
|
|
</div>
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
|
<div class="space-y-3">
|
|
{% for p in prompts %}
|
|
<div class="card p-4 cursor-pointer hover:border-blue-500 transition {% if p.is_default %}border-green-700{% endif %}"
|
|
onclick="loadPrompt({{ p.id }}, {{ p.system_prompt|tojson }}, {{ p.name|tojson }}, {{ p.is_default }})">
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-sm font-semibold text-white">{{ p.name }}</span>
|
|
{% if p.is_default %}<span class="text-xs bg-green-900 text-green-300 px-2 py-0.5 rounded-full">Standard</span>{% endif %}
|
|
</div>
|
|
{% if not p.is_default %}
|
|
<button onclick="event.stopPropagation(); deletePrompt({{ p.id }})"
|
|
class="text-slate-600 hover:text-red-400 text-xs px-1">🗑</button>
|
|
{% endif %}
|
|
</div>
|
|
<div class="text-xs text-slate-500 mt-1 truncate">{{ p.system_prompt[:80] }}...</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
<div class="card p-5">
|
|
<input type="hidden" id="prompt-id">
|
|
<div class="mb-3">
|
|
<label class="text-xs text-slate-400 block mb-1">Name</label>
|
|
<input type="text" id="prompt-name" class="w-full" placeholder="Prompt-Name">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="text-xs text-slate-400 block mb-1">
|
|
System-Prompt
|
|
<span class="text-slate-600 ml-2">Variablen: {source} {date} {tone}</span>
|
|
</label>
|
|
<textarea id="prompt-text" rows="12" class="w-full text-sm"></textarea>
|
|
</div>
|
|
<div class="flex gap-2 flex-wrap">
|
|
<button onclick="savePrompt()" class="btn btn-primary text-sm">💾 Speichern</button>
|
|
<button onclick="setDefault()" class="btn btn-success text-sm">⭐ Standard</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
{% block extra_js %}
|
|
function loadPrompt(id, text, name, is_default) {
|
|
document.getElementById('prompt-id').value = id;
|
|
document.getElementById('prompt-name').value = name;
|
|
document.getElementById('prompt-text').value = text;
|
|
}
|
|
function newPrompt() {
|
|
document.getElementById('prompt-id').value = '';
|
|
document.getElementById('prompt-name').value = '';
|
|
document.getElementById('prompt-text').value = '';
|
|
}
|
|
async function savePrompt() {
|
|
const r = await fetch('/api/prompts/save', {method:'POST',headers:{'Content-Type':'application/json'},
|
|
body: JSON.stringify({id: document.getElementById('prompt-id').value || null,
|
|
name: document.getElementById('prompt-name').value,
|
|
system_prompt: document.getElementById('prompt-text').value})});
|
|
if ((await r.json()).success) { showToast('💾 Gespeichert'); location.reload(); }
|
|
}
|
|
async function setDefault() {
|
|
const id = document.getElementById('prompt-id').value;
|
|
if (!id) { showToast('⚠️ Prompt zuerst speichern'); return; }
|
|
await fetch(`/api/prompts/${id}/default`, {method:'POST'});
|
|
showToast('⭐ Als Standard gesetzt'); location.reload();
|
|
}
|
|
async function deletePrompt(id) {
|
|
if (!confirm('Prompt löschen?')) return;
|
|
await fetch(`/api/prompts/${id}/delete`, {method:'POST'});
|
|
location.reload();
|
|
}
|
|
{% endblock %}
|