chatbot-ui/components/sidebar/items/collections/create-collection.tsx

105 lines
3.0 KiB
TypeScript

import { SidebarCreateItem } from "@/components/sidebar/items/all/sidebar-create-item"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { ChatbotUIContext } from "@/context/context"
import { COLLECTION_DESCRIPTION_MAX, COLLECTION_NAME_MAX } from "@/db/limits"
import { TablesInsert } from "@/supabase/types"
import { CollectionFile } from "@/types"
import { FC, useContext, useState } from "react"
import { CollectionFileSelect } from "./collection-file-select"
import { useTranslation } from 'react-i18next'
interface CreateCollectionProps {
isOpen: boolean
onOpenChange: (isOpen: boolean) => void
}
export const CreateCollection: FC<CreateCollectionProps> = ({
isOpen,
onOpenChange
}) => {
const { t } = useTranslation()
const { profile, selectedWorkspace } = useContext(ChatbotUIContext)
const [name, setName] = useState("")
const [isTyping, setIsTyping] = useState(false)
const [description, setDescription] = useState("")
const [selectedCollectionFiles, setSelectedCollectionFiles] = useState<
CollectionFile[]
>([])
const handleFileSelect = (file: CollectionFile) => {
setSelectedCollectionFiles(prevState => {
const isFileAlreadySelected = prevState.find(
selectedFile => selectedFile.id === file.id
)
if (isFileAlreadySelected) {
return prevState.filter(selectedFile => selectedFile.id !== file.id)
} else {
return [...prevState, file]
}
})
}
if (!profile) return null
if (!selectedWorkspace) return null
return (
<SidebarCreateItem
contentType="collections"
createState={
{
collectionFiles: selectedCollectionFiles.map(file => ({
user_id: profile.user_id,
collection_id: "",
file_id: file.id
})),
user_id: profile.user_id,
name,
description
} as TablesInsert<"collections">
}
isOpen={isOpen}
isTyping={isTyping}
onOpenChange={onOpenChange}
renderInputs={() => (
<>
<div className="space-y-1">
<Label>{t("side.files")}</Label>
<CollectionFileSelect
selectedCollectionFiles={selectedCollectionFiles}
onCollectionFileSelect={handleFileSelect}
/>
</div>
<div className="space-y-1">
<Label>{t("side.name")}</Label>
<Input
placeholder="Collection name..."
value={name}
onChange={e => setName(e.target.value)}
maxLength={COLLECTION_NAME_MAX}
/>
</div>
<div className="space-y-1">
<Label>{t("side.description")}</Label>
<Input
placeholder={t("side.collectionDescriptionPlaceholder")}
value={description}
onChange={e => setDescription(e.target.value)}
maxLength={COLLECTION_DESCRIPTION_MAX}
/>
</div>
</>
)}
/>
)
}