import { useState, useEffect, useCallback } from 'react'; import { Link, useSearchParams } from 'react-router-dom'; import { Project, PaginatedResponse } from '../types'; import { listProjects, createProject } from '../api'; import { Badge } from '../components/Badge'; import { SortDropdown, SortOption } from '../components/SortDropdown'; import { FilterDropdown, FilterOption } from '../components/FilterDropdown'; import { FilterChip, FilterChipGroup } from '../components/FilterChip'; import { Pagination } from '../components/Pagination'; import './Home.css'; const SORT_OPTIONS: SortOption[] = [ { value: 'name', label: 'Name' }, { value: 'created_at', label: 'Created' }, { value: 'updated_at', label: 'Updated' }, ]; const VISIBILITY_OPTIONS: FilterOption[] = [ { value: '', label: 'All Projects' }, { value: 'public', label: 'Public Only' }, { value: 'private', label: 'Private Only' }, ]; function Home() { const [searchParams, setSearchParams] = useSearchParams(); const [projectsData, setProjectsData] = useState | null>(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [showForm, setShowForm] = useState(false); const [newProject, setNewProject] = useState({ name: '', description: '', is_public: true }); const [creating, setCreating] = useState(false); // Get params from URL const page = parseInt(searchParams.get('page') || '1', 10); const sort = searchParams.get('sort') || 'name'; const order = (searchParams.get('order') || 'asc') as 'asc' | 'desc'; const visibility = searchParams.get('visibility') || ''; const updateParams = useCallback( (updates: Record) => { const newParams = new URLSearchParams(searchParams); Object.entries(updates).forEach(([key, value]) => { if (value === undefined || value === '' || (key === 'page' && value === '1')) { newParams.delete(key); } else { newParams.set(key, value); } }); setSearchParams(newParams); }, [searchParams, setSearchParams] ); const loadProjects = useCallback(async () => { try { setLoading(true); const data = await listProjects({ page, sort, order, visibility: visibility as 'public' | 'private' | undefined || undefined, }); setProjectsData(data); setError(null); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load projects'); } finally { setLoading(false); } }, [page, sort, order, visibility]); useEffect(() => { loadProjects(); }, [loadProjects]); async function handleCreateProject(e: React.FormEvent) { e.preventDefault(); try { setCreating(true); await createProject(newProject); setNewProject({ name: '', description: '', is_public: true }); setShowForm(false); loadProjects(); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to create project'); } finally { setCreating(false); } } const handleSortChange = (newSort: string, newOrder: 'asc' | 'desc') => { updateParams({ sort: newSort, order: newOrder, page: '1' }); }; const handleVisibilityChange = (value: string) => { updateParams({ visibility: value, page: '1' }); }; const handlePageChange = (newPage: number) => { updateParams({ page: String(newPage) }); }; const clearFilters = () => { setSearchParams({}); }; const hasActiveFilters = visibility !== ''; const projects = projectsData?.items || []; const pagination = projectsData?.pagination; if (loading && !projectsData) { return
Loading projects...
; } return (

Projects

{error &&
{error}
} {showForm && (

Create New Project

setNewProject({ ...newProject, name: e.target.value })} placeholder="my-project" required />
setNewProject({ ...newProject, description: e.target.value })} placeholder="Optional description" />
)}
{hasActiveFilters && ( {visibility && ( handleVisibilityChange('')} /> )} )} {projects.length === 0 ? (
{hasActiveFilters ? (

No projects match your filters. Try adjusting your search.

) : (

No projects yet. Create your first project to get started!

)}
) : ( <>
{projects.map((project) => (

{project.name}

{project.description &&

{project.description}

}
{project.is_public ? 'Public' : 'Private'}
Created {new Date(project.created_at).toLocaleDateString()} {project.updated_at !== project.created_at && ( Updated {new Date(project.updated_at).toLocaleDateString()} )}
by {project.created_by}
))}
{pagination && pagination.total_pages > 1 && ( )} )}
); } export default Home;