mirror of
https://github.com/certimate-go/certimate.git
synced 2026-06-22 21:05:48 +08:00
chore(ui): about
This commit is contained in:
parent
a63cd91ac6
commit
4c933c05ab
@ -11,14 +11,10 @@ export interface AppDocumentLinkButtonProps {
|
||||
}
|
||||
|
||||
const AppDocumentLinkButton = ({ className, style, showIcon = true }: AppDocumentLinkButtonProps) => {
|
||||
const { i18n, t } = useTranslation();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleDocumentClick = () => {
|
||||
if (i18n.language.startsWith("en")) {
|
||||
window.open(APP_DOCUMENT_URL + "/en/", "_blank");
|
||||
} else {
|
||||
window.open(APP_DOCUMENT_URL, "_blank");
|
||||
}
|
||||
window.open(APP_DOCUMENT_URL, "_blank");
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@ -1,8 +1,16 @@
|
||||
export const APP_REPO_URL = "https://github.com/certimate-go/certimate";
|
||||
|
||||
export const APP_DOWNLOAD_URL = APP_REPO_URL + "/releases";
|
||||
|
||||
export const APP_DOCUMENT_URL = "https://docs.certimate.me";
|
||||
import i18next from "i18next";
|
||||
|
||||
// fallback policy: .env > git tag > "v0.0.0-dev"
|
||||
export const APP_VERSION: string = import.meta.env.VITE_APP_VERSION || __APP_VERSION__ || "v0.0.0-dev";
|
||||
|
||||
export const APP_REPO_URL = "https://github.com/certimate-go/certimate";
|
||||
export const APP_DOWNLOAD_URL = APP_REPO_URL + "/releases";
|
||||
export let APP_DOCUMENT_URL = "https://docs.certimate.me";
|
||||
|
||||
i18next.on("languageChanged", (language) => {
|
||||
if (language.startsWith("zh")) {
|
||||
APP_DOCUMENT_URL = "https://docs.certimate.me";
|
||||
} else {
|
||||
APP_DOCUMENT_URL = "https://docs.certimate.me/en/";
|
||||
}
|
||||
});
|
||||
|
||||
@ -57,5 +57,17 @@
|
||||
"settings.diagnostics.workflow_dispatcher.title": "Workflow dispatcher",
|
||||
"settings.diagnostics.workflow_dispatcher.statistics.concurrency": "Concurrency",
|
||||
"settings.diagnostics.workflow_dispatcher.statistics.pending": "Pending",
|
||||
"settings.diagnostics.workflow_dispatcher.statistics.processing": "Processing"
|
||||
"settings.diagnostics.workflow_dispatcher.statistics.processing": "Processing",
|
||||
|
||||
"settings.about.tab": "About",
|
||||
"settings.about.version.new": "New version available",
|
||||
"settings.about.socials.document": "Documentation",
|
||||
"settings.about.socials.github": "GitHub",
|
||||
"settings.about.socials.telegram": "Telegram",
|
||||
"settings.about.socials.donate": "Donate",
|
||||
"settings.about.feedback.title": "Help us improve Certimate",
|
||||
"settings.about.feedback.subtitle": "Tell us how to make Certimate work better for you.",
|
||||
"settings.about.feedback.button": "Give feedback",
|
||||
"settings.about.contributors.title": "Contributors",
|
||||
"settings.about.contributors.tips": "Thanks to all the people who have contributed to this project."
|
||||
}
|
||||
|
||||
@ -57,5 +57,17 @@
|
||||
"settings.diagnostics.workflow_dispatcher.title": "工作流调度器",
|
||||
"settings.diagnostics.workflow_dispatcher.statistics.concurrency": "最大并发",
|
||||
"settings.diagnostics.workflow_dispatcher.statistics.pending": "等待运行",
|
||||
"settings.diagnostics.workflow_dispatcher.statistics.processing": "运行中"
|
||||
"settings.diagnostics.workflow_dispatcher.statistics.processing": "运行中",
|
||||
|
||||
"settings.about.tab": "关于",
|
||||
"settings.about.version.new": "有新版本可更新",
|
||||
"settings.about.socials.document": "文档",
|
||||
"settings.about.socials.github": "GitHub",
|
||||
"settings.about.socials.telegram": "Telegram",
|
||||
"settings.about.socials.donate": "捐赠",
|
||||
"settings.about.feedback.title": "帮助我们改进 Certimate",
|
||||
"settings.about.feedback.subtitle": "告诉我们如何让 Certimate 为你更好地服务。",
|
||||
"settings.about.feedback.button": "意见反馈",
|
||||
"settings.about.contributors.title": "贡献者",
|
||||
"settings.about.contributors.tips": "感谢所有贡献者对本项目做出的贡献。"
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ import { isBrowserHappy } from "@/utils/browser";
|
||||
const ConsoleLayout = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { i18n, t } = useTranslation();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { token: themeToken } = theme.useToken();
|
||||
|
||||
@ -40,11 +40,7 @@ const ConsoleLayout = () => {
|
||||
};
|
||||
|
||||
const handleDocumentClick = () => {
|
||||
if (i18n.language.startsWith("zh")) {
|
||||
window.open(APP_DOCUMENT_URL, "_blank");
|
||||
} else {
|
||||
window.open(APP_DOCUMENT_URL + "/en/", "_blank");
|
||||
}
|
||||
window.open(APP_DOCUMENT_URL, "_blank");
|
||||
};
|
||||
|
||||
const handleGitHubClick = () => {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Outlet, useLocation, useNavigate } from "react-router-dom";
|
||||
import { IconBracketsAngle, IconDatabaseCog, IconPalette, IconPlugConnected, IconUserShield } from "@tabler/icons-react";
|
||||
import { IconBracketsAngle, IconDatabaseCog, IconInfoCircle, IconPalette, IconPlugConnected, IconUserShield } from "@tabler/icons-react";
|
||||
import { Menu } from "antd";
|
||||
|
||||
const Settings = () => {
|
||||
@ -16,6 +16,7 @@ const Settings = () => {
|
||||
["ssl-provider", "settings.sslprovider.tab", <IconPlugConnected size="1em" />],
|
||||
["persistence", "settings.persistence.tab", <IconDatabaseCog size="1em" />],
|
||||
["diagnostics", "settings.diagnostics.tab", <IconBracketsAngle size="1em" />],
|
||||
["about", "settings.about.tab", <IconInfoCircle size="1em" />],
|
||||
] satisfies [string, string, React.ReactElement][];
|
||||
const [menuKey, setMenuKey] = useState<string>(() => location.pathname.split("/")[2]);
|
||||
useEffect(() => {
|
||||
|
||||
88
ui/src/pages/settings/SettingsAbout.tsx
Normal file
88
ui/src/pages/settings/SettingsAbout.tsx
Normal file
@ -0,0 +1,88 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { IconBook, IconBrandGithub, IconBrandTelegram, IconCoin, IconMessageChatbot } from "@tabler/icons-react";
|
||||
import { Badge, Button, Divider, List, Tooltip, Typography } from "antd";
|
||||
|
||||
import { APP_DOCUMENT_URL, APP_DOWNLOAD_URL, APP_REPO_URL, APP_VERSION } from "@/domain/app";
|
||||
import { useVersionChecker } from "@/hooks";
|
||||
|
||||
const SettingsAbout = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { hasUpdate } = useVersionChecker();
|
||||
|
||||
const handleDownloadClick = () => {
|
||||
window.open(APP_DOWNLOAD_URL, "_blank");
|
||||
};
|
||||
|
||||
const handleDocumentClick = () => {
|
||||
window.open(APP_DOCUMENT_URL, "_blank");
|
||||
};
|
||||
|
||||
const handleGithubClick = () => {
|
||||
window.open(APP_REPO_URL, "_blank");
|
||||
};
|
||||
|
||||
const handleTelegramClick = () => {
|
||||
window.open("https://t.me/+ZXphsppxUg41YmVl", "_blank");
|
||||
};
|
||||
|
||||
const handleDonateClick = () => {
|
||||
window.open("https://profile.ikit.fun/sponsors/", "_blank");
|
||||
};
|
||||
|
||||
const handleFeedbackClick = () => {
|
||||
window.open(APP_REPO_URL + "/issues", "_blank");
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>Certimate</h2>
|
||||
<div className="mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Typography.Text type="secondary">Version: {APP_VERSION}</Typography.Text>
|
||||
<Badge className="cursor-pointer" count={hasUpdate ? t("settings.about.version.new") : void 0} onClick={handleDownloadClick} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-2 flex flex-wrap items-center gap-2">
|
||||
<Tooltip title={t("settings.about.socials.document")}>
|
||||
<Button type="text" icon={<IconBook size="1.5em" onClick={handleDocumentClick} />} />
|
||||
</Tooltip>
|
||||
<Tooltip title={t("settings.about.socials.github")}>
|
||||
<Button type="text" icon={<IconBrandGithub size="1.5em" onClick={handleGithubClick} />} />
|
||||
</Tooltip>
|
||||
<Tooltip title={t("settings.about.socials.telegram")}>
|
||||
<Button type="text" icon={<IconBrandTelegram size="1.5em" onClick={handleTelegramClick} />} />
|
||||
</Tooltip>
|
||||
<Tooltip title={t("settings.about.socials.donate")}>
|
||||
<Button type="text" icon={<IconCoin size="1.5em" onClick={handleDonateClick} />} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<Divider />
|
||||
|
||||
<h2>{t("settings.about.contributors.title")}</h2>
|
||||
<div className="mb-4">
|
||||
<Typography.Text type="secondary">{t("settings.about.contributors.tips")}</Typography.Text>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<img className="max-w-full" src="https://contrib.rocks/image?repo=certimate-go/certimate" alt="Contributors" />
|
||||
</div>
|
||||
|
||||
<Divider />
|
||||
|
||||
<div className="md:max-w-160">
|
||||
<List bordered>
|
||||
<List.Item extra={<Button onClick={handleFeedbackClick}>{t("settings.about.feedback.button")}</Button>}>
|
||||
<List.Item.Meta
|
||||
avatar={<IconMessageChatbot size="1.5em" />}
|
||||
title={t("settings.about.feedback.title")}
|
||||
description={t("settings.about.feedback.subtitle")}
|
||||
/>
|
||||
</List.Item>
|
||||
</List>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsAbout;
|
||||
@ -306,7 +306,7 @@ const SettingsDiagnosticsWorkflowDispatcher = ({ className, style }: { className
|
||||
type Statistics = Awaited<ReturnType<typeof getWorkflowStats>>["data"];
|
||||
const [statistics, setStatistics] = useState<Statistics>();
|
||||
|
||||
const { loading } = useRequest(
|
||||
const { loading, cancel } = useRequest(
|
||||
() => {
|
||||
return getWorkflowStats();
|
||||
},
|
||||
@ -318,6 +318,11 @@ const SettingsDiagnosticsWorkflowDispatcher = ({ className, style }: { className
|
||||
onSuccess: (res) => {
|
||||
setStatistics(res.data);
|
||||
},
|
||||
onError: () => {
|
||||
if (!statistics) {
|
||||
cancel();
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import Dashboard from "@/pages/dashboard/Dashboard";
|
||||
import ErrorLayout from "@/pages/ErrorLayout";
|
||||
import Login from "@/pages/login/Login";
|
||||
import Settings from "@/pages/settings/Settings";
|
||||
import SettingsAbout from "@/pages/settings/SettingsAbout";
|
||||
import SettingsAccount from "@/pages/settings/SettingsAccount";
|
||||
import SettingsAppearance from "@/pages/settings/SettingsAppearance";
|
||||
import SettingsDiagnostics from "@/pages/settings/SettingsDiagnostics";
|
||||
@ -87,6 +88,10 @@ export const router = createHashRouter([
|
||||
path: "/settings/diagnostics",
|
||||
element: <SettingsDiagnostics />,
|
||||
},
|
||||
{
|
||||
path: "/settings/about",
|
||||
element: <SettingsAbout />,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user