""" BreakPilot Studio - Lerneinheiten/Arbeitsblaetter Modul Refactored: 2024-12-18 - Kachel-basierte Startansicht - Sub-Module fuer verschiedene Funktionen Funktionen (als Kacheln): - Lerneinheiten erstellen und verwalten - Dateien hochladen - Dateien bereinigen (OCR, Neuaufbau) - Lernflows (Interaktive Uebungen) - Multiple Choice Tests - Lueckentexte - Mindmap Generator - Uebersetzungen """ class WorksheetsModule: """Modul fuer Lerneinheiten und Arbeitsblaetter.""" @staticmethod def get_css() -> str: """CSS fuer das Worksheets-Modul.""" return """ /* ============================================= WORKSHEETS MODULE - Lerneinheiten & Arbeitsblaetter ============================================= */ /* Panel Layout */ .panel-worksheets { display: none; flex-direction: column; height: 100%; background: var(--bp-bg); overflow: hidden; } .panel-worksheets.active { display: flex; } /* Worksheets Header */ .worksheets-header { display: flex; justify-content: space-between; align-items: center; padding: 20px 32px; border-bottom: 1px solid var(--bp-border); background: var(--bp-surface); } .worksheets-title-section h1 { font-size: 24px; font-weight: 700; color: var(--bp-text); margin-bottom: 4px; } .worksheets-subtitle { font-size: 14px; color: var(--bp-text-muted); } .worksheets-nav { display: flex; gap: 8px; } .worksheets-nav-btn { padding: 8px 16px; border-radius: 8px; border: 1px solid var(--bp-border); background: var(--bp-surface); color: var(--bp-text-muted); font-size: 13px; cursor: pointer; transition: all 0.2s; } .worksheets-nav-btn:hover { background: var(--bp-surface-elevated); color: var(--bp-text); } .worksheets-nav-btn.active { background: var(--bp-primary); border-color: var(--bp-primary); color: white; } /* Worksheets Content - Kacheln */ .worksheets-content { flex: 1; overflow-y: auto; padding: 32px; } /* Tiles Grid */ .worksheets-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 24px; max-width: 1400px; margin: 0 auto; } /* Section Header */ .tiles-section { margin-bottom: 32px; } .tiles-section-header { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; } .tiles-section-icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 20px; } .tiles-section-icon.create { background: rgba(59, 130, 246, 0.15); } .tiles-section-icon.process { background: rgba(16, 185, 129, 0.15); } .tiles-section-icon.generate { background: rgba(245, 158, 11, 0.15); } .tiles-section-icon.translate { background: rgba(139, 92, 246, 0.15); } .tiles-section-title { font-size: 16px; font-weight: 600; color: var(--bp-text); } .tiles-section-desc { font-size: 13px; color: var(--bp-text-muted); } /* Worksheet Tile */ .worksheet-tile { background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 16px; padding: 24px; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; } .worksheet-tile:hover { transform: translateY(-4px); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1); border-color: var(--bp-primary); } .worksheet-tile::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: var(--bp-primary); opacity: 0; transition: opacity 0.3s; } .worksheet-tile:hover::before { opacity: 1; } .tile-icon-container { width: 56px; height: 56px; border-radius: 14px; display: flex; align-items: center; justify-content: center; font-size: 28px; margin-bottom: 16px; } /* Icon Colors */ .tile-icon-container.blue { background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%); } .tile-icon-container.green { background: linear-gradient(135deg, #10b981 0%, #059669 100%); } .tile-icon-container.orange { background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); } .tile-icon-container.purple { background: linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%); } .tile-icon-container.red { background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); } .tile-icon-container.cyan { background: linear-gradient(135deg, #06b6d4 0%, #0891b2 100%); } .tile-icon-container.pink { background: linear-gradient(135deg, #ec4899 0%, #be185d 100%); } .tile-icon-container.teal { background: linear-gradient(135deg, #14b8a6 0%, #0d9488 100%); } .tile-title { font-size: 16px; font-weight: 600; color: var(--bp-text); margin-bottom: 8px; } .tile-description { font-size: 13px; color: var(--bp-text-muted); line-height: 1.5; margin-bottom: 16px; } .tile-features { display: flex; flex-wrap: wrap; gap: 6px; } .tile-feature-tag { padding: 4px 10px; background: var(--bp-bg); border-radius: 12px; font-size: 11px; color: var(--bp-text-muted); } .tile-arrow { position: absolute; bottom: 20px; right: 20px; width: 32px; height: 32px; border-radius: 50%; background: var(--bp-bg); display: flex; align-items: center; justify-content: center; color: var(--bp-text-muted); transition: all 0.3s; } .worksheet-tile:hover .tile-arrow { background: var(--bp-primary); color: white; transform: translateX(4px); } /* Sub-Panel (hidden by default, shown when tile clicked) */ .worksheets-subpanel { display: none; flex-direction: column; height: 100%; } .worksheets-subpanel.active { display: flex; } .subpanel-header { display: flex; align-items: center; gap: 16px; padding: 16px 24px; border-bottom: 1px solid var(--bp-border); background: var(--bp-surface); } .subpanel-back { width: 36px; height: 36px; border-radius: 8px; border: 1px solid var(--bp-border); background: var(--bp-bg); color: var(--bp-text); cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 18px; transition: all 0.2s; } .subpanel-back:hover { background: var(--bp-surface-elevated); } .subpanel-title { font-size: 18px; font-weight: 600; } .subpanel-content { flex: 1; overflow-y: auto; padding: 24px; } /* Status Bar */ .worksheets-status { display: flex; align-items: center; gap: 12px; padding: 10px 24px; border-top: 1px solid var(--bp-border); background: var(--bp-surface); font-size: 12px; } .status-indicator { width: 8px; height: 8px; border-radius: 50%; background: #10b981; } .status-indicator.busy { background: #f59e0b; animation: statusPulse 1.5s infinite; } .status-indicator.error { background: #ef4444; } @keyframes statusPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .status-text { color: var(--bp-text); } .status-detail { color: var(--bp-text-muted); } /* ============================================ SUB-MODULE STYLES: Lerneinheiten Manager ============================================ */ .units-manager { display: grid; grid-template-columns: 320px 1fr; gap: 24px; height: 100%; } .units-sidebar { background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 12px; display: flex; flex-direction: column; overflow: hidden; } .units-form { padding: 16px; border-bottom: 1px solid var(--bp-border); } .units-form h3 { font-size: 14px; font-weight: 600; margin-bottom: 12px; color: var(--bp-text-muted); } .units-form input { width: 100%; padding: 10px 12px; margin-bottom: 8px; border: 1px solid var(--bp-border); border-radius: 8px; background: var(--bp-bg); color: var(--bp-text); font-size: 13px; } .units-form input:focus { outline: none; border-color: var(--bp-primary); } .units-form .form-row { display: flex; gap: 8px; } .units-form .form-row input { flex: 1; } .units-list { flex: 1; overflow-y: auto; padding: 8px; } .unit-list-item { display: flex; align-items: center; justify-content: space-between; padding: 12px; border-radius: 8px; cursor: pointer; transition: all 0.2s; margin-bottom: 4px; } .unit-list-item:hover { background: var(--bp-bg); } .unit-list-item.selected { background: var(--bp-primary); color: white; } .unit-info { flex: 1; min-width: 0; } .unit-name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .unit-meta { font-size: 11px; opacity: 0.7; margin-top: 2px; } .unit-delete { opacity: 0; cursor: pointer; padding: 4px; font-size: 12px; } .unit-list-item:hover .unit-delete { opacity: 0.6; } .unit-list-item:hover .unit-delete:hover { opacity: 1; color: #ef4444; } .units-main { background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 12px; padding: 24px; overflow-y: auto; } .units-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 300px; text-align: center; color: var(--bp-text-muted); } .units-empty-icon { font-size: 48px; margin-bottom: 16px; opacity: 0.5; } /* ============================================ SUB-MODULE STYLES: File Upload ============================================ */ .upload-container { max-width: 800px; margin: 0 auto; } .upload-drop-zone { border: 2px dashed var(--bp-border); border-radius: 16px; padding: 48px; text-align: center; cursor: pointer; transition: all 0.3s; background: var(--bp-surface); } .upload-drop-zone:hover, .upload-drop-zone.dragover { border-color: var(--bp-primary); background: rgba(59, 130, 246, 0.05); } .upload-icon { font-size: 48px; margin-bottom: 16px; } .upload-title { font-size: 18px; font-weight: 600; margin-bottom: 8px; } .upload-hint { font-size: 14px; color: var(--bp-text-muted); margin-bottom: 16px; } .upload-formats { font-size: 12px; color: var(--bp-text-muted); padding: 8px 16px; background: var(--bp-bg); border-radius: 20px; display: inline-block; } .upload-progress { margin-top: 24px; padding: 16px; background: var(--bp-bg); border-radius: 12px; } .upload-file-item { display: flex; align-items: center; gap: 12px; padding: 8px 0; } .upload-file-name { flex: 1; font-size: 13px; } .upload-file-status { font-size: 12px; color: var(--bp-text-muted); } /* ============================================ SUB-MODULE STYLES: Generator Tiles ============================================ */ .generator-options { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-top: 24px; } .generator-option { padding: 20px; background: var(--bp-surface); border: 1px solid var(--bp-border); border-radius: 12px; cursor: pointer; transition: all 0.2s; text-align: center; } .generator-option:hover { border-color: var(--bp-primary); transform: translateY(-2px); } .generator-option.selected { border-color: var(--bp-primary); background: rgba(59, 130, 246, 0.05); } .generator-option-icon { font-size: 32px; margin-bottom: 8px; } .generator-option-title { font-weight: 600; margin-bottom: 4px; } .generator-option-desc { font-size: 12px; color: var(--bp-text-muted); } /* ============================================ Legacy Support: Original 3-Column Layout ============================================ */ /* Linke Spalte - Lerneinheiten */ .worksheets-units-panel { width: 280px; border-right: 1px solid var(--bp-border); display: flex; flex-direction: column; background: var(--bp-surface); } .units-header { padding: 16px; border-bottom: 1px solid var(--bp-border); } .units-header h3 { font-size: 14px; font-weight: 600; color: var(--bp-text-muted); margin-bottom: 12px; } /* Mittlere Spalte - Dateiliste */ .worksheets-files-panel { width: 260px; border-right: 1px solid var(--bp-border); display: flex; flex-direction: column; background: var(--bp-bg); } .files-header { padding: 12px 16px; border-bottom: 1px solid var(--bp-border); display: flex; justify-content: space-between; align-items: center; } .files-list { flex: 1; overflow-y: auto; padding: 8px; } .file-item { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; margin-bottom: 2px; border-radius: 6px; cursor: pointer; transition: background 0.2s; } .file-item:hover { background: var(--bp-surface); } .file-item.active { background: var(--bp-primary); color: white; } /* Rechte Spalte - Preview */ .worksheets-preview-panel { flex: 1; display: flex; flex-direction: column; overflow: hidden; } /* Compare Wrapper */ .compare-wrapper { flex: 1; display: flex; gap: 16px; padding: 16px; overflow: hidden; } .compare-section { flex: 1; display: flex; flex-direction: column; border-radius: 12px; overflow: hidden; background: var(--bp-surface); border: 1px solid var(--bp-border); } .compare-header { display: flex; justify-content: space-between; align-items: center; padding: 10px 16px; background: var(--bp-bg); border-bottom: 1px solid var(--bp-border); font-size: 13px; font-weight: 500; } .compare-body { flex: 1; overflow: auto; padding: 16px; display: flex; justify-content: center; align-items: flex-start; } .preview-img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; cursor: zoom-in; } /* Lightbox */ .lightbox { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.9); display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 10000; padding: 20px; } .lightbox.hidden { display: none; } .lightbox-close { position: absolute; top: 20px; right: 20px; font-size: 32px; color: white; cursor: pointer; opacity: 0.7; transition: opacity 0.2s; } .lightbox-close:hover { opacity: 1; } .lightbox-img { max-width: 95%; max-height: 85%; object-fit: contain; } .lightbox-caption { margin-top: 16px; color: rgba(255, 255, 255, 0.7); font-size: 14px; } """ @staticmethod def get_html() -> str: """HTML fuer das Worksheets-Modul mit Kachel-basierter Startansicht.""" return """

Arbeitsblaetter Studio

Erstelle und verwalte Lernmaterialien fuer deine Schueler

📝
Erstellen & Verwalten
Lerneinheiten anlegen und Materialien hochladen
📚
Lerneinheiten
Erstelle und verwalte Lerneinheiten fuer deine Schueler. Ordne Materialien zu und verfolge den Fortschritt.
CRUD Organisation
📤
Dateien hochladen
Lade Arbeitsblaetter, Bilder und PDFs hoch. Unterstuetzt Drag & Drop und Batch-Upload.
PDF Bilder Batch
Verarbeiten
Automatische Aufbereitung und Bereinigung
🔧
Dateien bereinigen
OCR-Verarbeitung und automatischer Neuaufbau von gescannten Arbeitsblaettern.
OCR Neuaufbau AI
🎯
Lernflows
Interaktive Lernpfade erstellen. Kombiniere verschiedene Aufgabentypen zu einem Flow.
Interaktiv Sequenzen
Druckdateien generieren
AI-gestuetzte Erstellung von Uebungsmaterialien
Multiple Choice
Generiere Multiple-Choice-Tests aus deinen Lernmaterialien. Inkl. Antwortschluessel.
Tests AI Druckbar
📝
Lueckentexte
Erstelle Lueckentexte fuer effektives Vokabel- und Faktenlernen.
Uebung AI Druckbar
🗺
Mindmap
Visualisiere Zusammenhaenge in einer uebersichtlichen Mindmap.
Visualisierung AI
Fragen & Antworten
Generiere Fragenkataloge und Lernkarten aus deinen Materialien.
Lernkarten AI
🌐
Uebersetzen
Mehrsprachige Unterstuetzung fuer alle Materialien
🗣
Uebersetzungen
Uebersetze Arbeitsblaetter und generierte Inhalte in verschiedene Sprachen.
DE EN TR AR +10
Lerneinheiten verwalten

Neue Lerneinheit

📚

Lerneinheit auswaehlen

Waehle eine Lerneinheit aus der Liste oder erstelle eine neue.

Dateien hochladen
📤
Dateien hochladen
Dateien hierher ziehen oder klicken zum Auswaehlen
PDF, JPG, PNG - max. 50MB pro Datei
Dateien bereinigen

Waehle Dateien aus einer Lerneinheit und starte den OCR-Neuaufbau.

Multiple Choice Generator

Generiere Multiple-Choice-Tests aus deinen Lernmaterialien.

🌟
Einfach
5 Fragen, grundlegend
💪
Mittel
10 Fragen, ausgewogen
🔥
Schwer
15 Fragen, anspruchsvoll
Lueckentext Generator

Erstelle Lueckentexte aus deinen Lernmaterialien.

Mindmap Generator

Erstelle eine visuelle Mindmap aus deinen Lernmaterialien.

Fragen & Antworten Generator

Generiere Fragen und Antworten fuer Lernkarten.

Lernflows erstellen

Erstelle interaktive Lernpfade aus verschiedenen Aufgabentypen.

Uebersetzungen

Uebersetze deine Materialien in verschiedene Sprachen.

🇬🇧
Englisch
🇹🇷
Tuerkisch
🇦🇪
Arabisch
🇺🇦
Ukrainisch
Bereit
""" @staticmethod def get_js() -> str: """JavaScript fuer das Worksheets-Modul.""" return """ // ============================================= // WORKSHEETS MODULE - Refactored with Tiles // ============================================= let worksheetsInitialized = false; let worksheetsUnits = []; let worksheetsCurrentUnit = null; function loadWorksheetsModule() { if (worksheetsInitialized) { console.log('Worksheets module already initialized'); return; } console.log('Loading Worksheets Module (Tiles)...'); // Initialize upload zone initWorksheetsUpload(); // Load units loadWorksheetsUnits(); // Init lightbox initWorksheetsLightbox(); worksheetsInitialized = true; console.log('Worksheets Module loaded successfully'); } // ============================================= // VIEW SWITCHING // ============================================= function showWorksheetsTiles() { document.getElementById('worksheets-tiles-view').style.display = 'block'; closeWorksheetsSubpanel(); document.querySelectorAll('.worksheets-nav-btn').forEach(btn => btn.classList.remove('active')); document.querySelector('.worksheets-nav-btn').classList.add('active'); } function showWorksheetsManager() { openWorksheetsSubpanel('units'); document.querySelectorAll('.worksheets-nav-btn').forEach(btn => btn.classList.remove('active')); document.querySelectorAll('.worksheets-nav-btn')[1].classList.add('active'); } // ============================================= // SUBPANEL NAVIGATION // ============================================= function openWorksheetsSubpanel(panelId) { // Hide tiles view document.getElementById('worksheets-tiles-view').style.display = 'none'; // Hide all subpanels document.querySelectorAll('.worksheets-subpanel').forEach(p => { p.classList.remove('active'); }); // Show selected subpanel const panel = document.getElementById('worksheets-subpanel-' + panelId); if (panel) { panel.classList.add('active'); } } function closeWorksheetsSubpanel() { document.querySelectorAll('.worksheets-subpanel').forEach(p => { p.classList.remove('active'); }); document.getElementById('worksheets-tiles-view').style.display = 'block'; // Reset nav buttons document.querySelectorAll('.worksheets-nav-btn').forEach(btn => btn.classList.remove('active')); document.querySelector('.worksheets-nav-btn').classList.add('active'); } // ============================================= // STATUS // ============================================= function setWorksheetsStatus(text, detail = '', state = 'idle') { const indicator = document.getElementById('ws-status-indicator'); const textEl = document.getElementById('ws-status-text'); const detailEl = document.getElementById('ws-status-detail'); if (textEl) textEl.textContent = text; if (detailEl) detailEl.textContent = detail; if (indicator) { indicator.classList.remove('busy', 'error'); if (state === 'busy') indicator.classList.add('busy'); else if (state === 'error') indicator.classList.add('error'); } } // ============================================= // LERNEINHEITEN // ============================================= async function loadWorksheetsUnits() { try { const resp = await fetch('/api/learning-units/'); if (!resp.ok) { console.error('Failed to load units'); return; } worksheetsUnits = await resp.json(); renderWorksheetsUnits(); } catch (e) { console.error('Error loading units:', e); } } function renderWorksheetsUnits() { const container = document.getElementById('units-list-container'); if (!container) return; if (!worksheetsUnits.length) { container.innerHTML = '
Keine Lerneinheiten vorhanden
'; return; } container.innerHTML = worksheetsUnits.map(unit => `
${unit.label || unit.title || 'Lerneinheit'}
${unit.subject || ''} ${unit.grade || ''} - ${(unit.worksheet_files || []).length} Dateien
🗑
`).join(''); } function selectWorksheetsUnit(unitId) { worksheetsCurrentUnit = worksheetsUnits.find(u => u.id === unitId); renderWorksheetsUnits(); showUnitDetail(); } function showUnitDetail() { const container = document.getElementById('units-detail-container'); if (!container || !worksheetsCurrentUnit) return; const unit = worksheetsCurrentUnit; const files = unit.worksheet_files || []; container.innerHTML = `

${unit.label || unit.title}

${unit.student_name ? 'Schueler: ' + unit.student_name + ' | ' : ''} ${unit.subject || ''} ${unit.grade || ''}

Zugeordnete Dateien (${files.length})

${files.length ? `
${files.map(f => `
${f}
`).join('')}
` : '

Keine Dateien zugeordnet

'}
`; } async function createNewUnit() { const student = document.getElementById('new-unit-student')?.value.trim() || ''; const subject = document.getElementById('new-unit-subject')?.value.trim() || ''; const grade = document.getElementById('new-unit-grade')?.value.trim() || ''; const title = document.getElementById('new-unit-title')?.value.trim() || ''; if (!title) { alert('Bitte einen Titel eingeben'); return; } try { setWorksheetsStatus('Erstelle Lerneinheit...', '', 'busy'); const resp = await fetch('/api/learning-units/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ label: title, student_name: student, subject: subject, grade: grade, title: title }) }); if (!resp.ok) { throw new Error('Failed to create unit'); } const newUnit = await resp.json(); worksheetsUnits.push(newUnit); worksheetsCurrentUnit = newUnit; // Clear form ['new-unit-student', 'new-unit-subject', 'new-unit-grade', 'new-unit-title'].forEach(id => { const el = document.getElementById(id); if (el) el.value = ''; }); renderWorksheetsUnits(); showUnitDetail(); setWorksheetsStatus('Lerneinheit erstellt', ''); } catch (e) { console.error(e); setWorksheetsStatus('Fehler', String(e), 'error'); } } async function deleteWorksheetsUnit(unitId) { if (!confirm('Lerneinheit wirklich loeschen?')) return; try { setWorksheetsStatus('Loesche Lerneinheit...', '', 'busy'); const resp = await fetch(`/api/learning-units/${unitId}`, { method: 'DELETE' }); if (!resp.ok) { throw new Error('Failed to delete unit'); } worksheetsUnits = worksheetsUnits.filter(u => u.id !== unitId); if (worksheetsCurrentUnit?.id === unitId) { worksheetsCurrentUnit = null; } renderWorksheetsUnits(); setWorksheetsStatus('Lerneinheit geloescht', ''); } catch (e) { console.error(e); setWorksheetsStatus('Fehler', String(e), 'error'); } } // ============================================= // FILE UPLOAD // ============================================= function initWorksheetsUpload() { const dropZone = document.getElementById('worksheets-upload-zone'); const fileInput = document.getElementById('worksheets-file-input'); if (!dropZone || !fileInput) return; dropZone.addEventListener('click', () => fileInput.click()); dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.classList.add('dragover'); }); dropZone.addEventListener('dragleave', () => { dropZone.classList.remove('dragover'); }); dropZone.addEventListener('drop', (e) => { e.preventDefault(); dropZone.classList.remove('dragover'); if (e.dataTransfer.files.length) { uploadWorksheetsFiles(e.dataTransfer.files); } }); fileInput.addEventListener('change', () => { if (fileInput.files.length) { uploadWorksheetsFiles(fileInput.files); } }); } async function uploadWorksheetsFiles(files) { const formData = new FormData(); for (const file of files) { formData.append('files', file); } try { setWorksheetsStatus('Lade hoch...', `${files.length} Datei(en)`, 'busy'); const resp = await fetch('/api/upload', { method: 'POST', body: formData }); if (!resp.ok) { throw new Error('Upload failed'); } setWorksheetsStatus('Upload erfolgreich', `${files.length} Datei(en)`); // If unit selected, offer to add files if (worksheetsCurrentUnit) { // Could auto-add here } } catch (e) { console.error(e); setWorksheetsStatus('Upload fehlgeschlagen', String(e), 'error'); } } // ============================================= // GENERATORS - Connected to /api/worksheets/ // ============================================= let generatorDifficulty = 'medium'; let generatorNumQuestions = 10; let generatedContent = null; function selectGeneratorOption(el, difficulty) { document.querySelectorAll('.generator-option').forEach(o => o.classList.remove('selected')); el.classList.add('selected'); generatorDifficulty = difficulty; generatorNumQuestions = difficulty === 'easy' ? 5 : difficulty === 'medium' ? 10 : 15; } // Get source text from current unit or prompt user async function getSourceText() { if (worksheetsCurrentUnit && worksheetsCurrentUnit.worksheet_files?.length > 0) { // In production: extract text from files via OCR/parser // For now, prompt user for text input const text = prompt('Gib den Quelltext ein (min. 50 Zeichen) oder fuege Inhalt aus deiner Lerneinheit ein:'); return text; } return prompt('Gib den Quelltext ein (min. 50 Zeichen):'); } async function generateMC() { const sourceText = await getSourceText(); if (!sourceText || sourceText.length < 50) { alert('Bitte einen laengeren Text eingeben (mind. 50 Zeichen).'); return; } setWorksheetsStatus('Generiere MC-Test...', '', 'busy'); try { const resp = await fetch('/api/worksheets/generate/multiple-choice', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ source_text: sourceText, num_questions: generatorNumQuestions, difficulty: generatorDifficulty, topic: worksheetsCurrentUnit?.title || 'Lerneinheit', subject: worksheetsCurrentUnit?.subject || null }) }); const result = await resp.json(); if (!result.success) { throw new Error(result.error || 'Generation failed'); } generatedContent = result.content; setWorksheetsStatus('MC-Test generiert', `${result.content.data.questions.length} Fragen`); showGeneratedMC(result.content); } catch (e) { console.error(e); setWorksheetsStatus('Generation fehlgeschlagen', String(e), 'error'); alert('Fehler bei der MC-Generierung: ' + e.message); } } function showGeneratedMC(content) { const questions = content.data.questions; const container = document.querySelector('#worksheets-subpanel-mc .subpanel-content'); let html = `

Generierte Fragen (${questions.length})

`; questions.forEach((q, i) => { html += `
Frage ${i + 1}: ${q.question}
    ${q.options.map(opt => `
  • ${opt.text} ${opt.is_correct ? '✓' : ''}
  • `).join('')}
`; }); html += `
`; container.innerHTML = html; } async function generateCloze() { const sourceText = await getSourceText(); if (!sourceText || sourceText.length < 50) { alert('Bitte einen laengeren Text eingeben (mind. 50 Zeichen).'); return; } setWorksheetsStatus('Generiere Lueckentext...', '', 'busy'); try { const resp = await fetch('/api/worksheets/generate/cloze', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ source_text: sourceText, num_gaps: generatorDifficulty === 'easy' ? 3 : generatorDifficulty === 'medium' ? 5 : 8, difficulty: generatorDifficulty, cloze_type: 'fill_in', topic: worksheetsCurrentUnit?.title || null }) }); const result = await resp.json(); if (!result.success) { throw new Error(result.error || 'Generation failed'); } generatedContent = result.content; setWorksheetsStatus('Lueckentext generiert', `${result.content.data.gaps.length} Luecken`); showGeneratedCloze(result.content); } catch (e) { console.error(e); setWorksheetsStatus('Generation fehlgeschlagen', String(e), 'error'); alert('Fehler bei der Lueckentext-Generierung: ' + e.message); } } function showGeneratedCloze(content) { const container = document.querySelector('#worksheets-subpanel-cloze .subpanel-content'); const clozeData = content.data; let html = `

Generierter Lueckentext

${clozeData.text_with_gaps}

Loesungen:

${clozeData.gaps.map((g, i) => ` ${i + 1}. ${g.answer} `).join('')}
`; container.innerHTML = html; } async function generateMindmap() { const sourceText = await getSourceText(); if (!sourceText || sourceText.length < 50) { alert('Bitte einen laengeren Text eingeben (mind. 50 Zeichen).'); return; } setWorksheetsStatus('Generiere Mindmap...', '', 'busy'); try { const resp = await fetch('/api/worksheets/generate/mindmap', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ source_text: sourceText, topic: worksheetsCurrentUnit?.title || 'Thema', max_depth: 3 }) }); const result = await resp.json(); if (!result.success) { throw new Error(result.error || 'Generation failed'); } generatedContent = result.content; setWorksheetsStatus('Mindmap generiert', `${result.content.data.mindmap.total_nodes} Knoten`); showGeneratedMindmap(result.content); } catch (e) { console.error(e); setWorksheetsStatus('Generation fehlgeschlagen', String(e), 'error'); alert('Fehler bei der Mindmap-Generierung: ' + e.message); } } function showGeneratedMindmap(content) { const container = document.querySelector('#worksheets-subpanel-mindmap .subpanel-content'); const mindmap = content.data.mindmap; const mermaid = content.data.mermaid; let html = `

Generierte Mindmap: ${mindmap.title}

${mermaid}

Struktur:

${renderMindmapNode(mindmap.root)}
`; container.innerHTML = html; } function renderMindmapNode(node, indent = 0) { const padding = indent * 20; let html = `
${indent > 0 ? '├─ ' : ''}${node.label}
`; if (node.children) { node.children.forEach(child => { html += renderMindmapNode(child, indent + 1); }); } return html; } function copyMermaidCode() { if (generatedContent?.data?.mermaid) { navigator.clipboard.writeText(generatedContent.data.mermaid); alert('Mermaid-Code in Zwischenablage kopiert!'); } } async function generateQA() { const sourceText = await getSourceText(); if (!sourceText || sourceText.length < 50) { alert('Bitte einen laengeren Text eingeben (mind. 50 Zeichen).'); return; } setWorksheetsStatus('Generiere Quiz...', '', 'busy'); try { const resp = await fetch('/api/worksheets/generate/quiz', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ source_text: sourceText, quiz_types: ['true_false', 'matching'], num_items: generatorDifficulty === 'easy' ? 3 : 5, difficulty: generatorDifficulty, topic: worksheetsCurrentUnit?.title || null }) }); const result = await resp.json(); if (!result.success) { throw new Error(result.error || 'Generation failed'); } generatedContent = result.content; const totalItems = (result.content.data.true_false_questions?.length || 0) + (result.content.data.matching_pairs?.length || 0); setWorksheetsStatus('Quiz generiert', `${totalItems} Items`); showGeneratedQuiz(result.content); } catch (e) { console.error(e); setWorksheetsStatus('Generation fehlgeschlagen', String(e), 'error'); alert('Fehler bei der Quiz-Generierung: ' + e.message); } } function showGeneratedQuiz(content) { const container = document.querySelector('#worksheets-subpanel-qa .subpanel-content'); const quiz = content.data; let html = `

Generiertes Quiz

`; if (quiz.true_false_questions?.length > 0) { html += `

Richtig/Falsch Fragen:

`; quiz.true_false_questions.forEach((q, i) => { html += `
${i + 1}. ${q.statement} ${q.is_true ? '✓ Richtig' : '✗ Falsch'}
`; }); } if (quiz.matching_pairs?.length > 0) { html += `

Zuordnungsaufgaben:

`; quiz.matching_pairs.forEach((p, i) => { html += `
${p.left} ${p.right}
`; }); } html += `
`; container.innerHTML = html; } // Export functions async function exportGeneratedContent(format) { if (!generatedContent) { alert('Kein generierter Inhalt vorhanden.'); return; } if (format === 'h5p' && generatedContent.h5p_format) { // Download H5P format as JSON (real H5P package would need backend support) const blob = new Blob([JSON.stringify(generatedContent.h5p_format, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `content_h5p_${generatedContent.id}.json`; a.click(); URL.revokeObjectURL(url); } else if (format === 'json') { const blob = new Blob([JSON.stringify(generatedContent.data, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `content_${generatedContent.content_type}_${generatedContent.id}.json`; a.click(); URL.revokeObjectURL(url); } } function printGeneratedContent() { window.print(); } function createLernflow() { alert('Lernflow-Editor: Kombiniere mehrere Generatoren zu einem interaktiven Lernpfad. Kommt in einer spaeteren Version!'); } function selectLanguage(lang) { alert('Uebersetzung nach ' + lang.toUpperCase() + ': Diese Funktion wird mit DeepL/LLM-Integration umgesetzt. Kommt bald!'); } // ============================================= // LIGHTBOX // ============================================= function initWorksheetsLightbox() { const lightbox = document.getElementById('lightbox'); const closeBtn = document.getElementById('lightbox-close'); if (closeBtn) { closeBtn.addEventListener('click', closeLightbox); } if (lightbox) { lightbox.addEventListener('click', (e) => { if (e.target === lightbox) closeLightbox(); }); } } function openLightbox(src, caption) { const lightbox = document.getElementById('lightbox'); const img = document.getElementById('lightbox-img'); const captionEl = document.getElementById('lightbox-caption'); if (!lightbox || !src) return; img.src = src; captionEl.textContent = caption || ''; lightbox.classList.remove('hidden'); } function closeLightbox() { const lightbox = document.getElementById('lightbox'); if (lightbox) lightbox.classList.add('hidden'); } // ============================================= // SHOW PANEL // ============================================= function showWorksheetsPanel() { console.log('showWorksheetsPanel called'); hideAllPanels(); if (typeof hideStudioSubMenu === 'function') hideStudioSubMenu(); const panel = document.getElementById('panel-worksheets'); if (panel) { panel.style.display = 'flex'; loadWorksheetsModule(); console.log('Worksheets panel shown'); } else { console.error('panel-worksheets not found'); } } // Escape key to close subpanels document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { closeLightbox(); if (document.querySelector('.worksheets-subpanel.active')) { closeWorksheetsSubpanel(); } } }); """