This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
BreakPilot Dev 19855efacc
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed
feat: BreakPilot PWA - Full codebase (clean push without large binaries)
All services: admin-v2, studio-v2, website, ai-compliance-sdk,
consent-service, klausur-service, voice-service, and infrastructure.
Large PDFs and compiled binaries excluded via .gitignore.
2026-02-11 13:25:58 +01:00

207 lines
7.5 KiB
Python

"""
Meetings Module - Schedule Page
Schedule and manage upcoming meetings
"""
from ..templates import ICONS, render_base_page
def schedule_meetings() -> str:
"""Schedule and manage upcoming meetings"""
content = f'''
<div class="page-header">
<div>
<h1 class="page-title">Termine</h1>
<p class="page-subtitle">Geplante Meetings und Termine verwalten</p>
</div>
<button class="btn btn-primary" onclick="openScheduleModal()">
{ICONS['plus']} Meeting planen
</button>
</div>
<!-- Tabs -->
<div class="tabs">
<button class="tab active" onclick="filterMeetings('all')">Alle</button>
<button class="tab" onclick="filterMeetings('today')">Heute</button>
<button class="tab" onclick="filterMeetings('week')">Diese Woche</button>
<button class="tab" onclick="filterMeetings('month')">Dieser Monat</button>
</div>
<div class="meeting-list" id="scheduledMeetings">
<div class="meeting-item">
<div class="meeting-time">
<div class="meeting-time-value">14:00</div>
<div class="meeting-time-date">Mo, 16.12.</div>
</div>
<div class="meeting-info">
<div class="meeting-title">Team-Besprechung</div>
<div class="meeting-meta">
<span>{ICONS['clock']} 60 Min</span>
<span>{ICONS['users']} 5 Teilnehmer</span>
</div>
</div>
<span class="meeting-badge badge-scheduled">Geplant</span>
<div class="meeting-actions">
<button class="btn btn-primary" onclick="joinMeeting('team-abc')">Beitreten</button>
<button class="btn-icon" onclick="editMeeting('team-abc')">{ICONS['settings']}</button>
<button class="btn-icon" onclick="copyLink('team-abc')">{ICONS['link']}</button>
<button class="btn-icon" onclick="deleteMeeting('team-abc')">{ICONS['trash']}</button>
</div>
</div>
<div class="meeting-item">
<div class="meeting-time">
<div class="meeting-time-value">09:30</div>
<div class="meeting-time-date">Di, 17.12.</div>
</div>
<div class="meeting-info">
<div class="meeting-title">Elterngespräch - Anna Schmidt</div>
<div class="meeting-meta">
<span>{ICONS['clock']} 30 Min</span>
<span>{ICONS['users']} 2 Teilnehmer</span>
</div>
</div>
<span class="meeting-badge badge-scheduled">Geplant</span>
<div class="meeting-actions">
<button class="btn btn-primary" onclick="joinMeeting('parent-xyz')">Beitreten</button>
<button class="btn-icon" onclick="editMeeting('parent-xyz')">{ICONS['settings']}</button>
<button class="btn-icon" onclick="copyLink('parent-xyz')">{ICONS['link']}</button>
<button class="btn-icon" onclick="deleteMeeting('parent-xyz')">{ICONS['trash']}</button>
</div>
</div>
</div>
<!-- Schedule Modal -->
<div class="modal-overlay" id="scheduleModal">
<div class="modal">
<div class="modal-header">
<h2 class="modal-title">Meeting planen</h2>
<button class="modal-close" onclick="closeScheduleModal()">&times;</button>
</div>
<div class="modal-body">
<div class="form-group">
<label class="form-label">Titel</label>
<input type="text" class="form-input" id="scheduleTitle" placeholder="Meeting-Titel">
</div>
<div class="form-group">
<label class="form-label">Datum</label>
<input type="date" class="form-input" id="scheduleDate">
</div>
<div class="form-group">
<label class="form-label">Uhrzeit</label>
<input type="time" class="form-input" id="scheduleTime">
</div>
<div class="form-group">
<label class="form-label">Dauer</label>
<select class="form-select" id="scheduleDuration">
<option value="30">30 Minuten</option>
<option value="60" selected>60 Minuten</option>
<option value="90">90 Minuten</option>
<option value="120">120 Minuten</option>
</select>
</div>
<div class="form-group">
<label class="form-label">Beschreibung (optional)</label>
<textarea class="form-textarea" id="scheduleDescription" placeholder="Agenda oder Beschreibung..."></textarea>
</div>
<div class="form-group">
<label class="form-label">Teilnehmer einladen</label>
<input type="email" class="form-input" id="scheduleInvites" placeholder="E-Mail-Adressen (kommagetrennt)">
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" onclick="closeScheduleModal()">Abbrechen</button>
<button class="btn btn-primary" onclick="scheduleMeeting()">Meeting planen</button>
</div>
</div>
</div>
<script>
function openScheduleModal() {{
document.getElementById('scheduleModal').classList.add('active');
// Set default date to today
document.getElementById('scheduleDate').valueAsDate = new Date();
}}
function closeScheduleModal() {{
document.getElementById('scheduleModal').classList.remove('active');
}}
async function scheduleMeeting() {{
const title = document.getElementById('scheduleTitle').value;
const date = document.getElementById('scheduleDate').value;
const time = document.getElementById('scheduleTime').value;
const duration = document.getElementById('scheduleDuration').value;
const description = document.getElementById('scheduleDescription').value;
const invites = document.getElementById('scheduleInvites').value;
if (!title || !date || !time) {{
alert('Bitte füllen Sie alle Pflichtfelder aus.');
return;
}}
const payload = {{
title,
scheduled_at: `${{date}}T${{time}}`,
duration: parseInt(duration),
description,
invites: invites.split(',').map(e => e.trim()).filter(e => e)
}};
try {{
const response = await fetch('/api/meetings/schedule', {{
method: 'POST',
headers: {{ 'Content-Type': 'application/json' }},
body: JSON.stringify(payload)
}});
if (response.ok) {{
alert('Meeting erfolgreich geplant!');
closeScheduleModal();
location.reload();
}}
}} catch (error) {{
console.error('Error:', error);
}}
}}
function filterMeetings(filter) {{
// Update active tab
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
event.target.classList.add('active');
// Filter logic would go here
console.log('Filter:', filter);
}}
function joinMeeting(roomId) {{
window.location.href = '/meetings/room/' + roomId;
}}
function editMeeting(roomId) {{
// Open edit modal
console.log('Edit:', roomId);
}}
function copyLink(roomId) {{
const link = window.location.origin + '/meetings/room/' + roomId;
navigator.clipboard.writeText(link);
alert('Link kopiert!');
}}
function deleteMeeting(roomId) {{
if (confirm('Meeting wirklich löschen?')) {{
// Delete logic
console.log('Delete:', roomId);
}}
}}
</script>
'''
return render_base_page("Termine", content, "schedule")