https://dev.kronoz.win/r/marzneshin.git
1import {
2 UsersIcon,
3 ServerIcon,
4 BoxIcon,
5 ServerCogIcon,
6 SettingsIcon,
7} from "lucide-react";
8import { useState, useEffect } from "react";
9import { useTranslation } from "react-i18next";
10import {
11 CommandDialog,
12 CommandEmpty,
13 CommandGroup,
14 CommandInput,
15 CommandItem,
16 CommandList,
17 CommandSeparator,
18} from "@marzneshin/components";
19import { useNavigate } from "@tanstack/react-router";
20import { SearchBox } from "./search-box";
21import { useAuth } from "@marzneshin/features/auth";
22
23export function CommandBox() {
24 const [open, setOpen] = useState(false);
25 const { t } = useTranslation();
26 const navigate = useNavigate();
27
28 useEffect(() => {
29 const down = (e: KeyboardEvent) => {
30 if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
31 e.preventDefault();
32 setOpen((open) => !open);
33 }
34 };
35 document.addEventListener("keydown", down);
36 return () => document.removeEventListener("keydown", down);
37 }, []);
38
39 const { isSudo } = useAuth();
40
41 return (
42 <>
43 <SearchBox onClick={() => setOpen(true)} />
44 <CommandDialog open={open} onOpenChange={setOpen}>
45 <CommandInput
46 placeholder="Type a command or search..."
47 className="focus:ring-0 ring-0 m-1 border-none"
48 />
49 <CommandList>
50 <CommandEmpty>No results found.</CommandEmpty>
51 <CommandGroup heading="Pages">
52 <CommandItem
53 onSelect={() => {
54 navigate({ to: "/users" });
55 setOpen(false);
56 }}
57 >
58 <UsersIcon className="mr-2 size-4" />
59 <span>{t("users")}</span>
60 </CommandItem>
61 {isSudo() && (
62 <>
63 <CommandItem
64 onSelect={() => {
65 navigate({ to: "/services" });
66 setOpen(false);
67 }}
68 >
69 <ServerIcon className="mr-2 size-4" />
70 <span>{t("services")}</span>
71 </CommandItem>
72 <CommandItem
73 onSelect={() => {
74 navigate({ to: "/nodes" });
75 setOpen(false);
76 }}
77 >
78 <BoxIcon className="mr-2 h-4 w-4" />
79 <span>{t("nodes")}</span>
80 </CommandItem>
81 <CommandItem
82 onSelect={() => {
83 navigate({ to: "/hosts" });
84 setOpen(false);
85 }}
86 >
87 <ServerCogIcon className="mr-2 h-4 w-4" />
88 <span>{t("hosts")}</span>
89 </CommandItem>
90 </>
91 )}
92 </CommandGroup>
93 {isSudo() && (
94 <>
95 <CommandSeparator />
96 <CommandGroup heading="Settings">
97 <CommandItem
98 onSelect={() => {
99 navigate({ to: "/settings" });
100 setOpen(false);
101 }}
102 >
103 <SettingsIcon className="mr-2 h-4 w-4" />
104 <span>{t("settings")}</span>
105 </CommandItem>
106 </CommandGroup>
107 </>
108 )}
109 </CommandList>
110 </CommandDialog>
111 </>
112 );
113}