mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-01-23 18:07:34 +00:00
update: Add translations for some components
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<div align="center">
|
||||
<img src="public/logo.svg" alt="Claude Code UI" width="64" height="64">
|
||||
<h1>Cloud CLI (aka Claude Code UI)</h1>
|
||||
<h1>Cloud CLI (又名 Claude Code UI)</h1>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
45
src/App.jsx
45
src/App.jsx
@@ -36,7 +36,7 @@ import ProtectedRoute from './components/ProtectedRoute';
|
||||
import { useVersionCheck } from './hooks/useVersionCheck';
|
||||
import useLocalStorage from './hooks/useLocalStorage';
|
||||
import { api, authenticatedFetch } from './utils/api';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { I18nextProvider, useTranslation } from 'react-i18next';
|
||||
import i18n from './i18n/config.js';
|
||||
|
||||
|
||||
@@ -579,6 +579,7 @@ function AppContent() {
|
||||
|
||||
// Version Upgrade Modal Component
|
||||
const VersionUpgradeModal = () => {
|
||||
const { t } = useTranslation('common');
|
||||
const [isUpdating, setIsUpdating] = useState(false);
|
||||
const [updateOutput, setUpdateOutput] = useState('');
|
||||
const [updateError, setUpdateError] = useState('');
|
||||
@@ -639,7 +640,7 @@ function AppContent() {
|
||||
<button
|
||||
className="fixed inset-0 bg-black/50 backdrop-blur-sm"
|
||||
onClick={() => setShowVersionModal(false)}
|
||||
aria-label="Close version upgrade modal"
|
||||
aria-label={t('versionUpdate.ariaLabels.closeModal')}
|
||||
/>
|
||||
|
||||
{/* Modal */}
|
||||
@@ -653,9 +654,9 @@ function AppContent() {
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">Update Available</h2>
|
||||
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">{t('versionUpdate.title')}</h2>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">
|
||||
{releaseInfo?.title || 'A new version is ready'}
|
||||
{releaseInfo?.title || t('versionUpdate.newVersionReady')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -672,11 +673,11 @@ function AppContent() {
|
||||
{/* Version Info */}
|
||||
<div className="space-y-3">
|
||||
<div className="flex justify-between items-center p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
|
||||
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">Current Version</span>
|
||||
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">{t('versionUpdate.currentVersion')}</span>
|
||||
<span className="text-sm text-gray-900 dark:text-white font-mono">{currentVersion}</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-center p-3 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-700">
|
||||
<span className="text-sm font-medium text-blue-700 dark:text-blue-300">Latest Version</span>
|
||||
<span className="text-sm font-medium text-blue-700 dark:text-blue-300">{t('versionUpdate.latestVersion')}</span>
|
||||
<span className="text-sm text-blue-900 dark:text-blue-100 font-mono">{latestVersion}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -685,7 +686,7 @@ function AppContent() {
|
||||
{releaseInfo?.body && (
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 className="text-sm font-medium text-gray-900 dark:text-white">What's New:</h3>
|
||||
<h3 className="text-sm font-medium text-gray-900 dark:text-white">{t('versionUpdate.whatsNew')}</h3>
|
||||
{releaseInfo?.htmlUrl && (
|
||||
<a
|
||||
href={releaseInfo.htmlUrl}
|
||||
@@ -693,7 +694,7 @@ function AppContent() {
|
||||
rel="noopener noreferrer"
|
||||
className="text-xs text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 hover:underline flex items-center gap-1"
|
||||
>
|
||||
View full release
|
||||
{t('versionUpdate.viewFullRelease')}
|
||||
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||
</svg>
|
||||
@@ -711,7 +712,7 @@ function AppContent() {
|
||||
{/* Update Output */}
|
||||
{updateOutput && (
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-sm font-medium text-gray-900 dark:text-white">Update Progress:</h3>
|
||||
<h3 className="text-sm font-medium text-gray-900 dark:text-white">{t('versionUpdate.updateProgress')}</h3>
|
||||
<div className="bg-gray-900 dark:bg-gray-950 rounded-lg p-4 border border-gray-700 max-h-48 overflow-y-auto">
|
||||
<pre className="text-xs text-green-400 font-mono whitespace-pre-wrap">{updateOutput}</pre>
|
||||
</div>
|
||||
@@ -721,14 +722,14 @@ function AppContent() {
|
||||
{/* Upgrade Instructions */}
|
||||
{!isUpdating && !updateOutput && (
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-sm font-medium text-gray-900 dark:text-white">Manual upgrade:</h3>
|
||||
<h3 className="text-sm font-medium text-gray-900 dark:text-white">{t('versionUpdate.manualUpgrade')}</h3>
|
||||
<div className="bg-gray-100 dark:bg-gray-800 rounded-lg p-3 border">
|
||||
<code className="text-sm text-gray-800 dark:text-gray-200 font-mono">
|
||||
git checkout main && git pull && npm install
|
||||
</code>
|
||||
</div>
|
||||
<p className="text-xs text-gray-600 dark:text-gray-400">
|
||||
Or click "Update Now" to run the update automatically.
|
||||
{t('versionUpdate.manualUpgradeHint')}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
@@ -739,7 +740,7 @@ function AppContent() {
|
||||
onClick={() => setShowVersionModal(false)}
|
||||
className="flex-1 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-md transition-colors"
|
||||
>
|
||||
{updateOutput ? 'Close' : 'Later'}
|
||||
{updateOutput ? t('versionUpdate.buttons.close') : t('versionUpdate.buttons.later')}
|
||||
</button>
|
||||
{!updateOutput && (
|
||||
<>
|
||||
@@ -749,7 +750,7 @@ function AppContent() {
|
||||
}}
|
||||
className="flex-1 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-md transition-colors"
|
||||
>
|
||||
Copy Command
|
||||
{t('versionUpdate.buttons.copyCommand')}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleUpdateNow}
|
||||
@@ -759,10 +760,10 @@ function AppContent() {
|
||||
{isUpdating ? (
|
||||
<>
|
||||
<div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
|
||||
Updating...
|
||||
{t('versionUpdate.buttons.updating')}
|
||||
</>
|
||||
) : (
|
||||
'Update Now'
|
||||
t('versionUpdate.buttons.updateNow')
|
||||
)}
|
||||
</button>
|
||||
</>
|
||||
@@ -813,8 +814,8 @@ function AppContent() {
|
||||
<button
|
||||
onClick={() => setSidebarVisible(true)}
|
||||
className="p-2 hover:bg-accent rounded-md transition-colors duration-200 group"
|
||||
aria-label="Show sidebar"
|
||||
title="Show sidebar"
|
||||
aria-label={t('versionUpdate.ariaLabels.showSidebar')}
|
||||
title={t('versionUpdate.ariaLabels.showSidebar')}
|
||||
>
|
||||
<svg
|
||||
className="w-5 h-5 text-foreground group-hover:scale-110 transition-transform"
|
||||
@@ -830,8 +831,8 @@ function AppContent() {
|
||||
<button
|
||||
onClick={() => setShowSettings(true)}
|
||||
className="p-2 hover:bg-accent rounded-md transition-colors duration-200"
|
||||
aria-label="Settings"
|
||||
title="Settings"
|
||||
aria-label={t('versionUpdate.ariaLabels.settings')}
|
||||
title={t('versionUpdate.ariaLabels.settings')}
|
||||
>
|
||||
<SettingsIcon className="w-5 h-5 text-muted-foreground hover:text-foreground transition-colors" />
|
||||
</button>
|
||||
@@ -841,8 +842,8 @@ function AppContent() {
|
||||
<button
|
||||
onClick={() => setShowVersionModal(true)}
|
||||
className="relative p-2 hover:bg-accent rounded-md transition-colors duration-200"
|
||||
aria-label="Update available"
|
||||
title="Update available"
|
||||
aria-label={t('versionUpdate.ariaLabels.updateAvailable')}
|
||||
title={t('versionUpdate.ariaLabels.updateAvailable')}
|
||||
>
|
||||
<Sparkles className="w-5 h-5 text-blue-500" />
|
||||
<span className="absolute top-1 right-1 w-2 h-2 bg-blue-500 rounded-full animate-pulse" />
|
||||
@@ -870,7 +871,7 @@ function AppContent() {
|
||||
e.stopPropagation();
|
||||
setSidebarOpen(false);
|
||||
}}
|
||||
aria-label="Close sidebar"
|
||||
aria-label={t('versionUpdate.ariaLabels.closeSidebar')}
|
||||
/>
|
||||
<div
|
||||
className={`relative w-[85vw] max-w-sm sm:w-80 h-full bg-card border-r border-border transform transition-transform duration-150 ease-out ${
|
||||
|
||||
@@ -669,7 +669,7 @@ function Sidebar({
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t('projects.fetchingProjects')}
|
||||
</p>
|
||||
<h3 className="text-base font-medium text-foreground mb-2 md:mb-1">Loading projects...</h3>
|
||||
<h3 className="text-base font-medium text-foreground mb-2 md:mb-1">{t('projects.loadingProjects')}</h3>
|
||||
{loadingProgress && loadingProgress.total > 0 ? (
|
||||
<div className="space-y-2">
|
||||
<div className="w-full bg-muted rounded-full h-2 overflow-hidden">
|
||||
@@ -679,7 +679,7 @@ function Sidebar({
|
||||
/>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{loadingProgress.current}/{loadingProgress.total} projects
|
||||
{loadingProgress.current}/{loadingProgress.total} {t('projects.projects')}
|
||||
</p>
|
||||
{loadingProgress.currentProject && (
|
||||
<p className="text-xs text-muted-foreground/70 truncate max-w-[200px] mx-auto" title={loadingProgress.currentProject}>
|
||||
@@ -689,7 +689,7 @@ function Sidebar({
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Fetching your Claude projects and sessions
|
||||
{t('projects.fetchingProjects')}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -186,5 +186,33 @@
|
||||
"providePath": "Please provide a workspace path",
|
||||
"failedToCreate": "Failed to create workspace"
|
||||
}
|
||||
},
|
||||
"versionUpdate": {
|
||||
"title": "Update Available",
|
||||
"newVersionReady": "A new version is ready",
|
||||
"currentVersion": "Current Version",
|
||||
"latestVersion": "Latest Version",
|
||||
"whatsNew": "What's New:",
|
||||
"viewFullRelease": "View full release",
|
||||
"updateProgress": "Update Progress:",
|
||||
"manualUpgrade": "Manual upgrade:",
|
||||
"manualUpgradeHint": "Or click \"Update Now\" to run the update automatically.",
|
||||
"updateCompleted": "Update completed successfully!",
|
||||
"restartServer": "Please restart the server to apply changes.",
|
||||
"updateFailed": "Update failed",
|
||||
"buttons": {
|
||||
"close": "Close",
|
||||
"later": "Later",
|
||||
"copyCommand": "Copy Command",
|
||||
"updateNow": "Update Now",
|
||||
"updating": "Updating..."
|
||||
},
|
||||
"ariaLabels": {
|
||||
"closeModal": "Close version upgrade modal",
|
||||
"showSidebar": "Show sidebar",
|
||||
"settings": "Settings",
|
||||
"updateAvailable": "Update available",
|
||||
"closeSidebar": "Close sidebar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"newSession": "New Session",
|
||||
"codexSession": "Codex Session",
|
||||
"fetchingProjects": "Fetching your Claude projects and sessions",
|
||||
"projects": "projects",
|
||||
"noMatchingProjects": "No matching projects",
|
||||
"tryDifferentSearch": "Try adjusting your search term",
|
||||
"runClaudeCli": "Run Claude CLI in a project directory to get started"
|
||||
|
||||
@@ -186,5 +186,33 @@
|
||||
"providePath": "请提供工作区路径",
|
||||
"failedToCreate": "创建工作区失败"
|
||||
}
|
||||
},
|
||||
"versionUpdate": {
|
||||
"title": "有可用更新",
|
||||
"newVersionReady": "新版本已准备就绪",
|
||||
"currentVersion": "当前版本",
|
||||
"latestVersion": "最新版本",
|
||||
"whatsNew": "新内容:",
|
||||
"viewFullRelease": "查看完整发布",
|
||||
"updateProgress": "更新进度:",
|
||||
"manualUpgrade": "手动升级:",
|
||||
"manualUpgradeHint": "或点击'立即更新'以自动运行更新。",
|
||||
"updateCompleted": "更新成功完成!",
|
||||
"restartServer": "请重启服务器以应用更改。",
|
||||
"updateFailed": "更新失败",
|
||||
"buttons": {
|
||||
"close": "关闭",
|
||||
"later": "稍后",
|
||||
"copyCommand": "复制命令",
|
||||
"updateNow": "立即更新",
|
||||
"updating": "更新中..."
|
||||
},
|
||||
"ariaLabels": {
|
||||
"closeModal": "关闭版本升级模态框",
|
||||
"showSidebar": "显示侧边栏",
|
||||
"settings": "设置",
|
||||
"updateAvailable": "有可用更新",
|
||||
"closeSidebar": "关闭侧边栏"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"newSession": "新会话",
|
||||
"codexSession": "Codex 会话",
|
||||
"fetchingProjects": "正在获取您的 Claude 项目和会话",
|
||||
"projects": "项目",
|
||||
"noMatchingProjects": "未找到匹配的项目",
|
||||
"tryDifferentSearch": "尝试调整您的搜索词",
|
||||
"runClaudeCli": "在项目目录中运行 Claude CLI 以开始使用"
|
||||
|
||||
Reference in New Issue
Block a user