""" Legal Modal Component - AGB, Datenschutz, Cookies, Community Guidelines, GDPR Rights """ def get_legal_modal_css() -> str: """CSS für Legal Modal zurückgeben""" return """ /* ========================================== LEGAL MODAL STYLES ========================================== */ .legal-modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); z-index: 10000; justify-content: center; align-items: center; backdrop-filter: blur(4px); } .legal-modal.active { display: flex; } .legal-modal-content { background: var(--bp-surface); border-radius: 16px; width: 90%; max-width: 700px; max-height: 80vh; display: flex; flex-direction: column; box-shadow: 0 20px 60px rgba(0,0,0,0.4); border: 1px solid var(--bp-border); } .legal-modal-header { display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; border-bottom: 1px solid var(--bp-border); } .legal-modal-header h2 { margin: 0; font-size: 18px; font-weight: 600; } .legal-modal-close { background: none; border: none; font-size: 28px; cursor: pointer; color: var(--bp-text-muted); padding: 0; line-height: 1; } .legal-modal-close:hover { color: var(--bp-text); } .legal-tabs { display: flex; gap: 4px; padding: 12px 24px; border-bottom: 1px solid var(--bp-border); background: var(--bp-surface-elevated); } .legal-tab { padding: 8px 16px; border: none; background: transparent; color: var(--bp-text-muted); cursor: pointer; border-radius: 8px; font-size: 13px; transition: all 0.2s ease; } .legal-tab:hover { background: var(--bp-border-subtle); color: var(--bp-text); } .legal-tab.active { background: var(--bp-primary); color: white; } .legal-body { padding: 24px; overflow-y: auto; flex: 1; } .legal-content { display: none; } .legal-content.active { display: block; } .legal-content h3 { margin-top: 0; color: var(--bp-text); } .legal-content p { line-height: 1.6; color: var(--bp-text-muted); } .legal-content ul { color: var(--bp-text-muted); line-height: 1.8; } .cookie-categories { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; } .cookie-category { display: flex; align-items: flex-start; gap: 12px; padding: 12px; background: var(--bp-surface-elevated); border-radius: 8px; border: 1px solid var(--bp-border); cursor: pointer; } .cookie-category input { margin-top: 4px; } .cookie-category span { flex: 1; font-size: 13px; color: var(--bp-text); } .gdpr-actions { display: flex; flex-direction: column; gap: 16px; margin-top: 16px; } .gdpr-action { padding: 16px; background: var(--bp-surface-elevated); border-radius: 12px; border: 1px solid var(--bp-border); } .gdpr-action h4 { margin: 0 0 8px 0; font-size: 14px; color: var(--bp-text); } .gdpr-action p { margin: 0 0 12px 0; font-size: 13px; } .btn-danger { background: var(--bp-danger) !important; border-color: var(--bp-danger) !important; } .btn-danger:hover { filter: brightness(1.1); } [data-theme="light"] .legal-modal-content { background: #FFFFFF; border-color: #E0E0E0; } [data-theme="light"] .legal-tabs { background: #F5F5F5; } [data-theme="light"] .legal-tab.active { background: var(--bp-primary); color: white; } [data-theme="light"] .cookie-category, [data-theme="light"] .gdpr-action { background: #F8F8F8; border-color: #E0E0E0; } """ def get_legal_modal_html() -> str: """HTML für Legal Modal zurückgeben""" return """ """ def get_legal_modal_js() -> str: """JavaScript für Legal Modal zurückgeben""" return """ const legalModal = document.getElementById('legal-modal'); const legalModalClose = document.getElementById('legal-modal-close'); const legalTabs = document.querySelectorAll('.legal-tab'); const legalContents = document.querySelectorAll('.legal-content'); const btnLegal = document.getElementById('btn-legal'); // Imprint Modal const imprintModal = document.getElementById('imprint-modal'); const imprintModalClose = document.getElementById('imprint-modal-close'); // Open legal modal from footer function openLegalModal(tab = 'terms') { legalModal.classList.add('active'); // Switch to specified tab if (tab) { legalTabs.forEach(t => t.classList.remove('active')); legalContents.forEach(c => c.classList.remove('active')); const targetTab = document.querySelector(`.legal-tab[data-tab="${tab}"]`); if (targetTab) targetTab.classList.add('active'); document.getElementById(`legal-${tab}`)?.classList.add('active'); } loadLegalDocuments(); } // Open imprint modal from footer function openImprintModal() { imprintModal.classList.add('active'); loadImprintContent(); } // Open legal modal btnLegal?.addEventListener('click', async () => { openLegalModal(); }); // Close legal modal legalModalClose?.addEventListener('click', () => { legalModal.classList.remove('active'); }); // Close imprint modal imprintModalClose?.addEventListener('click', () => { imprintModal.classList.remove('active'); }); // Close on background click legalModal?.addEventListener('click', (e) => { if (e.target === legalModal) { legalModal.classList.remove('active'); } }); imprintModal?.addEventListener('click', (e) => { if (e.target === imprintModal) { imprintModal.classList.remove('active'); } }); // Tab switching legalTabs.forEach(tab => { tab.addEventListener('click', () => { const tabId = tab.dataset.tab; legalTabs.forEach(t => t.classList.remove('active')); legalContents.forEach(c => c.classList.remove('active')); tab.classList.add('active'); document.getElementById(`legal-${tabId}`)?.classList.add('active'); // Load cookie categories when switching to cookies tab if (tabId === 'cookies') { loadCookieCategories(); } }); }); // Load legal documents from consent service async function loadLegalDocuments() { const lang = document.getElementById('language-select')?.value || 'de'; // Load all documents in parallel await Promise.all([ loadDocumentContent('terms', 'legal-terms-content', getDefaultTerms, lang), loadDocumentContent('privacy', 'legal-privacy-content', getDefaultPrivacy, lang), loadDocumentContent('community_guidelines', 'legal-community-content', getDefaultCommunityGuidelines, lang) ]); } // Load imprint content async function loadImprintContent() { const lang = document.getElementById('language-select')?.value || 'de'; await loadDocumentContent('imprint', 'imprint-content', getDefaultImprint, lang); } // Generic function to load document content async function loadDocumentContent(docType, containerId, defaultFn, lang) { const container = document.getElementById(containerId); if (!container) return; try { const res = await fetch(`/api/consent/documents/${docType}/latest?language=${lang}`); if (res.ok) { const data = await res.json(); if (data.content) { container.innerHTML = data.content; return; } } } catch(e) { console.log(`Could not load ${docType}:`, e); } // Fallback to default container.innerHTML = defaultFn(lang); } // Load cookie categories for the cookie settings tab async function loadCookieCategories() { const container = document.getElementById('cookie-categories-container'); if (!container) return; try { const res = await fetch('/api/consent/cookies/categories'); if (res.ok) { const data = await res.json(); const categories = data.categories || []; if (categories.length === 0) { container.innerHTML = getDefaultCookieCategories(); return; } // Get current preferences from localStorage const savedPrefs = JSON.parse(localStorage.getItem('bp_cookie_consent') || '{}'); container.innerHTML = categories.map(cat => ` `).join(''); } else { container.innerHTML = getDefaultCookieCategories(); } } catch(e) { container.innerHTML = getDefaultCookieCategories(); } } function getDefaultCookieCategories() { return ` `; } function getDefaultTerms(lang) { const terms = { de: '

Allgemeine Geschäftsbedingungen

Die BreakPilot-Plattform wird von der BreakPilot UG bereitgestellt.

Nutzung: Die Plattform dient zur Erstellung und Verwaltung von Lernmaterialien für Bildungszwecke.

Haftung: Die Nutzung erfolgt auf eigene Verantwortung.

Änderungen: Wir behalten uns vor, diese AGB jederzeit zu ändern.

', en: '

Terms of Service

The BreakPilot platform is provided by BreakPilot UG.

Usage: The platform is designed for creating and managing learning materials for educational purposes.

Liability: Use at your own risk.

Changes: We reserve the right to modify these terms at any time.

' }; return terms[lang] || terms.de; } function getDefaultPrivacy(lang) { const privacy = { de: '

Datenschutzerklärung

Verantwortlicher: BreakPilot UG

Erhobene Daten: Bei der Nutzung werden technische Daten (IP-Adresse, Browser-Typ) sowie von Ihnen eingegebene Inhalte verarbeitet.

Zweck: Die Daten werden zur Bereitstellung der Plattform und zur Verbesserung unserer Dienste genutzt.

Ihre Rechte (DSGVO):

Kontakt: datenschutz@breakpilot.app

', en: '

Privacy Policy

Controller: BreakPilot UG

Data Collected: Technical data (IP address, browser type) and content you provide are processed.

Purpose: Data is used to provide the platform and improve our services.

Your Rights (GDPR):

Contact: privacy@breakpilot.app

' }; return privacy[lang] || privacy.de; } function getDefaultCommunityGuidelines(lang) { const guidelines = { de: '

Community Guidelines

Willkommen bei BreakPilot! Um eine positive und respektvolle Umgebung zu gewährleisten, bitten wir alle Nutzer, diese Richtlinien zu befolgen.

Respektvoller Umgang: Behandeln Sie andere Nutzer mit Respekt und Höflichkeit.

Keine illegalen Inhalte: Das Erstellen oder Teilen von illegalen Inhalten ist streng untersagt.

Urheberrecht: Respektieren Sie das geistige Eigentum anderer. Verwenden Sie nur Inhalte, für die Sie die Rechte besitzen.

Datenschutz: Teilen Sie keine persönlichen Daten anderer ohne deren ausdrückliche Zustimmung.

Qualität: Bemühen Sie sich um qualitativ hochwertige Lerninhalte.

Verstöße gegen diese Richtlinien können zur Sperrung des Accounts führen.

', en: '

Community Guidelines

Welcome to BreakPilot! To ensure a positive and respectful environment, we ask all users to follow these guidelines.

Respectful Behavior: Treat other users with respect and courtesy.

No Illegal Content: Creating or sharing illegal content is strictly prohibited.

Copyright: Respect the intellectual property of others. Only use content you have rights to.

Privacy: Do not share personal data of others without their explicit consent.

Quality: Strive for high-quality learning content.

Violations of these guidelines may result in account suspension.

' }; return guidelines[lang] || guidelines.de; } function getDefaultImprint(lang) { const imprint = { de: '

Impressum

Angaben gemäß § 5 TMG:

BreakPilot UG (haftungsbeschränkt)
Musterstraße 1
12345 Musterstadt
Deutschland

Vertreten durch:
Geschäftsführer: Max Mustermann

Kontakt:
Telefon: +49 (0) 123 456789
E-Mail: info@breakpilot.app

Registereintrag:
Eintragung im Handelsregister
Registergericht: Amtsgericht Musterstadt
Registernummer: HRB 12345

Umsatzsteuer-ID:
Umsatzsteuer-Identifikationsnummer gemäß § 27 a UStG: DE123456789

Verantwortlich für den Inhalt nach § 55 Abs. 2 RStV:
Max Mustermann
Musterstraße 1
12345 Musterstadt

', en: '

Legal Notice

Information according to § 5 TMG:

BreakPilot UG (limited liability)
Musterstraße 1
12345 Musterstadt
Germany

Represented by:
Managing Director: Max Mustermann

Contact:
Phone: +49 (0) 123 456789
Email: info@breakpilot.app

Register entry:
Entry in the commercial register
Register court: Amtsgericht Musterstadt
Register number: HRB 12345

VAT ID:
VAT identification number according to § 27 a UStG: DE123456789

Responsible for content according to § 55 Abs. 2 RStV:
Max Mustermann
Musterstraße 1
12345 Musterstadt

' }; return imprint[lang] || imprint.de; } // Save cookie preferences function saveCookiePreferences() { const prefs = {}; const checkboxes = document.querySelectorAll('#cookie-categories-container input[type="checkbox"]'); checkboxes.forEach(cb => { const name = cb.id.replace('cookie-', ''); if (name && !cb.disabled) { prefs[name] = cb.checked; } }); localStorage.setItem('bp_cookie_consent', JSON.stringify(prefs)); localStorage.setItem('bp_cookie_consent_date', new Date().toISOString()); // TODO: Send to consent service if user is logged in alert('Cookie-Einstellungen gespeichert!'); } """