import { useState } from 'react'; import { Plus, Edit2, Trash2, FolderOpen } from 'lucide-react'; import { useProjects } from '@/hooks/useProjects'; import { useClients } from '@/hooks/useClients'; import type { Project, CreateProjectInput, UpdateProjectInput } from '@/types'; const PRESET_COLORS = [ '#ef4444', '#f97316', '#f59e0b', '#84cc16', '#22c55e', '#10b981', '#14b8a6', '#06b6d4', '#0ea5e9', '#3b82f6', '#6366f1', '#8b5cf6', '#a855f7', '#d946ef', '#ec4899', '#f43f5e', '#6b7280', '#374151', ]; export function ProjectsPage() { const { projects, isLoading: projectsLoading, createProject, updateProject, deleteProject } = useProjects(); const { clients, isLoading: clientsLoading } = useClients(); const [isModalOpen, setIsModalOpen] = useState(false); const [editingProject, setEditingProject] = useState(null); const [formData, setFormData] = useState({ name: '', description: '', color: '#3b82f6', clientId: '', }); const [error, setError] = useState(null); const isLoading = projectsLoading || clientsLoading; const handleOpenModal = (project?: Project) => { if (project) { setEditingProject(project); setFormData({ name: project.name, description: project.description || '', color: project.color || '#3b82f6', clientId: project.clientId, }); } else { setEditingProject(null); setFormData({ name: '', description: '', color: '#3b82f6', clientId: clients?.[0]?.id || '', }); } setError(null); setIsModalOpen(true); }; const handleCloseModal = () => { setIsModalOpen(false); setEditingProject(null); setFormData({ name: '', description: '', color: '#3b82f6', clientId: '' }); setError(null); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); if (!formData.name.trim()) { setError('Project name is required'); return; } if (!formData.clientId) { setError('Please select a client'); return; } try { if (editingProject) { await updateProject.mutateAsync({ id: editingProject.id, input: formData as UpdateProjectInput, }); } else { await createProject.mutateAsync(formData); } handleCloseModal(); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to save project'); } }; const handleDelete = async (project: Project) => { if (!confirm(`Are you sure you want to delete "${project.name}"?`)) { return; } try { await deleteProject.mutateAsync(project.id); } catch (err) { alert(err instanceof Error ? err.message : 'Failed to delete project'); } }; if (isLoading) { return (
); } if (!clients?.length) { return (

Projects

Please create a client first.

); } return (

Projects

{projects?.map((project) => (

{project.name}

{project.client.name}

))}
{isModalOpen && (

{editingProject ? 'Edit Project' : 'Add Project'}

{error &&
{error}
}
setFormData({ ...formData, name: e.target.value })} className="input" />
{PRESET_COLORS.map((color) => (