""" BreakPilot Studio - Content Creator Modul Funktionen: - Educational Content erstellen & verwalten - H5P Interactive Content Editor Integration - Creative Commons Lizenzierung - Upload von Videos, PDFs, Bildern, Audio - Publishing zu Matrix Feed - Analytics & Impact Scoring """ class ContentCreatorModule: """Modul für Content Creation.""" @staticmethod def get_css() -> str: """CSS für das Content Creator Modul.""" return """ /* ============================================= CONTENT CREATOR MODULE ============================================= */ .panel-content-creator { display: flex; flex-direction: column; height: 100%; background: var(--bp-bg); overflow-y: auto; } /* Header */ .content-creator-header { padding: 32px 40px 24px; background: var(--bp-surface); border-bottom: 1px solid var(--bp-border); } .content-creator-header h2 { font-size: 24px; font-weight: 700; color: var(--bp-text); margin-bottom: 8px; } .content-creator-header p { font-size: 14px; color: var(--bp-text-muted); } /* Navigation Tabs */ .content-creator-tabs { display: flex; gap: 8px; margin-top: 16px; } .creator-tab { padding: 10px 20px; background: transparent; border: 1px solid var(--bp-border); border-radius: 8px; color: var(--bp-text-muted); font-size: 14px; cursor: pointer; transition: all 0.2s; } .creator-tab:hover { background: var(--bp-surface-elevated); border-color: var(--bp-primary); } .creator-tab.active { background: var(--bp-primary); border-color: var(--bp-primary); color: white; } /* Content Area */ .content-creator-content { padding: 32px 40px; flex: 1; } /* Tab Panels */ .creator-tab-panel { display: none; } .creator-tab-panel.active { display: block; animation: fadeIn 0.3s ease; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } /* Create Content Form */ .create-content-form { max-width: 800px; background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 12px; padding: 32px; } .form-section { margin-bottom: 32px; } .form-section-title { font-size: 16px; font-weight: 600; color: var(--bp-text); margin-bottom: 16px; padding-bottom: 8px; border-bottom: 1px solid var(--bp-border); } .form-group { margin-bottom: 20px; } .form-label { display: block; font-size: 14px; font-weight: 500; color: var(--bp-text); margin-bottom: 8px; } .form-label-required::after { content: ' *'; color: var(--bp-danger); } .form-input, .form-select, .form-textarea { width: 100%; padding: 12px 16px; background: var(--bp-bg); border: 1px solid var(--bp-border); border-radius: 8px; color: var(--bp-text); font-size: 14px; font-family: inherit; transition: all 0.2s; } .form-input:focus, .form-select:focus, .form-textarea:focus { outline: none; border-color: var(--bp-primary); box-shadow: 0 0 0 3px var(--bp-primary-soft); } .form-textarea { min-height: 100px; resize: vertical; } .form-hint { font-size: 12px; color: var(--bp-text-muted); margin-top: 6px; } /* File Upload Area */ .file-upload-area { border: 2px dashed var(--bp-border); border-radius: 12px; padding: 40px; text-align: center; background: var(--bp-bg); cursor: pointer; transition: all 0.3s; } .file-upload-area:hover { border-color: var(--bp-primary); background: var(--bp-primary-soft); } .file-upload-area.dragover { border-color: var(--bp-primary); background: var(--bp-primary-soft); transform: scale(1.02); } .upload-icon { font-size: 48px; color: var(--bp-text-muted); margin-bottom: 16px; } .upload-text { font-size: 16px; color: var(--bp-text); font-weight: 500; margin-bottom: 8px; } .upload-hint { font-size: 13px; color: var(--bp-text-muted); } .file-input-hidden { display: none; } /* Uploaded Files List */ .uploaded-files { margin-top: 16px; } .uploaded-file { display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 8px; margin-bottom: 8px; } .file-icon { font-size: 24px; color: var(--bp-primary); } .file-info { flex: 1; } .file-name { font-size: 14px; font-weight: 500; color: var(--bp-text); } .file-size { font-size: 12px; color: var(--bp-text-muted); } .file-remove { padding: 6px 12px; background: transparent; border: none; color: var(--bp-danger); cursor: pointer; font-size: 12px; transition: opacity 0.2s; } .file-remove:hover { opacity: 0.7; } /* License Selector */ .license-options { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; } .license-option { padding: 16px; background: var(--bp-bg); border: 2px solid var(--bp-border); border-radius: 8px; cursor: pointer; transition: all 0.2s; text-align: center; } .license-option:hover { border-color: var(--bp-primary); background: var(--bp-primary-soft); } .license-option.selected { border-color: var(--bp-primary); background: var(--bp-primary-soft); } .license-badge { font-size: 24px; margin-bottom: 8px; } .license-name { font-size: 13px; font-weight: 600; color: var(--bp-text); margin-bottom: 4px; } .license-desc { font-size: 11px; color: var(--bp-text-muted); } /* Category Pills */ .category-pills { display: flex; flex-wrap: wrap; gap: 8px; } .category-pill { padding: 8px 16px; background: var(--bp-bg); border: 1px solid var(--bp-border); border-radius: 999px; font-size: 13px; color: var(--bp-text); cursor: pointer; transition: all 0.2s; } .category-pill:hover { border-color: var(--bp-primary); background: var(--bp-primary-soft); } .category-pill.selected { background: var(--bp-primary); border-color: var(--bp-primary); color: white; } /* Tags Input */ .tags-container { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px; background: var(--bp-bg); border: 1px solid var(--bp-border); border-radius: 8px; min-height: 42px; } .tag { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; background: var(--bp-primary-soft); border: 1px solid var(--bp-primary); border-radius: 4px; font-size: 12px; color: var(--bp-primary); } .tag-remove { cursor: pointer; font-weight: 700; opacity: 0.7; } .tag-remove:hover { opacity: 1; } .tag-input { flex: 1; min-width: 150px; border: none; background: transparent; color: var(--bp-text); font-size: 14px; outline: none; } /* H5P Integration */ .h5p-editor-container { margin-top: 16px; border: 1px solid var(--bp-border); border-radius: 12px; overflow: hidden; background: white; } .h5p-editor-frame { width: 100%; min-height: 600px; border: none; } /* My Content Grid */ .my-content-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 24px; } .content-card { background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 12px; overflow: hidden; transition: all 0.3s; } .content-card:hover { transform: translateY(-4px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); } .content-thumbnail { width: 100%; height: 180px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; font-size: 48px; color: white; } .content-body { padding: 20px; } .content-title { font-size: 16px; font-weight: 600; color: var(--bp-text); margin-bottom: 8px; } .content-meta { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; } .meta-badge { padding: 4px 10px; background: var(--bp-bg); border-radius: 4px; font-size: 11px; color: var(--bp-text-muted); } .content-stats { display: flex; gap: 16px; padding-top: 12px; border-top: 1px solid var(--bp-border); font-size: 12px; color: var(--bp-text-muted); } .stat { display: flex; align-items: center; gap: 4px; } .content-actions { display: flex; gap: 8px; margin-top: 12px; } .btn-icon { padding: 8px; background: transparent; border: 1px solid var(--bp-border); border-radius: 6px; color: var(--bp-text-muted); cursor: pointer; transition: all 0.2s; } .btn-icon:hover { background: var(--bp-primary); border-color: var(--bp-primary); color: white; } /* Analytics Dashboard */ .analytics-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 24px; margin-bottom: 32px; } .analytics-card { background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 12px; padding: 24px; } .analytics-label { font-size: 13px; color: var(--bp-text-muted); margin-bottom: 8px; } .analytics-value { font-size: 32px; font-weight: 700; color: var(--bp-text); margin-bottom: 4px; } .analytics-change { font-size: 12px; color: var(--bp-success); } .analytics-change.negative { color: var(--bp-danger); } /* Action Buttons */ .form-actions { display: flex; gap: 12px; margin-top: 32px; padding-top: 24px; border-top: 1px solid var(--bp-border); } .btn-primary { flex: 1; padding: 14px 24px; background: var(--bp-primary); border: none; border-radius: 8px; color: white; font-size: 15px; font-weight: 600; cursor: pointer; transition: all 0.2s; } .btn-primary:hover { background: var(--bp-primary-hover); transform: translateY(-1px); box-shadow: 0 4px 12px rgba(108, 27, 27, 0.3); } .btn-secondary { padding: 14px 24px; background: transparent; border: 1px solid var(--bp-border); border-radius: 8px; color: var(--bp-text); font-size: 15px; font-weight: 500; cursor: pointer; transition: all 0.2s; } .btn-secondary:hover { background: var(--bp-surface-elevated); border-color: var(--bp-primary); } /* Status Badge */ .status-badge { display: inline-block; padding: 4px 10px; border-radius: 4px; font-size: 11px; font-weight: 600; text-transform: uppercase; } .status-draft { background: rgba(100, 116, 139, 0.15); color: #64748b; } .status-published { background: rgba(34, 197, 94, 0.15); color: #22c55e; } .status-review { background: rgba(245, 158, 11, 0.15); color: #f59e0b; } """ @staticmethod def get_html() -> str: """HTML für das Content Creator Modul.""" return """
""" @staticmethod def get_js() -> str: """JavaScript für das Content Creator Modul.""" return """ // ============================================= // CONTENT CREATOR MODULE // ============================================= (function() { 'use strict'; const ContentCreator = { selectedFiles: [], selectedCategory: null, selectedLicense: 'CC-BY-SA-4.0', tags: [], init() { this.bindTabSwitching(); this.bindFileUpload(); this.bindCategorySelection(); this.bindLicenseSelection(); this.bindTagsInput(); this.bindContentTypeChange(); this.bindFormSubmit(); // Set default license document.querySelector(`[data-license="${this.selectedLicense}"]`)?.classList.add('selected'); }, bindTabSwitching() { const tabs = document.querySelectorAll('.creator-tab'); tabs.forEach(tab => { tab.addEventListener('click', () => { const tabName = tab.dataset.tab; // Update tabs tabs.forEach(t => t.classList.remove('active')); tab.classList.add('active'); // Update panels document.querySelectorAll('.creator-tab-panel').forEach(panel => { panel.classList.remove('active'); }); document.getElementById(`tab-${tabName}`)?.classList.add('active'); // Load content if switching to my-content if (tabName === 'my-content') { this.loadMyContent(); } else if (tabName === 'analytics') { this.loadAnalytics(); } }); }); }, bindFileUpload() { const uploadArea = document.getElementById('file-upload-area'); const fileInput = document.getElementById('file-input'); uploadArea.addEventListener('click', () => fileInput.click()); uploadArea.addEventListener('dragover', (e) => { e.preventDefault(); uploadArea.classList.add('dragover'); }); uploadArea.addEventListener('dragleave', () => { uploadArea.classList.remove('dragover'); }); uploadArea.addEventListener('drop', (e) => { e.preventDefault(); uploadArea.classList.remove('dragover'); this.handleFiles(e.dataTransfer.files); }); fileInput.addEventListener('change', (e) => { this.handleFiles(e.target.files); }); }, handleFiles(files) { Array.from(files).forEach(file => { if (file.size > 100 * 1024 * 1024) { alert(`Datei ${file.name} ist zu groß (max. 100MB)`); return; } this.selectedFiles.push(file); this.renderUploadedFiles(); }); }, renderUploadedFiles() { const container = document.getElementById('uploaded-files'); container.innerHTML = ''; this.selectedFiles.forEach((file, index) => { const fileEl = document.createElement('div'); fileEl.className = 'uploaded-file'; fileEl.innerHTML = `