""" BreakPilot Studio - Alerts Guided Mode Modul Dieses Modul implementiert den Guided Mode fuer das Alerts-System: - 3-Schritt Wizard (Rolle -> Templates -> Bestaetigung) - InfoCards mit Wichtigkeitsstufen - 1-Klick Feedback - Wochenzusammenfassung (Digest) Zielgruppe: Lehrkraefte, Schulleitungen (nicht IT-affin) Design-Prinzip: Einfache Bedienung, max. 10 Karten/Tag, deutsche Erklaerungen """ class AlertsGuidedModule: """Guided Mode fuer das Alerts-System.""" @staticmethod def get_css() -> str: """CSS fuer den Guided Mode.""" return """ /* ========================================== ALERTS GUIDED MODE STYLES ========================================== */ /* Mode Switcher */ .alerts-mode-switcher { display: flex; gap: 8px; padding: 4px; background: var(--bp-surface-elevated); border-radius: 8px; border: 1px solid var(--bp-border); } .mode-btn { padding: 8px 16px; border: none; background: transparent; border-radius: 6px; font-size: 14px; font-weight: 500; color: var(--bp-text-muted); cursor: pointer; transition: all 0.2s; } .mode-btn:hover { background: var(--bp-surface); } .mode-btn.active { background: var(--bp-primary); color: white; } /* Wizard Container */ .guided-wizard { display: none; flex-direction: column; max-width: 800px; margin: 40px auto; padding: 0 20px; } .guided-wizard.active { display: flex; } /* Wizard Progress */ .wizard-progress { display: flex; justify-content: center; gap: 8px; margin-bottom: 40px; } .wizard-step-indicator { display: flex; align-items: center; gap: 8px; } .wizard-step-dot { width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 14px; background: var(--bp-surface); border: 2px solid var(--bp-border); color: var(--bp-text-muted); } .wizard-step-dot.active { background: var(--bp-primary); border-color: var(--bp-primary); color: white; } .wizard-step-dot.completed { background: var(--bp-success); border-color: var(--bp-success); color: white; } .wizard-step-line { width: 60px; height: 2px; background: var(--bp-border); } .wizard-step-line.completed { background: var(--bp-success); } /* Wizard Step Content */ .wizard-step { display: none; flex-direction: column; align-items: center; } .wizard-step.active { display: flex; } .wizard-step-title { font-size: 28px; font-weight: 700; color: var(--bp-text); margin-bottom: 12px; text-align: center; } .wizard-step-description { font-size: 16px; color: var(--bp-text-muted); text-align: center; max-width: 500px; margin-bottom: 32px; } /* Role Selection */ .role-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; width: 100%; max-width: 720px; } .role-card { display: flex; flex-direction: column; align-items: center; padding: 24px; background: var(--bp-surface); border: 2px solid var(--bp-border); border-radius: 16px; cursor: pointer; transition: all 0.2s; } .role-card:hover { border-color: var(--bp-primary); transform: translateY(-2px); } .role-card.selected { border-color: var(--bp-primary); background: rgba(var(--bp-primary-rgb), 0.05); } .role-card-icon { font-size: 40px; margin-bottom: 12px; } .role-card-title { font-size: 18px; font-weight: 600; color: var(--bp-text); margin-bottom: 4px; } .role-card-description { font-size: 13px; color: var(--bp-text-muted); text-align: center; } /* Template Selection */ .template-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; width: 100%; max-width: 900px; } .template-card { display: flex; flex-direction: column; padding: 20px; background: var(--bp-surface); border: 2px solid var(--bp-border); border-radius: 12px; cursor: pointer; transition: all 0.2s; position: relative; } .template-card:hover { border-color: var(--bp-primary); } .template-card.selected { border-color: var(--bp-primary); background: rgba(var(--bp-primary-rgb), 0.05); } .template-card.disabled { opacity: 0.5; cursor: not-allowed; } .template-card-header { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 12px; } .template-card-icon { font-size: 28px; flex-shrink: 0; } .template-card-info { flex: 1; } .template-card-name { font-size: 16px; font-weight: 600; color: var(--bp-text); margin-bottom: 4px; } .template-card-desc { font-size: 13px; color: var(--bp-text-muted); line-height: 1.4; } .template-card-check { position: absolute; top: 12px; right: 12px; width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--bp-border); display: flex; align-items: center; justify-content: center; font-size: 14px; color: white; background: transparent; } .template-card.selected .template-card-check { background: var(--bp-primary); border-color: var(--bp-primary); } .template-selection-info { text-align: center; margin-top: 16px; font-size: 14px; color: var(--bp-text-muted); } .template-selection-count { font-weight: 600; color: var(--bp-primary); } /* Confirmation Step */ .confirmation-summary { width: 100%; max-width: 500px; background: var(--bp-surface); border-radius: 16px; padding: 24px; border: 1px solid var(--bp-border); } .confirmation-item { display: flex; justify-content: space-between; padding: 12px 0; border-bottom: 1px solid var(--bp-border); } .confirmation-item:last-child { border-bottom: none; } .confirmation-label { font-size: 14px; color: var(--bp-text-muted); } .confirmation-value { font-size: 14px; font-weight: 500; color: var(--bp-text); } .confirmation-templates { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; } .confirmation-template-tag { background: var(--bp-primary-soft); color: var(--bp-primary); padding: 4px 10px; border-radius: 12px; font-size: 12px; font-weight: 500; } /* Email Input */ .email-input-group { margin-top: 24px; width: 100%; } .email-input-label { font-size: 14px; font-weight: 500; color: var(--bp-text); margin-bottom: 8px; display: block; } .email-input-hint { font-size: 12px; color: var(--bp-text-muted); margin-bottom: 8px; } .email-input { width: 100%; padding: 12px 16px; border: 1px solid var(--bp-border); border-radius: 8px; font-size: 14px; background: var(--bp-surface); color: var(--bp-text); } .email-input:focus { outline: none; border-color: var(--bp-primary); } /* Wizard Navigation */ .wizard-nav { display: flex; justify-content: space-between; margin-top: 40px; width: 100%; max-width: 500px; } .wizard-nav-btn { padding: 12px 24px; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.2s; } .wizard-nav-btn.secondary { background: transparent; border: 1px solid var(--bp-border); color: var(--bp-text-muted); } .wizard-nav-btn.secondary:hover { background: var(--bp-surface); } .wizard-nav-btn.primary { background: var(--bp-primary); border: none; color: white; } .wizard-nav-btn.primary:hover { opacity: 0.9; } .wizard-nav-btn:disabled { opacity: 0.5; cursor: not-allowed; } /* ========================================== INFO CARDS (Guided Inbox) ========================================== */ .guided-inbox { display: none; flex-direction: column; height: 100%; } .guided-inbox.active { display: flex; } /* Inbox Header */ .guided-inbox-header { display: flex; justify-content: space-between; align-items: center; padding: 20px 32px; border-bottom: 1px solid var(--bp-border); background: var(--bp-surface); } .guided-inbox-title h2 { font-size: 20px; font-weight: 600; color: var(--bp-text); margin-bottom: 4px; } .guided-inbox-subtitle { font-size: 14px; color: var(--bp-text-muted); } .guided-inbox-actions { display: flex; gap: 12px; } /* Info Cards List */ .info-cards-container { flex: 1; overflow-y: auto; padding: 24px 32px; } .info-cards-list { display: flex; flex-direction: column; gap: 16px; max-width: 800px; margin: 0 auto; } /* Single Info Card */ .info-card { background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 12px; overflow: hidden; transition: all 0.2s; } .info-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.08); } /* Card Header with Importance */ .info-card-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; background: var(--bp-surface-elevated); border-bottom: 1px solid var(--bp-border); } .info-card-importance { display: flex; align-items: center; gap: 8px; } .importance-badge { padding: 4px 10px; border-radius: 12px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; } .importance-badge.kritisch { background: #fef2f2; color: #dc2626; } .importance-badge.dringend { background: #fff7ed; color: #ea580c; } .importance-badge.wichtig { background: #fffbeb; color: #d97706; } .importance-badge.pruefen { background: #eff6ff; color: #2563eb; } .importance-badge.info { background: #f8fafc; color: #64748b; } .info-card-time { font-size: 12px; color: var(--bp-text-muted); } /* Card Body */ .info-card-body { padding: 16px; } .info-card-title { font-size: 16px; font-weight: 600; color: var(--bp-text); margin-bottom: 8px; line-height: 1.4; } .info-card-source { font-size: 13px; color: var(--bp-primary); margin-bottom: 12px; } /* Why Relevant Section */ .info-card-why { background: var(--bp-surface-elevated); border-radius: 8px; padding: 12px; margin-bottom: 12px; } .info-card-why-label { font-size: 12px; font-weight: 600; color: var(--bp-text-muted); margin-bottom: 6px; display: flex; align-items: center; gap: 6px; } .info-card-why-content { font-size: 14px; color: var(--bp-text); line-height: 1.5; } /* Next Steps Section */ .info-card-steps { margin-top: 12px; } .info-card-steps-label { font-size: 12px; font-weight: 600; color: var(--bp-text-muted); margin-bottom: 8px; } .info-card-step { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; color: var(--bp-text); margin-bottom: 6px; } .info-card-step-checkbox { width: 16px; height: 16px; border: 2px solid var(--bp-border); border-radius: 4px; flex-shrink: 0; margin-top: 2px; } /* Card Footer with Actions */ .info-card-footer { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; border-top: 1px solid var(--bp-border); background: var(--bp-surface-elevated); } .info-card-feedback { display: flex; gap: 8px; } .feedback-btn { display: flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 8px; font-size: 13px; font-weight: 500; cursor: pointer; border: 1px solid var(--bp-border); background: var(--bp-surface); color: var(--bp-text-muted); transition: all 0.2s; } .feedback-btn:hover { background: var(--bp-surface-elevated); } .feedback-btn.negative:hover { border-color: #ef4444; color: #ef4444; } .feedback-btn.positive:hover { border-color: var(--bp-success); color: var(--bp-success); } .info-card-open { display: flex; align-items: center; gap: 6px; padding: 8px 16px; background: var(--bp-primary); color: white; border: none; border-radius: 8px; font-size: 13px; font-weight: 500; cursor: pointer; transition: opacity 0.2s; } .info-card-open:hover { opacity: 0.9; } /* Empty State */ .guided-empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 80px 20px; text-align: center; } .guided-empty-icon { font-size: 64px; margin-bottom: 20px; opacity: 0.5; } .guided-empty-title { font-size: 20px; font-weight: 600; color: var(--bp-text); margin-bottom: 8px; } .guided-empty-description { font-size: 14px; color: var(--bp-text-muted); max-width: 400px; } /* ========================================== DIGEST VIEW ========================================== */ .digest-container { max-width: 800px; margin: 0 auto; padding: 24px; } .digest-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; } .digest-period { font-size: 14px; color: var(--bp-text-muted); } .digest-export-btn { display: flex; align-items: center; gap: 8px; padding: 10px 16px; background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 8px; font-size: 14px; color: var(--bp-text); cursor: pointer; } .digest-export-btn:hover { background: var(--bp-surface-elevated); } .digest-section { background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 12px; margin-bottom: 20px; overflow: hidden; } .digest-section-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; background: var(--bp-surface-elevated); border-bottom: 1px solid var(--bp-border); } .digest-section-title { font-size: 16px; font-weight: 600; color: var(--bp-text); } .digest-section-count { font-size: 14px; color: var(--bp-text-muted); } .digest-items { padding: 12px 20px; } .digest-item { display: flex; justify-content: space-between; align-items: flex-start; padding: 12px 0; border-bottom: 1px solid var(--bp-border); } .digest-item:last-child { border-bottom: none; } .digest-item-title { font-size: 14px; font-weight: 500; color: var(--bp-text); margin-bottom: 4px; } .digest-item-source { font-size: 12px; color: var(--bp-text-muted); } .digest-item-importance { font-size: 11px; padding: 4px 8px; border-radius: 8px; font-weight: 600; } """ @staticmethod def get_html() -> str: """HTML fuer den Guided Mode.""" return """ """ @staticmethod def get_js() -> str: """JavaScript fuer den Guided Mode.""" return """ /* ========================================== GUIDED MODE - STATE & CONFIG ========================================== */ const GUIDED_API_BASE = '/api/alerts'; let guidedState = { mode: 'guided', // 'guided' oder 'expert' wizardCompleted: false, wizardStep: 1, selectedRole: null, selectedTemplates: [], templates: [], infoCards: [], digestEmail: '' }; /* ========================================== MODE SWITCHING ========================================== */ function switchToGuidedMode() { guidedState.mode = 'guided'; document.getElementById('guided-mode-container').style.display = 'block'; document.getElementById('panel-alerts').querySelector('.alerts-content').style.display = 'none'; // Update mode buttons document.querySelectorAll('.mode-btn').forEach(btn => btn.classList.remove('active')); document.querySelector('.mode-btn[data-mode="guided"]').classList.add('active'); // Check wizard state checkWizardState(); } function switchToExpertMode() { guidedState.mode = 'expert'; document.getElementById('guided-mode-container').style.display = 'none'; document.getElementById('panel-alerts').querySelector('.alerts-content').style.display = 'block'; // Update mode buttons document.querySelectorAll('.mode-btn').forEach(btn => btn.classList.remove('active')); document.querySelector('.mode-btn[data-mode="expert"]').classList.add('active'); } async function checkWizardState() { try { const response = await fetch(`${GUIDED_API_BASE}/wizard/state`); const data = await response.json(); guidedState.wizardCompleted = data.wizard_completed; guidedState.selectedRole = data.user_role; guidedState.selectedTemplates = data.selected_template_ids || []; if (data.wizard_completed) { showGuidedInbox(); } else { showWizard(); } } catch (error) { console.log('Demo mode: wizard state check'); showWizard(); } } /* ========================================== WIZARD FUNCTIONS ========================================== */ function showWizard() { document.getElementById('guided-wizard').classList.add('active'); document.getElementById('guided-inbox').classList.remove('active'); loadTemplatesForWizard(); } function showGuidedInbox() { document.getElementById('guided-wizard').classList.remove('active'); document.getElementById('guided-inbox').classList.add('active'); loadInfoCards(); } function goToWizardStep(step) { // Update step visibility for (let i = 1; i <= 3; i++) { document.getElementById(`wizard-step-${i}`).classList.remove('active'); document.getElementById(`wizard-dot-${i}`).classList.remove('active', 'completed'); if (i < 3) { document.getElementById(`wizard-line-${i}`).classList.remove('completed'); } } document.getElementById(`wizard-step-${step}`).classList.add('active'); // Update progress indicators for (let i = 1; i <= step; i++) { if (i < step) { document.getElementById(`wizard-dot-${i}`).classList.add('completed'); if (i < 3) { document.getElementById(`wizard-line-${i}`).classList.add('completed'); } } else { document.getElementById(`wizard-dot-${i}`).classList.add('active'); } } guidedState.wizardStep = step; // Update confirmation if on step 3 if (step === 3) { updateConfirmation(); } } function selectRole(role) { guidedState.selectedRole = role; // Update UI document.querySelectorAll('.role-card').forEach(card => card.classList.remove('selected')); event.currentTarget.classList.add('selected'); // Enable next button document.getElementById('wizard-next-1').disabled = false; // Update template recommendations filterTemplatesByRole(role); } async function loadTemplatesForWizard() { try { const response = await fetch(`${GUIDED_API_BASE}/templates`); const data = await response.json(); guidedState.templates = data.templates || []; renderTemplateGrid(); } catch (error) { console.log('Demo mode: loading templates'); guidedState.templates = getDemoTemplates(); renderTemplateGrid(); } } function getDemoTemplates() { return [ { id: '1', slug: 'foerderprogramme', name: 'Foerderprogramme & Fristen', icon: '💰', description: 'Foerdergelder, Antragsfristen, EU-Programme', target_roles: ['schulleitung'] }, { id: '2', slug: 'abitur-updates', name: 'Abitur-Updates', icon: '📝', description: 'Pruefungstermine, Operatoren, KMK-Beschluesse', target_roles: ['lehrkraft'] }, { id: '3', slug: 'fortbildungen', name: 'Fortbildungen', icon: '🎓', description: 'Seminare, Workshops, Online-Kurse', target_roles: ['lehrkraft'] }, { id: '4', slug: 'datenschutz-recht', name: 'Datenschutz & Recht', icon: '⚖', description: 'DSGVO-Updates, Urteile, Handreichungen', target_roles: ['schulleitung', 'it_beauftragte'] }, { id: '5', slug: 'it-security', name: 'IT-Security', icon: '🔒', description: 'Sicherheitsluecken, Phishing-Warnungen', target_roles: ['it_beauftragte'] }, { id: '6', slug: 'wettbewerbe-projekte', name: 'Wettbewerbe & Projekte', icon: '🏆', description: 'Schueler-Wettbewerbe, Projekttage', target_roles: ['lehrkraft'] } ]; } function renderTemplateGrid() { const grid = document.getElementById('template-grid'); grid.innerHTML = guidedState.templates.map(template => `
${guidedState.selectedTemplates.includes(template.id) ? '✓' : ''}
${template.icon}
${template.name}
${template.description}
`).join(''); } function filterTemplatesByRole(role) { // Highlight recommended templates for role document.querySelectorAll('.template-card').forEach(card => { const id = card.dataset.id; const template = guidedState.templates.find(t => t.id === id); if (template && template.target_roles && template.target_roles.includes(role)) { card.style.order = '-1'; } else { card.style.order = '0'; } }); } function toggleTemplate(templateId) { const index = guidedState.selectedTemplates.indexOf(templateId); if (index > -1) { guidedState.selectedTemplates.splice(index, 1); } else if (guidedState.selectedTemplates.length < 3) { guidedState.selectedTemplates.push(templateId); } else { alert('Maximal 3 Themen auswaehlbar. Entfernen Sie erst ein Thema.'); return; } // Update UI renderTemplateGrid(); updateTemplateCount(); // Enable/disable next button document.getElementById('wizard-next-2').disabled = guidedState.selectedTemplates.length === 0; } function updateTemplateCount() { document.getElementById('template-count').textContent = guidedState.selectedTemplates.length; } function updateConfirmation() { // Role const roleLabels = { 'lehrkraft': 'Lehrkraft', 'schulleitung': 'Schulleitung', 'it_beauftragte': 'IT-Beauftragte/r' }; document.getElementById('confirm-role').textContent = roleLabels[guidedState.selectedRole] || '-'; // Templates const templatesContainer = document.getElementById('confirm-templates'); templatesContainer.innerHTML = guidedState.selectedTemplates.map(id => { const template = guidedState.templates.find(t => t.id === id); return `${template ? template.name : id}`; }).join(''); } async function completeWizard() { const email = document.getElementById('digest-email').value; guidedState.digestEmail = email; try { // Step 1 speichern await fetch(`${GUIDED_API_BASE}/wizard/step/1`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ role: guidedState.selectedRole }) }); // Step 2 speichern await fetch(`${GUIDED_API_BASE}/wizard/step/2`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ template_ids: guidedState.selectedTemplates }) }); // Step 3 speichern await fetch(`${GUIDED_API_BASE}/wizard/step/3`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ notification_email: email }) }); // Wizard abschliessen await fetch(`${GUIDED_API_BASE}/wizard/complete`, { method: 'POST' }); } catch (error) { console.log('Demo mode: completing wizard'); } guidedState.wizardCompleted = true; showGuidedInbox(); } function skipWizard() { if (confirm('Moechten Sie wirklich ueberspringen? Sie koennen die Einstellungen spaeter anpassen.')) { switchToExpertMode(); } } /* ========================================== INFO CARDS (Guided Inbox) ========================================== */ async function loadInfoCards() { try { const response = await fetch(`${GUIDED_API_BASE}/inbox/guided?limit=10`); const data = await response.json(); guidedState.infoCards = data.items || []; renderInfoCards(); } catch (error) { console.log('Demo mode: loading info cards'); guidedState.infoCards = getDemoInfoCards(); renderInfoCards(); } } function getDemoInfoCards() { return [ { id: '1', title: 'DigitalPakt 2.0: Neue Antragsphase startet am 1. April', source_name: 'Bundesministerium fuer Bildung', source_url: 'https://example.com/digitalpakt', importance_level: 'dringend', why_relevant: 'Frist endet in 45 Tagen. Betrifft alle Schulen mit Foerderbedarf.', next_steps: ['Schultraeger kontaktieren', 'Bedarfsanalyse erstellen'], fetched_at: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString() }, { id: '2', title: 'CVE-2026-1234: Kritische Sicherheitsluecke in Moodle', source_name: 'BSI CERT-Bund', source_url: 'https://example.com/cve', importance_level: 'kritisch', why_relevant: 'Sofortiges Update erforderlich. Exploit bereits aktiv.', next_steps: ['Betroffene Systeme pruefen', 'Update einspielen'], fetched_at: new Date(Date.now() - 30 * 60 * 1000).toISOString() }, { id: '3', title: 'Kostenlose Fortbildung: KI im Unterricht', source_name: 'Landesinstitut', source_url: 'https://example.com/fortbildung', importance_level: 'pruefen', why_relevant: 'Passt zu Ihrem Interessenprofil. Online-Format, 4 Stunden.', next_steps: ['Termin und Ort pruefen', 'Bei Interesse anmelden'], fetched_at: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString() } ]; } function renderInfoCards() { const list = document.getElementById('info-cards-list'); const emptyState = document.getElementById('guided-empty-state'); if (guidedState.infoCards.length === 0) { list.style.display = 'none'; emptyState.style.display = 'flex'; document.getElementById('guided-alert-count').textContent = '0'; return; } list.style.display = 'flex'; emptyState.style.display = 'none'; document.getElementById('guided-alert-count').textContent = guidedState.infoCards.length; list.innerHTML = guidedState.infoCards.map(card => { const timeAgo = formatTimeAgo(card.fetched_at); const importanceClass = (card.importance_level || 'info').toLowerCase(); const importanceLabel = { 'kritisch': 'Kritisch', 'dringend': 'Dringend', 'wichtig': 'Wichtig', 'pruefen': 'Zu pruefen', 'info': 'Info' }[importanceClass] || 'Info'; const stepsHtml = (card.next_steps || []).map(step => `
${escapeHtml(step)}
`).join(''); return `
${importanceLabel}
${timeAgo}
${escapeHtml(card.title)}
${escapeHtml(card.source_name || 'Unbekannte Quelle')}
💡 Warum relevant?
${escapeHtml(card.why_relevant || '')}
${stepsHtml ? `
Naechste Schritte:
${stepsHtml}
` : ''}
`; }).join(''); } function openInfoCard(cardId, url) { if (url) { window.open(url, '_blank'); } } async function sendQuickFeedback(cardId, feedbackType) { try { await fetch(`${GUIDED_API_BASE}/feedback/quick`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ alert_id: cardId, feedback_type: feedbackType }) }); } catch (error) { console.log('Demo mode: sending feedback'); } // Remove card from list guidedState.infoCards = guidedState.infoCards.filter(c => c.id !== cardId); renderInfoCards(); // Show confirmation const message = feedbackType === 'more_like_this' ? 'Danke! Sie erhalten mehr aehnliche Meldungen.' : 'Verstanden! Weniger solche Meldungen.'; showToast(message); } function showToast(message) { // Simple toast notification const toast = document.createElement('div'); toast.style.cssText = ` position: fixed; bottom: 20px; right: 20px; background: #1e293b; color: white; padding: 12px 20px; border-radius: 8px; font-size: 14px; z-index: 10000; animation: fadeIn 0.3s, fadeOut 0.3s 2.7s; `; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => toast.remove(), 3000); } /* ========================================== DIGEST VIEW ========================================== */ async function showDigestView() { document.getElementById('digest-modal').style.display = 'flex'; await loadDigest(); } function closeDigestModal() { document.getElementById('digest-modal').style.display = 'none'; } async function loadDigest() { const container = document.getElementById('digest-content'); try { const response = await fetch(`${GUIDED_API_BASE}/digests?limit=1`); const data = await response.json(); if (data.digests && data.digests.length > 0) { renderDigest(data.digests[0]); } else { container.innerHTML = '

Noch kein Wochenbericht verfuegbar.

'; } } catch (error) { console.log('Demo mode: loading digest'); renderDemoDigest(); } } function renderDemoDigest() { const container = document.getElementById('digest-content'); container.innerHTML = `

Wochenbericht

13.01.2026 - 19.01.2026
🔴 Kritisch & Dringend
2 Meldungen
CVE-2026-1234: Moodle Sicherheitsluecke
BSI CERT-Bund
Kritisch
DigitalPakt 2.0 Antragsphase
BMBF
Dringend
🟢 Wichtig
3 Meldungen
Neue Operatoren fuer Abitur Deutsch
KMK
Wichtig
Fortbildung: KI im Unterricht
Landesinstitut
Pruefen
Jugend forscht Anmeldeschluss
Jugend forscht e.V.
Wichtig
`; } function renderDigest(digest) { const container = document.getElementById('digest-content'); container.innerHTML = digest.summary_html || '

Kein Inhalt verfuegbar.

'; } async function exportDigestPDF() { try { const response = await fetch(`${GUIDED_API_BASE}/digests/latest/pdf`); const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'wochenbericht.pdf'; a.click(); } catch (error) { console.log('Demo mode: PDF export not available'); alert('PDF-Export wird in Kuerze verfuegbar sein.'); } } /* ========================================== SETTINGS ========================================== */ function openGuidedSettings() { // Zurueck zum Wizard um Einstellungen anzupassen guidedState.wizardCompleted = false; showWizard(); } /* ========================================== INITIALIZATION ========================================== */ // Add mode switcher to alerts header on load document.addEventListener('DOMContentLoaded', function() { const headerActions = document.querySelector('.alerts-header-actions'); if (headerActions) { const modeSwitcher = document.createElement('div'); modeSwitcher.className = 'alerts-mode-switcher'; modeSwitcher.innerHTML = ` `; headerActions.insertBefore(modeSwitcher, headerActions.firstChild); } // Default to guided mode for new users setTimeout(() => { if (document.getElementById('panel-alerts').classList.contains('active')) { switchToGuidedMode(); } }, 100); }); // Override showAlertsPanel to check mode const originalShowAlertsTab = window.showAlertsTab; window.showAlertsTab = function(tab) { if (guidedState.mode === 'guided') { // Stay in guided mode return; } if (originalShowAlertsTab) { originalShowAlertsTab(tab); } }; """