import { useEffect, useState } from 'react'; import { api } from '@/api/client'; import type { AvailableProject } from '@/api/types'; import { sessionEvents } from '@/hooks/sessionEvents'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; interface Props { open: boolean; onOpenChange: (open: boolean) => void; onAdded: () => void; } export function AddProjectModal({ open, onOpenChange, onAdded }: Props) { const [available, setAvailable] = useState(null); const [customPath, setCustomPath] = useState(''); const [error, setError] = useState(null); const [busy, setBusy] = useState(false); useEffect(() => { if (!open) return; setError(null); setCustomPath(''); setAvailable(null); api.projects .available() .then(setAvailable) .catch((err) => setError(err instanceof Error ? err.message : 'failed to list available projects') ); }, [open]); async function add(path: string) { setBusy(true); setError(null); try { const created = await api.projects.add({ path }); sessionEvents.emit({ type: 'project_created', project: created }); onAdded(); onOpenChange(false); } catch (err) { setError(err instanceof Error ? err.message : 'failed to add'); } finally { setBusy(false); } } return ( Add project Pick from detected repos in /opt or type a path.
{available === null && (
Loading…
)} {available && available.length === 0 && (
No undiscovered repos in /opt.
)} {available?.map((p) => ( ))}
setCustomPath(e.target.value)} disabled={busy} />
{error && (
{error}
)}
); }