'use client' import { useCallback, useEffect, useState } from 'react' import Link from 'next/link' import { useFlowRun } from '@/hooks/useFlowRun' import ConfirmDialog from '@/components/ConfirmDialog' import StreamingTerminal from '@/components/StreamingTerminal' type Phase = 'edit' | 'writing' | 'validating' | 'validated' | 'saving' | 'saved' type DialogPending = 'validate' | 'save' | null type Props = { initialContent: string initialError: string | null } const VALIDATE_PREVIEW = 'cat > /srv/scrum4me/caddy/Caddyfile.new \\\n && mv /srv/scrum4me/caddy/Caddyfile.new /srv/scrum4me/caddy/Caddyfile\ncaddy validate --config /srv/scrum4me/caddy/Caddyfile' const SAVE_PREVIEW = 'caddy reload --config /srv/scrum4me/caddy/Caddyfile' export default function CaddyEditor({ initialContent, initialError }: Props) { const [content, setContent] = useState(initialContent) const [phase, setPhase] = useState('edit') const [dialogPending, setDialogPending] = useState(null) const writeFlow = useFlowRun() const validateFlow = useFlowRun() const reloadFlow = useFlowRun() // Chain: write done → start validate useEffect(() => { if (phase === 'writing' && writeFlow.status === 'done') { setPhase('validating') validateFlow.start('caddy_validate') } else if (phase === 'writing' && (writeFlow.status === 'failed' || writeFlow.status === 'error')) { setPhase('edit') } }, [writeFlow.status, phase, validateFlow.start]) // Validate done → validated phase useEffect(() => { if (phase === 'validating' && validateFlow.status === 'done') { setPhase('validated') } else if (phase === 'validating' && (validateFlow.status === 'failed' || validateFlow.status === 'error')) { setPhase('edit') } }, [validateFlow.status, phase]) // Reload done → saved useEffect(() => { if (phase === 'saving' && reloadFlow.status === 'done') { setPhase('saved') } else if (phase === 'saving' && (reloadFlow.status === 'failed' || reloadFlow.status === 'error')) { setPhase('validated') } }, [reloadFlow.status, phase]) const handleValidateConfirm = useCallback(() => { setDialogPending(null) setPhase('writing') writeFlow.reset() validateFlow.reset() writeFlow.start('caddy_write_config', [], content) }, [content, writeFlow.reset, writeFlow.start, validateFlow.reset]) const handleSaveConfirm = useCallback(() => { setDialogPending(null) setPhase('saving') reloadFlow.reset() reloadFlow.start('caddy_reload') }, [reloadFlow.reset, reloadFlow.start]) const handleEditAgain = () => { writeFlow.reset() validateFlow.reset() reloadFlow.reset() setPhase('edit') } const isActive = phase === 'writing' || phase === 'validating' || phase === 'saving' return (
{initialError && (
Failed to load current config: {initialError}
)} {/* Textarea */}

Caddyfile

{phase === 'saved' && ( Reloaded successfully )} {phase === 'validated' && ( Config is valid )}