style: format
This commit is contained in:
@@ -1,27 +1,15 @@
|
||||
import {
|
||||
Link,
|
||||
Navigate,
|
||||
Outlet,
|
||||
useLocation,
|
||||
useNavigate,
|
||||
} from "react-router-dom";
|
||||
import { CircleUser, Earth, History, Home, Menu, Server } from "lucide-react";
|
||||
import { Link, Navigate, Outlet, useLocation, useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { CircleUser, Earth, History, Home, Menu, Server } from "lucide-react";
|
||||
|
||||
import LocaleToggle from "@/components/LocaleToggle";
|
||||
import { ThemeToggle } from "@/components/ThemeToggle";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ConfigProvider } from "@/providers/config";
|
||||
import { getPb } from "@/repository/api";
|
||||
import { ThemeToggle } from "@/components/ThemeToggle";
|
||||
import LocaleToggle from "@/components/LocaleToggle";
|
||||
import { ConfigProvider } from "@/providers/config";
|
||||
|
||||
import Version from "@/components/certimate/Version";
|
||||
|
||||
@@ -33,14 +21,15 @@ export default function Dashboard() {
|
||||
if (!getPb().authStore.isValid || !getPb().authStore.isAdmin) {
|
||||
return <Navigate to="/login" />;
|
||||
}
|
||||
|
||||
const currentPath = location.pathname;
|
||||
const getClass = (path: string) => {
|
||||
console.log(currentPath);
|
||||
if (path == currentPath) {
|
||||
return "bg-muted text-primary";
|
||||
}
|
||||
return "text-muted-foreground";
|
||||
};
|
||||
|
||||
const handleLogoutClick = () => {
|
||||
getPb().authStore.clear();
|
||||
navigate("/login");
|
||||
@@ -49,6 +38,7 @@ export default function Dashboard() {
|
||||
const handleSettingClick = () => {
|
||||
navigate("/setting/account");
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ConfigProvider>
|
||||
@@ -63,44 +53,20 @@ export default function Dashboard() {
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<nav className="grid items-start px-2 text-sm font-medium lg:px-4">
|
||||
<Link
|
||||
to="/"
|
||||
className={cn(
|
||||
"flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary",
|
||||
getClass("/")
|
||||
)}
|
||||
>
|
||||
<Link to="/" className={cn("flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary", getClass("/"))}>
|
||||
<Home className="h-4 w-4" />
|
||||
{t("dashboard.page.title")}
|
||||
</Link>
|
||||
<Link
|
||||
to="/domains"
|
||||
className={cn(
|
||||
"flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary",
|
||||
getClass("/domains")
|
||||
)}
|
||||
>
|
||||
<Link to="/domains" className={cn("flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary", getClass("/domains"))}>
|
||||
<Earth className="h-4 w-4" />
|
||||
{t("domain.page.title")}
|
||||
</Link>
|
||||
<Link
|
||||
to="/access"
|
||||
className={cn(
|
||||
"flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary",
|
||||
getClass("/access")
|
||||
)}
|
||||
>
|
||||
<Link to="/access" className={cn("flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary", getClass("/access"))}>
|
||||
<Server className="h-4 w-4" />
|
||||
{t("access.page.title")}
|
||||
</Link>
|
||||
|
||||
<Link
|
||||
to="/history"
|
||||
className={cn(
|
||||
"flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary",
|
||||
getClass("/history")
|
||||
)}
|
||||
>
|
||||
<Link to="/history" className={cn("flex items-center gap-3 rounded-lg px-3 py-2 transition-all hover:text-primary", getClass("/history"))}>
|
||||
<History className="h-4 w-4" />
|
||||
{t("history.page.title")}
|
||||
</Link>
|
||||
@@ -112,51 +78,32 @@ export default function Dashboard() {
|
||||
<header className="flex h-14 items-center gap-4 border-b dark:border-stone-500 bg-muted/40 px-4 lg:h-[60px] lg:px-6">
|
||||
<Sheet>
|
||||
<SheetTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="shrink-0 md:hidden"
|
||||
>
|
||||
<Button variant="outline" size="icon" className="shrink-0 md:hidden">
|
||||
<Menu className="h-5 w-5 dark:text-white" />
|
||||
<span className="sr-only">Toggle navigation menu</span>
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="left" className="flex flex-col">
|
||||
<nav className="grid gap-2 text-lg font-medium">
|
||||
<Link
|
||||
to="/"
|
||||
className="flex items-center gap-2 text-lg font-semibold"
|
||||
>
|
||||
<Link to="/" className="flex items-center gap-2 text-lg font-semibold">
|
||||
<img src="/vite.svg" className="w-[36px] h-[36px]" />
|
||||
<span className="dark:text-white">Certimate</span>
|
||||
<span className="sr-only">Certimate</span>
|
||||
</Link>
|
||||
<Link
|
||||
to="/"
|
||||
className={cn(
|
||||
"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 hover:text-foreground",
|
||||
getClass("/")
|
||||
)}
|
||||
>
|
||||
<Link to="/" className={cn("mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 hover:text-foreground", getClass("/"))}>
|
||||
<Home className="h-5 w-5" />
|
||||
{t("dashboard.page.title")}
|
||||
</Link>
|
||||
<Link
|
||||
to="/domains"
|
||||
className={cn(
|
||||
"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 hover:text-foreground",
|
||||
getClass("/domains")
|
||||
)}
|
||||
className={cn("mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 hover:text-foreground", getClass("/domains"))}
|
||||
>
|
||||
<Earth className="h-5 w-5" />
|
||||
{t("domain.page.title")}
|
||||
</Link>
|
||||
<Link
|
||||
to="/access"
|
||||
className={cn(
|
||||
"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 hover:text-foreground",
|
||||
getClass("/access")
|
||||
)}
|
||||
className={cn("mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 hover:text-foreground", getClass("/access"))}
|
||||
>
|
||||
<Server className="h-5 w-5" />
|
||||
{t("access.page.title")}
|
||||
@@ -164,10 +111,7 @@ export default function Dashboard() {
|
||||
|
||||
<Link
|
||||
to="/history"
|
||||
className={cn(
|
||||
"mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 hover:text-foreground",
|
||||
getClass("/history")
|
||||
)}
|
||||
className={cn("mx-[-0.65rem] flex items-center gap-4 rounded-xl px-3 py-2 hover:text-foreground", getClass("/history"))}
|
||||
>
|
||||
<History className="h-5 w-5" />
|
||||
{t("history.page.title")}
|
||||
@@ -180,22 +124,14 @@ export default function Dashboard() {
|
||||
<LocaleToggle />
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
className="rounded-full"
|
||||
>
|
||||
<Button variant="secondary" size="icon" className="rounded-full">
|
||||
<CircleUser className="h-5 w-5" />
|
||||
<span className="sr-only">Toggle user menu</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={handleSettingClick}>
|
||||
{t("common.menu.settings")}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={handleLogoutClick}>
|
||||
{t("common.menu.logout")}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={handleSettingClick}>{t("common.menu.settings")}</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={handleLogoutClick}>{t("common.menu.logout")}</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</header>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import Version from "@/components/certimate/Version";
|
||||
|
||||
import { getPb } from "@/repository/api";
|
||||
|
||||
import { Navigate, Outlet } from "react-router-dom";
|
||||
|
||||
import Version from "@/components/certimate/Version";
|
||||
import { getPb } from "@/repository/api";
|
||||
|
||||
const LoginLayout = () => {
|
||||
if (getPb().authStore.isValid && getPb().authStore.isAdmin) {
|
||||
return <Navigate to="/" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<Outlet />
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
import { KeyRound, Megaphone, ShieldCheck, UserRound } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { Outlet, useLocation, useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { KeyRound, Megaphone, ShieldCheck, UserRound } from "lucide-react";
|
||||
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
|
||||
const SettingLayout = () => {
|
||||
const location = useLocation();
|
||||
@@ -21,9 +21,7 @@ const SettingLayout = () => {
|
||||
return (
|
||||
<div>
|
||||
<Toaster />
|
||||
<div className="text-muted-foreground border-b dark:border-stone-500 py-5">
|
||||
{t("settings.page.title")}
|
||||
</div>
|
||||
<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">
|
||||
|
||||
@@ -1,17 +1,7 @@
|
||||
import { AccessEdit } from "@/components/certimate/AccessEdit";
|
||||
import AccessGroupEdit from "@/components/certimate/AccessGroupEdit";
|
||||
import AccessGroupList from "@/components/certimate/AccessGroupList";
|
||||
import XPagination from "@/components/certimate/XPagination";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Access as AccessType, accessTypeMap } from "@/domain/access";
|
||||
import { convertZulu2Beijing } from "@/lib/time";
|
||||
import { useConfig } from "@/providers/config";
|
||||
import { remove } from "@/repository/access";
|
||||
import { t } from "i18next";
|
||||
import { Key } from "lucide-react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Key } from "lucide-react";
|
||||
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
@@ -23,8 +13,20 @@ import {
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog.tsx";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import AccessEdit from "@/components/certimate/AccessEdit";
|
||||
import AccessGroupEdit from "@/components/certimate/AccessGroupEdit";
|
||||
import AccessGroupList from "@/components/certimate/AccessGroupList";
|
||||
import XPagination from "@/components/certimate/XPagination";
|
||||
import { convertZulu2Beijing } from "@/lib/time";
|
||||
import { Access as AccessType, accessTypeMap } from "@/domain/access";
|
||||
import { remove } from "@/repository/access";
|
||||
import { useConfig } from "@/providers/config";
|
||||
|
||||
const Access = () => {
|
||||
const { t } = useTranslation();
|
||||
const { config, deleteAccess } = useConfig();
|
||||
const { accesses } = config;
|
||||
|
||||
@@ -66,11 +68,7 @@ const Access = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Tabs
|
||||
defaultValue={tab ? tab : "access"}
|
||||
value={tab ? tab : "access"}
|
||||
className="w-full mt-5"
|
||||
>
|
||||
<Tabs defaultValue={tab ? tab : "access"} value={tab ? tab : "access"} className="w-full mt-5">
|
||||
<TabsList className="space-x-5 px-3">
|
||||
<TabsTrigger
|
||||
value="access"
|
||||
@@ -96,14 +94,8 @@ const Access = () => {
|
||||
<Key size={40} className="text-primary" />
|
||||
</span>
|
||||
|
||||
<div className="text-center text-sm text-muted-foreground mt-3">
|
||||
{t("access.authorization.nodata")}
|
||||
</div>
|
||||
<AccessEdit
|
||||
trigger={<Button>{t("access.authorization.add")}</Button>}
|
||||
op="add"
|
||||
className="mt-3"
|
||||
/>
|
||||
<div className="text-center text-sm text-muted-foreground mt-3">{t("access.authorization.nodata")}</div>
|
||||
<AccessEdit trigger={<Button>{t("access.authorization.add")}</Button>} op="add" className="mt-3" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
@@ -125,25 +117,14 @@ const Access = () => {
|
||||
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={access.id}
|
||||
>
|
||||
<div className="sm:w-48 w-full pt-1 sm:pt-0 flex items-center">
|
||||
{access.name}
|
||||
</div>
|
||||
<div className="sm:w-48 w-full pt-1 sm:pt-0 flex items-center">{access.name}</div>
|
||||
<div className="sm:w-48 w-full pt-1 sm:pt-0 flex items-center space-x-2">
|
||||
<img
|
||||
src={accessTypeMap.get(access.configType)?.[1]}
|
||||
className="w-6"
|
||||
/>
|
||||
<div>
|
||||
{t(accessTypeMap.get(access.configType)?.[0] || "")}
|
||||
</div>
|
||||
<img src={accessTypeMap.get(access.configType)?.[1]} className="w-6" />
|
||||
<div>{t(accessTypeMap.get(access.configType)?.[0] || "")}</div>
|
||||
</div>
|
||||
|
||||
<div className="sm:w-60 w-full pt-1 sm:pt-0 flex items-center">
|
||||
{access.created && convertZulu2Beijing(access.created)}
|
||||
</div>
|
||||
<div className="sm:w-60 w-full pt-1 sm:pt-0 flex items-center">
|
||||
{access.updated && convertZulu2Beijing(access.updated)}
|
||||
</div>
|
||||
<div className="sm:w-60 w-full pt-1 sm:pt-0 flex items-center">{access.created && convertZulu2Beijing(access.created)}</div>
|
||||
<div className="sm:w-60 w-full pt-1 sm:pt-0 flex items-center">{access.updated && convertZulu2Beijing(access.updated)}</div>
|
||||
<div className="flex items-center grow justify-start pt-1 sm:pt-0">
|
||||
<AccessEdit
|
||||
trigger={
|
||||
@@ -173,17 +154,11 @@ const Access = () => {
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle className="dark:text-gray-200">
|
||||
{t("access.authorization.delete")}
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{t("access.authorization.delete.confirm")}
|
||||
</AlertDialogDescription>
|
||||
<AlertDialogTitle className="dark:text-gray-200">{t("access.authorization.delete")}</AlertDialogTitle>
|
||||
<AlertDialogDescription>{t("access.authorization.delete.confirm")}</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel className="dark:text-gray-200">
|
||||
{t("common.cancel")}
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogCancel className="dark:text-gray-200">{t("common.cancel")}</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={() => {
|
||||
handleDelete(access);
|
||||
|
||||
@@ -1,30 +1,18 @@
|
||||
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 {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from "@/components/ui/sheet";
|
||||
import { Deployment, DeploymentListReq, Log } from "@/domain/deployment";
|
||||
import { Statistic } from "@/domain/domain";
|
||||
import { convertZulu2Beijing } from "@/lib/time";
|
||||
import { list } from "@/repository/deployment";
|
||||
import { statistics } from "@/repository/domains";
|
||||
|
||||
import {
|
||||
Ban,
|
||||
CalendarX2,
|
||||
LoaderPinwheel,
|
||||
Smile,
|
||||
SquareSigma,
|
||||
} from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Ban, CalendarX2, LoaderPinwheel, Smile, SquareSigma } from "lucide-react";
|
||||
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
|
||||
import DeployProgress from "@/components/certimate/DeployProgress";
|
||||
import DeployState from "@/components/certimate/DeployState";
|
||||
import { convertZulu2Beijing } from "@/lib/time";
|
||||
import { Statistic } from "@/domain/domain";
|
||||
import { Deployment, DeploymentListReq, Log } from "@/domain/deployment";
|
||||
import { statistics } from "@/repository/domains";
|
||||
import { list } from "@/repository/deployment";
|
||||
|
||||
const Dashboard = () => {
|
||||
const [statistic, setStatistic] = useState<Statistic>();
|
||||
@@ -65,9 +53,7 @@ const Dashboard = () => {
|
||||
<SquareSigma size={48} strokeWidth={1} className="text-blue-400" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-muted-foreground font-semibold">
|
||||
{t("dashboard.statistics.all")}
|
||||
</div>
|
||||
<div className="text-muted-foreground font-semibold">{t("dashboard.statistics.all")}</div>
|
||||
<div className="flex items-baseline">
|
||||
<div className="text-3xl text-stone-700 dark:text-stone-200">
|
||||
{statistic?.total ? (
|
||||
@@ -78,9 +64,7 @@ const Dashboard = () => {
|
||||
0
|
||||
)}
|
||||
</div>
|
||||
<div className="ml-1 text-stone-700 dark:text-stone-200">
|
||||
{t("dashboard.statistics.unit")}
|
||||
</div>
|
||||
<div className="ml-1 text-stone-700 dark:text-stone-200">{t("dashboard.statistics.unit")}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -90,9 +74,7 @@ const Dashboard = () => {
|
||||
<CalendarX2 size={48} strokeWidth={1} className="text-red-400" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-muted-foreground font-semibold">
|
||||
{t("dashboard.statistics.near_expired")}
|
||||
</div>
|
||||
<div className="text-muted-foreground font-semibold">{t("dashboard.statistics.near_expired")}</div>
|
||||
<div className="flex items-baseline">
|
||||
<div className="text-3xl text-stone-700 dark:text-stone-200">
|
||||
{statistic?.expired ? (
|
||||
@@ -103,25 +85,17 @@ const Dashboard = () => {
|
||||
0
|
||||
)}
|
||||
</div>
|
||||
<div className="ml-1 text-stone-700 dark:text-stone-200">
|
||||
{t("dashboard.statistics.unit")}
|
||||
</div>
|
||||
<div className="ml-1 text-stone-700 dark:text-stone-200">{t("dashboard.statistics.unit")}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border w-full md:w-[250px] 3xl:w-[300px] flex items-center rounded-md p-3 shadow-lg">
|
||||
<div className="p-3">
|
||||
<LoaderPinwheel
|
||||
size={48}
|
||||
strokeWidth={1}
|
||||
className="text-green-400"
|
||||
/>
|
||||
<LoaderPinwheel size={48} strokeWidth={1} className="text-green-400" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-muted-foreground font-semibold">
|
||||
{t("dashboard.statistics.enabled")}
|
||||
</div>
|
||||
<div className="text-muted-foreground font-semibold">{t("dashboard.statistics.enabled")}</div>
|
||||
<div className="flex items-baseline">
|
||||
<div className="text-3xl text-stone-700 dark:text-stone-200">
|
||||
{statistic?.enabled ? (
|
||||
@@ -132,9 +106,7 @@ const Dashboard = () => {
|
||||
0
|
||||
)}
|
||||
</div>
|
||||
<div className="ml-1 text-stone-700 dark:text-stone-200">
|
||||
{t("dashboard.statistics.unit")}
|
||||
</div>
|
||||
<div className="ml-1 text-stone-700 dark:text-stone-200">{t("dashboard.statistics.unit")}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -144,25 +116,18 @@ const Dashboard = () => {
|
||||
<Ban size={48} strokeWidth={1} className="text-gray-400" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-muted-foreground font-semibold">
|
||||
{t("dashboard.statistics.disabled")}
|
||||
</div>
|
||||
<div className="text-muted-foreground font-semibold">{t("dashboard.statistics.disabled")}</div>
|
||||
<div className="flex items-baseline">
|
||||
<div className="text-3xl text-stone-700 dark:text-stone-200">
|
||||
{statistic?.disabled ? (
|
||||
<Link
|
||||
to="/domains?state=disabled"
|
||||
className="hover:underline"
|
||||
>
|
||||
<Link to="/domains?state=disabled" className="hover:underline">
|
||||
{statistic?.disabled}
|
||||
</Link>
|
||||
) : (
|
||||
0
|
||||
)}
|
||||
</div>
|
||||
<div className="ml-1 text-stone-700 dark:text-stone-200">
|
||||
{t("dashboard.statistics.unit")}
|
||||
</div>
|
||||
<div className="ml-1 text-stone-700 dark:text-stone-200">{t("dashboard.statistics.unit")}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -173,9 +138,7 @@ const Dashboard = () => {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="text-muted-foreground mt-5 text-sm">
|
||||
{t("dashboard.history")}
|
||||
</div>
|
||||
<div className="text-muted-foreground mt-5 text-sm">{t("dashboard.history")}</div>
|
||||
|
||||
{deployments?.length == 0 ? (
|
||||
<>
|
||||
@@ -207,9 +170,7 @@ const Dashboard = () => {
|
||||
|
||||
<div className="w-24">{t("history.props.status")}</div>
|
||||
<div className="w-56">{t("history.props.stage")}</div>
|
||||
<div className="w-56 sm:ml-2 text-center">
|
||||
{t("history.props.last_execution_time")}
|
||||
</div>
|
||||
<div className="w-56 sm:ml-2 text-center">{t("history.props.last_execution_time")}</div>
|
||||
|
||||
<div className="grow">{t("common.text.operations")}</div>
|
||||
</div>
|
||||
@@ -220,27 +181,20 @@ const Dashboard = () => {
|
||||
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"
|
||||
>
|
||||
<div className="sm:w-48 w-full pt-1 sm:pt-0 flex items-center">
|
||||
{deployment.expand.domain?.domain
|
||||
.split(";")
|
||||
.map((domain: string) => (
|
||||
<>
|
||||
{domain}
|
||||
<br />
|
||||
</>
|
||||
))}
|
||||
{deployment.expand.domain?.domain.split(";").map((domain: string) => (
|
||||
<>
|
||||
{domain}
|
||||
<br />
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
<div className="sm:w-24 w-full pt-1 sm:pt-0 flex items-center">
|
||||
<DeployState deployment={deployment} />
|
||||
</div>
|
||||
<div className="sm:w-56 w-full pt-1 sm:pt-0 flex items-center">
|
||||
<DeployProgress
|
||||
phase={deployment.phase}
|
||||
phaseSuccess={deployment.phaseSuccess}
|
||||
/>
|
||||
</div>
|
||||
<div className="sm:w-56 w-full pt-1 sm:pt-0 flex items-center sm:justify-center">
|
||||
{convertZulu2Beijing(deployment.deployedAt)}
|
||||
<DeployProgress phase={deployment.phase} phaseSuccess={deployment.phaseSuccess} />
|
||||
</div>
|
||||
<div className="sm:w-56 w-full pt-1 sm:pt-0 flex items-center sm:justify-center">{convertZulu2Beijing(deployment.deployedAt)}</div>
|
||||
<div className="flex items-center grow justify-start pt-1 sm:pt-0 sm:ml-2">
|
||||
<Sheet>
|
||||
<SheetTrigger asChild>
|
||||
@@ -265,11 +219,7 @@ const Dashboard = () => {
|
||||
<div>[{item.time}]</div>
|
||||
<div className="ml-2">{item.message}</div>
|
||||
</div>
|
||||
{item.error && (
|
||||
<div className="mt-1 text-red-600">
|
||||
{item.error}
|
||||
</div>
|
||||
)}
|
||||
{item.error && <div className="mt-1 text-red-600">{item.error}</div>}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
@@ -287,17 +237,9 @@ const Dashboard = () => {
|
||||
</div>
|
||||
{item.info &&
|
||||
item.info.map((info: string) => {
|
||||
return (
|
||||
<div className="mt-1 text-green-600">
|
||||
{info}
|
||||
</div>
|
||||
);
|
||||
return <div className="mt-1 text-green-600">{info}</div>;
|
||||
})}
|
||||
{item.error && (
|
||||
<div className="mt-1 text-red-600">
|
||||
{item.error}
|
||||
</div>
|
||||
)}
|
||||
{item.error && <div className="mt-1 text-red-600">{item.error}</div>}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
@@ -313,11 +255,7 @@ const Dashboard = () => {
|
||||
<div>[{item.time}]</div>
|
||||
<div className="ml-2">{item.message}</div>
|
||||
</div>
|
||||
{item.error && (
|
||||
<div className="mt-1 text-red-600">
|
||||
{item.error}
|
||||
</div>
|
||||
)}
|
||||
{item.error && <div className="mt-1 text-red-600">{item.error}</div>}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -1,53 +1,30 @@
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
import z from "zod";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectLabel,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { useConfig } from "@/providers/config";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import z from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Plus } from "lucide-react";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import AccessEdit from "@/components/certimate/AccessEdit";
|
||||
import DeployList from "@/components/certimate/DeployList";
|
||||
import EmailsEdit from "@/components/certimate/EmailsEdit";
|
||||
import StringList from "@/components/certimate/StringList";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { accessTypeMap } from "@/domain/access";
|
||||
import { EmailsSetting } from "@/domain/settings";
|
||||
import { DeployConfig, Domain } from "@/domain/domain";
|
||||
import { save, get } from "@/repository/domains";
|
||||
import { ClientResponseError } from "pocketbase";
|
||||
import { PbErrorData } from "@/domain/base";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { Plus } from "lucide-react";
|
||||
import { AccessEdit } from "@/components/certimate/AccessEdit";
|
||||
import { accessTypeMap } from "@/domain/access";
|
||||
import EmailsEdit from "@/components/certimate/EmailsEdit";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { EmailsSetting } from "@/domain/settings";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import StringList from "@/components/certimate/StringList";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import DeployList from "@/components/certimate/DeployList";
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from "@/components/ui/breadcrumb";
|
||||
import { useConfig } from "@/providers/config";
|
||||
|
||||
const Edit = () => {
|
||||
const {
|
||||
@@ -115,7 +92,6 @@ const Edit = () => {
|
||||
const { toast } = useToast();
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||
console.log(data);
|
||||
const req: Domain = {
|
||||
id: data.id as string,
|
||||
crontab: "0 0 * * *",
|
||||
@@ -147,14 +123,12 @@ const Edit = () => {
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
Object.entries(err.response.data as PbErrorData).forEach(
|
||||
([key, value]) => {
|
||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
||||
type: "manual",
|
||||
message: value.message,
|
||||
});
|
||||
}
|
||||
);
|
||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
||||
type: "manual",
|
||||
message: value.message,
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -182,14 +156,12 @@ const Edit = () => {
|
||||
} catch (e) {
|
||||
const err = e as ClientResponseError;
|
||||
|
||||
Object.entries(err.response.data as PbErrorData).forEach(
|
||||
([key, value]) => {
|
||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
||||
type: "manual",
|
||||
message: value.message,
|
||||
});
|
||||
}
|
||||
);
|
||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
||||
type: "manual",
|
||||
message: value.message,
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -203,16 +175,12 @@ const Edit = () => {
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="#/domains">
|
||||
{t("domain.page.title")}
|
||||
</BreadcrumbLink>
|
||||
<BreadcrumbLink href="#/domains">{t("domain.page.title")}</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>
|
||||
{domain?.id ? t("domain.edit") : t("domain.add")}
|
||||
</BreadcrumbPage>
|
||||
<BreadcrumbPage>{domain?.id ? t("domain.edit") : t("domain.add")}</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
@@ -220,10 +188,7 @@ const Edit = () => {
|
||||
<div className="mt-5 flex w-full justify-center md:space-x-10 flex-col md:flex-row">
|
||||
<div className="w-full md:w-[200px] text-muted-foreground space-x-3 md:space-y-3 flex-row md:flex-col flex md:mt-5">
|
||||
<div
|
||||
className={cn(
|
||||
"cursor-pointer text-right",
|
||||
tab === "apply" ? "text-primary" : ""
|
||||
)}
|
||||
className={cn("cursor-pointer text-right", tab === "apply" ? "text-primary" : "")}
|
||||
onClick={() => {
|
||||
setTab("apply");
|
||||
}}
|
||||
@@ -231,10 +196,7 @@ const Edit = () => {
|
||||
{t("domain.application.tab")}
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
"cursor-pointer text-right",
|
||||
tab === "deploy" ? "text-primary" : ""
|
||||
)}
|
||||
className={cn("cursor-pointer text-right", tab === "deploy" ? "text-primary" : "")}
|
||||
onClick={() => {
|
||||
if (!domain?.id) {
|
||||
toast({
|
||||
@@ -251,17 +213,9 @@ const Edit = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<div
|
||||
className={cn(
|
||||
"w-full md:w-[35em] p-5 rounded mt-3 md:mt-0",
|
||||
tab == "deploy" && "hidden"
|
||||
)}
|
||||
>
|
||||
<div className={cn("w-full md:w-[35em] p-5 rounded mt-3 md:mt-0", tab == "deploy" && "hidden")}>
|
||||
<Form {...form}>
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
className="space-y-8 dark:text-stone-200"
|
||||
>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8 dark:text-stone-200">
|
||||
{/* 域名 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
@@ -288,11 +242,7 @@ const Edit = () => {
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel className="flex w-full justify-between">
|
||||
<div>
|
||||
{t("domain.application.form.email.label") +
|
||||
" " +
|
||||
t("domain.application.form.email.tips")}
|
||||
</div>
|
||||
<div>{t("domain.application.form.email.label") + " " + t("domain.application.form.email.tips")}</div>
|
||||
<EmailsEdit
|
||||
trigger={
|
||||
<div className="font-normal text-primary hover:underline cursor-pointer flex items-center">
|
||||
@@ -311,24 +261,16 @@ const Edit = () => {
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue
|
||||
placeholder={t(
|
||||
"domain.application.form.email.errmsg.empty"
|
||||
)}
|
||||
/>
|
||||
<SelectValue placeholder={t("domain.application.form.email.errmsg.empty")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>
|
||||
{t("domain.application.form.email.list")}
|
||||
</SelectLabel>
|
||||
{(emails.content as EmailsSetting).emails.map(
|
||||
(item) => (
|
||||
<SelectItem key={item} value={item}>
|
||||
<div>{item}</div>
|
||||
</SelectItem>
|
||||
)
|
||||
)}
|
||||
<SelectLabel>{t("domain.application.form.email.list")}</SelectLabel>
|
||||
{(emails.content as EmailsSetting).emails.map((item) => (
|
||||
<SelectItem key={item} value={item}>
|
||||
<div>{item}</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@@ -365,30 +307,17 @@ const Edit = () => {
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue
|
||||
placeholder={t(
|
||||
"domain.application.form.access.placeholder"
|
||||
)}
|
||||
/>
|
||||
<SelectValue placeholder={t("domain.application.form.access.placeholder")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>
|
||||
{t("domain.application.form.access.list")}
|
||||
</SelectLabel>
|
||||
<SelectLabel>{t("domain.application.form.access.list")}</SelectLabel>
|
||||
{accesses
|
||||
.filter((item) => item.usage != "deploy")
|
||||
.map((item) => (
|
||||
<SelectItem key={item.id} value={item.id}>
|
||||
<div className="flex items-center space-x-2">
|
||||
<img
|
||||
className="w-6"
|
||||
src={
|
||||
accessTypeMap.get(
|
||||
item.configType
|
||||
)?.[1]
|
||||
}
|
||||
/>
|
||||
<img className="w-6" src={accessTypeMap.get(item.configType)?.[1]} />
|
||||
<div>{item.name}</div>
|
||||
</div>
|
||||
</SelectItem>
|
||||
@@ -409,22 +338,15 @@ const Edit = () => {
|
||||
name="timeout"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("domain.application.form.timeout.label")}
|
||||
</FormLabel>
|
||||
<FormLabel>{t("domain.application.form.timeout.label")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder={t(
|
||||
"ddomain.application.form.timeout.placeholder"
|
||||
)}
|
||||
placeholder={t("ddomain.application.form.timeout.placeholder")}
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={(e) => {
|
||||
form.setValue(
|
||||
"timeout",
|
||||
parseInt(e.target.value)
|
||||
);
|
||||
form.setValue("timeout", parseInt(e.target.value));
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
@@ -454,20 +376,13 @@ const Edit = () => {
|
||||
/>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Button type="submit">
|
||||
{domain?.id ? t("common.save") : t("common.next")}
|
||||
</Button>
|
||||
<Button type="submit">{domain?.id ? t("common.save") : t("common.next")}</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col space-y-5 w-full md:w-[35em]",
|
||||
tab == "apply" && "hidden"
|
||||
)}
|
||||
>
|
||||
<div className={cn("flex flex-col space-y-5 w-full md:w-[35em]", tab == "apply" && "hidden")}>
|
||||
<DeployList
|
||||
deploys={domain?.deployConfig ?? []}
|
||||
onChange={(list: DeployConfig[]) => {
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
import { TooltipContent, TooltipProvider } from "@radix-ui/react-tooltip";
|
||||
import { Earth } from "lucide-react";
|
||||
|
||||
import Show from "@/components/Show";
|
||||
import DeployProgress from "@/components/certimate/DeployProgress";
|
||||
import DeployState from "@/components/certimate/DeployState";
|
||||
import XPagination from "@/components/certimate/XPagination";
|
||||
import Show from "@/components/Show";
|
||||
import {
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
@@ -14,28 +20,15 @@ import {
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Toaster } from "@/components/ui/toaster";
|
||||
import { Tooltip, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { Domain } from "@/domain/domain";
|
||||
import { CustomFile, saveFiles2ZIP } from "@/lib/file";
|
||||
import { convertZulu2Beijing, getDate } from "@/lib/time";
|
||||
import {
|
||||
list,
|
||||
remove,
|
||||
save,
|
||||
subscribeId,
|
||||
unsubscribeId,
|
||||
} from "@/repository/domains";
|
||||
|
||||
import { TooltipContent, TooltipProvider } from "@radix-ui/react-tooltip";
|
||||
import { Earth } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
import { Domain } from "@/domain/domain";
|
||||
import { list, remove, save, subscribeId, unsubscribeId } from "@/repository/domains";
|
||||
|
||||
const Home = () => {
|
||||
const toast = useToast();
|
||||
@@ -115,7 +108,6 @@ const Home = () => {
|
||||
try {
|
||||
unsubscribeId(domain.id ?? "");
|
||||
subscribeId(domain.id ?? "", (resp) => {
|
||||
console.log(resp);
|
||||
const updatedDomains = domains.map((domain) => {
|
||||
if (domain.id === resp.id) {
|
||||
return { ...resp };
|
||||
@@ -139,10 +131,7 @@ const Home = () => {
|
||||
// 这里的 text 只是占位作用,实际文案在 src/i18n/locales/[lang].json
|
||||
<Trans i18nKey="domain.deploy.failed.tips">
|
||||
text1
|
||||
<Link
|
||||
to={`/history?domain=${domain.id}`}
|
||||
className="underline text-blue-500"
|
||||
>
|
||||
<Link to={`/history?domain=${domain.id}`} className="underline text-blue-500">
|
||||
text2
|
||||
</Link>
|
||||
text3
|
||||
@@ -189,9 +178,7 @@ const Home = () => {
|
||||
<Earth size={40} className="text-primary" />
|
||||
</span>
|
||||
|
||||
<div className="text-center text-sm text-muted-foreground mt-3">
|
||||
{t("domain.nodata")}
|
||||
</div>
|
||||
<div className="text-center text-sm text-muted-foreground mt-3">{t("domain.nodata")}</div>
|
||||
<Button onClick={handleCreateClick} className="mt-3">
|
||||
{t("domain.add")}
|
||||
</Button>
|
||||
@@ -202,15 +189,9 @@ const Home = () => {
|
||||
<div className="hidden sm:flex sm:flex-row text-muted-foreground text-sm border-b dark:border-stone-500 sm:p-2 mt-5">
|
||||
<div className="w-36">{t("common.text.domain")}</div>
|
||||
<div className="w-40">{t("domain.props.expiry")}</div>
|
||||
<div className="w-32">
|
||||
{t("domain.props.last_execution_status")}
|
||||
</div>
|
||||
<div className="w-64">
|
||||
{t("domain.props.last_execution_stage")}
|
||||
</div>
|
||||
<div className="w-40 sm:ml-2">
|
||||
{t("domain.props.last_execution_time")}
|
||||
</div>
|
||||
<div className="w-32">{t("domain.props.last_execution_status")}</div>
|
||||
<div className="w-64">{t("domain.props.last_execution_stage")}</div>
|
||||
<div className="w-40 sm:ml-2">{t("domain.props.last_execution_time")}</div>
|
||||
<div className="w-24">{t("domain.props.enable")}</div>
|
||||
<div className="grow">{t("common.text.operations")}</div>
|
||||
</div>
|
||||
@@ -232,9 +213,7 @@ const Home = () => {
|
||||
<div>
|
||||
{domain.expiredAt ? (
|
||||
<>
|
||||
<div>
|
||||
{t("domain.props.expiry.date1", { date: 90 })}
|
||||
</div>
|
||||
<div>{t("domain.props.expiry.date1", { date: 90 })}</div>
|
||||
<div>
|
||||
{t("domain.props.expiry.date2", {
|
||||
date: getDate(domain.expiredAt),
|
||||
@@ -257,18 +236,13 @@ const Home = () => {
|
||||
</div>
|
||||
<div className="sm:w-64 w-full pt-1 sm:pt-0 flex items-center">
|
||||
{domain.lastDeployedAt && domain.expand?.lastDeployment ? (
|
||||
<DeployProgress
|
||||
phase={domain.expand.lastDeployment?.phase}
|
||||
phaseSuccess={domain.expand.lastDeployment?.phaseSuccess}
|
||||
/>
|
||||
<DeployProgress phase={domain.expand.lastDeployment?.phase} phaseSuccess={domain.expand.lastDeployment?.phaseSuccess} />
|
||||
) : (
|
||||
"---"
|
||||
)}
|
||||
</div>
|
||||
<div className="sm:w-40 pt-1 sm:pt-0 sm:ml-2 flex items-center">
|
||||
{domain.lastDeployedAt
|
||||
? convertZulu2Beijing(domain.lastDeployedAt)
|
||||
: "---"}
|
||||
{domain.lastDeployedAt ? convertZulu2Beijing(domain.lastDeployedAt) : "---"}
|
||||
</div>
|
||||
<div className="sm:w-24 flex items-center">
|
||||
<TooltipProvider>
|
||||
@@ -283,57 +257,33 @@ const Home = () => {
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<div className="border rounded-sm px-3 bg-background text-muted-foreground text-xs">
|
||||
{domain.enabled
|
||||
? t("domain.props.enable.disabled")
|
||||
: t("domain.props.enable.enabled")}
|
||||
{domain.enabled ? t("domain.props.enable.disabled") : t("domain.props.enable.enabled")}
|
||||
</div>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</div>
|
||||
<div className="flex items-center grow justify-start pt-1 sm:pt-0">
|
||||
<Button
|
||||
variant={"link"}
|
||||
className="p-0"
|
||||
onClick={() => handleHistoryClick(domain.id ?? "")}
|
||||
>
|
||||
<Button variant={"link"} className="p-0" onClick={() => handleHistoryClick(domain.id ?? "")}>
|
||||
{t("domain.history")}
|
||||
</Button>
|
||||
<Show when={domain.enabled ? true : false}>
|
||||
<Separator orientation="vertical" className="h-4 mx-2" />
|
||||
<Button
|
||||
variant={"link"}
|
||||
className="p-0"
|
||||
onClick={() => handleRightNowClick(domain)}
|
||||
>
|
||||
<Button variant={"link"} className="p-0" onClick={() => handleRightNowClick(domain)}>
|
||||
{t("domain.deploy")}
|
||||
</Button>
|
||||
</Show>
|
||||
|
||||
<Show
|
||||
when={
|
||||
(domain.enabled ? true : false) && domain.deployed
|
||||
? true
|
||||
: false
|
||||
}
|
||||
>
|
||||
<Show when={(domain.enabled ? true : false) && domain.deployed ? true : false}>
|
||||
<Separator orientation="vertical" className="h-4 mx-2" />
|
||||
<Button
|
||||
variant={"link"}
|
||||
className="p-0"
|
||||
onClick={() => handleForceClick(domain)}
|
||||
>
|
||||
<Button variant={"link"} className="p-0" onClick={() => handleForceClick(domain)}>
|
||||
{t("domain.deploy_forced")}
|
||||
</Button>
|
||||
</Show>
|
||||
|
||||
<Show when={domain.expiredAt ? true : false}>
|
||||
<Separator orientation="vertical" className="h-4 mx-2" />
|
||||
<Button
|
||||
variant={"link"}
|
||||
className="p-0"
|
||||
onClick={() => handleDownloadClick(domain)}
|
||||
>
|
||||
<Button variant={"link"} className="p-0" onClick={() => handleDownloadClick(domain)}>
|
||||
{t("common.download")}
|
||||
</Button>
|
||||
</Show>
|
||||
@@ -349,17 +299,11 @@ const Home = () => {
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>
|
||||
{t("domain.delete")}
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
{t("domain.delete.confirm")}
|
||||
</AlertDialogDescription>
|
||||
<AlertDialogTitle>{t("domain.delete")}</AlertDialogTitle>
|
||||
<AlertDialogDescription>{t("domain.delete.confirm")}</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>
|
||||
{t("common.cancel")}
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogCancel>{t("common.cancel")}</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={() => {
|
||||
handleDeleteClick(domain.id ?? "");
|
||||
@@ -372,11 +316,7 @@ const Home = () => {
|
||||
</AlertDialog>
|
||||
|
||||
<Separator orientation="vertical" className="h-4 mx-2" />
|
||||
<Button
|
||||
variant={"link"}
|
||||
className="p-0"
|
||||
onClick={() => handleEditClick(domain.id ?? "")}
|
||||
>
|
||||
<Button variant={"link"} className="p-0" onClick={() => handleEditClick(domain.id ?? "")}>
|
||||
{t("common.edit")}
|
||||
</Button>
|
||||
</>
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
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";
|
||||
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from "@/components/ui/sheet";
|
||||
import { Deployment, DeploymentListReq, Log } from "@/domain/deployment";
|
||||
import { convertZulu2Beijing } from "@/lib/time";
|
||||
import { list } from "@/repository/deployment";
|
||||
import { Smile } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Smile } from "lucide-react";
|
||||
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
|
||||
import DeployProgress from "@/components/certimate/DeployProgress";
|
||||
import DeployState from "@/components/certimate/DeployState";
|
||||
import { convertZulu2Beijing } from "@/lib/time";
|
||||
import { Deployment, DeploymentListReq, Log } from "@/domain/deployment";
|
||||
import { list } from "@/repository/deployment";
|
||||
|
||||
const History = () => {
|
||||
const navigate = useNavigate();
|
||||
@@ -71,9 +65,7 @@ const History = () => {
|
||||
|
||||
<div className="w-24">{t("history.props.status")}</div>
|
||||
<div className="w-56">{t("history.props.stage")}</div>
|
||||
<div className="w-56 sm:ml-2 text-center">
|
||||
{t("history.props.last_execution_time")}
|
||||
</div>
|
||||
<div className="w-56 sm:ml-2 text-center">{t("history.props.last_execution_time")}</div>
|
||||
|
||||
<div className="grow">{t("common.text.operations")}</div>
|
||||
</div>
|
||||
@@ -84,27 +76,20 @@ const History = () => {
|
||||
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"
|
||||
>
|
||||
<div className="sm:w-48 w-full pt-1 sm:pt-0 flex items-center">
|
||||
{deployment.expand.domain?.domain
|
||||
.split(";")
|
||||
.map((domain: string) => (
|
||||
<>
|
||||
{domain}
|
||||
<br />
|
||||
</>
|
||||
))}
|
||||
{deployment.expand.domain?.domain.split(";").map((domain: string) => (
|
||||
<>
|
||||
{domain}
|
||||
<br />
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
<div className="sm:w-24 w-full pt-1 sm:pt-0 flex items-center">
|
||||
<DeployState deployment={deployment} />
|
||||
</div>
|
||||
<div className="sm:w-56 w-full pt-1 sm:pt-0 flex items-center">
|
||||
<DeployProgress
|
||||
phase={deployment.phase}
|
||||
phaseSuccess={deployment.phaseSuccess}
|
||||
/>
|
||||
</div>
|
||||
<div className="sm:w-56 w-full pt-1 sm:pt-0 flex items-center sm:justify-center">
|
||||
{convertZulu2Beijing(deployment.deployedAt)}
|
||||
<DeployProgress phase={deployment.phase} phaseSuccess={deployment.phaseSuccess} />
|
||||
</div>
|
||||
<div className="sm:w-56 w-full pt-1 sm:pt-0 flex items-center sm:justify-center">{convertZulu2Beijing(deployment.deployedAt)}</div>
|
||||
<div className="flex items-center grow justify-start pt-1 sm:pt-0 sm:ml-2">
|
||||
<Sheet>
|
||||
<SheetTrigger asChild>
|
||||
@@ -129,11 +114,7 @@ const History = () => {
|
||||
<div>[{item.time}]</div>
|
||||
<div className="ml-2">{item.message}</div>
|
||||
</div>
|
||||
{item.error && (
|
||||
<div className="mt-1 text-red-600">
|
||||
{item.error}
|
||||
</div>
|
||||
)}
|
||||
{item.error && <div className="mt-1 text-red-600">{item.error}</div>}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
@@ -151,17 +132,9 @@ const History = () => {
|
||||
</div>
|
||||
{item.info &&
|
||||
item.info.map((info: string) => {
|
||||
return (
|
||||
<div className="mt-1 text-green-600">
|
||||
{info}
|
||||
</div>
|
||||
);
|
||||
return <div className="mt-1 text-green-600">{info}</div>;
|
||||
})}
|
||||
{item.error && (
|
||||
<div className="mt-1 text-red-600">
|
||||
{item.error}
|
||||
</div>
|
||||
)}
|
||||
{item.error && <div className="mt-1 text-red-600">{item.error}</div>}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
@@ -177,11 +150,7 @@ const History = () => {
|
||||
<div>[{item.time}]</div>
|
||||
<div className="ml-2">{item.message}</div>
|
||||
</div>
|
||||
{item.error && (
|
||||
<div className="mt-1 text-red-600">
|
||||
{item.error}
|
||||
</div>
|
||||
)}
|
||||
{item.error && <div className="mt-1 text-red-600">{item.error}</div>}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { z } from "zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { z } from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { getErrMessage } from "@/lib/error";
|
||||
import { getPb } from "@/repository/api";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
const formSchema = z.object({
|
||||
username: z.string().email({
|
||||
@@ -56,10 +49,7 @@ const Login = () => {
|
||||
<img src="/vite.svg" className="w-16" />
|
||||
</div>
|
||||
<Form {...form}>
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
className="space-y-8 dark:text-stone-200"
|
||||
>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8 dark:text-stone-200">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="username"
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
import { useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { z } from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { getErrMessage } from "@/lib/error";
|
||||
import { getPb } from "@/repository/api";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
const formSchema = z.object({
|
||||
email: z.string().email("settings.account.email.errmsg.invalid"),
|
||||
@@ -65,10 +58,7 @@ const Account = () => {
|
||||
<>
|
||||
<div className="w-full md:max-w-[35em]">
|
||||
<Form {...form}>
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
className="space-y-8 dark:text-stone-200"
|
||||
>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8 dark:text-stone-200">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
|
||||
import DingTalk from "@/components/notify/DingTalk";
|
||||
import NotifyTemplate from "@/components/notify/NotifyTemplate";
|
||||
import Telegram from "@/components/notify/Telegram";
|
||||
import Webhook from "@/components/notify/Webhook";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { NotifyProvider } from "@/providers/notify";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const Notify = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -20,9 +16,7 @@ const Notify = () => {
|
||||
<div className="border rounded-sm p-5 shadow-lg">
|
||||
<Accordion type={"multiple"} className="dark:text-stone-200">
|
||||
<AccordionItem value="item-1" className="dark:border-stone-200">
|
||||
<AccordionTrigger>
|
||||
{t("settings.notification.template.label")}
|
||||
</AccordionTrigger>
|
||||
<AccordionTrigger>{t("settings.notification.template.label")}</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<NotifyTemplate />
|
||||
</AccordionContent>
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { z } from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { getErrMessage } from "@/lib/error";
|
||||
import { getPb } from "@/repository/api";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
const formSchema = z
|
||||
.object({
|
||||
@@ -51,10 +44,7 @@ const Password = () => {
|
||||
|
||||
const onSubmit = async (values: z.infer<typeof formSchema>) => {
|
||||
try {
|
||||
await getPb().admins.authWithPassword(
|
||||
getPb().authStore.model?.email,
|
||||
values.oldPassword
|
||||
);
|
||||
await getPb().admins.authWithPassword(getPb().authStore.model?.email, values.oldPassword);
|
||||
} catch (e) {
|
||||
const message = getErrMessage(e);
|
||||
form.setError("oldPassword", { message });
|
||||
@@ -88,26 +78,15 @@ const Password = () => {
|
||||
<>
|
||||
<div className="w-full md:max-w-[35em]">
|
||||
<Form {...form}>
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
className="space-y-8 dark:text-stone-200"
|
||||
>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8 dark:text-stone-200">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="oldPassword"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("settings.password.current_password.label")}
|
||||
</FormLabel>
|
||||
<FormLabel>{t("settings.password.current_password.label")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t(
|
||||
"settings.password.current_password.placeholder"
|
||||
)}
|
||||
{...field}
|
||||
type="password"
|
||||
/>
|
||||
<Input placeholder={t("settings.password.current_password.placeholder")} {...field} type="password" />
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
@@ -120,17 +99,9 @@ const Password = () => {
|
||||
name="newPassword"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("settings.password.new_password.label")}
|
||||
</FormLabel>
|
||||
<FormLabel>{t("settings.password.new_password.label")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t(
|
||||
"settings.password.new_password.placeholder"
|
||||
)}
|
||||
{...field}
|
||||
type="password"
|
||||
/>
|
||||
<Input placeholder={t("settings.password.new_password.placeholder")} {...field} type="password" />
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
@@ -143,17 +114,9 @@ const Password = () => {
|
||||
name="confirmPassword"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
{t("settings.password.confirm_password.label")}
|
||||
</FormLabel>
|
||||
<FormLabel>{t("settings.password.confirm_password.label")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t(
|
||||
"settings.password.confirm_password.placeholder"
|
||||
)}
|
||||
{...field}
|
||||
type="password"
|
||||
/>
|
||||
<Input placeholder={t("settings.password.confirm_password.placeholder")} {...field} type="password" />
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
|
||||
@@ -1,34 +1,19 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
|
||||
import {
|
||||
SSLProvider as SSLProviderType,
|
||||
SSLProviderSetting,
|
||||
Setting,
|
||||
} from "@/domain/settings";
|
||||
import { getErrMessage } from "@/lib/error";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { getSetting, update } from "@/repository/settings";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { z } from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { getErrMessage } from "@/lib/error";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { SSLProvider as SSLProviderType, SSLProviderSetting, Setting } from "@/domain/settings";
|
||||
import { getSetting, update } from "@/repository/settings";
|
||||
|
||||
const SSLProvider = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -64,10 +49,7 @@ const SSLProvider = () => {
|
||||
|
||||
form.setValue("provider", content.provider);
|
||||
form.setValue("eabKid", content.config[content.provider].eabKid);
|
||||
form.setValue(
|
||||
"eabHmacKey",
|
||||
content.config[content.provider].eabHmacKey
|
||||
);
|
||||
form.setValue("eabHmacKey", content.config[content.provider].eabHmacKey);
|
||||
setProvider(content.provider);
|
||||
} else {
|
||||
form.setValue("provider", "letsencrypt");
|
||||
@@ -137,10 +119,7 @@ const SSLProvider = () => {
|
||||
<>
|
||||
<div className="w-full md:max-w-[35em]">
|
||||
<Form {...form}>
|
||||
<form
|
||||
onSubmit={form.handleSubmit(onSubmit)}
|
||||
className="space-y-8 dark:text-stone-200"
|
||||
>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8 dark:text-stone-200">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="provider"
|
||||
@@ -160,16 +139,8 @@ const SSLProvider = () => {
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="letsencrypt" id="letsencrypt" />
|
||||
<Label htmlFor="letsencrypt">
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center space-x-2 border p-2 rounded cursor-pointer",
|
||||
getOptionCls("letsencrypt")
|
||||
)}
|
||||
>
|
||||
<img
|
||||
src={"/imgs/providers/letsencrypt.svg"}
|
||||
className="h-6"
|
||||
/>
|
||||
<div className={cn("flex items-center space-x-2 border p-2 rounded cursor-pointer", getOptionCls("letsencrypt"))}>
|
||||
<img src={"/imgs/providers/letsencrypt.svg"} className="h-6" />
|
||||
<div>{"Let's Encrypt"}</div>
|
||||
</div>
|
||||
</Label>
|
||||
@@ -177,16 +148,8 @@ const SSLProvider = () => {
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="zerossl" id="zerossl" />
|
||||
<Label htmlFor="zerossl">
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center space-x-2 border p-2 rounded cursor-pointer",
|
||||
getOptionCls("zerossl")
|
||||
)}
|
||||
>
|
||||
<img
|
||||
src={"/imgs/providers/zerossl.svg"}
|
||||
className="h-6"
|
||||
/>
|
||||
<div className={cn("flex items-center space-x-2 border p-2 rounded cursor-pointer", getOptionCls("zerossl"))}>
|
||||
<img src={"/imgs/providers/zerossl.svg"} className="h-6" />
|
||||
<div>{"ZeroSSL"}</div>
|
||||
</div>
|
||||
</Label>
|
||||
@@ -201,11 +164,7 @@ const SSLProvider = () => {
|
||||
<FormItem hidden={provider !== "zerossl"}>
|
||||
<FormLabel>EAB_KID</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t("settings.ca.eab_kid.errmsg.empty")}
|
||||
{...field}
|
||||
type="text"
|
||||
/>
|
||||
<Input placeholder={t("settings.ca.eab_kid.errmsg.empty")} {...field} type="text" />
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
@@ -220,13 +179,7 @@ const SSLProvider = () => {
|
||||
<FormItem hidden={provider !== "zerossl"}>
|
||||
<FormLabel>EAB_HMAC_KEY</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t(
|
||||
"settings.ca.eab_hmac_key.errmsg.empty"
|
||||
)}
|
||||
{...field}
|
||||
type="text"
|
||||
/>
|
||||
<Input placeholder={t("settings.ca.eab_hmac_key.errmsg.empty")} {...field} type="text" />
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
|
||||
Reference in New Issue
Block a user