diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx new file mode 100644 index 0000000..a8686e2 --- /dev/null +++ b/src/components/Sidebar.tsx @@ -0,0 +1,221 @@ +'use client'; + +import { useApp } from './AppProvider'; +import { useState } from 'react'; + +export default function Sidebar() { + const { + view, setView, selectedProject, setSelectedProject, + sidebarOpen, setSidebarOpen, showNewProjectModal, setShowNewProjectModal, + showNewTaskModal, setShowNewTaskModal, projects, setProjects, refreshTasks, refreshProjects, + } = useApp(); + + const [projectName, setProjectName] = useState(''); + const [projectDescription, setProjectDescription] = useState(''); + const [projectColor, setProjectColor] = useState('#3b82f6'); + const [creatingProject, setCreatingProject] = useState(false); + + const views: { key: typeof view; label: string; icon: string }[] = [ + { key: 'list', label: 'List View', icon: '☰' }, + { key: 'kanban', label: 'Kanban Board', icon: '▦' }, + { key: 'calendar', label: 'Calendar', icon: '📅' }, + ]; + + const handleNewProject = async () => { + if (!projectName.trim()) return; + try { + await fetch('/api/projects', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + name: projectName.trim(), + description: projectDescription.trim(), + color: projectColor, + }), + }); + setProjectName(''); + setProjectDescription(''); + setProjectColor('#3b82f6'); + setCreatingProject(false); + refreshProjects(); + } catch (error) { + console.error('Failed to create project:', error); + } + }; + + const handleDeleteProject = async (id: string) => { + if (!confirm('Delete this project and all its tasks?')) return; + try { + await fetch(`/api/projects/${id}`, { method: 'DELETE' }); + if (selectedProject === id) setSelectedProject(null); + refreshProjects(); + refreshTasks(); + } catch (error) { + console.error('Failed to delete project:', error); + } + }; + + return ( +
+ {/* Header */} +
+ {sidebarOpen && ( +
+ VixTix +
+ )} + +
+ + {/* New Task Button */} +
+ +
+ + {/* Views */} + {sidebarOpen && ( +
+

Views

+
+ {views.map((v) => ( + + ))} +
+
+ )} + + {/* Projects */} +
+ {sidebarOpen && ( +
+

Projects

+ +
+ )} + + {/* New project form */} + {creatingProject && sidebarOpen && ( +
+ setProjectName(e.target.value)} + placeholder="Project name" + className="w-full bg-transparent border border-white/20 rounded px-2 py-1.5 text-sm text-white placeholder-gray-500 mb-2 focus:outline-none focus:border-accent" + autoFocus + /> + setProjectDescription(e.target.value)} + placeholder="Description (optional)" + className="w-full bg-transparent border border-white/20 rounded px-2 py-1.5 text-sm text-white placeholder-gray-500 mb-2 focus:outline-none focus:border-accent" + /> +
+ Color: + setProjectColor(e.target.value)} + className="w-8 h-8 rounded cursor-pointer border-0 bg-transparent" + /> +
+
+ + +
+
+ )} + + {/* Project list */} +
+ {/* All Projects option */} + + + {projects.map((project) => ( +
+ + {sidebarOpen && ( + <> + {project.name} + + + )} +
+ ))} +
+
+ + {/* Footer */} + {sidebarOpen && ( +
+ VixTix v1.0 +
+ )} +
+ ); +}