gitscope
← marzneshin / v0.3.0 / 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";
 21
 22export function CommandBox() {
 23  const [open, setOpen] = useState(false);
 24  const { t } = useTranslation();
 25  const navigate = useNavigate();
 26
 27  useEffect(() => {
 28    const down = (e: KeyboardEvent) => {
 29      if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
 30        e.preventDefault();
 31        setOpen((open) => !open);
 32      }
 33    };
 34    document.addEventListener("keydown", down);
 35    return () => document.removeEventListener("keydown", down);
 36  }, []);
 37
 38  return (
 39    <>
 40      <SearchBox onClick={() => setOpen(true)} />
 41      <CommandDialog open={open} onOpenChange={setOpen}>
 42        <CommandInput
 43          placeholder="Type a command or search..."
 44          className="focus:ring-0 ring-0 m-1 border-none"
 45        />
 46        <CommandList>
 47          <CommandEmpty>No results found.</CommandEmpty>
 48          <CommandGroup heading="Pages">
 49            <CommandItem
 50              onSelect={() => {
 51                navigate({ to: "/users" });
 52                setOpen(false);
 53              }}
 54            >
 55              <UsersIcon className="mr-2 size-4" />
 56              <span>{t("users")}</span>
 57            </CommandItem>
 58            <CommandItem
 59              onSelect={() => {
 60                navigate({ to: "/services" });
 61                setOpen(false);
 62              }}
 63            >
 64              <ServerIcon className="mr-2 size-4" />
 65              <span>{t("services")}</span>
 66            </CommandItem>
 67            <CommandItem
 68              onSelect={() => {
 69                navigate({ to: "/nodes" });
 70                setOpen(false);
 71              }}
 72            >
 73              <BoxIcon className="mr-2 h-4 w-4" />
 74              <span>{t("nodes")}</span>
 75            </CommandItem>
 76            <CommandItem
 77              onSelect={() => {
 78                navigate({ to: "/hosts" });
 79                setOpen(false);
 80              }}
 81            >
 82              <ServerCogIcon className="mr-2 h-4 w-4" />
 83              <span>{t("hosts")}</span>
 84            </CommandItem>
 85          </CommandGroup>
 86          <CommandSeparator />
 87          <CommandGroup heading="Settings">
 88            <CommandItem
 89              onSelect={() => {
 90                navigate({ to: "/settings" });
 91                setOpen(false);
 92              }}
 93            >
 94              <SettingsIcon className="mr-2 h-4 w-4" />
 95              <span>{t("settings")}</span>
 96            </CommandItem>
 97          </CommandGroup>
 98        </CommandList>
 99      </CommandDialog>
100    </>
101  );
102}