/* BAN YARO — Social Media Manager (Luna-Coach) */ window.Page_social = (() => { let _el, _state, _breeds = [], _activeTab = 'idee', _stats = null; const _SL = { idea:'Idee', draft:'Entwurf', scheduled:'Geplant', published:'Veröffentlicht', archived:'Archiviert' }; const _SC = { idea:'var(--c-text-muted)', draft:'var(--c-warning)', scheduled:'var(--c-primary)', published:'var(--c-success)', archived:'var(--c-text-muted)' }; const _FL = { reel:'🎬 Reel', story:'⭕ Story', post:'🖼 Post', carousel:'🎠 Carousel' }; const _PL = { tiktok:'🎵 TikTok', instagram:'📸 Instagram', both:'🌐 Beide' }; // Luna-Wartebotschaften (alle 10s rotierend) const _LUNA_MSGS = [ ['🌙','Ich überlege…'], ['🤔','Einen Moment noch…'], ['💡','Mir ist da was eingefallen…'], ['✍️','Ich arbeite das aus…'], ['⏳','Kleinen Moment noch…'], ['✨','Gleich hab ich es…'], ['🎯','Ich feile noch etwas dran…'], ['🐾','Fast fertig für dich…'], ]; let _diversity = null, _unusedBreeds = []; async function init(el, state) { _el = el; _state = state; [_breeds, _stats, _diversity, _unusedBreeds] = await Promise.all([ API.get('/social/breeds').catch(() => []), API.get('/social/stats').catch(() => null), API.get('/social/diversity').catch(() => null), API.get('/social/unused-breeds?limit=6').catch(() => []), ]); _render(); } function refresh() { if (_el) init(_el, _state); } // --------------------------------------------------------------- // HAUPT-RENDER // --------------------------------------------------------------- function _render() { const lvlBar = _stats ? _levelBar(_stats) : ''; _el.innerHTML = `
📱
Social Media
Luna ist dein KI-Coach
${_stats ? `
${_stats.level}
${_stats.xp} XP
` : ''}
${lvlBar}
${[['idee','✨ Ideen'],['archiv','📂 Archiv'],['bewerten','🔍 Prüfen']].map(([t,l]) => ` `).join('')}
`; _el.querySelectorAll('.sm-tab').forEach(b => b.addEventListener('click', () => { _activeTab = b.dataset.tab; _render(); })); const c = _el.querySelector('#sm-content'); if (_activeTab === 'idee') _renderIdee(c); if (_activeTab === 'archiv') _renderArchiv(c); if (_activeTab === 'bewerten') _renderBewerten(c); } function _levelBar(s) { if (!s.xp_next) return ''; const pct = Math.min(100, Math.round( ((s.xp - s.xp_current_min) / (s.xp_next - s.xp_current_min)) * 100)); return `
${s.level} ${s.next_level ? `${s.xp_next - s.xp} XP bis ${s.next_level}` : ''}
`; } // --------------------------------------------------------------- // IDEEN-TAB // --------------------------------------------------------------- function _renderIdee(el) { let selPlatform = 'both', selFormat = 'post', uploadedMediaUrl = null; el.innerHTML = `
🌙
Hey, ich bin Luna 👋
Ich schlage dir Ideen vor und erkläre warum sie funktionieren. Lern Social Media richtig — nicht nur kopieren!
${_diversity?.warning ? `
⚠️
Luna bemerkt eine Wiederholung!
${_diversity.warning.pct}% deiner letzten Posts waren ${_diversity.warning.dominant_de}-Content. Versuch mal was anderes, damit dein Feed abwechslungsreicher wird!
${_diversity.warning.suggestions_de.length ? `
💡 Probier mal: ${_diversity.warning.suggestions_de.join(', ')}
` : ''}
` : ''}
💡 Was könntest du heute posten?
${_lunaThinking('Klein...')}
✏️ Oder eigenes Thema
Plattform
${['both','instagram','tiktok'].map((p,i) => ` `).join('')}
Format
${['post','reel','story','carousel'].map((f,i) => ` `).join('')}
Thema
Foto / Video (optional)
Rasse (optional)
${_unusedBreeds.length ? `
🌙 Noch nicht gezeigt:
${_unusedBreeds.map(b => ``).join('')}
` : ''} ${_breeds.map(b => `
Schnell generieren
`; // Platform toggle el.querySelectorAll('.sm-plat').forEach(b => b.addEventListener('click', () => { selPlatform = b.dataset.p; el.querySelectorAll('.sm-plat').forEach(x => x.className = `btn btn-sm sm-plat ${x===b?'btn-primary':'btn-secondary'}`); })); el.querySelectorAll('.sm-fmt').forEach(b => b.addEventListener('click', () => { selFormat = b.dataset.f; el.querySelectorAll('.sm-fmt').forEach(x => x.className = `btn btn-sm sm-fmt ${x===b?'btn-primary':'btn-secondary'}`); })); // Breed-Chips el.querySelectorAll('.sm-breed-chip').forEach(chip => { chip.addEventListener('click', () => { const search = el.querySelector('#sm-breed-search'); const hiddenId = el.querySelector('#sm-breed-id'); if (search) search.value = chip.dataset.name; if (hiddenId) hiddenId.value = chip.dataset.id; el.querySelectorAll('.sm-breed-chip').forEach(c => c.style.background = c === chip ? 'var(--c-primary)' : 'var(--c-surface-2)'); el.querySelectorAll('.sm-breed-chip').forEach(c => c.style.color = c === chip ? '#fff' : 'var(--c-text)'); }); }); // Datalist-Autocomplete → breed-id setzen el.querySelector('#sm-breed-search')?.addEventListener('input', e => { const val = e.target.value.trim().toLowerCase(); const match = _breeds.find(b => b.name.toLowerCase() === val); const hiddenId = el.querySelector('#sm-breed-id'); if (hiddenId) hiddenId.value = match ? match.id : ''; }); // Media upload function handleMedia(file) { if (!file) return; const preview = el.querySelector('#sm-media-preview'); const reader = new FileReader(); reader.onload = e => { preview.style.display = ''; if (file.type.startsWith('video/')) { preview.innerHTML = ``; } else { preview.innerHTML = ``; } // Upload const fd = new FormData(); fd.append('file', file); fetch('/api/social/media', { method: 'POST', headers: {Authorization: `Bearer ${localStorage.getItem('by_token')}`}, body: fd, }).then(r => r.json()).then(d => { uploadedMediaUrl = d.url; }); }; reader.readAsDataURL(file); } el.querySelector('#sm-media-file').addEventListener('change', e => handleMedia(e.target.files[0])); el.querySelector('#sm-media-file2').addEventListener('change', e => handleMedia(e.target.files[0])); // Vorschläge laden async function loadSuggestions() { const box = el.querySelector('#sm-suggestions'); box.innerHTML = `
🌙
Luna: Ich überlege…
`; let mi = 0; const sgInt = setInterval(() => { mi = (mi + 1) % _LUNA_MSGS.length; const [e, t] = _LUNA_MSGS[mi]; const te = box.querySelector('#sg-text'); const ee = box.querySelector('#sg-emoji'); if (te) te.textContent = 'Luna: ' + t; if (ee) ee.textContent = e; }, 10000); try { const ideas = await API.get('/social/suggestions'); clearInterval(sgInt); if (!ideas?.length) { box.innerHTML = '
Keine Ideen erhalten.
'; return; } box.innerHTML = ideas.map((idea, i) => `
${idea.emoji||'💡'}
${_esc(idea.thema)}
🎓 ${_esc(idea.warum)}
${_FL[idea.format]||idea.format} ${_PL[idea.platform]||idea.platform}
`).join(''); box.querySelectorAll('.sm-use').forEach(btn => { btn.addEventListener('click', e => { e.stopPropagation(); el.querySelector('#sm-topic').value = btn.dataset.thema; const fb = el.querySelector(`.sm-fmt[data-f="${btn.dataset.format}"]`); if (fb) fb.click(); const pb = el.querySelector(`.sm-plat[data-p="${btn.dataset.platform}"]`); if (pb) pb.click(); // Banner + Scroll zu "Los geht's!" const hint = el.querySelector('#sm-next-hint'); if (hint) hint.style.display = ''; const genBtn = el.querySelector('#sm-gen'); if (genBtn) { setTimeout(() => { genBtn.scrollIntoView({behavior:'smooth', block:'center'}); genBtn.style.transform = 'scale(1.04)'; setTimeout(() => genBtn.style.transform = '', 600); }, 200); } }); }); box.querySelectorAll('.sm-idea').forEach(card => { card.addEventListener('mouseenter', () => card.style.borderColor = 'var(--c-primary)'); card.addEventListener('mouseleave', () => card.style.borderColor = 'transparent'); }); } catch { clearInterval(sgInt); box.innerHTML = '
Ideen konnten nicht geladen werden.
'; } } el.querySelector('#sm-refresh').addEventListener('click', loadSuggestions); loadSuggestions(); // Übungs-Übersicht el.querySelector('#sm-show-exercises').addEventListener('click', async () => { const exercises = await API.get('/social/exercises').catch(() => []); const cats = [...new Set(exercises.map(e => e.kategorie))]; const modal = document.createElement('div'); modal.style.cssText = `position:fixed;inset:0;background:rgba(0,0,0,.75); z-index:9999;overflow-y:auto;padding:16px`; modal.innerHTML = `
🎾 ${exercises.length} Übungen
${cats.map(cat => `
${cat}
${exercises.filter(e=>e.kategorie===cat).map(e => `
${_esc(e.name)}
${_esc(e.schwierigkeit||'')} · ${_esc(e.alter_ab||'')} · ${_esc(e.dauer||'')}
${e.posts_count > 0 ? `✓ ${e.posts_count}x` : ''}
`).join('')}
`).join('')}
`; document.body.appendChild(modal); ['sm-ex-close','sm-ex-close2'].forEach(id => modal.querySelector(`#${id}`)?.addEventListener('click', () => modal.remove())); modal.addEventListener('click', e => { if(e.target===modal) modal.remove(); }); modal.querySelectorAll('.sm-ex-use').forEach(btn => { btn.addEventListener('click', () => { // Trainingstipp für diese spezifische Übung generieren modal.remove(); const res = el.querySelector('#sm-gen-result'); const trainBtn = el.querySelector('#sm-training-tip'); // Direkt generieren mit exercise filter via topic-Feld el.querySelector('#sm-topic').value = btn.dataset.name; trainBtn.scrollIntoView({behavior:'smooth', block:'center'}); const hint = el.querySelector('#sm-next-hint'); if (hint) { hint.style.display=''; hint.querySelector('strong').textContent = 'Trainingstipp generieren! 🎾'; } }); }); }); // Trainingstipp el.querySelector('#sm-training-tip').addEventListener('click', async () => { const btn = el.querySelector('#sm-training-tip'); const res = el.querySelector('#sm-gen-result'); btn.disabled = true; res.innerHTML = _lunaProgressHtml(); const interval = _startProgress(res); try { const data = await API.post('/social/training-tip', {}); clearInterval(interval.bar); clearInterval(interval.msg); _progressDone(res); await new Promise(r => setTimeout(r, 400)); const stilLabel = {tutorial:'📹 Tutorial', community:'🙋 Community', aspirational:'💪 Aspirational'}[data.stil] || ''; res.innerHTML = `
🎾
Trainingstipp · ${_esc(data.exercise_kat||'')} · ${stilLabel}
${_esc(data.exercise_name||'')}
${_renderResult(data, null)}`; _bindResultEvents(res); Promise.all([API.get('/social/stats'), API.get('/social/diversity')]) .then(([s,d]) => { _stats = s; _diversity = d; }); } catch(e) { clearInterval(interval.bar); clearInterval(interval.msg); res.innerHTML = `
😬 ${_esc(e.message||String(e))}
`; } finally { btn.disabled = false; } }); // Pflegetipp el.querySelector('#sm-pflege-tip').addEventListener('click', async () => { const btn = el.querySelector('#sm-pflege-tip'); const res = el.querySelector('#sm-gen-result'); btn.disabled = true; res.innerHTML = _lunaProgressHtml(); const interval = _startProgress(res); const breedId = parseInt(el.querySelector('#sm-breed-id')?.value) || null; try { const url = breedId ? `/social/pflege-tipp?breed_id=${breedId}` : '/social/pflege-tipp'; const data = await API.post(url, {}); clearInterval(interval.bar); clearInterval(interval.msg); _progressDone(res); await new Promise(r => setTimeout(r, 400)); res.innerHTML = `
🛁
Pflegetipp · ${_esc(data.pflege_kat||'')} ${data.rasse_name ? ` · speziell für ${_esc(data.rasse_name)}` : ''}
${_esc(data.pflege_titel||'')}
${_renderResult(data, null)}`; _bindResultEvents(res); Promise.all([API.get('/social/stats'), API.get('/social/diversity')]) .then(([s,d]) => { _stats = s; _diversity = d; }); } catch(e) { clearInterval(interval.bar); clearInterval(interval.msg); res.innerHTML = `
😬 ${_esc(e.message||String(e))}
`; } finally { btn.disabled = false; } }); // Rasse des Tages el.querySelector('#sm-breed-day').addEventListener('click', async () => { const btn = el.querySelector('#sm-breed-day'); const res = el.querySelector('#sm-gen-result'); btn.disabled = true; res.innerHTML = _lunaProgressHtml(); const interval = _startProgress(res); try { const data = await API.post('/social/breed-of-day', {}); clearInterval(interval.bar); clearInterval(interval.msg); _progressDone(res); await new Promise(r => setTimeout(r, 400)); // Foto anzeigen wenn vorhanden const mediaUrl = data.breed_foto || data.media_url || null; res.innerHTML = `
${mediaUrl ? `` : '🐶'}
Rasse des Tages
${_esc(data.topic?.replace('Rasse des Tages: ',''))}
${_renderResult(data, mediaUrl)}`; _bindResultEvents(res); // unused breeds neu laden API.get('/social/unused-breeds?limit=6').then(r => { _unusedBreeds = r; }); Promise.all([API.get('/social/stats'), API.get('/social/diversity')]) .then(([s,d]) => { _stats = s; _diversity = d; }); } catch(e) { clearInterval(interval.bar); clearInterval(interval.msg); res.innerHTML = `
😬 ${_esc(e.message||String(e))}
`; } finally { btn.disabled = false; } }); // Generieren el.querySelector('#sm-gen').addEventListener('click', async () => { const topic = el.querySelector('#sm-topic').value.trim(); if (!topic) { UI.toast('Gib ein Thema ein 🐾', 'warning'); return; } const btn = el.querySelector('#sm-gen'); const res = el.querySelector('#sm-gen-result'); btn.disabled = true; // Luna-Progress starten res.innerHTML = _lunaProgressHtml(); const interval = _startProgress(res); try { const data = await API.post('/social/generate', { platform: selPlatform, format: selFormat, topic, breed_id: parseInt(el.querySelector('#sm-breed-id')?.value) || null, }); clearInterval(interval.bar); clearInterval(interval.msg); _progressDone(res); await new Promise(r => setTimeout(r, 400)); res.innerHTML = _renderResult(data, uploadedMediaUrl); _bindResultEvents(res); el.querySelector('#sm-topic').value = ''; const hint = el.querySelector('#sm-next-hint'); if (hint) hint.style.display = 'none'; uploadedMediaUrl = null; el.querySelector('#sm-media-preview').style.display = 'none'; // Stats + Diversity aktualisieren Promise.all([ API.get('/social/stats'), API.get('/social/diversity'), ]).then(([s, d]) => { _stats = s; _diversity = d; _updateLevelDisplay(); }); } catch(e) { clearInterval(interval); res.innerHTML = `
😬 Ups: ${_esc(e.message||String(e))}
`; } finally { btn.disabled = false; btn.innerHTML = '✨ Los geht\'s!'; } }); } // --------------------------------------------------------------- // LUNA PROGRESS ANIMATION // --------------------------------------------------------------- function _lunaThinking(msg = 'Denkt nach…') { return `
🌙
${msg}
`; } function _lunaProgressHtml() { return `
🌙
Luna liest dein Thema…
0%
`; } function _startProgress(container) { let elapsed = 0, msgIdx = 0; const totalMs = 2800; // Fortschrittsbalken: alle 250ms const barInterval = setInterval(() => { elapsed += 250; const pct = Math.min(93, Math.round((elapsed / totalMs) * 100)); const bar = container.querySelector('#lp-bar'); const pctEl = container.querySelector('#lp-pct'); if (bar) bar.style.width = pct + '%'; if (pctEl) pctEl.textContent = pct + '%'; }, 250); // Text: alle 10s rotieren const [e0, t0] = _LUNA_MSGS[0]; const txt = container.querySelector('#lp-text'); const emoji = container.querySelector('#lp-emoji'); if (txt) txt.textContent = 'Luna: ' + t0; if (emoji) emoji.textContent = e0; const msgInterval = setInterval(() => { msgIdx = (msgIdx + 1) % _LUNA_MSGS.length; const [e, t] = _LUNA_MSGS[msgIdx]; const txt2 = container.querySelector('#lp-text'); const emoji2 = container.querySelector('#lp-emoji'); if (txt2) txt2.textContent = 'Luna: ' + t; if (emoji2) emoji2.textContent = e; }, 10000); // Beide Intervalle zurückgeben return { bar: barInterval, msg: msgInterval }; } function _progressDone(container) { const bar = container.querySelector('#lp-bar'); const txt = container.querySelector('#lp-text'); const emoji = container.querySelector('#lp-emoji'); const pctEl = container.querySelector('#lp-pct'); if (bar) bar.style.width = '100%'; if (pctEl) pctEl.textContent = '100%'; if (txt) txt.textContent = '🎉 Fertig!'; if (emoji) emoji.textContent = '✨'; } // --------------------------------------------------------------- // RESULT RENDER // --------------------------------------------------------------- function _renderResult(data, mediaUrl) { const score = data.ai_score ? '⭐'.repeat(Math.min(data.ai_score,5)) : ''; const unsplash = data.unsplash_query ? `https://unsplash.com/s/photos/${encodeURIComponent(data.unsplash_query)}` : null; return ` ${data.coaching ? `
🌙
Luna sagt:
${_esc(data.coaching)}
` : ''}
✓ Gespeichert ${score ? `${score}` : ''}
${mediaUrl ? `
📎 Dein Medien-Upload
` : ''} ${_resultBlock('📝 Caption', data.caption, true)} ${data.hashtags ? `
🏷 Hashtags
${data.hashtags.split(',').map(h=>`#${h.trim()}`).join(' ')}
${_copyBtn(data.hashtags.split(',').map(h=>`#${h.trim()}`).join(' '))}
` : ''} ${(data.hook||data.cta) ? `
${data.hook ? `
🎣 Hook
"${_esc(data.hook)}"
` : ''} ${data.cta ? `
📣 Call-to-Action
${_esc(data.cta)}
` : ''}
` : ''} ${_resultBlock('📸 Was du filmen/fotografieren solltest', data.visual_brief, false)} ${data.script ? `
🎬 Video-Aufbau
${_esc(data.script)}
` : ''} ${(data.image_prompt||data.canva_notes||unsplash) ? `
🛠 Wenn du kein eigenes Bild hast
${data.image_prompt ? `
DALL-E / Midjourney:
${_esc(data.image_prompt)}
${_copyBtn(data.image_prompt)}` : ''} ${data.canva_notes ? `
Canva:
${_esc(data.canva_notes)}
` : ''} ${unsplash ? ` 🔍 Kostenlose Fotos auf Unsplash →` : ''}
` : ''}`; } function _resultBlock(label, text, copyable) { if (!text) return ''; return `
${label}
${_esc(text)}
${copyable ? _copyBtn(text) : ''}
`; } function _copyBtn(text) { return ``; } function _bindResultEvents(el) { el.querySelectorAll('.sm-copy').forEach(btn => { btn.addEventListener('click', () => { const text = btn.getAttribute('data-copy') .replace(/&/g,'&').replace(/</g,'<') .replace(/>/g,'>').replace(/"/g,'"'); navigator.clipboard?.writeText(text).then(() => { btn.textContent = '✓ Kopiert!'; setTimeout(() => btn.textContent = '📋 Kopieren', 2000); }); }); }); el.querySelectorAll('.sm-preview-btn').forEach(btn => { btn.addEventListener('click', async () => { const id = parseInt(btn.dataset.id); const contents = await API.get('/social/content').catch(() => []); const item = contents.find(c => c.id === id); if (item) _showPreview(item); }); }); // "Habe ich gepostet!" — Formular einblenden el.querySelectorAll('.sm-posted-btn').forEach(btn => { btn.addEventListener('click', () => { const form = el.querySelector(`#sm-posted-form-${btn.dataset.id}`); if (form) { form.style.display = form.style.display === 'none' ? '' : 'none'; // Heute als Default-Datum const dateInput = form.querySelector('.sm-post-date'); if (dateInput && !dateInput.value) { dateInput.value = new Date().toISOString().slice(0,10); } } }); }); // Bestätigen el.querySelectorAll('.sm-confirm-posted').forEach(btn => { btn.addEventListener('click', async () => { const id = parseInt(btn.dataset.id); const form = el.querySelector(`#sm-posted-form-${id}`); const date = form?.querySelector('.sm-post-date')?.value || new Date().toISOString().slice(0,16); const url = form?.querySelector('.sm-post-url')?.value || null; btn.disabled = true; btn.textContent = '…'; await API.patch(`/social/content/${id}`, { status: 'published', published_at: date, post_url: url || undefined, }); // Form durch Bestätigung ersetzen if (form) form.innerHTML = `
🎉 Super! Post als veröffentlicht markiert. ${url ? `
Post ansehen →` : ''}
`; // Stats aktualisieren API.get('/social/stats').then(s => { _stats = s; }); }); }); } // --------------------------------------------------------------- // POST-VORSCHAU // --------------------------------------------------------------- function _showPreview(item) { const modal = document.createElement('div'); modal.style.cssText = `position:fixed;inset:0;background:rgba(0,0,0,.7); z-index:9999;display:flex;align-items:center;justify-content:center;padding:16px; overflow-y:auto`; const isReel = item.format === 'reel'; const w = isReel ? '220px' : '280px'; const h = isReel ? '390px' : '300px'; modal.innerHTML = `
${item.platform==='tiktok'?'🎵 TikTok':'📸 Instagram'} Vorschau
🐾
banyaro.app
Jetzt
···
🐶
🤍💬↗️ 🔖
banyaro.app
${_esc((item.caption||'').substring(0,150))}${(item.caption||'').length>150?'…':''}
${item.hashtags ? `
${item.hashtags.split(',').slice(0,5).map(h=>`#${h.trim()}`).join(' ')}
` : ''}
`; document.body.appendChild(modal); ['sm-close-preview','sm-close-preview2'].forEach(id => { modal.querySelector(`#${id}`)?.addEventListener('click', () => modal.remove()); }); modal.addEventListener('click', e => { if (e.target===modal) modal.remove(); }); } function _updateLevelDisplay() { if (!_stats || !_el) return; const lvlEl = _el.querySelector('[data-level]'); if (lvlEl) lvlEl.textContent = _stats.level; } // --------------------------------------------------------------- // ARCHIV // --------------------------------------------------------------- async function _renderArchiv(el) { el.innerHTML = _lunaThinking('Lädt…'); let filter = 'alle'; const fLabel = {alle:'Alle',idea:'Ideen',draft:'Entwürfe', scheduled:'Geplant',published:'Veröffentlicht',archived:'Archiviert'}; async function load(f) { filter = f; const url = f==='alle' ? '/social/content' : `/social/content?status=${f}`; const [items, allItems] = await Promise.all([ API.get(url).catch(() => []), f !== 'alle' ? API.get('/social/content').catch(() => []) : Promise.resolve(null), ]); const pending = (allItems || items).filter(c => c.status === 'idea' || c.status === 'draft').length; render(items, pending); } function render(items, pending) { el.innerHTML = ` ${pending > 0 ? `
${pending} Post${pending>1?'s':''} warten auf Bestätigung
Tippe auf 📤 wenn du einen Post abgesetzt hast — so lernt Luna was wirklich live ging.
` : ''}
${['alle','idea','draft','scheduled','published','archived'].map(s => ` `).join('')}
${!items.length ? UI.emptyState({icon:'camera',title:'Noch nichts hier', text:'Geh zu "✨ Ideen" und erstelle deinen ersten Post!'}) : items.map(c => `
${_SL[c.status]||c.status} ${c.created_at?.slice(0,10)||''} ${c.ai_score ? `${'⭐'.repeat(c.ai_score)}` : ''}
${_esc(c.topic)}
${c.hook ? `
🎣 ${_esc(c.hook)}
` : ''}
${c.status !== 'published' ? ` ` : `
`}
`).join('')}`; el.querySelectorAll('[data-f]').forEach(b => b.addEventListener('click', () => load(b.dataset.f))); el.querySelectorAll('.sm-quick-post').forEach(b => b.addEventListener('click', async () => { const url = prompt('Post-URL (optional, leer lassen wenn keine):', '') ?? null; await API.patch(`/social/content/${b.dataset.id}`, { status: 'published', published_at: new Date().toISOString().slice(0,16), post_url: url || undefined, }); load(filter); })); el.querySelectorAll('.sm-exp').forEach(b => b.addEventListener('click', () => { const d = el.querySelector(`#sm-d-${b.dataset.id}`); if (d) { d.style.display = d.style.display==='none'?'':'none'; } })); el.querySelectorAll('.sm-copy').forEach(b => b.addEventListener('click', () => { const text = b.getAttribute('data-copy') .replace(/&/g,'&').replace(/</g,'<') .replace(/>/g,'>').replace(/"/g,'"'); navigator.clipboard?.writeText(text).then(() => { b.textContent = '✓ Kopiert!'; setTimeout(() => b.textContent = '📋 Kopieren', 2000); }); })); el.querySelectorAll('.sm-sts').forEach(b => b.addEventListener('click', async () => { await API.patch(`/social/content/${b.dataset.id}`, {status: b.dataset.s}); load(filter); })); el.querySelectorAll('.sm-del').forEach(b => b.addEventListener('click', async () => { if (!window.confirm('Löschen?')) return; await API.delete(`/social/content/${b.dataset.id}`); load(filter); })); el.querySelectorAll('.sm-prev-arch').forEach(b => b.addEventListener('click', async () => { const it = items.find(c => c.id === parseInt(b.dataset.id)); if (it) _showPreview(it); })); } await load('alle'); } // --------------------------------------------------------------- // BEWERTEN // --------------------------------------------------------------- function _renderBewerten(el) { let selPlatform = 'instagram'; el.innerHTML = `
🌙
Zeig mir deinen Entwurf — ich sage dir was gut ist und wie du ihn noch besser machen kannst!
${['instagram','tiktok','both'].map((p,i) => ` `).join('')}
`; el.querySelectorAll('.sm-ep').forEach(b => b.addEventListener('click', () => { selPlatform = b.dataset.p; el.querySelectorAll('.sm-ep').forEach(x => x.className = `btn btn-sm sm-ep ${x===b?'btn-primary':'btn-secondary'}`); })); el.querySelector('#sm-eval').addEventListener('click', async () => { const draft = el.querySelector('#sm-draft').value.trim(); if (!draft) { UI.toast('Gib einen Text ein 😊', 'warning'); return; } const btn = el.querySelector('#sm-eval'); const res = el.querySelector('#sm-eval-res'); btn.disabled = true; res.innerHTML = _lunaProgressHtml(); const interval = _startProgress(res); try { const data = await API.post('/social/evaluate', { platform: selPlatform, format: 'post', draft, }); clearInterval(interval.bar); clearInterval(interval.msg); _progressDone(res); await new Promise(r => setTimeout(r, 400)); res.innerHTML = ` ${data.notes ? `
🌙
Lunas Feedback:
${_esc(data.notes)}
` : ''} ${_renderResult(data, null)}`; _bindResultEvents(res); API.get('/social/stats').then(s => { _stats = s; }); } catch(e) { clearInterval(interval); res.innerHTML = `
😬 Fehler: ${_esc(e.message||String(e))}
`; } finally { btn.disabled = false; btn.innerHTML = '🔍 Luna, schau mal drüber!'; } }); } function _lunaBreedSuggestions(breeds, n = 3) { // 3 zufällige Rassen aus den ersten 100 (bekannte Rassen) const pool = breeds.slice(0, 100); const picked = []; const used = new Set(); while (picked.length < n && picked.length < pool.length) { const i = Math.floor(Math.random() * pool.length); if (!used.has(i)) { used.add(i); picked.push(pool[i]); } } return picked; } function _esc(s) { if (!s) return ''; return String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } // CSS const style = document.createElement('style'); style.textContent = ` .sm-label{font-size:11px;font-weight:700;color:var(--c-text-muted); text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px;display:block} @keyframes luna-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.15)}} #sm-breed-day:hover,#sm-training-tip:hover,#sm-pflege-tip:hover{ transform:translateY(-2px);box-shadow:var(--shadow-md)!important} #sm-breed-day:active,#sm-training-tip:active,#sm-pflege-tip:active{ transform:translateY(0)} #sm-show-exercises:hover{background:var(--c-surface-2)!important; border-color:var(--c-border)!important;color:var(--c-text-secondary)!important} .sm-breed-chip:hover{background:var(--c-primary-subtle)!important; border-color:var(--c-primary)!important;color:var(--c-primary-dark)!important} `; document.head.appendChild(style); return { init, refresh }; })();