wip: i18n chinese

This commit is contained in:
elvis liao
2024-09-26 17:57:30 +08:00
parent 85df8eb09d
commit 0abb030889
18 changed files with 289 additions and 184 deletions

View File

@@ -1,4 +1,5 @@
import { Moon, Sun } from "lucide-react";
import { useTranslation } from 'react-i18next'
import { Button } from "@/components/ui/button";
import {
@@ -11,6 +12,8 @@ import { useTheme } from "./ThemeProvider";
export function ThemeToggle() {
const { setTheme } = useTheme();
const { t } = useTranslation();
return (
<DropdownMenu>
@@ -23,13 +26,13 @@ export function ThemeToggle() {
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>
{t('theme.light')}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
{t('theme.dark')}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
{t('theme.system')}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>

View File

@@ -1,3 +1,5 @@
import { useTranslation } from "react-i18next";
import { Separator } from "../ui/separator";
type DeployProgressProps = {
@@ -6,26 +8,40 @@ type DeployProgressProps = {
};
const DeployProgress = ({ phase, phaseSuccess }: DeployProgressProps) => {
const { t } = useTranslation();
let rs = <> </>;
if (phase === "check") {
if (phaseSuccess) {
rs = (
<div className="flex items-center">
<div className="text-xs text-nowrap text-green-600"> </div>
<div className="text-xs text-nowrap text-green-600">
{t('deploy.progress.check')}
</div>
<Separator className="h-1 grow" />
<div className="text-xs text-nowrap text-muted-foreground"></div>
<div className="text-xs text-nowrap text-muted-foreground">
{t('deploy.progress.apply')}
</div>
<Separator className="h-1 grow" />
<div className="text-xs text-nowrap text-muted-foreground"></div>
<div className="text-xs text-nowrap text-muted-foreground">
{t('deploy.progress.deploy')}
</div>
</div>
);
} else {
rs = (
<div className="flex items-center">
<div className="text-xs text-nowrap text-red-600"> </div>
<div className="text-xs text-nowrap text-red-600">
{t('deploy.progress.check')}
</div>
<Separator className="h-1 grow" />
<div className="text-xs text-nowrap text-muted-foreground"></div>
<div className="text-xs text-nowrap text-muted-foreground">
{t('deploy.progress.apply')}
</div>
<Separator className="h-1 grow" />
<div className="text-xs text-nowrap text-muted-foreground"></div>
<div className="text-xs text-nowrap text-muted-foreground">
{t('deploy.progress.deploy')}
</div>
</div>
);
}
@@ -35,21 +51,33 @@ const DeployProgress = ({ phase, phaseSuccess }: DeployProgressProps) => {
if (phaseSuccess) {
rs = (
<div className="flex items-center">
<div className="text-xs text-nowrap text-green-600"> </div>
<div className="text-xs text-nowrap text-green-600">
{t('deploy.progress.check')}
</div>
<Separator className="h-1 grow bg-green-600" />
<div className="text-xs text-nowrap text-green-600"></div>
<div className="text-xs text-nowrap text-green-600">
{t('deploy.progress.apply')}
</div>
<Separator className="h-1 grow" />
<div className="text-xs text-nowrap text-muted-foreground"></div>
<div className="text-xs text-nowrap text-muted-foreground">
{t('deploy.progress.deploy')}
</div>
</div>
);
} else {
rs = (
<div className="flex items-center">
<div className="text-xs text-nowrap text-green-600"> </div>
<div className="text-xs text-nowrap text-green-600">
{t('deploy.progress.check')}
</div>
<Separator className="h-1 grow bg-green-600" />
<div className="text-xs text-nowrap text-red-600"></div>
<div className="text-xs text-nowrap text-red-600">
{t('deploy.progress.apply')}
</div>
<Separator className="h-1 grow" />
<div className="text-xs text-nowrap text-muted-foreground"></div>
<div className="text-xs text-nowrap text-muted-foreground">
{t('deploy.progress.deploy')}
</div>
</div>
);
}
@@ -59,21 +87,33 @@ const DeployProgress = ({ phase, phaseSuccess }: DeployProgressProps) => {
if (phaseSuccess) {
rs = (
<div className="flex items-center">
<div className="text-xs text-nowrap text-green-600"> </div>
<div className="text-xs text-nowrap text-green-600">
{t('deploy.progress.check')}
</div>
<Separator className="h-1 grow bg-green-600" />
<div className="text-xs text-nowrap text-green-600"></div>
<div className="text-xs text-nowrap text-green-600">
{t('deploy.progress.apply')}
</div>
<Separator className="h-1 grow bg-green-600" />
<div className="text-xs text-nowrap text-green-600"></div>
<div className="text-xs text-nowrap text-green-600">
{t('deploy.progress.deploy')}
</div>
</div>
);
} else {
rs = (
<div className="flex items-center">
<div className="text-xs text-nowrap text-green-600"> </div>
<div className="text-xs text-nowrap text-green-600">
{t('deploy.progress.check')}
</div>
<Separator className="h-1 grow bg-green-600" />
<div className="text-xs text-nowrap text-green-600"></div>
<div className="text-xs text-nowrap text-green-600">
{t('deploy.progress.apply')}
</div>
<Separator className="h-1 grow bg-green-600" />
<div className="text-xs text-nowrap text-red-600"></div>
<div className="text-xs text-nowrap text-red-600">
{t('deploy.progress.deploy')}
</div>
</div>
);
}

View File

@@ -8,6 +8,7 @@ import { useEffect, useState } from "react";
import { update } from "@/repository/settings";
import { getErrMessage } from "@/lib/error";
import { useToast } from "../ui/use-toast";
import { useTranslation } from 'react-i18next'
type DingTalkSetting = {
id: string;
@@ -17,6 +18,7 @@ type DingTalkSetting = {
const DingTalk = () => {
const { config, setChannels } = useNotify();
const { t } = useTranslation();
const [dingtalk, setDingtalk] = useState<DingTalkSetting>({
id: config.id ?? "",
@@ -70,15 +72,15 @@ const DingTalk = () => {
setChannels(resp);
toast({
title: "保存成功",
description: "配置保存成功",
title: t('save.succeed'),
description: t('setting.notify.config.save.succeed'),
});
} catch (e) {
const msg = getErrMessage(e);
toast({
title: "保存失败",
description: "配置保存失败:" + msg,
title: t('save.failed'),
description: `${t('setting.notify.config.save.failed')}: ${msg}`,
variant: "destructive",
});
}
@@ -127,7 +129,7 @@ const DingTalk = () => {
});
}}
/>
<Label htmlFor="airplane-mode"></Label>
<Label htmlFor="airplane-mode">{t('setting.notify.config.enable')}</Label>
</div>
<div className="flex justify-end mt-2">
@@ -136,7 +138,7 @@ const DingTalk = () => {
handleSaveClick();
}}
>
{t('save')}
</Button>
</div>
</div>

View File

@@ -9,6 +9,7 @@ import {
} from "@/domain/settings";
import { getSetting, update } from "@/repository/settings";
import { useToast } from "../ui/use-toast";
import { useTranslation } from 'react-i18next'
const NotifyTemplate = () => {
const [id, setId] = useState("");
@@ -17,6 +18,7 @@ const NotifyTemplate = () => {
]);
const { toast } = useToast();
const { t } = useTranslation();
useEffect(() => {
const featchData = async () => {
@@ -66,8 +68,8 @@ const NotifyTemplate = () => {
}
toast({
title: "保存成功",
description: "通知模板保存成功",
title: t('save.succeed'),
description: t('setting.notify.template.save.succeed'),
});
};
@@ -81,7 +83,7 @@ const NotifyTemplate = () => {
/>
<div className="text-muted-foreground text-sm mt-1">
, COUNT:即将过期张数
{t('setting.notify.template.variables.tips.title')}
</div>
<Textarea
@@ -92,10 +94,10 @@ const NotifyTemplate = () => {
}}
></Textarea>
<div className="text-muted-foreground text-sm mt-1">
, COUNT:即将过期张数DOMAINS:域名列表
{t('setting.notify.template.variables.tips.content')}
</div>
<div className="flex justify-end mt-2">
<Button onClick={handleSaveClick}></Button>
<Button onClick={handleSaveClick}>{t('save')}</Button>
</div>
</div>
);

View File

@@ -8,6 +8,7 @@ import { useEffect, useState } from "react";
import { update } from "@/repository/settings";
import { getErrMessage } from "@/lib/error";
import { useToast } from "../ui/use-toast";
import { useTranslation } from "react-i18next";
type TelegramSetting = {
id: string;
@@ -17,6 +18,7 @@ type TelegramSetting = {
const Telegram = () => {
const { config, setChannels } = useNotify();
const { t } = useTranslation();
const [telegram, setTelegram] = useState<TelegramSetting>({
id: config.id ?? "",
@@ -70,15 +72,15 @@ const Telegram = () => {
setChannels(resp);
toast({
title: "保存成功",
description: "配置保存成功",
title: t('save.succeed'),
description: t('setting.notify.config.save.succeed'),
});
} catch (e) {
const msg = getErrMessage(e);
toast({
title: "保存失败",
description: "配置保存失败:" + msg,
title: t('save.failed'),
description: `${t('setting.notify.config.save.failed')}: ${msg}`,
variant: "destructive",
});
}
@@ -128,7 +130,7 @@ const Telegram = () => {
});
}}
/>
<Label htmlFor="airplane-mode"></Label>
<Label htmlFor="airplane-mode">{t('setting.notify.config.enable')}</Label>
</div>
<div className="flex justify-end mt-2">
@@ -137,7 +139,7 @@ const Telegram = () => {
handleSaveClick();
}}
>
{t('save')}
</Button>
</div>
</div>

View File

@@ -9,6 +9,7 @@ import { update } from "@/repository/settings";
import { getErrMessage } from "@/lib/error";
import { useToast } from "../ui/use-toast";
import { isValidURL } from "@/lib/url";
import { useTranslation } from 'react-i18next'
type WebhookSetting = {
id: string;
@@ -18,6 +19,7 @@ type WebhookSetting = {
const Webhook = () => {
const { config, setChannels } = useNotify();
const { t } = useTranslation();
const [webhook, setWebhook] = useState<WebhookSetting>({
id: config.id ?? "",
@@ -59,8 +61,8 @@ const Webhook = () => {
webhook.data.url = webhook.data.url.trim();
if (!isValidURL(webhook.data.url)) {
toast({
title: "保存失败",
description: "Url格式不正确",
title: t('save.failed'),
description: t('setting.notify.config.save.failed.url.not.valid'),
variant: "destructive",
});
return;
@@ -79,15 +81,15 @@ const Webhook = () => {
setChannels(resp);
toast({
title: "保存成功",
description: "配置保存成功",
title: t('save.succeed'),
description: t('setting.notify.config.save.succeed'),
});
} catch (e) {
const msg = getErrMessage(e);
toast({
title: "保存失败",
description: "配置保存失败:" + msg,
title: t('save.failed'),
description: `${t('setting.notify.config.save.failed')}: ${msg}`,
variant: "destructive",
});
}
@@ -123,7 +125,7 @@ const Webhook = () => {
});
}}
/>
<Label htmlFor="airplane-mode"></Label>
<Label htmlFor="airplane-mode">{t('setting.notify.config.enable')}</Label>
</div>
<div className="flex justify-end mt-2">
@@ -132,7 +134,7 @@ const Webhook = () => {
handleSaveClick();
}}
>
{t('save')}
</Button>
</div>
</div>

View File

@@ -12,6 +12,7 @@ import {
import { cn } from "@/lib/utils"
import { Label } from "@/components/ui/label"
import { useTranslation } from "react-i18next"
const Form = FormProvider
@@ -145,7 +146,9 @@ const FormMessage = React.forwardRef<
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, children, ...props }, ref) => {
const { error, formMessageId } = useFormField()
const body = error ? String(error?.message) : children
const { t } = useTranslation()
const body = error ? t(String(error?.message)) : children
if (!body) {
return null

View File

@@ -3,6 +3,7 @@ import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
import { cn } from "@/lib/utils";
import { ButtonProps, buttonVariants } from "@/components/ui/button";
import { useTranslation } from "react-i18next";
const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
<nav
@@ -62,33 +63,41 @@ PaginationLink.displayName = "PaginationLink";
const PaginationPrevious = ({
className,
...props
}: React.ComponentProps<typeof PaginationLink>) => (
<PaginationLink
aria-label="Go to previous page"
size="default"
className={cn("gap-1 pl-2.5", className)}
{...props}
>
<ChevronLeft className="h-4 w-4" />
<span></span>
</PaginationLink>
);
}: React.ComponentProps<typeof PaginationLink>) => {
const { t } = useTranslation()
return (
<PaginationLink
aria-label="Go to previous page"
size="default"
className={cn("gap-1 pl-2.5", className)}
{...props}
>
<ChevronLeft className="h-4 w-4" />
<span>{t('pagination.prev')}</span>
</PaginationLink>
)
};
PaginationPrevious.displayName = "PaginationPrevious";
const PaginationNext = ({
className,
...props
}: React.ComponentProps<typeof PaginationLink>) => (
<PaginationLink
aria-label="Go to next page"
size="default"
className={cn("gap-1 pr-2.5", className)}
{...props}
>
<span></span>
<ChevronRight className="h-4 w-4" />
</PaginationLink>
);
}: React.ComponentProps<typeof PaginationLink>) => {
const { t } = useTranslation()
return (
<PaginationLink
aria-label="Go to next page"
size="default"
className={cn("gap-1 pr-2.5", className)}
{...props}
>
<span>{t('pagination.next')}</span>
<ChevronRight className="h-4 w-4" />
</PaginationLink>
)
};
PaginationNext.displayName = "PaginationNext";
const PaginationEllipsis = ({