import { ChatbotUIContext } from "@/context/context" import { Tables } from "@/supabase/types" import { IconRobotFace } from "@tabler/icons-react" import Image from "next/image" import { FC, useContext, useEffect, useRef } from "react" import { usePromptAndCommand } from "./chat-hooks/use-prompt-and-command" interface AssistantPickerProps {} export const AssistantPicker: FC = ({}) => { const { assistants, assistantImages, focusAssistant, atCommand, isAssistantPickerOpen, setIsAssistantPickerOpen } = useContext(ChatbotUIContext) const { handleSelectAssistant } = usePromptAndCommand() const itemsRef = useRef<(HTMLDivElement | null)[]>([]) useEffect(() => { if (focusAssistant && itemsRef.current[0]) { itemsRef.current[0].focus() } }, [focusAssistant]) const filteredAssistants = assistants.filter(assistant => assistant.name.toLowerCase().includes(atCommand.toLowerCase()) ) const handleOpenChange = (isOpen: boolean) => { setIsAssistantPickerOpen(isOpen) } const callSelectAssistant = (assistant: Tables<"assistants">) => { handleSelectAssistant(assistant) handleOpenChange(false) } const getKeyDownHandler = (index: number) => (e: React.KeyboardEvent) => { if (e.key === "Backspace") { e.preventDefault() handleOpenChange(false) } else if (e.key === "Enter") { e.preventDefault() callSelectAssistant(filteredAssistants[index]) } else if ( (e.key === "Tab" || e.key === "ArrowDown") && !e.shiftKey && index === filteredAssistants.length - 1 ) { e.preventDefault() itemsRef.current[0]?.focus() } else if (e.key === "ArrowUp" && !e.shiftKey && index === 0) { // go to last element if arrow up is pressed on first element e.preventDefault() itemsRef.current[itemsRef.current.length - 1]?.focus() } else if (e.key === "ArrowUp") { e.preventDefault() const prevIndex = index - 1 >= 0 ? index - 1 : itemsRef.current.length - 1 itemsRef.current[prevIndex]?.focus() } else if (e.key === "ArrowDown") { e.preventDefault() const nextIndex = index + 1 < itemsRef.current.length ? index + 1 : 0 itemsRef.current[nextIndex]?.focus() } } return ( <> {isAssistantPickerOpen && (
{filteredAssistants.length === 0 ? (
No matching assistants.
) : ( <> {filteredAssistants.map((item, index) => (
{ itemsRef.current[index] = ref }} tabIndex={0} className="hover:bg-accent focus:bg-accent flex cursor-pointer items-center rounded p-2 focus:outline-none" onClick={() => callSelectAssistant(item as Tables<"assistants">) } onKeyDown={getKeyDownHandler(index)} > {item.image_path ? ( image.path === item.image_path )?.url || "" } alt={item.name} width={32} height={32} className="rounded" /> ) : ( )}
{item.name}
{item.description || "No description."}
))} )}
)} ) }