import { Button } from "@/components/ui/button" import { Sheet, SheetContent, SheetFooter, SheetHeader, SheetTitle } from "@/components/ui/sheet" import { ChatbotUIContext } from "@/context/context" import { createAssistantCollections } from "@/db/assistant-collections" import { createAssistantFiles } from "@/db/assistant-files" import { createAssistantTools } from "@/db/assistant-tools" import { createAssistant, updateAssistant } from "@/db/assistants" import { createChat } from "@/db/chats" import { createCollectionFiles } from "@/db/collection-files" import { createCollection } from "@/db/collections" import { createFileBasedOnExtension } from "@/db/files" import { createModel } from "@/db/models" import { createPreset } from "@/db/presets" import { createPrompt } from "@/db/prompts" import { getAssistantImageFromStorage, uploadAssistantImage } from "@/db/storage/assistant-images" import { createTool } from "@/db/tools" import { convertBlobToBase64 } from "@/lib/blob-to-b64" import { Tables, TablesInsert } from "@/supabase/types" import { ContentType } from "@/types" import { FC, useContext, useRef, useState } from "react" import { toast } from "sonner" interface SidebarCreateItemProps { isOpen: boolean isTyping: boolean onOpenChange: (isOpen: boolean) => void contentType: ContentType renderInputs: () => JSX.Element createState: any } export const SidebarCreateItem: FC = ({ isOpen, onOpenChange, contentType, renderInputs, createState, isTyping }) => { const { selectedWorkspace, setChats, setPresets, setPrompts, setFiles, setCollections, setAssistants, setAssistantImages, setTools, setModels } = useContext(ChatbotUIContext) const buttonRef = useRef(null) const [creating, setCreating] = useState(false) const createFunctions = { chats: createChat, presets: createPreset, prompts: createPrompt, files: async ( createState: { file: File } & TablesInsert<"files">, workspaceId: string ) => { if (!selectedWorkspace) return const { file, ...rest } = createState const createdFile = await createFileBasedOnExtension( file, rest, workspaceId, selectedWorkspace.embeddings_provider as "openai" | "local" ) return createdFile }, collections: async ( createState: { image: File collectionFiles: TablesInsert<"collection_files">[] } & Tables<"collections">, workspaceId: string ) => { const { collectionFiles, ...rest } = createState const createdCollection = await createCollection(rest, workspaceId) const finalCollectionFiles = collectionFiles.map(collectionFile => ({ ...collectionFile, collection_id: createdCollection.id })) await createCollectionFiles(finalCollectionFiles) return createdCollection }, assistants: async ( createState: { image: File files: Tables<"files">[] collections: Tables<"collections">[] tools: Tables<"tools">[] } & Tables<"assistants">, workspaceId: string ) => { const { image, files, collections, tools, ...rest } = createState const createdAssistant = await createAssistant(rest, workspaceId) let updatedAssistant = createdAssistant if (image) { const filePath = await uploadAssistantImage(createdAssistant, image) updatedAssistant = await updateAssistant(createdAssistant.id, { image_path: filePath }) const url = (await getAssistantImageFromStorage(filePath)) || "" if (url) { const response = await fetch(url) const blob = await response.blob() const base64 = await convertBlobToBase64(blob) setAssistantImages(prev => [ ...prev, { assistantId: updatedAssistant.id, path: filePath, base64, url } ]) } } const assistantFiles = files.map(file => ({ user_id: rest.user_id, assistant_id: createdAssistant.id, file_id: file.id })) const assistantCollections = collections.map(collection => ({ user_id: rest.user_id, assistant_id: createdAssistant.id, collection_id: collection.id })) const assistantTools = tools.map(tool => ({ user_id: rest.user_id, assistant_id: createdAssistant.id, tool_id: tool.id })) await createAssistantFiles(assistantFiles) await createAssistantCollections(assistantCollections) await createAssistantTools(assistantTools) return updatedAssistant }, tools: createTool, models: createModel } const stateUpdateFunctions = { chats: setChats, presets: setPresets, prompts: setPrompts, files: setFiles, collections: setCollections, assistants: setAssistants, tools: setTools, models: setModels } const handleCreate = async () => { try { if (!selectedWorkspace) return if (isTyping) return // Prevent creation while typing const createFunction = createFunctions[contentType] const setStateFunction = stateUpdateFunctions[contentType] if (!createFunction || !setStateFunction) return setCreating(true) const newItem = await createFunction(createState, selectedWorkspace.id) setStateFunction((prevItems: any) => [...prevItems, newItem]) onOpenChange(false) setCreating(false) } catch (error) { toast.error(`Error creating ${contentType.slice(0, -1)}. ${error}.`) setCreating(false) } } const handleKeyDown = (e: React.KeyboardEvent) => { if (!isTyping && e.key === "Enter" && !e.shiftKey) { e.preventDefault() buttonRef.current?.click() } } return (
Create{" "} {contentType.charAt(0).toUpperCase() + contentType.slice(1, -1)}
{renderInputs()}
) }