task-managment / src / components / SearchCommand.tsx
SearchCommand.tsx
Raw
"use client";

import * as React from "react";
import {
  MagnifyingGlassIcon,
} from "@radix-ui/react-icons";

import {
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandItem,
  CommandList,
  CommandSeparator,
  CommandShortcut,
} from "@/components/ui/command";
import {
  FolderSearch,
  LoaderCircle,
  PanelsTopLeft,
  Search,
} from "lucide-react";
import { trpc } from "@/app/_trpc/client";
import { useDebounce } from "use-debounce";
import useHandleParams from "@/hooks/useHandleParams";
import { useRouter } from "next/navigation";

export default function SearchCommand({isSearchQuery}:{isSearchQuery:boolean}) {
  const [open, setOpen] = React.useState(false);
  const [searchValue, setSearchValue] = React.useState<string>("");
  const [query] = useDebounce(searchValue, 400);
  const { setParams, getParam } = useHandleParams();
  const router = useRouter()
  const {
    data: projects,
    isPending,
    isFetching,
    isError,
  } = trpc.projects.getProjectsSearch.useQuery(
    { searchQuery:query },
    {
      refetchOnMount: false,
      refetchOnWindowFocus: false,
      enabled: !!query,
    }
  );
  
  React.useEffect(() => {
    const down = (e: KeyboardEvent) => {
      if (e.key === "j" && (e.metaKey || e.ctrlKey)) {
        e.preventDefault();
        setOpen((open) => !open);
      }
    };

    document.addEventListener("keydown", down);
    return () => document.removeEventListener("keydown", down);
  }, []);


  const handleSearchByQuery=(id:number,name:string)=>{
    if(isSearchQuery){
      setParams("q",name );
      setOpen(false);
    }else{
      router.push(`/dashboard/projects/${id}`)
    }
  }

  return (
    <>
      <button
        onClick={() => setOpen(true)}
        className="py-1.5 px-2 rounded-full bg-white"
      >
        <Search size={20} />
      </button>
      <CommandDialog open={open} onOpenChange={setOpen}>
        <div className="flex items-center border-b px-3">
          <MagnifyingGlassIcon className="mr-2 h-4 w-4 shrink-0 opacity-50" />
          <input
            value={searchValue}
            defaultValue={getParam("q") ? getParam("q") : ""}
            onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
              setSearchValue(e.target.value)
            }
            autoFocus
            className="flex h-10 w-full border-none border-transparent rounded-md bg-transparent py-3 text-sm outline-none focus:ring-0 focus:border-none focus:outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
          />
        </div>
        <CommandList>
          <CommandSeparator />
          <CommandGroup heading="Resultados" className="min-h-[150px]">
            <div>
              {isFetching && (
                <CommandItem className="mt-5">
                  <LoaderCircle className="m-auto animate-spin" />
                </CommandItem>
              )}
              {!isError && !searchValue && (
                <CommandItem className="min-h-10 bg-transparent">
                  <FolderSearch className="mr-2 h-4 w-4" />
                  <span>Escribe el nombre de projecto a buscar...</span>
                </CommandItem>
              )}
              {!isFetching && projects?.length === 0 && (
                <CommandEmpty>No resultados encontrados.</CommandEmpty>
              )}
               {isError &&  (
                <CommandEmpty>Error al obtener resultados.</CommandEmpty>
              )}

              {projects &&
                projects.map((item) => (
                  <div key={item?.id}
                  onClick={()=>handleSearchByQuery(item?.id! as any,item?.name!)}
                  >
                    <CommandItem key={item?.id} className="cursor-pointer">
                      <PanelsTopLeft className="mr-2 h-4 w-4" />
                      <span>{item?.name}</span>
                      <CommandShortcut>{item?.status}</CommandShortcut>
                    </CommandItem>
                  </div>
                ))}
            </div>
          </CommandGroup>
        </CommandList>
      </CommandDialog>
    </>
  );
}