""" Kalender Widget fuer das Lehrer-Dashboard. Zeigt anstehende Termine und Events. """ class KalenderWidget: widget_id = 'kalender' widget_name = 'Termine' widget_icon = '📆' # Calendar widget_color = '#ec4899' # Pink default_width = 'half' has_settings = True @staticmethod def get_css() -> str: return """ /* ===== Kalender Widget Styles ===== */ .widget-kalender { background: var(--bp-surface, #1e293b); border: 1px solid var(--bp-border, #475569); border-radius: 12px; padding: 16px; height: 100%; display: flex; flex-direction: column; } .widget-kalender .widget-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--bp-border-subtle, rgba(255,255,255,0.1)); } .widget-kalender .widget-title { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: var(--bp-text, #e5e7eb); } .widget-kalender .widget-icon { width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; background: rgba(236, 72, 153, 0.15); color: #ec4899; border-radius: 8px; font-size: 14px; } .widget-kalender .kalender-list { flex: 1; overflow-y: auto; } .widget-kalender .termin-item { display: flex; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--bp-border-subtle, rgba(255,255,255,0.05)); } .widget-kalender .termin-item:last-child { border-bottom: none; } .widget-kalender .termin-date { width: 48px; text-align: center; flex-shrink: 0; } .widget-kalender .termin-day { font-size: 20px; font-weight: 700; color: var(--bp-text, #e5e7eb); line-height: 1; } .widget-kalender .termin-month { font-size: 11px; color: var(--bp-text-muted, #9ca3af); text-transform: uppercase; } .widget-kalender .termin-content { flex: 1; min-width: 0; } .widget-kalender .termin-title { font-size: 13px; font-weight: 500; color: var(--bp-text, #e5e7eb); margin-bottom: 4px; } .widget-kalender .termin-meta { font-size: 11px; color: var(--bp-text-muted, #9ca3af); display: flex; gap: 8px; } .widget-kalender .termin-type { display: inline-flex; align-items: center; gap: 4px; padding: 2px 6px; border-radius: 4px; font-size: 10px; } .widget-kalender .termin-type.konferenz { background: rgba(139, 92, 246, 0.15); color: #8b5cf6; } .widget-kalender .termin-type.elterngespraech { background: rgba(245, 158, 11, 0.15); color: #f59e0b; } .widget-kalender .termin-type.fortbildung { background: rgba(59, 130, 246, 0.15); color: #3b82f6; } .widget-kalender .termin-type.pruefung { background: rgba(239, 68, 68, 0.15); color: #ef4444; } .widget-kalender .kalender-empty { text-align: center; padding: 24px; color: var(--bp-text-muted, #9ca3af); font-size: 13px; } .widget-kalender .kalender-empty-icon { font-size: 32px; margin-bottom: 8px; opacity: 0.5; } .widget-kalender .kalender-footer { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--bp-border-subtle, rgba(255,255,255,0.1)); } .widget-kalender .kalender-add-btn { width: 100%; padding: 10px; background: transparent; border: 1px dashed var(--bp-border, #475569); border-radius: 8px; color: var(--bp-text-muted, #9ca3af); font-size: 12px; cursor: pointer; transition: all 0.2s; } .widget-kalender .kalender-add-btn:hover { border-color: #ec4899; color: #ec4899; } """ @staticmethod def get_html() -> str: return """
📆 Anstehende Termine
""" @staticmethod def get_js() -> str: return """ // ===== Kalender Widget JavaScript ===== const KALENDER_STORAGE_KEY = 'bp-lehrer-kalender'; function getDefaultTermine() { const today = new Date(); return [ { id: 1, titel: 'Fachkonferenz Deutsch', datum: new Date(today.getTime() + 2 * 24 * 60 * 60 * 1000).toISOString(), zeit: '14:00 - 16:00', ort: 'Konferenzraum A', typ: 'konferenz' }, { id: 2, titel: 'Elterngespraech Mueller', datum: new Date(today.getTime() + 4 * 24 * 60 * 60 * 1000).toISOString(), zeit: '17:30 - 18:00', ort: 'Klassenraum 204', typ: 'elterngespraech' }, { id: 3, titel: 'Fortbildung: Digitale Medien', datum: new Date(today.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(), zeit: '09:00 - 15:00', ort: 'Online', typ: 'fortbildung' } ]; } function loadTermine() { const stored = localStorage.getItem(KALENDER_STORAGE_KEY); return stored ? JSON.parse(stored) : getDefaultTermine(); } function saveTermine(termine) { localStorage.setItem(KALENDER_STORAGE_KEY, JSON.stringify(termine)); } function formatTerminDate(dateStr) { const date = new Date(dateStr); return { day: date.getDate(), month: date.toLocaleDateString('de-DE', { month: 'short' }) }; } function getTypLabel(typ) { const labels = { konferenz: '👥 Konferenz', elterngespraech: '👪 Eltern', fortbildung: '📚 Fortbildung', pruefung: '📝 Pruefung' }; return labels[typ] || typ; } function renderKalender() { const list = document.getElementById('kalender-list'); if (!list) return; let termine = loadTermine(); // Sort by date termine.sort((a, b) => new Date(a.datum) - new Date(b.datum)); // Filter only future events const now = new Date(); termine = termine.filter(t => new Date(t.datum) >= now); if (termine.length === 0) { list.innerHTML = `
📆
Keine anstehenden Termine
`; return; } list.innerHTML = termine.slice(0, 4).map(termin => { const dateInfo = formatTerminDate(termin.datum); return `
${dateInfo.day}
${dateInfo.month}
${termin.titel}
${getTypLabel(termin.typ)} 🕑 ${termin.zeit}
`; }).join(''); } function addTermin() { alert('Termin-Editor wird in einer zukuenftigen Version verfuegbar sein.'); } function initKalenderWidget() { renderKalender(); } """