/**
* 🌐 MASTER 08: INTERAKTIVE TASK-APP (VIEW & CONTROLLER) 🌐
* ==========================================================
* Verbindet die TaskManager-Geschäftslogik mit einer modernen,
* reaktiven Benutzeroberfläche im Browser.
*/
// Falls TaskManager noch nicht global vorhanden ist (z.B. Standalone):
if (typeof TaskManager === "undefined") {
// Fallback Minimal-Implementation oder Import
console.warn("TaskManager nicht gefunden. Lade Fallback-Definition.");
}
class TaskApp {
constructor(rootElementId = "app") {
this.root = document.getElementById(rootElementId) || document.body;
this.manager = new TaskManager([
{ id: 1, title: "TypeScript Interfaces & Union Types verstehen", priority: "high", completed: true, dueDate: "2026-08-30", createdAt: new Date().toISOString() },
{ id: 2, title: "Model-View-Controller Architektur im Web umsetzen", priority: "high", completed: false, dueDate: "2026-09-01", createdAt: new Date().toISOString() },
{ id: 3, title: "Design System & Dark Mode Akzente optimieren", priority: "medium", completed: false, dueDate: "2026-09-05", createdAt: new Date().toISOString() },
{ id: 4, title: "Automatisierte Unittests mit 100% Abdeckung schreiben", priority: "low", completed: false, dueDate: null, createdAt: new Date().toISOString() }
]);
this.currentFilter = "all";
this.searchQuery = "";
this.init();
}
init() {
this.renderLayout();
this.attachEventListeners();
this.updateView();
}
renderLayout() {
this.root.innerHTML = `
🎯 Modern Task & Project Planner
Statussichere Aufgabenverwaltung mit TypeScript & Clean Architecture
`;
}
attachEventListeners() {
// Formular-Submit
const form = document.getElementById("task-form");
if (form) {
form.addEventListener("submit", (e) => {
e.preventDefault();
const titleInput = document.getElementById("task-input-title");
const prioritySelect = document.getElementById("task-select-priority");
const dueInput = document.getElementById("task-input-due");
const title = titleInput.value.trim();
const priority = prioritySelect.value;
const dueDate = dueInput.value || null;
if (title) {
try {
this.manager.addTask(title, priority, dueDate);
titleInput.value = "";
dueInput.value = "";
this.updateView();
} catch (err) {
alert(err.message);
}
}
});
}
// Filter Buttons
const filterContainer = document.getElementById("filter-buttons");
if (filterContainer) {
filterContainer.addEventListener("click", (e) => {
const btn = e.target.closest("button[data-filter]");
if (btn) {
this.currentFilter = btn.getAttribute("data-filter");
// Button-Stile aktualisieren
filterContainer.querySelectorAll(".filter-btn").forEach((b) => {
b.style.background = "white";
b.style.color = "#475569";
b.style.borderColor = "#cbd5e1";
});
btn.style.background = "#4f46e5";
btn.style.color = "white";
btn.style.borderColor = "#4f46e5";
this.updateView();
}
});
}
// Live-Suche
const searchInput = document.getElementById("search-input");
if (searchInput) {
searchInput.addEventListener("input", (e) => {
this.searchQuery = e.target.value;
this.updateView();
});
}
// Erledigte aufräumen
const clearBtn = document.getElementById("btn-clear-completed");
if (clearBtn) {
clearBtn.addEventListener("click", () => {
if (confirm("Möchtest du alle erledigten Aufgaben wirklich entfernen?")) {
this.manager.clearCompleted();
this.updateView();
}
});
}
// Task-Liste Delegation (Toggle & Delete)
const listContainer = document.getElementById("task-list");
if (listContainer) {
listContainer.addEventListener("click", (e) => {
const target = e.target;
const taskCard = target.closest("[data-task-id]");
if (!taskCard) return;
const id = Number(taskCard.getAttribute("data-task-id"));
if (target.classList.contains("btn-delete") || target.closest(".btn-delete")) {
this.manager.deleteTask(id);
this.updateView();
} else if (target.classList.contains("task-checkbox")) {
this.manager.toggleTask(id);
this.updateView();
}
});
}
}
updateView() {
this.renderStats();
this.renderTasks();
}
renderStats() {
const stats = this.manager.getStatistics();
const elTotal = document.getElementById("stat-total");
const elActive = document.getElementById("stat-active");
const elCompleted = document.getElementById("stat-completed");
const elHigh = document.getElementById("stat-high");
if (elTotal) elTotal.textContent = stats.total;
if (elActive) elActive.textContent = stats.active;
if (elCompleted) elCompleted.textContent = stats.completed;
if (elHigh) elHigh.textContent = stats.highPriorityCount;
}
renderTasks() {
const container = document.getElementById("task-list");
if (!container) return;
const filtered = this.manager.getFilteredTasks(this.currentFilter, this.searchQuery);
if (filtered.length === 0) {
container.innerHTML = `
✨
Keine Aufgaben gefunden
Alle Aufgaben erledigt oder kein Treffer für den aktuellen Filter.
`;
return;
}
container.innerHTML = filtered
.map((t) => {
const priorityColors = {
high: { bg: "#fee2e2", text: "#991b1b", label: "🔥 Hoch" },
medium: { bg: "#fef3c7", text: "#92400e", label: "⚡ Mittel" },
low: { bg: "#dcfce7", text: "#166534", label: "🌱 Niedrig" }
};
const p = priorityColors[t.priority] || priorityColors.medium;
const dueHtml = t.dueDate
? `
📅 ${t.dueDate}
`
: "";
return `
`;
})
.join("");
}
escapeHtml(str) {
if (!str) return "";
return str
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
}
// Bei DOMContentLoaded automatisch starten wenn im Browser
if (typeof document !== "undefined") {
document.addEventListener("DOMContentLoaded", () => {
if (document.getElementById("app") || document.getElementById("task-app-root")) {
new TaskApp(document.getElementById("task-app-root") ? "task-app-root" : "app");
}
});
}