feat: 界面全部改为中文
- 侧边栏导航:仪表盘、登录、内容浏览、发布、互动、API 测试、设置 - 7 个页面所有按钮、标签、提示、错误信息改为中文 - API 端点列表分类改为中文(登录、内容、发布、互动) - 组件内文本:展开/收起、复制、点赞、收藏、评论等 - 页面标题改为 Social MCP - 管理后台
This commit is contained in:
@@ -52,12 +52,12 @@ export function ApiTesterPage() {
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<h1 className="text-2xl font-bold">API Tester</h1>
|
||||
<h1 className="text-2xl font-bold">API 测试</h1>
|
||||
|
||||
<Tabs
|
||||
tabs={[
|
||||
{ key: 'rest', label: 'REST API' },
|
||||
{ key: 'mcp', label: 'MCP Tools' },
|
||||
{ key: 'mcp', label: 'MCP 工具' },
|
||||
]}
|
||||
active={mode}
|
||||
onChange={(k) => setMode(k as 'rest' | 'mcp')}
|
||||
@@ -87,11 +87,11 @@ export function ApiTesterPage() {
|
||||
{response !== null && (
|
||||
<Card>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<h2 className="text-sm font-semibold text-dark-muted uppercase tracking-wider">Response</h2>
|
||||
<h2 className="text-sm font-semibold text-dark-muted uppercase tracking-wider">响应</h2>
|
||||
<div className="flex items-center gap-2">
|
||||
{responseStatus && (
|
||||
<Badge variant={responseStatus === 'success' ? 'success' : 'danger'}>
|
||||
{responseStatus}
|
||||
{responseStatus === 'success' ? '成功' : '失败'}
|
||||
</Badge>
|
||||
)}
|
||||
{duration !== null && (
|
||||
@@ -108,11 +108,11 @@ export function ApiTesterPage() {
|
||||
<div>
|
||||
<Card>
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<h2 className="text-sm font-semibold text-dark-muted uppercase tracking-wider">History</h2>
|
||||
<Button variant="ghost" size="sm" onClick={() => setHistory([])}>Clear</Button>
|
||||
<h2 className="text-sm font-semibold text-dark-muted uppercase tracking-wider">历史记录</h2>
|
||||
<Button variant="ghost" size="sm" onClick={() => setHistory([])}>清空</Button>
|
||||
</div>
|
||||
{history.length === 0 ? (
|
||||
<p className="text-sm text-dark-muted">No requests yet</p>
|
||||
<p className="text-sm text-dark-muted">暂无请求</p>
|
||||
) : (
|
||||
<div className="space-y-2 max-h-[600px] overflow-y-auto">
|
||||
{history.map((entry) => (
|
||||
@@ -136,7 +136,7 @@ export function ApiTesterPage() {
|
||||
</div>
|
||||
<div className="flex items-center gap-2 mt-1 text-dark-muted">
|
||||
<Badge variant={entry.status === 'success' ? 'success' : 'danger'} className="text-[10px]">
|
||||
{entry.status}
|
||||
{entry.status === 'success' ? '成功' : '失败'}
|
||||
</Badge>
|
||||
<span>{entry.time}</span>
|
||||
<span>{entry.duration}ms</span>
|
||||
@@ -227,10 +227,10 @@ function RestPanel({
|
||||
return (
|
||||
<>
|
||||
<Card>
|
||||
<h2 className="text-sm font-semibold text-dark-muted uppercase tracking-wider mb-3">REST Request</h2>
|
||||
<h2 className="text-sm font-semibold text-dark-muted uppercase tracking-wider mb-3">REST 请求</h2>
|
||||
<div className="space-y-3">
|
||||
<Select
|
||||
label="Endpoint"
|
||||
label="端点"
|
||||
options={categories.flatMap((cat) => [
|
||||
{ value: `__cat_${cat}`, label: `── ${cat} ──` },
|
||||
...API_ENDPOINTS.filter((e) => e.category === cat).map((e) => ({
|
||||
@@ -253,7 +253,7 @@ function RestPanel({
|
||||
</div>
|
||||
{endpoint.method !== 'GET' && (
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<label className="text-sm text-dark-muted">Request Body (JSON)</label>
|
||||
<label className="text-sm text-dark-muted">请求体 (JSON)</label>
|
||||
<textarea
|
||||
value={bodyText}
|
||||
onChange={(e) => setBodyText(e.target.value)}
|
||||
@@ -263,8 +263,8 @@ function RestPanel({
|
||||
</div>
|
||||
)}
|
||||
<div className="flex gap-2">
|
||||
<Button onClick={() => void handleSend()} loading={loading}>Send Request</Button>
|
||||
<Button variant="ghost" size="sm" onClick={() => void navigator.clipboard.writeText(curl)}>Copy cURL</Button>
|
||||
<Button onClick={() => void handleSend()} loading={loading}>发送请求</Button>
|
||||
<Button variant="ghost" size="sm" onClick={() => void navigator.clipboard.writeText(curl)}>复制 cURL</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
@@ -375,20 +375,20 @@ function McpPanel({
|
||||
<>
|
||||
{/* Connection */}
|
||||
<Card>
|
||||
<h2 className="text-sm font-semibold text-dark-muted uppercase tracking-wider mb-3">MCP Connection</h2>
|
||||
<h2 className="text-sm font-semibold text-dark-muted uppercase tracking-wider mb-3">MCP 连接</h2>
|
||||
<div className="flex items-center gap-3">
|
||||
<Badge variant={connState === 'connected' ? 'success' : connState === 'connecting' ? 'warning' : 'default'}>
|
||||
{connState}
|
||||
{connState === 'connected' ? '已连接' : connState === 'connecting' ? '连接中' : '未连接'}
|
||||
</Badge>
|
||||
{connState === 'disconnected' && (
|
||||
<Button size="sm" onClick={() => void handleConnect()} loading={connecting}>
|
||||
Connect
|
||||
连接
|
||||
</Button>
|
||||
)}
|
||||
{connState === 'connected' && (
|
||||
<>
|
||||
<span className="text-xs text-dark-muted">{tools.length} tools available</span>
|
||||
<Button size="sm" variant="ghost" onClick={handleDisconnect}>Disconnect</Button>
|
||||
<span className="text-xs text-dark-muted">{tools.length} 个工具可用</span>
|
||||
<Button size="sm" variant="ghost" onClick={handleDisconnect}>断开</Button>
|
||||
</>
|
||||
)}
|
||||
{connState === 'connecting' && <Spinner size="sm" />}
|
||||
@@ -398,10 +398,10 @@ function McpPanel({
|
||||
{/* Tool Call */}
|
||||
{connState === 'connected' && tools.length > 0 && (
|
||||
<Card>
|
||||
<h2 className="text-sm font-semibold text-dark-muted uppercase tracking-wider mb-3">MCP Tool Call</h2>
|
||||
<h2 className="text-sm font-semibold text-dark-muted uppercase tracking-wider mb-3">MCP 工具调用</h2>
|
||||
<div className="space-y-3">
|
||||
<Select
|
||||
label="Tool"
|
||||
label="工具"
|
||||
options={tools.map((t) => ({ value: t.name, label: t.name }))}
|
||||
value={selectedTool}
|
||||
onChange={(e) => handleToolChange(e.target.value)}
|
||||
@@ -415,13 +415,13 @@ function McpPanel({
|
||||
)}
|
||||
{currentTool.inputSchema?.properties && (
|
||||
<div>
|
||||
<p className="text-dark-muted font-semibold mb-1">Parameters:</p>
|
||||
<p className="text-dark-muted font-semibold mb-1">参数:</p>
|
||||
{Object.entries(currentTool.inputSchema.properties).map(([key, prop]) => (
|
||||
<div key={key} className="flex gap-2 ml-2">
|
||||
<code className="text-dark-accent">{key}</code>
|
||||
<span className="text-dark-muted">
|
||||
{prop.type || ''}
|
||||
{currentTool.inputSchema?.required?.includes(key) ? ' (required)' : ' (optional)'}
|
||||
{currentTool.inputSchema?.required?.includes(key) ? ' (必填)' : ' (可选)'}
|
||||
{prop.description ? ` — ${prop.description}` : ''}
|
||||
</span>
|
||||
</div>
|
||||
@@ -433,7 +433,7 @@ function McpPanel({
|
||||
|
||||
{/* Arguments editor */}
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<label className="text-sm text-dark-muted">Arguments (JSON)</label>
|
||||
<label className="text-sm text-dark-muted">参数 (JSON)</label>
|
||||
<textarea
|
||||
value={argsText}
|
||||
onChange={(e) => setArgsText(e.target.value)}
|
||||
@@ -443,7 +443,7 @@ function McpPanel({
|
||||
</div>
|
||||
|
||||
<Button onClick={() => void handleCall()} loading={loading}>
|
||||
Call Tool
|
||||
调用工具
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
@@ -452,8 +452,8 @@ function McpPanel({
|
||||
{connState === 'disconnected' && (
|
||||
<Card>
|
||||
<div className="text-center py-8 text-dark-muted">
|
||||
<p>Connect to the MCP server to discover and test tools.</p>
|
||||
<p className="text-xs mt-2">This uses the same SSE + JSON-RPC protocol that AI clients use.</p>
|
||||
<p>连接到 MCP 服务器以发现和测试工具。</p>
|
||||
<p className="text-xs mt-2">使用与 AI 客户端相同的 SSE + JSON-RPC 协议。</p>
|
||||
</div>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user