""" 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 => `Noch kein Wochenbericht verfuegbar.
'; } } catch (error) { console.log('Demo mode: loading digest'); renderDemoDigest(); } } function renderDemoDigest() { const container = document.getElementById('digest-content'); container.innerHTML = `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); } }; """