import { useTranslation } from "react-i18next"; import { Loader2 } from "lucide-react"; import { useEngineStatus } from "../hooks/useEngineStatus"; import "./EngineStatusBanner.css"; interface EngineStatusBannerProps { projectId: string; } /* * FNXC:EngineStatusBanner 2026-06-22-00:00: * The project banner stack needs a single visible remediation when the dashboard is loaded but the current project's engine is absent. Hide the entire component once `connected` is true so no empty wrapper, button shell, or stale aria surface remains in the DOM. */ export function EngineStatusBanner({ projectId }: EngineStatusBannerProps) { const { t } = useTranslation("app"); const { status, canStart, starting, error, start } = useEngineStatus(projectId); if (!status || status.connected) return null; const isDashboardOnly = status.reason === "dashboard-only" || status.reason === "unreachable"; const statusDotClass = starting ? "status-dot status-dot--connecting" : "status-dot status-dot--error"; const body = canStart ? t("engineBanner.body", "The engine for this project is not running, so task automation and live updates may be paused. Start it now to reconnect the dashboard.") : t("engineBanner.dashboardOnly", "This dashboard cannot start engines from the current process. Run `fn serve` for this project to enable task execution and live automation."); return (
{t("engineBanner.title", "Project engine is not connected")}

{isDashboardOnly ? ( <> {t("engineBanner.dashboardOnlyPrefix", "This dashboard cannot start engines from the current process. Run")} fn serve {t("engineBanner.dashboardOnlySuffix", "for this project to enable task execution and live automation.")} ) : body}

{error && (

{t("engineBanner.error", "Start failed: {{message}}", { message: error })}

)}
{canStart ? ( ) : null}
); }