import { useState, useEffect } from 'react'; import { useUser } from '../context/UserContext'; import { useProject } from '../context/ProjectContext'; import { api } from '../api/client'; import type { Project } from '../types'; type Mode = 'select' | 'create' | 'join'; export function ProjectSelectionPage() { const { user, logout } = useUser(); const { setCurrentProject } = useProject(); const [mode, setMode] = useState('select'); const [existingProjects, setExistingProjects] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(''); // Create form state const [projectName, setProjectName] = useState(''); const [projectDescription, setProjectDescription] = useState(''); // Join form state const [joinProjectId, setJoinProjectId] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); // Fetch existing projects on mount useEffect(() => { if (!user) return; const fetchProjects = async () => { try { const response = await api.listProjects(user.id); setExistingProjects(response.projects || []); } catch (err) { console.error('Failed to fetch projects:', err); } finally { setIsLoading(false); } }; fetchProjects(); }, [user]); const handleSelectProject = (project: Project) => { setCurrentProject(project); }; const handleCreateProject = async (e: React.FormEvent) => { e.preventDefault(); setError(''); if (!projectName.trim()) { setError('Project name is required'); return; } if (!user) return; setIsSubmitting(true); try { // Check if project name is available (since name = id) const availability = await api.checkProjectAvailability(projectName.trim()); if (!availability.available) { setError('Project name already taken. Try a different name.'); setIsSubmitting(false); return; } const project = await api.createProject({ name: projectName.trim(), description: projectDescription.trim(), userId: user.id, }); setCurrentProject({ ...project, role: 'owner' }); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to create project'); } finally { setIsSubmitting(false); } }; const handleJoinProject = async (e: React.FormEvent) => { e.preventDefault(); setError(''); if (!joinProjectId.trim()) { setError('Project ID is required'); return; } if (!user) return; setIsSubmitting(true); try { const result = await api.joinProject(joinProjectId.trim(), user.id); // Fetch the full project details const projects = await api.listProjects(user.id); const joinedProject = projects.projects?.find(p => p.id === result.project_id); if (joinedProject) { setCurrentProject(joinedProject); } else { // Fallback if project not found in list setCurrentProject({ id: result.project_id, name: result.project_id, description: '', created_at: new Date().toISOString(), role: result.role, }); } } catch (err) { setError(err instanceof Error ? err.message : 'Failed to join project'); } finally { setIsSubmitting(false); } }; if (!user) return null; return (
{/* Header */}

Project Memory

{user.firstName} ({user.id})
{/* Main Content */}

Select a Project

Choose an existing project or start fresh

{/* Error Display */} {error && (
{error}
)} {/* Loading State */} {isLoading ? (
Loading projects...
) : ( <> {/* Existing Projects */} {existingProjects.length > 0 && mode === 'select' && (

Your Projects

{existingProjects.map((project) => ( ))}
)} {/* Action Buttons (when in select mode) */} {mode === 'select' && (
)} {/* Create Project Form */} {mode === 'create' && (

Create New Project

setProjectName(e.target.value)} placeholder="e.g., fastgate" className="w-full px-4 py-3 bg-white/5 border border-white/10 rounded-lg text-white placeholder-white/40 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent" disabled={isSubmitting} />

Must be unique. This will be the project ID.