Files
cc-switch/src/renderer/components/AddProviderModal.tsx
farion1231 fe71373e7d 界面改进和代码重构:设置窗口最小尺寸并抽象预设供应商配置
- 设置窗口最小尺寸为600x400,防止界面缩放问题
- 将预设供应商配置提取到独立文件providerPresets.ts
- 便于管理和维护预设供应商列表

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-08 12:12:28 +08:00

206 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState } from "react";
import { Provider } from "../../shared/types";
import { updateCoAuthoredSetting, checkCoAuthoredSetting, extractWebsiteUrl } from "../utils/providerConfigUtils";
import { providerPresets } from "../config/providerPresets";
import "./AddProviderModal.css";
interface AddProviderModalProps {
onAdd: (provider: Omit<Provider, "id">) => void;
onClose: () => void;
}
const AddProviderModal: React.FC<AddProviderModalProps> = ({
onAdd,
onClose,
}) => {
const [formData, setFormData] = useState({
name: "",
websiteUrl: "",
settingsConfig: ""
});
const [error, setError] = useState("");
const [disableCoAuthored, setDisableCoAuthored] = useState(false);
// 预设的供应商配置模板
const presets = providerPresets;
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
setError("");
if (!formData.name) {
setError("请填写供应商名称");
return;
}
if (!formData.settingsConfig.trim()) {
setError("请填写配置内容");
return;
}
let settingsConfig: object;
try {
settingsConfig = JSON.parse(formData.settingsConfig);
} catch (err) {
setError("配置JSON格式错误请检查语法");
return;
}
onAdd({
name: formData.name,
websiteUrl: formData.websiteUrl,
settingsConfig
});
};
const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
const { name, value } = e.target;
if (name === 'settingsConfig') {
// 当用户修改配置时,尝试自动提取官网地址
const extractedWebsiteUrl = extractWebsiteUrl(value);
// 同时检查并同步选择框状态
const hasCoAuthoredDisabled = checkCoAuthoredSetting(value);
setDisableCoAuthored(hasCoAuthoredDisabled);
setFormData({
...formData,
[name]: value,
// 只有在官网地址为空时才自动填入
websiteUrl: formData.websiteUrl || extractedWebsiteUrl,
});
} else {
setFormData({
...formData,
[name]: value,
});
}
};
// 处理选择框变化
const handleCoAuthoredToggle = (checked: boolean) => {
setDisableCoAuthored(checked);
// 更新JSON配置
const updatedConfig = updateCoAuthoredSetting(formData.settingsConfig, checked);
setFormData({
...formData,
settingsConfig: updatedConfig,
});
};
const applyPreset = (preset: typeof presets[0]) => {
const configString = JSON.stringify(preset.settingsConfig, null, 2);
setFormData({
name: preset.name,
websiteUrl: preset.websiteUrl,
settingsConfig: configString
});
// 同步选择框状态
const hasCoAuthoredDisabled = checkCoAuthoredSetting(configString);
setDisableCoAuthored(hasCoAuthoredDisabled);
};
return (
<div className="modal-overlay">
<div className="modal-content">
<h2></h2>
{error && <div className="error-message">{error}</div>}
<div className="presets">
<label></label>
<div className="preset-buttons">
{presets.map((preset, index) => (
<button
key={index}
type="button"
className="preset-btn"
onClick={() => applyPreset(preset)}
>
{preset.name}
</button>
))}
</div>
</div>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="name"> *</label>
<input
type="text"
id="name"
name="name"
value={formData.name}
onChange={handleChange}
placeholder="例如Anthropic 官方"
required
/>
</div>
<div className="form-group">
<label htmlFor="websiteUrl"></label>
<input
type="url"
id="websiteUrl"
name="websiteUrl"
value={formData.websiteUrl}
onChange={handleChange}
placeholder="https://example.com可选"
/>
</div>
<div className="form-group">
<div className="label-with-checkbox">
<label htmlFor="settingsConfig">Claude Code (JSON) *</label>
<label className="checkbox-label">
<input
type="checkbox"
checked={disableCoAuthored}
onChange={(e) => handleCoAuthoredToggle(e.target.checked)}
/>
Claude Code
</label>
</div>
<textarea
id="settingsConfig"
name="settingsConfig"
value={formData.settingsConfig}
onChange={handleChange}
placeholder={`{
"env": {
"ANTHROPIC_BASE_URL": "https://api.anthropic.com",
"ANTHROPIC_AUTH_TOKEN": "sk-your-api-key-here"
}
}`}
rows={12}
style={{fontFamily: 'monospace', fontSize: '14px'}}
required
/>
<small className="field-hint">
Claude Code settings.json
</small>
</div>
<div className="form-actions">
<button type="button" className="cancel-btn" onClick={onClose}>
</button>
<button type="submit" className="submit-btn">
</button>
</div>
</form>
</div>
</div>
);
};
export default AddProviderModal;