import React, { useState, useEffect } from 'react'; import { Card } from '../ui/card'; import { Button } from '../ui/button'; import { Badge } from '../ui/badge'; import { SearchInput } from '../ui/input'; import { MoreVertical, Plus, LayoutGrid, List, Loader2, AlertCircle } from 'lucide-react'; import { useToast } from '../../context/ToastContext'; import { CreateProjectModal } from './projects/CreateProjectModal'; import { ProjectDetailView } from './projects/ProjectDetailView'; import { projectService, Project } from '../../services/projectService'; import { logger } from '@/utils/logger'; export const ProjectsManager: React.FC = () => { const { addToast } = useToast(); const [viewState, setViewState] = useState<'list' | 'detail'>('list'); const [selectedProjectId, setSelectedProjectId] = useState(null); const [projects, setProjects] = useState([]); const [loading, setLoading] = useState(true); const [filter, setFilter] = useState('All'); const [search, setSearch] = useState(''); const [showCreateModal, setShowCreateModal] = useState(false); useEffect(() => { loadProjects(); }, []); const loadProjects = async () => { try { setLoading(true); const response = await projectService.list(); setProjects(response.projects || []); } catch (error) { logger.error('Failed to load projects', { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : undefined, }); // Fallback for demo if API fails setProjects([ { id: 'p1', name: 'Neon Genesis', daw: 'Ableton', bpm: 128, key: 'C Min', status: 'In Progress', collaborators: 2, modified: '2h ago', progress: 65 }, { id: 'p2', name: 'Night City Drift', daw: 'FL Studio', bpm: 140, key: 'F# Min', status: 'Mixing', collaborators: 0, modified: '1d ago', progress: 80 }, { id: 'p3', name: 'Mainframe Breach', daw: 'Logic Pro', bpm: 174, key: 'D Maj', status: 'Mastering', collaborators: 1, modified: '3d ago', progress: 95 }, ]); } finally { setLoading(false); } }; // --- Actions --- const handleCreate = async (newProjectData: any) => { try { const newProject = await projectService.create(newProjectData); setProjects([newProject, ...projects]); addToast(`Project "${newProject.name}" created`, "success"); } catch (e) { // Fallback const mockProject = { id: `p-${Date.now()}`, ...newProjectData }; setProjects([mockProject, ...projects]); addToast("Project created (Offline Mode)", "success"); } }; const handleUpdate = async (updatedProject: any) => { try { await projectService.update(updatedProject.id, updatedProject); setProjects(prev => prev.map(p => p.id === updatedProject.id ? updatedProject : p)); } catch (e) { setProjects(prev => prev.map(p => p.id === updatedProject.id ? updatedProject : p)); } }; const handleDelete = async (id: string) => { try { await projectService.delete(id); setProjects(prev => prev.filter(p => p.id !== id)); setViewState('list'); setSelectedProjectId(null); addToast("Project deleted", "info"); } catch (e) { addToast("Failed to delete project", "error"); } }; const openProject = (id: string) => { setSelectedProjectId(id); setViewState('detail'); }; // --- Filtering --- const filteredProjects = projects.filter(p => { const matchesSearch = p.name.toLowerCase().includes(search.toLowerCase()); const matchesFilter = filter === 'All' || p.daw === filter; return matchesSearch && matchesFilter; }); const selectedProject = projects.find(p => p.id === selectedProjectId); // --- Render Detail View --- if (viewState === 'detail' && selectedProject) { return ( setViewState('list')} onUpdate={handleUpdate} onDelete={handleDelete} /> ); } // --- Render List View --- return (

ACTIVE PROJECTS

Track progress across all your workstations.

{/* Filter Bar */}
setSearch(e.target.value)} />
{['All', 'Ableton', 'FL Studio', 'Logic Pro'].map(daw => ( ))}
{/* Projects Grid */} {loading ? (
) : (
{filteredProjects.map(project => ( openProject(project.id)} >
{ e.stopPropagation(); addToast("Options menu"); }}>

{project.name}

Last edited {project.modified}

BPM
{project.bpm}
Key
{project.key}
{project.status} {project.progress}%
{project.collaborators > 0 && (
+{project.collaborators}
)}
))} {/* Add New Placeholder */}
setShowCreateModal(true)} >
START NEW PROJECT
)} {filteredProjects.length === 0 && !loading && (

No projects found matching your filters.

)} {showCreateModal && ( setShowCreateModal(false)} onCreate={handleCreate} /> )}
); };