/** * Main Layout Component * Sidebar + Header + Content Area */ import { store } from '../state.js'; import { router, Route } from '../router.js'; export class Layout { constructor(container) { this.container = container; this.unsubscribe = null; } render(contentComponent) { const currentUser = store.state.currentUser; const isSidebarOpen = store.state.ui.sidebarOpen; this.container.innerHTML = `

Dashboard

`; // Initialize icons lucide.createIcons(); // Bind events this.bindEvents(); // Render content const mainContent = this.container.querySelector('#mainContent'); if (contentComponent && mainContent) { contentComponent.render(mainContent); } // Subscribe to state changes this.unsubscribe = store.subscribe('*', () => { this.updateUI(); }); } renderProjectList() { return store.state.projects.map(project => ` ${project.name} ${this.getProjectTaskCount(project.id) > 0 ? ` ${this.getProjectTaskCount(project.id)} ` : ''} `).join(''); } getTaskBadge() { const count = store.state.tasks.filter(t => t.assigneeId === store.state.currentUser?.id && t.status !== 'done').length; if (count === 0) return ''; return `${count}`; } getProjectTaskCount(projectId) { return store.state.tasks.filter(t => t.projectId === projectId && t.status !== 'done').length; } isActive(route) { return window.location.pathname === route; } isProjectActive(projectId) { return window.location.pathname === Route.PROJECT && store.state.ui.selectedProjectId === projectId; } bindEvents() { // Sidebar toggle const toggleBtn = this.container.querySelector('#toggleSidebar'); const toggleDesktopBtn = this.container.querySelector('#toggleSidebarDesktop'); const closeBtn = this.container.querySelector('#closeSidebar'); const overlay = this.container.querySelector('#sidebarOverlay'); [toggleBtn, toggleDesktopBtn].forEach(btn => { btn?.addEventListener('click', () => { const isOpen = !store.state.ui.sidebarOpen; store.setUISState('sidebarOpen', isOpen); this.updateSidebarVisibility(isOpen); }); }); closeBtn?.addEventListener('click', () => { store.setUISState('sidebarOpen', false); this.updateSidebarVisibility(false); }); overlay?.addEventListener('click', () => { store.setUISState('sidebarOpen', false); this.updateSidebarVisibility(false); }); // Dark mode this.container.querySelector('#toggleDarkMode')?.addEventListener('click', () => { store.toggleDarkMode(); }); // Search const searchInput = this.container.querySelector('#globalSearch'); searchInput?.addEventListener('input', (e) => { store.setUISState('searchQuery', e.target.value); }); // Add Project this.container.querySelector('#addProjectBtn')?.addEventListener('click', () => { this.showAddProjectModal(); }); } updateSidebarVisibility(isOpen) { const sidebar = this.container.querySelector('#sidebar'); const overlay = this.container.querySelector('#sidebarOverlay'); if (isOpen) { sidebar.classList.remove('-translate-x-full'); overlay.classList.remove('hidden'); overlay.classList.add('block'); } else { sidebar.classList.add('-translate-x-full'); overlay.classList.add('hidden'); overlay.classList.remove('block'); } } updateUI() { // Update project list const projectList = this.container.querySelector('#projectList'); if (projectList) { projectList.innerHTML = this.renderProjectList(); } // Update search value if changed elsewhere const searchInput = this.container.querySelector('#globalSearch'); if (searchInput && searchInput.value !== store.state.ui.searchQuery) { searchInput.value = store.state.ui.searchQuery; } // Update icons lucide.createIcons(); } showAddProjectModal() { // Einfache Prompt-Implementation für Demo const name = prompt('Projektname:'); if (name) { const description = prompt('Beschreibung (optional):') || ''; const colors = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899']; const color = colors[Math.floor(Math.random() * colors.length)]; store.addProject({ name, description, color, ownerId: store.state.currentUser.id, memberIds: [store.state.currentUser.id] }); } } destroy() { if (this.unsubscribe) { this.unsubscribe(); } } }