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:
76
backend/frontend/meetings/pages/active.py
Normal file
76
backend/frontend/meetings/pages/active.py
Normal file
@@ -0,0 +1,76 @@
|
||||
"""
|
||||
Meetings Module - Active Meetings Page
|
||||
List of currently active meetings
|
||||
"""
|
||||
|
||||
from ..templates import ICONS, render_base_page
|
||||
|
||||
|
||||
def active_meetings() -> str:
|
||||
"""Active meetings list"""
|
||||
content = f'''
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h1 class="page-title">Aktive Meetings</h1>
|
||||
<p class="page-subtitle">Laufende Videokonferenzen und Schulungen</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="window.location.href='/meetings/quick'">
|
||||
{ICONS['plus']} Neues Meeting starten
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Active Meetings List -->
|
||||
<div class="meeting-list" id="activeMeetingsList">
|
||||
<div style="text-align: center; padding: 3rem; color: var(--bp-text-muted);">
|
||||
<p>Keine aktiven Meetings</p>
|
||||
<p style="font-size: 0.875rem; margin-top: 0.5rem;">
|
||||
Starten Sie ein neues Meeting oder warten Sie, bis ein geplantes Meeting beginnt.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function loadActiveMeetings() {{
|
||||
try {{
|
||||
const response = await fetch('/api/meetings/active');
|
||||
if (response.ok) {{
|
||||
const meetings = await response.json();
|
||||
renderMeetings(meetings);
|
||||
}}
|
||||
}} catch (error) {{
|
||||
console.error('Error loading active meetings:', error);
|
||||
}}
|
||||
}}
|
||||
|
||||
function renderMeetings(meetings) {{
|
||||
const container = document.getElementById('activeMeetingsList');
|
||||
|
||||
if (!meetings || meetings.length === 0) {{
|
||||
return;
|
||||
}}
|
||||
|
||||
container.innerHTML = meetings.map(meeting => `
|
||||
<div class="meeting-item">
|
||||
<div class="meeting-time">
|
||||
<div class="meeting-time-value">${{meeting.participants || 0}}</div>
|
||||
<div class="meeting-time-date">Teilnehmer</div>
|
||||
</div>
|
||||
<div class="meeting-info">
|
||||
<div class="meeting-title">${{meeting.title}}</div>
|
||||
<div class="meeting-meta">
|
||||
<span>{ICONS['clock']} Seit ${{meeting.started_at}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="meeting-badge badge-live">LIVE</span>
|
||||
<div class="meeting-actions">
|
||||
<button class="btn btn-primary" onclick="window.location.href='/meetings/room/${{meeting.room_name}}'">Beitreten</button>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
}}
|
||||
|
||||
loadActiveMeetings();
|
||||
</script>
|
||||
'''
|
||||
|
||||
return render_base_page("Aktive Meetings", content, "active")
|
||||
Reference in New Issue
Block a user