Skip to content

Commit 6ca731f

Browse files
authored
feat: 添加可切换的中文界面
Merge pull request #69 from youzibigg/codex/add-chinese-ui
2 parents fb29978 + 7bfbb8d commit 6ca731f

7 files changed

Lines changed: 453 additions & 83 deletions

File tree

apps/web/src/app/layout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Metadata } from "next";
22
import { Geist, Geist_Mono } from "next/font/google";
3+
import { LanguageProvider } from "@/lib/i18n";
34
import "./globals.css";
45

56
const geistSans = Geist({
@@ -27,7 +28,9 @@ export default function RootLayout({
2728
lang="zh-CN"
2829
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
2930
>
30-
<body className="min-h-full flex flex-col">{children}</body>
31+
<body className="min-h-full flex flex-col">
32+
<LanguageProvider>{children}</LanguageProvider>
33+
</body>
3134
</html>
3235
);
3336
}

apps/web/src/app/page.tsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
createTask,
1111
listTasks,
1212
} from "@/lib/api"
13+
import { useI18n } from "@/lib/i18n"
1314
import { statusBadgeClass } from "@/lib/status"
1415
import { AppHeader } from "@/components/app-header"
1516
import { Badge } from "@/components/ui/badge"
@@ -45,6 +46,7 @@ function activeCount(tasks: TaskSummary[]) {
4546

4647
export default function Home() {
4748
const router = useRouter()
49+
const { activeTasksText, stageLabel, statusLabel, t } = useI18n()
4850
const [youtubeUrl, setYoutubeUrl] = useState("")
4951
const [bilibiliUrl, setBilibiliUrl] = useState("")
5052
const [tasks, setTasks] = useState<TaskSummary[]>([])
@@ -64,7 +66,7 @@ export default function Home() {
6466
if (cancelled) return
6567
setTasks(list)
6668
} catch (err) {
67-
if (!cancelled) setError(err instanceof Error ? err.message : "Failed to load tasks")
69+
if (!cancelled) setError(err instanceof Error ? err.message : t.home.loadError)
6870
}
6971
}
7072
load()
@@ -73,7 +75,7 @@ export default function Home() {
7375
cancelled = true
7476
window.clearInterval(interval)
7577
}
76-
}, [])
78+
}, [t.home.loadError])
7779

7880
async function submitTask(event: FormEvent<HTMLFormElement>) {
7981
event.preventDefault()
@@ -88,7 +90,7 @@ export default function Home() {
8890
refreshTasks().catch(() => undefined)
8991
router.push(`/tasks/${created.id}`)
9092
} catch (err) {
91-
setError(err instanceof Error ? err.message : "Failed to create task")
93+
setError(err instanceof Error ? err.message : t.home.createError)
9294
} finally {
9395
setSubmitting(false)
9496
}
@@ -104,12 +106,12 @@ export default function Home() {
104106

105107
<Card>
106108
<CardHeader>
107-
<CardTitle>Create new task</CardTitle>
109+
<CardTitle>{t.home.createTitle}</CardTitle>
108110
</CardHeader>
109111
<CardContent>
110112
<form onSubmit={submitTask} className="space-y-4">
111113
<div className="space-y-2">
112-
<Label htmlFor="youtube-url">YouTube URL (English → Chinese)</Label>
114+
<Label htmlFor="youtube-url">{t.home.youtubeLabel}</Label>
113115
<Input
114116
id="youtube-url"
115117
value={youtubeUrl}
@@ -119,7 +121,7 @@ export default function Home() {
119121
/>
120122
</div>
121123
<div className="space-y-2">
122-
<Label htmlFor="bilibili-url">Bilibili URL (Chinese → English)</Label>
124+
<Label htmlFor="bilibili-url">{t.home.bilibiliLabel}</Label>
123125
<Input
124126
id="bilibili-url"
125127
value={bilibiliUrl}
@@ -131,14 +133,14 @@ export default function Home() {
131133
<div className="flex items-center justify-between gap-3">
132134
{queued > 0 ? (
133135
<p className="text-xs text-muted-foreground">
134-
{queued} task{queued > 1 ? "s" : ""} queued / running
136+
{activeTasksText(queued)}
135137
</p>
136138
) : (
137139
<span />
138140
)}
139141
<Button type="submit" disabled={!canSubmit}>
140142
<Play className="size-4" />
141-
{submitting ? "Submitting" : "Create task"}
143+
{submitting ? t.home.submitting : t.home.createTask}
142144
</Button>
143145
</div>
144146
</form>
@@ -153,12 +155,12 @@ export default function Home() {
153155

154156
<Card>
155157
<CardHeader>
156-
<CardTitle>Task history ({tasks.length})</CardTitle>
158+
<CardTitle>{t.home.taskHistory} ({tasks.length})</CardTitle>
157159
</CardHeader>
158160
<CardContent className="px-0">
159161
{tasks.length === 0 ? (
160162
<div className="px-6 py-12 text-center text-sm text-muted-foreground">
161-
No tasks yet. Submit a YouTube or Bilibili URL above to start.
163+
{t.home.empty}
162164
</div>
163165
) : (
164166
<ScrollArea className="max-h-[70dvh]">
@@ -174,10 +176,10 @@ export default function Home() {
174176
{item.title || shortUrl(item.url)}
175177
</p>
176178
<div className="mt-1 flex items-center gap-2 text-xs text-muted-foreground">
177-
<Badge className={statusBadgeClass(item.status)}>{item.status}</Badge>
179+
<Badge className={statusBadgeClass(item.status)}>{statusLabel(item.status)}</Badge>
178180
<span>{formatTime(item.created_at)}</span>
179181
{isActive(item.status) && item.current_stage ? (
180-
<span>· {item.current_stage}</span>
182+
<span>· {stageLabel(item.current_stage)}</span>
181183
) : null}
182184
</div>
183185
</div>

0 commit comments

Comments
 (0)