style: format

This commit is contained in:
Fu Diwei
2024-10-15 20:45:39 +08:00
parent b0923d54ee
commit 7ef885319e
184 changed files with 2080 additions and 10779 deletions

View File

@@ -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>

View File

@@ -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 />

View File

@@ -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">

View File

@@ -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);

View File

@@ -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>
);
})}

View File

@@ -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[]) => {

View File

@@ -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>
</>

View File

@@ -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>
);
})}

View File

@@ -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"

View File

@@ -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"

View File

@@ -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>

View File

@@ -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 />

View File

@@ -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 />