From 5e3db19ed676039d5333066a33a9d97b24d2a349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=93=E9=BC=A0?= <71394853+hamster1963@users.noreply.github.com> Date: Mon, 23 Dec 2024 00:38:40 +0800 Subject: [PATCH] fix: i18n (#71) * fix: block_identifier text * fix: i18n * chore: auto-fix linting and formatting issues * fix: block button * fix: ConfirmBlock text * fix: i18n --------- Co-authored-by: hamster1963 --- src/components/action-button-group.tsx | 52 +++++++++++++++++++ src/components/header-button-group.tsx | 69 ++++++++++++++++++++++++++ src/components/xui/icon-button.tsx | 5 ++ src/locales/en/translation.json | 12 ++++- src/locales/zh-CN/translation.json | 12 ++++- src/locales/zh-TW/translation.json | 12 ++++- src/routes/online-user.tsx | 16 +++--- src/routes/waf.tsx | 10 ++-- 8 files changed, 172 insertions(+), 16 deletions(-) diff --git a/src/components/action-button-group.tsx b/src/components/action-button-group.tsx index f3e6de0..b1a5e98 100644 --- a/src/components/action-button-group.tsx +++ b/src/components/action-button-group.tsx @@ -21,6 +21,12 @@ interface ButtonGroupProps { delete: { fn: (id: E[]) => Promise; id: E; mutate: KeyedMutator } } +interface BlockButtonGroupProps { + className?: string + children?: React.ReactNode + block: { fn: (id: E[]) => Promise; id: E; mutate: KeyedMutator } +} + export function ActionButtonGroup({ className, children, @@ -66,3 +72,49 @@ export function ActionButtonGroup({ ) } + +export function BlockButtonGroup({ + className, + children, + block: { fn, id, mutate }, +}: BlockButtonGroupProps) { + const { t } = useTranslation() + + const handleBlock = async () => { + try { + await fn([id]) + } catch (error: any) { + toast(t("Error"), { + description: error.message, + }) + } + await mutate() + } + return ( +
+ {children} + + + + + + + {t("ConfirmBlock")} + + {t("Results.ThisOperationIsUnrecoverable")} + + + + {t("Close")} + + {t("Confirm")} + + + + +
+ ) +} diff --git a/src/components/header-button-group.tsx b/src/components/header-button-group.tsx index 51fc62c..7a86460 100644 --- a/src/components/header-button-group.tsx +++ b/src/components/header-button-group.tsx @@ -21,6 +21,12 @@ interface ButtonGroupProps { delete: { fn: (id: E[]) => Promise; id: E[]; mutate: KeyedMutator } } +interface ButtonBlockGroupProps { + className?: string + children?: React.ReactNode + block: { fn: (id: E[]) => Promise; id: E[]; mutate: KeyedMutator } +} + export function HeaderButtonGroup({ className, children, @@ -83,3 +89,66 @@ export function HeaderButtonGroup({ ) } + +export function HeaderBlockButtonGroup({ + className, + children, + block: { fn, id, mutate }, +}: ButtonBlockGroupProps) { + const { t } = useTranslation() + + const handleBlock = async () => { + try { + await fn(id) + } catch (error: any) { + toast(t("Error"), { + description: error.message, + }) + } + await mutate() + } + return ( +
+ {id.length < 1 ? ( + <> + { + toast(t("Error"), { + description: t("Results.NoRowsAreSelected"), + }) + }} + /> + {children} + + ) : ( + <> + + + + + + + {t("ConfirmBlock")} + + {t("Results.ThisOperationIsUnrecoverable")} + + + + {t("Close")} + + {t("Confirm")} + + + + + {children} + + )} +
+ ) +} diff --git a/src/components/xui/icon-button.tsx b/src/components/xui/icon-button.tsx index d8e7023..fc62aad 100644 --- a/src/components/xui/icon-button.tsx +++ b/src/components/xui/icon-button.tsx @@ -1,5 +1,6 @@ import { Button, ButtonProps } from "@/components/ui/button" import { + BanIcon, Check, CircleArrowUp, Clipboard, @@ -29,6 +30,7 @@ export interface IconButtonProps extends ButtonProps { | "download" | "upload" | "menu" + | "ban" } export const IconButton = forwardRef((props, ref) => { @@ -77,6 +79,9 @@ export const IconButton = forwardRef((props, case "menu": { return } + case "ban": { + return + } } })()} diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 713eb0e..3c43d26 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -164,5 +164,15 @@ "CommunityThemeDescription": "This theme is provided by the community, use at your own risk", "Cancel": "Cancel", "EnableDDNS": "Enable DDNS", - "PushSuccessful": "Push if Successful" + "PushSuccessful": "Push if Successful", + "GrpcAuthFailed": "gRPC authentication failed", + "APITokenInvalid": "API token is invalid", + "UserInvalid": "User is invalid", + "BlockByUser": "Blocked by user", + "BlockIdentifier": "Block identifier", + "UserId": "User ID", + "ConnectedAt": "Connected at", + "OnlineUser": "Online User", + "Total": "Total", + "ConfirmBlock": "Confirm Block" } diff --git a/src/locales/zh-CN/translation.json b/src/locales/zh-CN/translation.json index bed0d46..5975b36 100644 --- a/src/locales/zh-CN/translation.json +++ b/src/locales/zh-CN/translation.json @@ -164,5 +164,15 @@ "CommunityThemeDescription": "社区主题未经官方审计,需自行甄别风险", "Cancel": "取消", "EnableDDNS": "启用 DDNS", - "PushSuccessful": "推送成功的通知" + "PushSuccessful": "推送成功的通知", + "GrpcAuthFailed": "gRPC 认证失败", + "APITokenInvalid": "API 令牌无效", + "UserInvalid": "用户无效", + "BlockByUser": "被用户封禁", + "BlockIdentifier": "封禁标识", + "UserId": "用户 ID", + "ConnectedAt": "连接时间", + "OnlineUser": "在线用户", + "Total": "总数", + "ConfirmBlock": "确认封禁" } diff --git a/src/locales/zh-TW/translation.json b/src/locales/zh-TW/translation.json index 64d1c48..39a0b5d 100644 --- a/src/locales/zh-TW/translation.json +++ b/src/locales/zh-TW/translation.json @@ -164,5 +164,15 @@ "CommunityThemeDescription": "社群主題未經官方審計,需自行甄別風險", "Cancel": "取消", "EnableDDNS": "啟用 DDNS", - "PushSuccessful": "推送成功的通知" + "PushSuccessful": "推送成功的通知", + "GrpcAuthFailed": "gRPC 認證失敗", + "APITokenInvalid": "API 令牌無效", + "UserInvalid": "使用者無效", + "BlockByUser": "被使用者封鎖", + "BlockIdentifier": "封鎖標識符", + "UserId": "使用者 ID", + "ConnectedAt": "連接時間", + "OnlineUser": "線上使用者", + "Total": "總數", + "ConfirmBlock": "確認封鎖" } diff --git a/src/routes/online-user.tsx b/src/routes/online-user.tsx index 9fe80d9..bc84de0 100644 --- a/src/routes/online-user.tsx +++ b/src/routes/online-user.tsx @@ -1,7 +1,7 @@ import { swrFetcher } from "@/api/api" import { blockUser } from "@/api/online-user" -import { ActionButtonGroup } from "@/components/action-button-group" -import { HeaderButtonGroup } from "@/components/header-button-group" +import { BlockButtonGroup } from "@/components/action-button-group" +import { HeaderBlockButtonGroup } from "@/components/header-button-group" import { SettingsTab } from "@/components/settings-tab" import { Checkbox } from "@/components/ui/checkbox" import { @@ -104,16 +104,16 @@ export default function OnlineUserPage() { cell: ({ row }) => { const s = row.original return ( - <> - + ) }, }, @@ -242,16 +242,16 @@ export default function OnlineUserPage() {
{isAdmin && ( - r.original.ip ?? ""), mutate: mutate, }} > <> - + )}
diff --git a/src/routes/waf.tsx b/src/routes/waf.tsx index db8efc9..3463f6f 100644 --- a/src/routes/waf.tsx +++ b/src/routes/waf.tsx @@ -96,11 +96,11 @@ export default function WAFPage() { cell: ({ row }) => {wafBlockReasons[row.original.block_reason] || ""}, }, { - header: t("LastBlockIdentifier"), - accessorKey: "lastBlockIdentifier", - accessorFn: (row) => ( - {wafBlockIdentifiers[row.block_identifier] || row.block_identifier} - ), + header: t("BlockIdentifier"), + accessorKey: "BlockIdentifier", + accessorFn: (row) => { + return wafBlockIdentifiers[row.block_identifier] || row.block_identifier + }, }, { header: t("LastBlockTime"),