import React, { useState, useRef } from "react"; import { X, Save } from "lucide-react"; import { useTranslation } from "react-i18next"; import { isLinux } from "@/lib/platform"; import { generateThirdPartyAuth, generateThirdPartyConfig, } from "@/config/codexProviderPresets"; interface CodexQuickWizardModalProps { isOpen: boolean; onClose: () => void; onApply: (auth: string, config: string, extras: { websiteUrl?: string; displayName?: string; }) => void; } /** * CodexQuickWizardModal - Codex quick configuration wizard * Helps users quickly generate auth.json and config.toml */ export const CodexQuickWizardModal: React.FC = ({ isOpen, onClose, onApply, }) => { const { t } = useTranslation(); const [templateApiKey, setTemplateApiKey] = useState(""); const [templateProviderName, setTemplateProviderName] = useState(""); const [templateBaseUrl, setTemplateBaseUrl] = useState(""); const [templateWebsiteUrl, setTemplateWebsiteUrl] = useState(""); const [templateModelName, setTemplateModelName] = useState("gpt-5-codex"); const [templateDisplayName, setTemplateDisplayName] = useState(""); const apiKeyInputRef = useRef(null); const baseUrlInputRef = useRef(null); const modelNameInputRef = useRef(null); const displayNameInputRef = useRef(null); const resetForm = () => { setTemplateApiKey(""); setTemplateProviderName(""); setTemplateBaseUrl(""); setTemplateWebsiteUrl(""); setTemplateModelName("gpt-5-codex"); setTemplateDisplayName(""); }; const handleClose = () => { resetForm(); onClose(); }; const applyTemplate = () => { const requiredInputs = [ displayNameInputRef.current, apiKeyInputRef.current, baseUrlInputRef.current, modelNameInputRef.current, ]; for (const input of requiredInputs) { if (input && !input.checkValidity()) { input.reportValidity(); input.focus(); return; } } const trimmedKey = templateApiKey.trim(); const trimmedBaseUrl = templateBaseUrl.trim(); const trimmedModel = templateModelName.trim(); const auth = generateThirdPartyAuth(trimmedKey); const config = generateThirdPartyConfig( templateProviderName || "custom", trimmedBaseUrl, trimmedModel, ); onApply( JSON.stringify(auth, null, 2), config, { websiteUrl: templateWebsiteUrl.trim(), displayName: templateDisplayName.trim(), } ); resetForm(); onClose(); }; const handleInputKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Enter") { e.preventDefault(); e.stopPropagation(); applyTemplate(); } }; if (!isOpen) return null; return (
{ if (e.target === e.currentTarget) { handleClose(); } }} >
{/* Header */}

{t("codexConfig.quickWizard")}

{/* Content */}

{t("codexConfig.wizardHint")}

{/* API Key */}
setTemplateApiKey(e.target.value)} onKeyDown={handleInputKeyDown} pattern=".*\S.*" title={t("common.enterValidValue")} placeholder={t("codexConfig.apiKeyPlaceholder")} required className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm font-mono text-gray-900 focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100" />
{/* Display Name */}
setTemplateDisplayName(e.target.value)} onKeyDown={handleInputKeyDown} placeholder={t("codexConfig.supplierNamePlaceholder")} required pattern=".*\S.*" title={t("common.enterValidValue")} className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100" />

{t("codexConfig.supplierNameHint")}

{/* Provider Name */}
setTemplateProviderName(e.target.value)} onKeyDown={handleInputKeyDown} placeholder={t("codexConfig.supplierCodePlaceholder")} className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100" />

{t("codexConfig.supplierCodeHint")}

{/* Base URL */}
setTemplateBaseUrl(e.target.value)} onKeyDown={handleInputKeyDown} placeholder={t("codexConfig.apiUrlPlaceholder")} required className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100" />
{/* Website URL */}
setTemplateWebsiteUrl(e.target.value)} onKeyDown={handleInputKeyDown} placeholder={t("codexConfig.websitePlaceholder")} className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100" />

{t("codexConfig.websiteHint")}

{/* Model Name */}
setTemplateModelName(e.target.value)} onKeyDown={handleInputKeyDown} pattern=".*\S.*" title={t("common.enterValidValue")} placeholder={t("codexConfig.modelNamePlaceholder")} required className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-100" />
{/* Preview */} {(templateApiKey || templateProviderName || templateBaseUrl) && (

{t("codexConfig.configPreview")}

                      {JSON.stringify(
                        generateThirdPartyAuth(templateApiKey),
                        null,
                        2,
                      )}
                    
                      {templateProviderName && templateBaseUrl
                        ? generateThirdPartyConfig(
                            templateProviderName,
                            templateBaseUrl,
                            templateModelName,
                          )
                        : ""}
                    
)}
{/* Footer */}
); };