diff --git a/bun.lockb b/bun.lockb index 36fa3f4..edf2874 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 6affba7..96a256b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@radix-ui/react-scroll-area": "^1.2.1", "@radix-ui/react-select": "^2.1.2", "@radix-ui/react-separator": "^1.1.0", - "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-tabs": "^1.1.1", "@tanstack/react-table": "^8.20.5", "@trivago/prettier-plugin-sort-imports": "^5.2.0", diff --git a/src/api/online-user.ts b/src/api/online-user.ts new file mode 100644 index 0000000..4b4319e --- /dev/null +++ b/src/api/online-user.ts @@ -0,0 +1,5 @@ +import { FetcherMethod, fetcher } from "./api" + +export const blockUser = async (ip: string[]): Promise => { + return fetcher(FetcherMethod.POST, "/api/v1/online-user/batch-block", ip) +} diff --git a/src/components/install-commands.tsx b/src/components/install-commands.tsx index 425692e..6a92efd 100644 --- a/src/components/install-commands.tsx +++ b/src/components/install-commands.tsx @@ -5,9 +5,10 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" +import { useAuth } from "@/hooks/useAuth" import useSettings from "@/hooks/useSetting" import { copyToClipboard } from "@/lib/utils" -import { ModelSettingResponse } from "@/types" +import { ModelProfile, ModelSettingResponse } from "@/types" import i18next from "i18next" import { Check, Clipboard } from "lucide-react" import { forwardRef, useState } from "react" @@ -23,14 +24,17 @@ enum OSTypes { export const InstallCommandsMenu = forwardRef((props, ref) => { const [copy, setCopy] = useState(false) const { data: settings } = useSettings() + const { profile } = useAuth() + const { t } = useTranslation() const switchState = async (type: number) => { if (!copy) { try { setCopy(true) + if (!profile) throw new Error("Profile is not found.") if (!settings) throw new Error("Settings is not found.") - await copyToClipboard(generateCommand(type, settings) || "") + await copyToClipboard(generateCommand(type, settings, profile) || "") } catch (e: Error | any) { console.error(e) toast(t("Error"), { @@ -85,9 +89,19 @@ export const InstallCommandsMenu = forwardRef((p const generateCommand = ( type: number, { agent_secret_key, install_host, tls }: ModelSettingResponse, + { agent_secret, role }: ModelProfile, ) => { if (!install_host) throw new Error(i18next.t("Results.InstallHostRequired")) + // 如果 agent_secret 为空且 role 为 0 ,则使用 agent_secret_key,否则如果 agent_secret 为空则报错 + if (!agent_secret && role === 0) { + agent_secret = agent_secret_key + } else if (!agent_secret) { + throw new Error(i18next.t("Results.AgentSecretRequired")) + } + + agent_secret_key = agent_secret + const env = `NZ_SERVER=${install_host} NZ_TLS=${tls || false} NZ_CLIENT_SECRET=${agent_secret_key}` const env_win = `$env:NZ_SERVER=\"${install_host}\";$env:NZ_TLS=\"${tls || false}\";$env:NZ_CLIENT_SECRET=\"${agent_secret_key}\";` diff --git a/src/components/settings-tab.tsx b/src/components/settings-tab.tsx index 5c5380e..80eeaf0 100644 --- a/src/components/settings-tab.tsx +++ b/src/components/settings-tab.tsx @@ -1,20 +1,30 @@ import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs" +import { useAuth } from "@/hooks/useAuth" import { useTranslation } from "react-i18next" -import { Link, useLocation } from "react-router-dom" +import { Link } from "react-router-dom" export const SettingsTab = ({ className }: { className?: string }) => { const { t } = useTranslation() - const location = useLocation() + const { profile } = useAuth() + + const isAdmin = profile?.role === 0 return ( - - - - {t("Settings")} - - - {t("User")} - + + + {isAdmin && ( + <> + + {t("Settings")} + + + {t("User")} + + + {t("OnlineUser")} + + + )} {t("WAF")} diff --git a/src/components/ui/pagination.tsx b/src/components/ui/pagination.tsx new file mode 100644 index 0000000..7d0f32d --- /dev/null +++ b/src/components/ui/pagination.tsx @@ -0,0 +1,97 @@ +import { ButtonProps, buttonVariants } from "@/components/ui/button" +import { cn } from "@/lib/utils" +import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react" +import * as React from "react" + +const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => ( +