Files
AgentCompany/src/renderer/components/CompanyOnboarding/ConnectorReadiness.tsx
T
ZacharyZhang-NY 36b0d39102 refactor(01-05): decompose CompanyOnboarding.tsx (686 lines) into 8 focused sub-components
- Extract ConnectorReadiness.tsx (84 lines): connector status display
- Extract CompanyStep.tsx (158 lines): company name, connector, workspace setup
- Extract MissionStep.tsx (97 lines): goal title and description panel
- Extract LaunchStep.tsx (91 lines): launch summary grid
- Extract ClaudeSettingsDialog.tsx (85 lines): Claude Code settings modal
- Extract LanguageStep.tsx (76 lines): language selection step
- Extract OnboardingHero.tsx (97 lines): left hero panel with step indicators
- OnboardingWizard.tsx (287 lines): main orchestrator with state and handlers
- CompanyOnboarding.tsx becomes re-export barrel (2 lines)
- All sub-components under 300 lines
2026-03-22 02:55:42 -04:00

85 lines
3.5 KiB
TypeScript

import {
CheckCircle,
GearSix,
WarningCircle,
XCircle,
} from "@phosphor-icons/react";
import { getConnectorExecutionReadinessIssue } from "@shared/connector-policy";
import type { ProfileSnapshot } from "@shared/types";
import type { AppLocale } from "@shared/locale";
interface ConnectorReadinessProps {
connectors: ProfileSnapshot["connectors"];
currentLocale: AppLocale;
hasRunnableConnector: boolean;
onOpenClaudeSettings: () => void;
t: (key: string) => string;
}
export function ConnectorReadiness({
connectors,
currentLocale,
hasRunnableConnector,
onOpenClaudeSettings,
t,
}: ConnectorReadinessProps) {
return (
<div className="mt-10">
<div className="mb-3 text-[10px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]">
{t("onboarding.connectorReadiness")}
</div>
<div className="space-y-2.5">
{connectors.map((connector) => {
const isChecking = connector.status === "detected";
const isReady = connector.status === "ready";
const isMissing = connector.status === "not_installed";
const issue = !isChecking ? getConnectorExecutionReadinessIssue(connector) : null;
return (
<div key={connector.id} className="flex items-start gap-2.5 text-[13px]">
{isChecking ? (
<span className="mt-0.5 h-4 w-4 shrink-0 animate-spin rounded-full border-2 border-[color:var(--muted)] border-t-[color:var(--accent)]" />
) : isReady ? (
<CheckCircle size={16} weight="fill" className="shrink-0 text-[color:var(--success)]" />
) : isMissing ? (
<XCircle size={16} weight="fill" className="shrink-0 text-[color:var(--muted)]" />
) : (
<WarningCircle size={16} weight="fill" className="shrink-0 text-[color:var(--warn)]" />
)}
<div className="min-w-0 flex-1">
<div className="flex items-center gap-2">
<span className={isReady ? "font-medium text-[color:var(--text)]" : isChecking ? "text-[color:var(--text)]" : "text-[color:var(--muted)]"}>
{connector.label}
</span>
<span className="text-[11px] text-[color:var(--muted)]">
{isChecking ? (currentLocale === "zh" ? "检测中..." : "checking...") : connector.status.replaceAll("_", " ")}
</span>
</div>
{issue ? (
<div className="mt-0.5 text-[11px] leading-relaxed text-[color:var(--muted)]">
{issue}
</div>
) : null}
</div>
{connector.id === "claude_local" ? (
<button
type="button"
onClick={(e) => { e.stopPropagation(); onOpenClaudeSettings(); }}
className="shrink-0 rounded-[6px] p-1.5 text-[color:var(--muted)] transition hover:bg-[color:var(--panel-soft)] hover:text-[color:var(--text)]"
title={currentLocale === "zh" ? "Claude Code 设置" : "Claude Code Settings"}
>
<GearSix size={14} />
</button>
) : null}
</div>
);
})}
</div>
{!hasRunnableConnector ? (
<div className="mt-4 rounded-[10px] border border-[color:var(--warn)] bg-[color:var(--warn-soft)] px-4 py-3 text-[12px] text-[color:var(--warn)]">
{t("onboarding.connectorWarning")}
</div>
) : null}
</div>
);
}