diff --git a/src/components/install-commands.tsx b/src/components/install-commands.tsx index 4dbf8f2..61a82cc 100644 --- a/src/components/install-commands.tsx +++ b/src/components/install-commands.tsx @@ -6,19 +6,40 @@ import { } from "@/components/ui/dropdown-menu" import { Button, ButtonProps } from "@/components/ui/button" import { forwardRef, useState } from "react" +import { useConfig } from "@/hooks/useConfig" +import { ConfigEssential } from "@/types" import { Check, Clipboard } from "lucide-react" -import { t } from "i18next" +import { toast } from "sonner" + +import { useTranslation } from "react-i18next" + +enum OSTypes { + Linux = 1, + macOS, + Windows +} export const InstallCommandsMenu = forwardRef((props, ref) => { const [copy, setCopy] = useState(false); + const { config } = useConfig(); + const { t } = useTranslation(); - const switchState = async () => { + const switchState = async (type: number) => { if (!copy) { - setCopy(true); - await navigator.clipboard.writeText("stub"); - setTimeout(() => { - setCopy(false); - }, 1000); + try { + setCopy(true); + if (config) + await navigator.clipboard.writeText(generateCommand(type, config)); + } catch (e) { + console.error(e); + toast(t("Error"), { + description: t("Results.UnExpectedError"), + }) + } finally { + setTimeout(() => { + setCopy(false); + }, 2 * 1000); + } } } @@ -31,10 +52,30 @@ export const InstallCommandsMenu = forwardRef((p - Linux - macOS - Windows + { switchState(OSTypes.Linux) }}>Linux + { switchState(OSTypes.macOS) }}>macOS + { switchState(OSTypes.Windows) }}>Windows ); }) + +const generateCommand = (type: number, { agent_secret_key, install_host, listen_port, tls }: ConfigEssential) => { + if (!install_host) + throw new Error("You have not specify the installed host."); + + const env = `NZ_SERVER=${install_host}:${listen_port} NZ_TLS=${tls || false} NZ_CLIENT_SECRET=${agent_secret_key}`; + + switch (type) { + case OSTypes.Linux: + case OSTypes.macOS: { + return `curl -L https://raw.githubusercontent.com/nezhahq/scripts/main/agent/install.sh -o nezha.sh && chmod +x nezha.sh && env ${env} ./nezha.sh` + } + case OSTypes.Windows: { + return `${env} [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Ssl3 -bor [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12;set-ExecutionPolicy RemoteSigned;Invoke-WebRequest https://raw.githubusercontent.com/nezhahq/scripts/main/agent/install.ps1 -OutFile C:\install.ps1;powershell.exe C:\install.ps1` + } + default: { + throw new Error(`Unknown OS: ${type}`); + } + } +} diff --git a/src/hooks/useConfig.tsx b/src/hooks/useConfig.tsx new file mode 100644 index 0000000..8a81a4f --- /dev/null +++ b/src/hooks/useConfig.tsx @@ -0,0 +1,48 @@ +import { createContext, useContext, useEffect, useMemo } from "react" +import { useConfigStore } from "./useConfigStore" +import { getSettings } from "@/api/settings" +import { ConfigContextProps } from "@/types" +import { useLocation } from "react-router-dom" + +const ConfigContext = createContext({}); + +interface ConfigProviderProps { + children: React.ReactNode; +} + +export const ConfigProvider: React.FC = ({ children }) => { + const config = useConfigStore(store => store.config); + const setConfig = useConfigStore(store => store.setConfig); + + const location = useLocation(); + + useEffect(() => { + (async () => { + if (location.pathname !== "/dashboard/settings") + try { + const c = await getSettings(); + const { agent_secret_key, language, listen_port, install_host, site_name, tls } = c; + const data = { + agent_secret_key, + language, + listen_port, + install_host, + site_name, + tls, + }; + setConfig(data); + } catch (error) { + setConfig(undefined); + } + })(); + }, [location.pathname]) + + const value: ConfigContextProps = useMemo(() => ({ + config: config, + }), [config]); + return {children}; +} + +export const useConfig = () => { + return useContext(ConfigContext); +}; diff --git a/src/hooks/useConfigStore.ts b/src/hooks/useConfigStore.ts new file mode 100644 index 0000000..e6cb0c4 --- /dev/null +++ b/src/hooks/useConfigStore.ts @@ -0,0 +1,16 @@ +import { ConfigStore } from '@/types' +import { create } from 'zustand' +import { persist, createJSONStorage } from 'zustand/middleware' + +export const useConfigStore = create( + persist( + (set, get) => ({ + config: get()?.config, + setConfig: config => set({ config }), + }), + { + name: 'configStore', + storage: createJSONStorage(() => localStorage), + }, + ), +) diff --git a/src/main.tsx b/src/main.tsx index 14c352c..6b24711 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -22,6 +22,7 @@ import ServerGroupPage from './routes/server-group'; import NotificationGroupPage from './routes/notification-group'; import { ServerProvider } from './hooks/useServer'; import { NotificationProvider } from './hooks/useNotfication'; +import { ConfigProvider } from './hooks/useConfig'; import CronPage from './routes/cron'; import NotificationPage from './routes/notification'; import AlertRulePage from './routes/alert-rule'; @@ -33,7 +34,15 @@ import ProfilePage from './routes/profile'; const router = createBrowserRouter([ { path: "/dashboard", - element: , + element: ( + + + + + + + + ), errorElement: , children: [ { diff --git a/src/routes/settings.tsx b/src/routes/settings.tsx index 64266b1..7663307 100644 --- a/src/routes/settings.tsx +++ b/src/routes/settings.tsx @@ -74,7 +74,10 @@ export default function SettingsPage() { const form = useForm>({ resolver: zodResolver(settingFormSchema), defaultValues: config - ? config + ? { + ...config, + site_name: config.site_name || "", + } : { ip_change_notification_group_id: 0, cover: 1, diff --git a/src/types/configContext.ts b/src/types/configContext.ts new file mode 100644 index 0000000..a29afc2 --- /dev/null +++ b/src/types/configContext.ts @@ -0,0 +1,5 @@ +import { ConfigEssential } from "@/types"; + +export interface ConfigContextProps { + config?: ConfigEssential; +} diff --git a/src/types/configStore.ts b/src/types/configStore.ts new file mode 100644 index 0000000..e974ae3 --- /dev/null +++ b/src/types/configStore.ts @@ -0,0 +1,13 @@ +export interface ConfigEssential { + language: string; + agent_secret_key: string; + install_host: string; + listen_port: number; + site_name: string; + tls: boolean; +} + +export interface ConfigStore { + config?: ConfigEssential; + setConfig: (config?: ConfigEssential) => void; +} diff --git a/src/types/index.ts b/src/types/index.ts index 583ce58..d40b10c 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -12,3 +12,5 @@ export * from './notificationStore'; export * from './notificationContext'; export * from './fm'; export * from './settings'; +export * from './configStore'; +export * from './configContext';