{% extends "base.html" %} {% block title %}Redax-WP โ€” Studio{% endblock %} {% block content %}
{% if last_published %} Letzter Post: {{ last_published.wp_url[:50] if last_published.wp_url else last_published.title[:40] }} โ€” {{ last_published.published_at[:16] if last_published.published_at else '' }} {% endif %} {% if queue_count > 0 %} ๐Ÿ“ฅ {{ queue_count }} RSS-Artikel in Queue {% endif %}

โœ๏ธ Artikel-Studio

Vorschau erscheint beim Tippen...
๐Ÿ” SEO

๐Ÿ“… Redaktionsplan โ€” 7 Tage

{% set status_icons = {'draft':'๐Ÿ“','scheduled':'๐Ÿ—“๏ธ','published':'๐Ÿ“ค'} %} {% set type_icons = {'ki':'๐Ÿค–','rss':'๐Ÿ“ก'} %} {% for d in plan_days %} {% set arts = plan_articles.get(d, []) %} {% set is_today = (d == today) %}
{{ d[8:] }}.{{ d[5:7] }}. {% if is_today %}Heute{% endif %} {% if not arts %}โ€” leer{% endif %}
{% for art in arts %}
{{ type_icons.get(art.article_type, '๐Ÿ“') }} {{ art.post_time }}
{{ (art.title or 'Kein Titel')[:55] }}
{{ {'draft':'Entwurf','scheduled':'Geplant','published':'Live'}.get(art.status, art.status) }} {% if art.status != 'published' %}
{% endif %}
{% endfor %} {% endfor %}
{% endblock %} {% block extra_js %} let currentArticleId = null; function updatePreview() { const content = document.getElementById('article-content').value; const title = document.getElementById('article-title').value; const preview = document.getElementById('wp-preview'); preview.innerHTML = (title ? `

${title}

` : '') + content; } async function generateArticle() { const source = document.getElementById('source-input').value.trim(); const tone = document.getElementById('tone-select').value; if (!source) { showToast('โš ๏ธ Bitte Quelle eingeben'); return; } document.getElementById('gen-spinner').classList.remove('hidden'); const r = await fetch('/api/generate', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({source, tone}) }); document.getElementById('gen-spinner').classList.add('hidden'); const d = await r.json(); if (d.error) { showToast('โŒ ' + d.error); return; } document.getElementById('article-title').value = d.title || ''; document.getElementById('article-content').value = d.content || ''; document.getElementById('seo-title').value = d.seo_title || ''; document.getElementById('seo-description').value = d.seo_description || ''; document.getElementById('focus-keyword').value = d.focus_keyword || ''; updatePreview(); // og:image automatisch holen if (source.startsWith('http')) { fetchOgImage(source); } showToast('โœ… Artikel generiert'); } async function fetchOgImage(url) { try { const r = await fetch('/api/og-image', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({url}) }); const d = await r.json(); if (d.image) document.getElementById('featured-image').value = d.image; } catch(e) {} } function getArticleData() { return { id: currentArticleId, title: document.getElementById('article-title').value, content: document.getElementById('article-content').value, source_url: document.getElementById('source-input').value, tone: document.getElementById('tone-select').value, seo_title: document.getElementById('seo-title').value, seo_description: document.getElementById('seo-description').value, focus_keyword: document.getElementById('focus-keyword').value, featured_image_url: document.getElementById('featured-image').value, category_id: document.getElementById('category-select').value || null, article_type: 'ki', }; } async function saveDraft() { const r = await fetch('/api/article/save', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({...getArticleData(), status: 'draft'}) }); const d = await r.json(); if (d.success) { currentArticleId = d.id; showToast('๐Ÿ’พ Entwurf gespeichert'); } } async function publishNow() { if (!document.getElementById('article-title').value) { showToast('โš ๏ธ Titel fehlt'); return; } const r = await fetch('/api/article/schedule', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ ...getArticleData(), status: 'scheduled', post_date: new Date().toISOString().split('T')[0], post_time: new Date().toTimeString().slice(0,5), }) }); const d = await r.json(); if (d.success) { currentArticleId = d.id; showToast('๐Ÿš€ Wird sofort verรถffentlicht!'); setTimeout(() => location.reload(), 2000); } } function toggleSchedulePanel() { const p = document.getElementById('schedule-panel'); p.classList.toggle('hidden'); if (!p.classList.contains('hidden')) { const today = new Date().toISOString().split('T')[0]; document.getElementById('schedule-date').value = today; } } async function checkSlot() { const date = document.getElementById('schedule-date').value; const time = document.getElementById('schedule-time').value; if (!date || !time) return; const r = await fetch(`/api/slots/${date}`); const d = await r.json(); const statusEl = document.getElementById('slot-status'); statusEl.classList.remove('hidden'); if (d.taken && d.taken.includes(time)) { statusEl.className = 'text-xs mt-2 text-red-400'; statusEl.textContent = `โŒ Slot ${date} ${time} bereits belegt`; document.getElementById('schedule-confirm-btn').disabled = true; } else { statusEl.className = 'text-xs mt-2 text-green-400'; statusEl.textContent = `โœ… Slot ${date} ${time} ist frei`; document.getElementById('schedule-confirm-btn').disabled = false; } } async function confirmSchedule() { const post_date = document.getElementById('schedule-date').value; const post_time = document.getElementById('schedule-time').value; if (!post_date || !post_time) { showToast('โš ๏ธ Datum und Uhrzeit wรคhlen'); return; } if (!document.getElementById('article-title').value) { showToast('โš ๏ธ Titel fehlt'); return; } const r = await fetch('/api/article/schedule', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({...getArticleData(), post_date, post_time}) }); const d = await r.json(); if (d.success) { showToast(`๐Ÿ“… Eingeplant: ${post_date} ${post_time}`); setTimeout(() => location.reload(), 1500); } else { showToast('โŒ Fehler beim Einplanen'); } } async function loadArticle(id) { const r = await fetch(`/api/article/${id}`); const d = await r.json(); currentArticleId = id; document.getElementById('article-title').value = d.title || ''; document.getElementById('article-content').value = d.content || ''; document.getElementById('source-input').value = d.source_url || ''; document.getElementById('seo-title').value = d.seo_title || ''; document.getElementById('seo-description').value = d.seo_description || ''; document.getElementById('focus-keyword').value = d.focus_keyword || ''; document.getElementById('featured-image').value = d.featured_image_url || ''; if (d.category_id) document.getElementById('category-select').value = d.category_id; updatePreview(); window.scrollTo({top: 0, behavior: 'smooth'}); } // โ”€โ”€ Board: Umplanen โ”€โ”€ function openReschedule(id, date, time) { document.querySelectorAll('[id^="rs-panel-"]').forEach(el => el.classList.add('hidden')); document.getElementById(`rs-panel-${id}`).classList.remove('hidden'); } function closeReschedule(id) { document.getElementById(`rs-panel-${id}`).classList.add('hidden'); } async function confirmReschedule(id) { const date = document.getElementById(`rs-date-${id}`).value; const time = document.getElementById(`rs-time-${id}`).value; const r = await fetch(`/api/article/${id}/reschedule`, { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({post_date: date, post_time: time}) }); const d = await r.json(); if (d.success) { showToast(`โœ… Umgeplant: ${date} ${time}`); setTimeout(() => location.reload(), 1200); } else showToast('โŒ ' + (d.error || 'Fehler')); } async function deleteArticle(id) { if (!confirm('Artikel wirklich lรถschen?')) return; const r = await fetch(`/api/article/${id}/delete`, {method: 'POST'}); const d = await r.json(); if (d.success) { showToast('๐Ÿ—‘๏ธ Gelรถscht'); setTimeout(() => location.reload(), 1000); } } // Datum-Vorauswahl document.addEventListener('DOMContentLoaded', () => { const today = new Date().toISOString().split('T')[0]; document.getElementById('schedule-date').value = today; }); {% endblock %}