mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-06 01:14:36 +08:00
feat(i18n): implement internationalization framework and update UI components for language support
This commit is contained in:
@@ -2,12 +2,14 @@ import { ArrowRight } from "lucide-react";
|
||||
import { type ReactNode, useEffect, useState } from "react";
|
||||
import { App, Button, Image, Tag } from "antd";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
|
||||
import { fetchPrompts, type Prompt } from "@/services/api/prompts";
|
||||
import { navigationTools } from "@/constant/navigation-tools";
|
||||
import i18n from "@/i18n";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function Highlighter({ action, color, children }: { action: "highlight" | "underline"; color: string; children: ReactNode }) {
|
||||
function Highlighter({ action, color, children }: { action: "highlight" | "underline"; color: string; children?: ReactNode }) {
|
||||
return (
|
||||
<span className="relative inline-block px-1">
|
||||
{action === "highlight" ? (
|
||||
@@ -22,6 +24,7 @@ function Highlighter({ action, color, children }: { action: "highlight" | "under
|
||||
|
||||
export default function IndexPage() {
|
||||
const { message } = App.useApp();
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const [primaryTool] = navigationTools;
|
||||
const [promptShowcase, setPromptShowcase] = useState<Prompt[]>([]);
|
||||
@@ -31,7 +34,7 @@ export default function IndexPage() {
|
||||
useEffect(() => {
|
||||
void fetchPrompts({ pageSize: 12 })
|
||||
.then((data) => setPromptShowcase(data.items))
|
||||
.catch((error) => message.error(error instanceof Error ? error.message : "获取提示词失败"));
|
||||
.catch((error) => message.error(error instanceof Error ? error.message : i18n.t("home.promptError")));
|
||||
}, [message]);
|
||||
|
||||
return (
|
||||
@@ -41,24 +44,16 @@ export default function IndexPage() {
|
||||
<div className="pointer-events-none absolute right-[23%] top-[48%] size-20 rounded-full border border-dashed border-stone-200 dark:border-stone-800" />
|
||||
|
||||
<div className="relative flex min-h-[620px] flex-col items-center justify-center pt-10 text-center">
|
||||
<h1 className="ai-title-aurora max-w-5xl text-balance text-5xl font-semibold tracking-normal sm:text-7xl lg:text-8xl">无限画布</h1>
|
||||
<h1 className="ai-title-aurora max-w-5xl text-balance text-5xl font-semibold tracking-normal sm:text-7xl lg:text-8xl">{t("meta.title")}</h1>
|
||||
<p className="mt-8 max-w-3xl text-balance text-lg leading-8 text-stone-500 dark:text-stone-400">
|
||||
在
|
||||
<Highlighter action="underline" color="#FF9800">
|
||||
无限画布
|
||||
</Highlighter>
|
||||
中生成、连接和重组
|
||||
<Highlighter action="highlight" color="#87CEFA">
|
||||
图片、文字与图形
|
||||
</Highlighter>
|
||||
,让创作从单次生成变成连续推演。
|
||||
<Trans i18nKey="home.description" components={{ canvas: <Highlighter action="underline" color="#FF9800" />, content: <Highlighter action="highlight" color="#87CEFA" /> }} />
|
||||
</p>
|
||||
<div className="mt-10 flex flex-wrap items-center justify-center gap-3">
|
||||
<Button type="primary" size="large" onClick={() => navigate(`/${primaryTool.slug}`)} icon={<ArrowRight className="size-4" />} iconPlacement="end">
|
||||
开始使用
|
||||
{t("home.start")}
|
||||
</Button>
|
||||
<Button size="large" onClick={() => navigate("/canvas")}>
|
||||
打开画布
|
||||
{t("home.openCanvas")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,11 +62,11 @@ export default function IndexPage() {
|
||||
<div className="mb-8 grid gap-4 md:grid-cols-[1fr_auto_1fr] md:items-start">
|
||||
<div />
|
||||
<div className="max-w-2xl text-center">
|
||||
<h2 className="text-3xl font-semibold text-stone-950 dark:text-stone-100">沉淀每一次好结果</h2>
|
||||
<p className="mt-3 text-base leading-7 text-stone-500 dark:text-stone-400">收藏稳定出图的提示词、参考风格和结果图片,让下一次创作从已有经验开始。</p>
|
||||
<h2 className="text-3xl font-semibold text-stone-950 dark:text-stone-100">{t("home.showcaseTitle")}</h2>
|
||||
<p className="mt-3 text-base leading-7 text-stone-500 dark:text-stone-400">{t("home.showcaseDescription")}</p>
|
||||
</div>
|
||||
<Button type="link" onClick={() => navigate("/prompts")} className="justify-self-center md:justify-self-end" icon={<ArrowRight className="size-4" />} iconPlacement="end">
|
||||
查看提示词库
|
||||
{t("home.viewPrompts")}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="grid auto-rows-[210px] gap-4 md:grid-cols-4">
|
||||
|
||||
Reference in New Issue
Block a user