fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
138
backend/frontend/meetings/pages/quick_actions.py
Normal file
138
backend/frontend/meetings/pages/quick_actions.py
Normal file
@@ -0,0 +1,138 @@
|
||||
"""
|
||||
Meetings Module - Quick Actions Pages
|
||||
Quick meeting start and parent-teacher meeting creation
|
||||
"""
|
||||
|
||||
import uuid
|
||||
from ..templates import ICONS, render_base_page
|
||||
|
||||
|
||||
def quick_meeting() -> str:
|
||||
"""Start a quick meeting immediately"""
|
||||
room_name = f"quick-{uuid.uuid4().hex[:8]}"
|
||||
|
||||
content = f'''
|
||||
<div style="text-align: center; padding: 3rem;">
|
||||
<h1 class="page-title">Sofort-Meeting wird gestartet...</h1>
|
||||
<p class="page-subtitle">Sie werden in wenigen Sekunden weitergeleitet.</p>
|
||||
<div style="margin-top: 2rem;">
|
||||
<div class="card-icon primary" style="margin: 0 auto; width: 80px; height: 80px; font-size: 2rem;">
|
||||
{ICONS['video']}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
setTimeout(() => {{
|
||||
window.location.href = '/meetings/room/{room_name}';
|
||||
}}, 1000);
|
||||
</script>
|
||||
'''
|
||||
|
||||
return render_base_page("Sofort-Meeting", content, "active")
|
||||
|
||||
|
||||
def parent_teacher_meeting() -> str:
|
||||
"""Create a parent-teacher meeting"""
|
||||
content = f'''
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h1 class="page-title">Elterngespräch planen</h1>
|
||||
<p class="page-subtitle">Sicheres Meeting mit Warteraum und Passwort</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card" style="max-width: 600px;">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Schüler/in</label>
|
||||
<input type="text" class="form-input" id="studentName" placeholder="Name des Schülers/der Schülerin">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">Elternteil</label>
|
||||
<input type="text" class="form-input" id="parentName" placeholder="Name der Eltern">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">E-Mail (für Einladung)</label>
|
||||
<input type="email" class="form-input" id="parentEmail" placeholder="eltern@example.com">
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Datum</label>
|
||||
<input type="date" class="form-input" id="meetingDate">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Uhrzeit</label>
|
||||
<input type="time" class="form-input" id="meetingTime">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">Anlass (optional)</label>
|
||||
<textarea class="form-textarea" id="meetingReason" placeholder="Grund für das Gespräch..."></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
<input type="checkbox" id="sendInvite" checked> Einladung per E-Mail senden
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" style="margin-top: 1.5rem;">
|
||||
<button class="btn btn-secondary" onclick="window.location.href='/meetings'">Abbrechen</button>
|
||||
<button class="btn btn-primary" onclick="createParentTeacherMeeting()">Termin erstellen</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Set minimum date to today
|
||||
document.getElementById('meetingDate').min = new Date().toISOString().split('T')[0];
|
||||
|
||||
async function createParentTeacherMeeting() {{
|
||||
const studentName = document.getElementById('studentName').value;
|
||||
const parentName = document.getElementById('parentName').value;
|
||||
const parentEmail = document.getElementById('parentEmail').value;
|
||||
const date = document.getElementById('meetingDate').value;
|
||||
const time = document.getElementById('meetingTime').value;
|
||||
const reason = document.getElementById('meetingReason').value;
|
||||
const sendInvite = document.getElementById('sendInvite').checked;
|
||||
|
||||
if (!studentName || !parentName || !date || !time) {{
|
||||
alert('Bitte füllen Sie alle Pflichtfelder aus.');
|
||||
return;
|
||||
}}
|
||||
|
||||
const payload = {{
|
||||
type: 'parent-teacher',
|
||||
student_name: studentName,
|
||||
parent_name: parentName,
|
||||
parent_email: parentEmail,
|
||||
scheduled_at: `${{date}}T${{time}}`,
|
||||
reason: reason,
|
||||
send_invite: sendInvite,
|
||||
duration: 30
|
||||
}};
|
||||
|
||||
try {{
|
||||
const response = await fetch('/api/meetings/parent-teacher', {{
|
||||
method: 'POST',
|
||||
headers: {{ 'Content-Type': 'application/json' }},
|
||||
body: JSON.stringify(payload)
|
||||
}});
|
||||
|
||||
if (response.ok) {{
|
||||
const data = await response.json();
|
||||
alert('Elterngespräch erfolgreich geplant!\\n\\nLink: ' + data.join_url + '\\nPasswort: ' + data.password);
|
||||
window.location.href = '/meetings/schedule';
|
||||
}}
|
||||
}} catch (error) {{
|
||||
console.error('Error:', error);
|
||||
alert('Fehler beim Erstellen des Termins');
|
||||
}}
|
||||
}}
|
||||
</script>
|
||||
'''
|
||||
|
||||
return render_base_page("Elterngespräch", content, "schedule")
|
||||
Reference in New Issue
Block a user