refactor: split CodexConfigEditor into specialized components
Before optimization: - CodexConfigEditor.tsx: 675 lines (monolithic component) After optimization: - CodexConfigEditor.tsx: 131 lines (-81%, orchestration only) - CodexQuickWizardModal.tsx: 325 lines (quick wizard modal) - CodexCommonConfigModal.tsx: 126 lines (common config modal) - CodexConfigSections.tsx: 150 lines (auth & config sections) - Total: 732 lines (+57 lines, but highly modular) Benefits: ✅ Single Responsibility: each component has one clear purpose ✅ Maintainability: reduced file size makes code easier to understand ✅ Reusability: modal components can be used independently ✅ Testability: isolated components are easier to test ✅ Readability: main component is now just orchestration logic ✅ Consistency: follows same modal patterns across app Component breakdown: - CodexConfigEditor: orchestration + state management (131 lines) - CodexQuickWizardModal: step-by-step wizard for quick config (325 lines) - CodexCommonConfigModal: common TOML configuration editor (126 lines) - CodexAuthSection: auth.json editor UI (70 lines) - CodexConfigSection: config.toml editor UI (80 lines)
This commit is contained in:
150
src/components/providers/forms/CodexConfigSections.tsx
Normal file
150
src/components/providers/forms/CodexConfigSections.tsx
Normal file
@@ -0,0 +1,150 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
interface CodexAuthSectionProps {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
onBlur?: () => void;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* CodexAuthSection - Auth JSON editor section
|
||||
*/
|
||||
export const CodexAuthSection: React.FC<CodexAuthSectionProps> = ({
|
||||
value,
|
||||
onChange,
|
||||
onBlur,
|
||||
error,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<label
|
||||
htmlFor="codexAuth"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-gray-100"
|
||||
>
|
||||
{t("codexConfig.authJson")}
|
||||
</label>
|
||||
|
||||
<textarea
|
||||
id="codexAuth"
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
onBlur={onBlur}
|
||||
placeholder={t("codexConfig.authJsonPlaceholder")}
|
||||
rows={6}
|
||||
required
|
||||
className="w-full px-3 py-2 border border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-blue-500 dark:focus:border-blue-400 transition-colors resize-y min-h-[8rem]"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="none"
|
||||
spellCheck={false}
|
||||
lang="en"
|
||||
inputMode="text"
|
||||
data-gramm="false"
|
||||
data-gramm_editor="false"
|
||||
data-enable-grammarly="false"
|
||||
/>
|
||||
|
||||
{error && (
|
||||
<p className="text-xs text-red-500 dark:text-red-400">{error}</p>
|
||||
)}
|
||||
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
{t("codexConfig.authJsonHint")}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface CodexConfigSectionProps {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
useCommonConfig: boolean;
|
||||
onCommonConfigToggle: (checked: boolean) => void;
|
||||
onEditCommonConfig: () => void;
|
||||
commonConfigError?: string;
|
||||
configError?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* CodexConfigSection - Config TOML editor section
|
||||
*/
|
||||
export const CodexConfigSection: React.FC<CodexConfigSectionProps> = ({
|
||||
value,
|
||||
onChange,
|
||||
useCommonConfig,
|
||||
onCommonConfigToggle,
|
||||
onEditCommonConfig,
|
||||
commonConfigError,
|
||||
configError,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<label
|
||||
htmlFor="codexConfig"
|
||||
className="block text-sm font-medium text-gray-900 dark:text-gray-100"
|
||||
>
|
||||
{t("codexConfig.configToml")}
|
||||
</label>
|
||||
|
||||
<label className="inline-flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={useCommonConfig}
|
||||
onChange={(e) => onCommonConfigToggle(e.target.checked)}
|
||||
className="w-4 h-4 text-blue-500 bg-white dark:bg-gray-800 border-gray-200 dark:border-gray-700 rounded focus:ring-blue-500 dark:focus:ring-blue-400 focus:ring-2"
|
||||
/>
|
||||
{t("codexConfig.writeCommonConfig")}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-end">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onEditCommonConfig}
|
||||
className="text-xs text-blue-500 dark:text-blue-400 hover:underline"
|
||||
>
|
||||
{t("codexConfig.editCommonConfig")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{commonConfigError && (
|
||||
<p className="text-xs text-red-500 dark:text-red-400 text-right">
|
||||
{commonConfigError}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<textarea
|
||||
id="codexConfig"
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
placeholder=""
|
||||
rows={8}
|
||||
className="w-full px-3 py-2 border border-gray-200 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100 rounded-lg text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:focus:ring-blue-400/20 focus:border-blue-500 dark:focus:border-blue-400 transition-colors resize-y min-h-[10rem]"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="none"
|
||||
spellCheck={false}
|
||||
lang="en"
|
||||
inputMode="text"
|
||||
data-gramm="false"
|
||||
data-gramm_editor="false"
|
||||
data-enable-grammarly="false"
|
||||
/>
|
||||
|
||||
{configError && (
|
||||
<p className="text-xs text-red-500 dark:text-red-400">{configError}</p>
|
||||
)}
|
||||
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
{t("codexConfig.configTomlHint")}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user