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
This commit is contained in:
1 parent
93e599befd
commit
36b0d39102
9 files changed
+977
-686
No files matched your search
@@ -0,0 +1,76 @@
|
||||
import { motion } from "framer-motion";
|
||||
import { CheckCircle, GlobeSimple } from "@phosphor-icons/react";
|
||||
import type { AppLocale } from "@shared/locale";
|
||||
import { APP_LOCALES, LOCALE_LABELS } from "@shared/locale";
|
||||
import { ActionButton } from "../ui";
|
||||
|
||||
interface LanguageStepProps {
|
||||
currentLocale: AppLocale;
|
||||
onLocaleChange: (locale: AppLocale) => void;
|
||||
onContinue: () => void;
|
||||
t: (key: string) => string;
|
||||
}
|
||||
|
||||
export function LanguageStep({
|
||||
currentLocale,
|
||||
onLocaleChange,
|
||||
onContinue,
|
||||
t,
|
||||
}: LanguageStepProps) {
|
||||
return (
|
||||
<motion.div
|
||||
key="language"
|
||||
initial={{ opacity: 0, y: 18 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -18 }}
|
||||
transition={{ duration: 0.32, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="surface w-full rounded-[12px] p-7"
|
||||
>
|
||||
<div className="mb-2 flex items-center gap-2 text-[10px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]">
|
||||
<GlobeSimple size={12} />
|
||||
{t("onboarding.languageSelection")} / Language
|
||||
</div>
|
||||
<div className="mb-1 text-[18px] font-semibold tracking-[-0.01em] text-[color:var(--text)]">
|
||||
{t("onboarding.selectLanguage")} / Select Language
|
||||
</div>
|
||||
<div className="mb-6 h-px bg-[color:var(--line)]" />
|
||||
|
||||
<div className="space-y-2.5">
|
||||
{APP_LOCALES.map((locale) => (
|
||||
<button
|
||||
key={locale}
|
||||
type="button"
|
||||
onClick={() => onLocaleChange(locale)}
|
||||
className={`flex w-full items-center gap-3 rounded-[10px] border px-4 py-3.5 text-left transition ${
|
||||
currentLocale === locale
|
||||
? "border-[color:var(--accent)] bg-[color:var(--accent-soft)]"
|
||||
: "border-[color:var(--line)] bg-[color:var(--panel-soft)] hover:border-[color:var(--muted)]"
|
||||
}`}
|
||||
>
|
||||
<div className={`flex h-5 w-5 shrink-0 items-center justify-center rounded-full border ${
|
||||
currentLocale === locale
|
||||
? "border-[color:var(--accent)] bg-[color:var(--accent)]"
|
||||
: "border-[color:var(--line)]"
|
||||
}`}>
|
||||
{currentLocale === locale ? <CheckCircle size={14} weight="fill" className="text-white" /> : null}
|
||||
</div>
|
||||
<span className={`text-[14px] font-medium ${
|
||||
currentLocale === locale ? "text-[color:var(--text)]" : "text-[color:var(--muted-strong)]"
|
||||
}`}>
|
||||
{LOCALE_LABELS[locale]}
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-8 flex items-center justify-end">
|
||||
<ActionButton
|
||||
label={t("onboarding.continue")}
|
||||
onClick={onContinue}
|
||||
icon={GlobeSimple}
|
||||
tone="accent"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user