diff --git a/ui/src/components/certimate/DeployState.tsx b/ui/src/components/certimate/DeployState.tsx new file mode 100644 index 00000000..0bc34d79 --- /dev/null +++ b/ui/src/components/certimate/DeployState.tsx @@ -0,0 +1,49 @@ +import { Deployment } from "@/domain/deployment"; +import { CircleCheck, CircleX } from "lucide-react"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "../ui/tooltip"; + +type DeployStateProps = { + deployment: Deployment; +}; + +const DeployState = ({ deployment }: DeployStateProps) => { + // 获取指定阶段的错误信息 + const error = (state: "check" | "apply" | "deploy") => { + if (!deployment.log[state]) { + return ""; + } + return deployment.log[state][deployment.log[state].length - 1].error; + }; + + return ( + <> + {deployment.phase === "deploy" && deployment.phaseSuccess ? ( + + ) : ( + <> + {error(deployment.phase).length ? ( + + + + + + + {error(deployment.phase)} + + + + ) : ( + + )} + + )} + + ); +}; + +export default DeployState; diff --git a/ui/src/pages/DashboardLayout.tsx b/ui/src/pages/DashboardLayout.tsx index ab234222..49db0d38 100644 --- a/ui/src/pages/DashboardLayout.tsx +++ b/ui/src/pages/DashboardLayout.tsx @@ -46,12 +46,12 @@ export default function Dashboard() { }; const handleSettingClick = () => { - navigate("/setting/password"); + navigate("/setting/account"); }; return ( <> -
+
diff --git a/ui/src/pages/SettingLayout.tsx b/ui/src/pages/SettingLayout.tsx index 9739a76b..bc9964b0 100644 --- a/ui/src/pages/SettingLayout.tsx +++ b/ui/src/pages/SettingLayout.tsx @@ -1,20 +1,57 @@ +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Toaster } from "@/components/ui/toaster"; -import { Outlet } from "react-router-dom"; +import { KeyRound, UserRound } from "lucide-react"; +import { useEffect, useState } from "react"; + +import { Outlet, useLocation, useNavigate } from "react-router-dom"; const SettingLayout = () => { + const location = useLocation(); + const [tabValue, setTabValue] = useState("account"); + const navigate = useNavigate(); + + useEffect(() => { + const pathname = location.pathname; + const tabValue = pathname.split("/")[2]; + setTabValue(tabValue); + }, [location]); + return (
- 设置密码 + 偏好设置
-
- {/*
- - 密码 - -
*/} - +
+ + + { + navigate("/setting/account"); + }} + className="px-5" + > + +
账户
+
+ { + navigate("/setting/password"); + }} + className="px-5" + > + +
密码
+
+
+ +
+ +
+
+
); diff --git a/ui/src/pages/dashboard/Dashboard.tsx b/ui/src/pages/dashboard/Dashboard.tsx index 5e3da9e9..33388373 100644 --- a/ui/src/pages/dashboard/Dashboard.tsx +++ b/ui/src/pages/dashboard/Dashboard.tsx @@ -1,4 +1,5 @@ import DeployProgress from "@/components/certimate/DeployProgress"; +import DeployState from "@/components/certimate/DeployState"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { @@ -204,11 +205,7 @@ const Dashboard = () => { {deployment.expand.domain?.domain}
- {deployment.phase === "deploy" && deployment.phaseSuccess ? ( - - ) : ( - - )} +
{ ) : ( <>
-
域名
-
有效期限
+
域名
+
有效期限
最近执行状态
最近执行阶段
最近执行时间
-
是否启用
+
是否启用
操作
@@ -213,10 +214,10 @@ const Home = () => { className="flex flex-col sm:flex-row text-secondary-foreground border-b dark:border-stone-500 sm:p-2 hover:bg-muted/50 text-sm" key={domain.id} > -
+
{domain.domain}
-
+
{domain.expiredAt ? ( <> @@ -231,12 +232,7 @@ const Home = () => {
{domain.lastDeployedAt && domain.expand?.lastDeployment ? ( <> - {domain.expand.lastDeployment?.phase === "deploy" && - domain.expand.lastDeployment?.phaseSuccess ? ( - - ) : ( - - )} + ) : ( "---" @@ -257,7 +253,7 @@ const Home = () => { ? convertZulu2Beijing(domain.lastDeployedAt) : "---"}
-
+
diff --git a/ui/src/pages/history/History.tsx b/ui/src/pages/history/History.tsx index d1b584a7..03212de5 100644 --- a/ui/src/pages/history/History.tsx +++ b/ui/src/pages/history/History.tsx @@ -1,4 +1,5 @@ import DeployProgress from "@/components/certimate/DeployProgress"; +import DeployState from "@/components/certimate/DeployState"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { ScrollArea } from "@/components/ui/scroll-area"; @@ -88,11 +89,7 @@ const History = () => { {deployment.expand.domain?.domain}
- {deployment.phase === "deploy" && deployment.phaseSuccess ? ( - - ) : ( - - )} +
{ + const { toast } = useToast(); + const navigate = useNavigate(); + + const [changed, setChanged] = useState(false); + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + email: getPb().authStore.model?.email, + }, + }); + + const onSubmit = async (values: z.infer) => { + try { + await getPb().admins.update(getPb().authStore.model?.id, { + email: values.email, + }); + + getPb().authStore.clear(); + toast({ + title: "修改账户邮箱功", + description: "请重新登录", + }); + setTimeout(() => { + navigate("/login"); + }, 500); + } catch (e) { + const message = getErrMessage(e); + toast({ + title: "修改账户邮箱失败", + description: message, + variant: "destructive", + }); + } + }; + + return ( + <> +
+
+ + ( + + 邮箱 + + { + setChanged(true); + form.setValue("email", e.target.value); + }} + /> + + + + + )} + /> + +
+ {changed ? ( + + ) : ( + + )} +
+ + +
+ + ); +}; + +export default Account; diff --git a/ui/src/pages/setting/Password.tsx b/ui/src/pages/setting/Password.tsx index 138a3f6a..8733a5cf 100644 --- a/ui/src/pages/setting/Password.tsx +++ b/ui/src/pages/setting/Password.tsx @@ -84,64 +84,70 @@ const Password = () => { return ( <> -
- - ( - - 当前密码 - - - +
+ + + ( + + 当前密码 + + + - - - )} - /> + + + )} + /> - ( - - 新密码 - - - + ( + + 新密码 + + + - - - )} - /> + + + )} + /> - ( - - 确认密码 - - - + ( + + 确认密码 + + + - - - )} - /> -
- -
- - + +
+ )} + /> +
+ +
+ + +
); }; diff --git a/ui/src/router.tsx b/ui/src/router.tsx index 3dc7cade..8eb3aa23 100644 --- a/ui/src/router.tsx +++ b/ui/src/router.tsx @@ -10,6 +10,7 @@ import LoginLayout from "./pages/LoginLayout"; import Password from "./pages/setting/Password"; import SettingLayout from "./pages/SettingLayout"; import Dashboard from "./pages/dashboard/Dashboard"; +import Account from "./pages/setting/Account"; export const router = createHashRouter([ { @@ -44,6 +45,10 @@ export const router = createHashRouter([ path: "/setting/password", element: , }, + { + path: "/setting/account", + element: , + }, ], }, ],