import { useState, useEffect } from 'react' import { Loader2, RotateCcw, Terminal } from 'lucide-react' import { useQueryClient } from '@tanstack/react-query' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { useDevServerConfig, useUpdateDevServerConfig } from '@/hooks/useProjects' import { startDevServer } from '@/lib/api' interface DevServerConfigDialogProps { projectName: string isOpen: boolean onClose: () => void autoStartOnSave?: boolean } export function DevServerConfigDialog({ projectName, isOpen, onClose, autoStartOnSave = false, }: DevServerConfigDialogProps) { const { data: config } = useDevServerConfig(isOpen ? projectName : null) const updateConfig = useUpdateDevServerConfig(projectName) const queryClient = useQueryClient() const [command, setCommand] = useState('') const [error, setError] = useState(null) const [isSaving, setIsSaving] = useState(false) // Sync input with config when dialog opens or config loads useEffect(() => { if (isOpen && config) { setCommand(config.custom_command ?? config.effective_command ?? '') setError(null) } }, [isOpen, config]) const hasCustomCommand = !!config?.custom_command const handleSaveAndStart = async () => { const trimmed = command.trim() if (!trimmed) { setError('Please enter a dev server command.') return } setIsSaving(true) setError(null) try { await updateConfig.mutateAsync(trimmed) if (autoStartOnSave) { await startDevServer(projectName) queryClient.invalidateQueries({ queryKey: ['dev-server-status', projectName] }) } onClose() } catch (err) { setError(err instanceof Error ? err.message : 'Failed to save configuration') } finally { setIsSaving(false) } } const handleClear = async () => { setIsSaving(true) setError(null) try { await updateConfig.mutateAsync(null) setCommand(config?.detected_command ?? '') } catch (err) { setError(err instanceof Error ? err.message : 'Failed to clear configuration') } finally { setIsSaving(false) } } return ( !open && onClose()}>
Dev Server Configuration
{/* Detection info */}
{config?.detected_type ? (

Detected project type: {config.detected_type} {config.detected_command && ( — {config.detected_command} )}

) : (

No project type detected. Enter a custom command below.

)}
{/* Command input */}
{ setCommand(e.target.value) setError(null) }} placeholder="npm run dev" onKeyDown={(e) => { if (e.key === 'Enter' && !isSaving) { handleSaveAndStart() } }} />

Allowed runners: npm, npx, pnpm, yarn, python, uvicorn, flask, poetry, cargo, go

{/* Clear custom command button */} {hasCustomCommand && ( )} {/* Error display */} {error && (

{error}

)}
) }