gitscope
← marzneshin / v0.3.2 / dashboard/src/features/search-command/command-box.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/search-command/command-box.tsx · TypeScript
Blame Raw
  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}