mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-07-01 01:23:06 +08:00
Implemented comprehensive i18n translation support for the following components: 1. GitSettings.jsx - Git configuration interface 2. ApiKeysSettings.jsx - API keys settings 3. CredentialsSettings.jsx - Credentials settings (GitHub tokens) 4. TasksSettings.jsx - TaskMaster task management settings 5. ChatInterface.jsx - Chat interface (major translation work) New translation files: - src/i18n/locales/en/chat.json - English chat interface translations - src/i18n/locales/zh-CN/chat.json - Chinese chat interface translations ChatInterface.jsx translations: - Code block copy buttons (Copy, Copied, Copy code) - Message type labels (User, Error, Tool, Claude, Cursor, Codex) - Tool settings tooltip - Search result display (pattern, in, results) - Codex permission modes (Default, Accept Edits, Bypass Permissions, Plan) - Input placeholder and hint text - Keyboard shortcut hints (Ctrl+Enter/Enter modes) - Command menu button i18n configuration updates: - Registered chat namespace in config.js - Extended settings.json translations (git, apiKeys, tasks, agents, mcpServers sections) 完成以下组件的 i18n 翻译工作: 1. GitSettings.jsx - Git 配置界面 2. ApiKeysSettings.jsx - API 密钥设置 3. CredentialsSettings.jsx - 凭据设置(GitHub Token) 4. TasksSettings.jsx - TaskMaster 任务管理设置 5. ChatInterface.jsx - 聊天界面(主要翻译工作) 新增翻译文件: - src/i18n/locales/en/chat.json - 英文聊天界面翻译 - src/i18n/locales/zh-CN/chat.json - 中文聊天界面翻译 ChatInterface.jsx 翻译内容: - 代码块复制按钮 - 消息类型标签 - 工具设置提示 - 搜索结果显示 - Codex 权限模式(默认、编辑、无限制、计划模式) - 输入框占位符和提示文本 - 键盘快捷键提示 - 命令菜单按钮 更新 i18n 配置: - 在 config.js 中注册 chat 命名空间 - 扩展 settings.json 翻译(git、apiKeys、tasks、agents、mcpServers 等部分)
132 lines
4.1 KiB
JavaScript
132 lines
4.1 KiB
JavaScript
import { useState, useEffect } from 'react';
|
|
import { Button } from './ui/button';
|
|
import { Input } from './ui/input';
|
|
import { GitBranch, Check } from 'lucide-react';
|
|
import { authenticatedFetch } from '../utils/api';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
function GitSettings() {
|
|
const { t } = useTranslation('settings');
|
|
const [gitName, setGitName] = useState('');
|
|
const [gitEmail, setGitEmail] = useState('');
|
|
const [gitConfigLoading, setGitConfigLoading] = useState(false);
|
|
const [gitConfigSaving, setGitConfigSaving] = useState(false);
|
|
const [saveStatus, setSaveStatus] = useState(null);
|
|
|
|
useEffect(() => {
|
|
loadGitConfig();
|
|
}, []);
|
|
|
|
const loadGitConfig = async () => {
|
|
try {
|
|
setGitConfigLoading(true);
|
|
const response = await authenticatedFetch('/api/user/git-config');
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setGitName(data.gitName || '');
|
|
setGitEmail(data.gitEmail || '');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error loading git config:', error);
|
|
} finally {
|
|
setGitConfigLoading(false);
|
|
}
|
|
};
|
|
|
|
const saveGitConfig = async () => {
|
|
try {
|
|
setGitConfigSaving(true);
|
|
const response = await authenticatedFetch('/api/user/git-config', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ gitName, gitEmail })
|
|
});
|
|
|
|
if (response.ok) {
|
|
setSaveStatus('success');
|
|
setTimeout(() => setSaveStatus(null), 3000);
|
|
} else {
|
|
const data = await response.json();
|
|
setSaveStatus('error');
|
|
console.error('Failed to save git config:', data.error);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error saving git config:', error);
|
|
setSaveStatus('error');
|
|
} finally {
|
|
setGitConfigSaving(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-8">
|
|
<div>
|
|
<div className="flex items-center gap-2 mb-4">
|
|
<GitBranch className="h-5 w-5" />
|
|
<h3 className="text-lg font-semibold">{t('git.title')}</h3>
|
|
</div>
|
|
|
|
<p className="text-sm text-muted-foreground mb-4">
|
|
{t('git.description')}
|
|
</p>
|
|
|
|
<div className="p-4 border rounded-lg bg-card space-y-3">
|
|
<div>
|
|
<label htmlFor="settings-git-name" className="block text-sm font-medium text-foreground mb-2">
|
|
{t('git.name.label')}
|
|
</label>
|
|
<Input
|
|
id="settings-git-name"
|
|
type="text"
|
|
value={gitName}
|
|
onChange={(e) => setGitName(e.target.value)}
|
|
placeholder="John Doe"
|
|
disabled={gitConfigLoading}
|
|
className="w-full"
|
|
/>
|
|
<p className="mt-1 text-xs text-muted-foreground">
|
|
{t('git.name.help')}
|
|
</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label htmlFor="settings-git-email" className="block text-sm font-medium text-foreground mb-2">
|
|
{t('git.email.label')}
|
|
</label>
|
|
<Input
|
|
id="settings-git-email"
|
|
type="email"
|
|
value={gitEmail}
|
|
onChange={(e) => setGitEmail(e.target.value)}
|
|
placeholder="john@example.com"
|
|
disabled={gitConfigLoading}
|
|
className="w-full"
|
|
/>
|
|
<p className="mt-1 text-xs text-muted-foreground">
|
|
{t('git.email.help')}
|
|
</p>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-2">
|
|
<Button
|
|
onClick={saveGitConfig}
|
|
disabled={gitConfigSaving || !gitName || !gitEmail}
|
|
>
|
|
{gitConfigSaving ? t('git.actions.saving') : t('git.actions.save')}
|
|
</Button>
|
|
|
|
{saveStatus === 'success' && (
|
|
<div className="text-sm text-green-600 dark:text-green-400 flex items-center gap-2">
|
|
<Check className="w-4 h-4" />
|
|
{t('git.status.success')}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default GitSettings;
|