/**
* 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 = `
`;
// 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();
}
}
}