""" To-Do Widget fuer das Lehrer-Dashboard. Zeigt eine interaktive To-Do-Liste mit localStorage-Persistierung. """ class TodosWidget: widget_id = 'todos' widget_name = 'To-Dos' widget_icon = '✓' # Checkmark widget_color = '#10b981' # Green default_width = 'half' has_settings = True @staticmethod def get_css() -> str: return """ /* ===== To-Do Widget Styles ===== */ .widget-todos { 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-todos .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-todos .widget-title { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: var(--bp-text, #e5e7eb); } .widget-todos .widget-icon { width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; background: rgba(16, 185, 129, 0.15); color: #10b981; border-radius: 8px; font-size: 14px; } .widget-todos .todo-list { flex: 1; overflow-y: auto; margin-bottom: 12px; } .widget-todos .todo-item { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--bp-border-subtle, rgba(255,255,255,0.05)); transition: background 0.2s; } .widget-todos .todo-item:last-child { border-bottom: none; } .widget-todos .todo-item:hover { background: var(--bp-surface-elevated, #334155); margin: 0 -8px; padding: 10px 8px; border-radius: 6px; } .widget-todos .todo-checkbox { width: 18px; height: 18px; border: 2px solid var(--bp-border, #475569); border-radius: 4px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s; flex-shrink: 0; } .widget-todos .todo-checkbox:hover { border-color: #10b981; } .widget-todos .todo-checkbox.checked { background: #10b981; border-color: #10b981; } .widget-todos .todo-checkbox.checked::after { content: '\\2713'; color: white; font-size: 12px; font-weight: bold; } .widget-todos .todo-text { flex: 1; font-size: 13px; color: var(--bp-text, #e5e7eb); line-height: 1.4; } .widget-todos .todo-item.completed .todo-text { text-decoration: line-through; color: var(--bp-text-muted, #9ca3af); } .widget-todos .todo-delete { opacity: 0; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; background: rgba(239, 68, 68, 0.1); color: #ef4444; border: none; border-radius: 4px; cursor: pointer; transition: all 0.2s; font-size: 14px; } .widget-todos .todo-item:hover .todo-delete { opacity: 1; } .widget-todos .todo-delete:hover { background: rgba(239, 68, 68, 0.2); } .widget-todos .todo-add { display: flex; gap: 8px; } .widget-todos .todo-input { flex: 1; background: var(--bp-bg, #0f172a); border: 1px solid var(--bp-border, #475569); border-radius: 6px; padding: 8px 12px; font-size: 13px; color: var(--bp-text, #e5e7eb); outline: none; transition: border-color 0.2s; } .widget-todos .todo-input:focus { border-color: #10b981; } .widget-todos .todo-input::placeholder { color: var(--bp-text-muted, #9ca3af); } .widget-todos .todo-add-btn { background: #10b981; color: white; border: none; border-radius: 6px; padding: 8px 14px; font-size: 13px; font-weight: 500; cursor: pointer; transition: background 0.2s; } .widget-todos .todo-add-btn:hover { background: #059669; } .widget-todos .todo-empty { text-align: center; padding: 24px; color: var(--bp-text-muted, #9ca3af); font-size: 13px; } .widget-todos .todo-empty-icon { font-size: 32px; margin-bottom: 8px; opacity: 0.5; } """ @staticmethod def get_html() -> str: return """
""" @staticmethod def get_js() -> str: return """ // ===== To-Do Widget JavaScript ===== const TODOS_STORAGE_KEY = 'bp-lehrer-todos'; function loadTodos() { const stored = localStorage.getItem(TODOS_STORAGE_KEY); return stored ? JSON.parse(stored) : []; } function saveTodos(todos) { localStorage.setItem(TODOS_STORAGE_KEY, JSON.stringify(todos)); } function renderTodos() { const todoList = document.getElementById('todo-list'); if (!todoList) return; const todos = loadTodos(); if (todos.length === 0) { todoList.innerHTML = `