feat(ui): new Settings layout using antd

This commit is contained in:
Fu Diwei
2024-12-18 21:22:25 +08:00
parent afa446aabe
commit abe6dbb5a2
12 changed files with 205 additions and 195 deletions

View File

@@ -1,84 +0,0 @@
import { useEffect, useState } from "react";
import { Outlet, useLocation, useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { Card } from "antd";
import { KeyRound, Megaphone, ShieldCheck, UserRound } from "lucide-react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Toaster } from "@/components/ui/toaster";
const SettingsLayout = () => {
const location = useLocation();
const [tabValue, setTabValue] = useState("account");
const navigate = useNavigate();
const { t } = useTranslation();
useEffect(() => {
const pathname = location.pathname;
const tabValue = pathname.split("/")[2];
setTabValue(tabValue);
}, [location]);
return (
<Card>
<Toaster />
<div className="text-muted-foreground border-b dark:border-stone-500 py-5">{t("settings.page.title")}</div>
<div className="w-full mt-5 p-0 md:p-3 flex justify-center">
<Tabs defaultValue="account" className="w-full" value={tabValue}>
<TabsList className="mx-auto">
<TabsTrigger
value="account"
onClick={() => {
navigate("/settings/account");
}}
className="px-5"
>
<UserRound size={14} />
<div className="ml-1">{t("settings.account.tab")}</div>
</TabsTrigger>
<TabsTrigger
value="password"
onClick={() => {
navigate("/settings/password");
}}
className="px-5"
>
<KeyRound size={14} />
<div className="ml-1">{t("settings.password.tab")}</div>
</TabsTrigger>
<TabsTrigger
value="notify"
onClick={() => {
navigate("/settings/notify");
}}
className="px-5"
>
<Megaphone size={14} />
<div className="ml-1">{t("settings.notification.tab")}</div>
</TabsTrigger>
<TabsTrigger
value="ssl-provider"
onClick={() => {
navigate("/settings/ssl-provider");
}}
className="px-5"
>
<ShieldCheck size={14} />
<div className="ml-1">{t("settings.ca.tab")}</div>
</TabsTrigger>
</TabsList>
<TabsContent value={tabValue}>
<div className="mt-5 w-full md:w-[45em]">
<Outlet />
</div>
</TabsContent>
</Tabs>
</div>
</Card>
);
};
export default SettingsLayout;

View File

@@ -11,7 +11,7 @@ import Email from "@/components/notify/Email";
import Bark from "@/components/notify/Bark";
import { NotifyProvider } from "@/providers/notify";
const Notify = () => {
const Notification = () => {
const { t } = useTranslation();
return (
@@ -31,49 +31,49 @@ const Notify = () => {
<div className="border rounded-md p-5 mt-7 shadow-lg">
<Accordion type={"single"} collapsible={true} className="dark:text-stone-200">
<AccordionItem value="item-email" className="dark:border-stone-200">
<AccordionTrigger>{t("common.provider.email")}</AccordionTrigger>
<AccordionTrigger>{t("common.notifier.email")}</AccordionTrigger>
<AccordionContent>
<Email />
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-webhook" className="dark:border-stone-200">
<AccordionTrigger>{t("common.provider.webhook")}</AccordionTrigger>
<AccordionTrigger>{t("common.notifier.webhook")}</AccordionTrigger>
<AccordionContent>
<Webhook />
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-dingtalk" className="dark:border-stone-200">
<AccordionTrigger>{t("common.provider.dingtalk")}</AccordionTrigger>
<AccordionTrigger>{t("common.notifier.dingtalk")}</AccordionTrigger>
<AccordionContent>
<DingTalk />
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-lark" className="dark:border-stone-200">
<AccordionTrigger>{t("common.provider.lark")}</AccordionTrigger>
<AccordionTrigger>{t("common.notifier.lark")}</AccordionTrigger>
<AccordionContent>
<Lark />
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-telegram" className="dark:border-stone-200">
<AccordionTrigger>{t("common.provider.telegram")}</AccordionTrigger>
<AccordionTrigger>{t("common.notifier.telegram")}</AccordionTrigger>
<AccordionContent>
<Telegram />
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-serverchan" className="dark:border-stone-200">
<AccordionTrigger>{t("common.provider.serverchan")}</AccordionTrigger>
<AccordionTrigger>{t("common.notifier.serverchan")}</AccordionTrigger>
<AccordionContent>
<ServerChan />
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-bark" className="dark:border-stone-200">
<AccordionTrigger>{t("common.provider.bark")}</AccordionTrigger>
<AccordionTrigger>{t("common.notifier.bark")}</AccordionTrigger>
<AccordionContent>
<Bark />
</AccordionContent>
@@ -85,4 +85,4 @@ const Notify = () => {
);
};
export default Notify;
export default Notification;

View File

@@ -0,0 +1,83 @@
import { useEffect, useState } from "react";
import { Outlet, useLocation, useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { Card, Space } from "antd";
import { PageHeader } from "@ant-design/pro-components";
import { KeyRound as KeyRoundIcon, Megaphone as MegaphoneIcon, ShieldCheck as ShieldCheckIcon, UserRound as UserRoundIcon } from "lucide-react";
import { Toaster } from "@/components/ui/toaster";
const Settings = () => {
const location = useLocation();
const navigate = useNavigate();
const { t } = useTranslation();
const [tabValue, setTabValue] = useState("account");
useEffect(() => {
const path = location.pathname.split("/")[2];
if (!path) {
navigate("/settings/account");
return;
}
setTabValue(path);
}, [location]);
return (
<>
<PageHeader title={t("settings.page.title")} />
<Card
tabList={[
{
key: "account",
label: (
<Space>
<UserRoundIcon size={14} />
<label>{t("settings.account.tab")}</label>
</Space>
),
},
{
key: "password",
label: (
<Space>
<KeyRoundIcon size={14} />
<label>{t("settings.password.tab")}</label>
</Space>
),
},
{
key: "notification",
label: (
<Space>
<MegaphoneIcon size={14} />
<label>{t("settings.notification.tab")}</label>
</Space>
),
},
{
key: "ssl-provider",
label: (
<Space>
<ShieldCheckIcon size={14} />
<label>{t("settings.ca.tab")}</label>
</Space>
),
},
]}
activeTabKey={tabValue}
onTabChange={(key) => {
setTabValue(key);
navigate(`/settings/${key}`);
}}
>
<Toaster />
<Outlet />
</Card>
</>
);
};
export default Settings;