"use client" import { AnimatePresence, motion } from "framer-motion" import { useEffect, useState, KeyboardEvent as ReactKeyboardEvent } from "react" import { Icon } from "../la-editor/components/ui/icon" import { linkShowCreateAtom } from "@/store/link" import { generateUniqueSlug } from "@/lib/utils" import { useAtom } from "jotai" import { PersonalPage } from "@/lib/schema/personal-page" import { useRouter } from "next/navigation" import { useAccount } from "@/lib/providers/jazz-provider" import { toast } from "sonner" export function CommandPalette() { const [showPalette, setShowPalette] = useState(false) const [showCreate, setShowCreate] = useAtom(linkShowCreateAtom) const router = useRouter() const { me } = useAccount() const [commands, setCommands] = useState< { name: string; icon?: React.ReactNode; keybind?: string[]; action: () => void }[] >([ { name: "Create new link", icon: , // keybind: ["Ctrl", "K"], action: () => { if (window.location.pathname !== "/") { router.push("/") } setShowCreate(true) } }, { name: "Create page", icon: , // keybind: ["Ctrl", "P"], action: () => { const personalPages = me?.root?.personalPages?.toJSON() || [] const slug = generateUniqueSlug(personalPages, "Untitled Page") const newPersonalPage = PersonalPage.create( { title: "Untitled Page", slug: slug, content: "" }, { owner: me._owner } ) me.root?.personalPages?.push(newPersonalPage) router.push(`/pages/${newPersonalPage.id}`) } } // { // name: "Assign status..", // // icon: , // // keybind: ["Ctrl", "P"], // action: () => {} // } ]) const [searchTerm, setSearchTerm] = useState("") const [commandResults, setCommandResults] = useState(commands) const [selectedIndex, setSelectedIndex] = useState(0) useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if ((event.metaKey || event.ctrlKey) && event.key === "k") { event.preventDefault() setShowPalette(prev => !prev) } else if (showPalette) { if (["Escape", "Enter", "ArrowDown", "ArrowUp"].includes(event.key)) { event.preventDefault() event.stopPropagation() // Handle the key events here if (event.key === "Escape") { setShowPalette(false) } else if (event.key === "Enter" && commandResults.length > 0) { commandResults[selectedIndex].action() setShowPalette(false) } else if (event.key === "ArrowDown") { setSelectedIndex(prevIndex => (prevIndex < commandResults.length - 1 ? prevIndex + 1 : prevIndex)) } else if (event.key === "ArrowUp") { setSelectedIndex(prevIndex => (prevIndex > 0 ? prevIndex - 1 : prevIndex)) } } } } document.addEventListener("keydown", handleKeyDown, true) return () => { document.removeEventListener("keydown", handleKeyDown, true) } }, [showPalette, commandResults, selectedIndex]) // Remove the separate handleKeyDown function for the input // as we're now handling all key events in the global listener if (!showPalette) return null return ( setShowPalette(false)} >
e.stopPropagation()} className="relative h-fit w-[600px] rounded-lg border border-slate-400/20 bg-white drop-shadow-xl dark:bg-neutral-900" >
    {commandResults.map((command, index) => (
  • { command.action() setShowPalette(false) }} >
    {command.name}
    {command.keybind && (
    {command.keybind.map(key => ( {key} ))}
    )}
  • ))} {commandResults.length === 0 && (
  • No results found
  • )}
) }