import React from "react"; import { ExternalLink, LogIn, LogOut, RefreshCw, RotateCcw, X } from "lucide-react"; import { useI18n } from "../../../../application/i18n/I18nProvider"; import { Button } from "../../../ui/button"; import { Switch } from "../../../ui/switch"; import { cn } from "../../../../lib/utils"; import type { AgentPathInfo, CodexAppServerStatus, CodexIntegrationStatus, CodexLoginSession } from "./types"; export const CodexConnectionCard: React.FC<{ pathInfo: AgentPathInfo | null; isResolvingPath: boolean; customPath: string; onCustomPathChange: (path: string) => void; onRecheckPath: () => void; onResetPath: () => void; integration: CodexIntegrationStatus | null; loginSession: CodexLoginSession | null; isLoading: boolean; hasPendingCustomPath?: boolean; error: string | null; onRefresh: () => void; onConnect: () => void; onCancel: () => void; onOpenUrl: () => void; onLogout: () => void; appServerRuntime: 'sdk' | 'app-server'; appServerStatus: CodexAppServerStatus | null; onAppServerRuntimeChange: (runtime: 'sdk' | 'app-server') => void; }> = ({ pathInfo, isResolvingPath, customPath, onCustomPathChange, onRecheckPath, onResetPath, integration, loginSession, isLoading, hasPendingCustomPath = false, error, onRefresh, onConnect, onCancel, onOpenUrl, onLogout, appServerRuntime, appServerStatus, onAppServerRuntimeChange, }) => { const { t } = useI18n(); const found = pathInfo?.available; const customConfigIncomplete = Boolean( integration?.state === "connected_custom_config" && integration.customConfig && integration.customConfig.envKey && !integration.customConfig.envKeyPresent && !integration.customConfig.hasHardcodedApiKey, ); const status = isResolvingPath ? t('ai.codex.detecting') : !found ? t('ai.codex.notFound') : loginSession?.state === "running" ? t('ai.codex.awaitingLogin') : integration?.state === "connected_chatgpt" ? t('ai.codex.connectedChatGPT') : integration?.state === "connected_api_key" ? t('ai.codex.connectedApiKey') : integration?.state === "connected_custom_config" ? customConfigIncomplete ? t('ai.codex.customConfigIncomplete') : t('ai.codex.connectedCustomConfig') : integration?.state === "not_logged_in" ? t('ai.codex.notConnected') : t('ai.codex.statusUnknown'); const statusClassName = isResolvingPath ? "text-muted-foreground" : !found ? "text-amber-500" : loginSession?.state === "running" ? "text-amber-500" : customConfigIncomplete ? "text-amber-500" : integration?.isConnected ? "text-emerald-500" : "text-muted-foreground"; const outputText = loginSession?.error ? loginSession.error : loginSession?.output?.trim() ? loginSession.output.trim() : integration?.rawOutput?.trim() ? integration.rawOutput.trim() : ""; return (
{t('ai.codex.description')}
{t('ai.codex.notFoundHint')}
)}{t('ai.codex.appServer.description')}
{appServerStatus?.checking ? ({t('ai.codex.appServer.checking')}
) : appServerStatus?.available ? ({t('ai.codex.appServer.available')}
) : appServerStatus?.error ? ({appServerStatus.error}
) : null}{t('ai.codex.customConfigHint').replace( '{provider}', integration.customConfig.displayName || integration.customConfig.providerName, )}
{integration.customConfig.envKey && !integration.customConfig.envKeyPresent && !integration.customConfig.hasHardcodedApiKey && ({t('ai.codex.customConfigMissingEnvKey').replace( '{envKey}', integration.customConfig.envKey, )}
)} > )} > )} {error && ({error}
)} {found && outputText && (
{outputText}
)}