Spaces:
No application file
No application file
import { useState } from "react"; | |
import PlusIcon from "../../public/icons/plus.svg"; | |
import CrossIcon from "../../public/icons/cross.svg"; | |
import YoutubeIcon from "../../public/icons/youtube.svg"; | |
import PDFIcon from "../../public/icons/pdf.svg"; | |
import WebIcon from "../../public/icons/web.svg"; | |
import DocIcon from "../../public/icons/doc.svg"; | |
import SitemapIcon from "../../public/icons/sitemap.svg"; | |
import TextIcon from "../../public/icons/text.svg"; | |
export default function SetSources({ | |
setChats, | |
embedding_model, | |
setSelectChat, | |
}) { | |
const [sourceName, setSourceName] = useState(""); | |
const [sourceValue, setSourceValue] = useState(""); | |
const [isDropdownOpen, setIsDropdownOpen] = useState(false); | |
const [isLoading, setIsLoading] = useState(false); | |
const dataTypes = { | |
youtube_video: "YouTube Video", | |
pdf_file: "PDF File", | |
web_page: "Web Page", | |
doc_file: "Doc File", | |
sitemap: "Sitemap", | |
text: "Text", | |
}; | |
const dataIcons = { | |
youtube_video: <YoutubeIcon className="w-5 h-5 mr-3" />, | |
pdf_file: <PDFIcon className="w-5 h-5 mr-3" />, | |
web_page: <WebIcon className="w-5 h-5 mr-3" />, | |
doc_file: <DocIcon className="w-5 h-5 mr-3" />, | |
sitemap: <SitemapIcon className="w-5 h-5 mr-3" />, | |
text: <TextIcon className="w-5 h-5 mr-3" />, | |
}; | |
const handleDropdownClose = () => { | |
setIsDropdownOpen(false); | |
setSourceName(""); | |
setSelectChat(true); | |
}; | |
const handleDropdownSelect = (dataType) => { | |
setSourceName(dataType); | |
setSourceValue(""); | |
setIsDropdownOpen(false); | |
setSelectChat(false); | |
}; | |
const handleAddDataSource = async (e) => { | |
e.preventDefault(); | |
setIsLoading(true); | |
const addDataSourceEntry = { | |
sender: "B", | |
message: `Adding the following ${dataTypes[sourceName]}: ${sourceValue}`, | |
}; | |
setChats((prevChats) => [...prevChats, addDataSourceEntry]); | |
let name = sourceName; | |
let value = sourceValue; | |
setSourceValue(""); | |
const response = await fetch("/api/add_sources", { | |
method: "POST", | |
body: JSON.stringify({ | |
embedding_model, | |
name, | |
value, | |
}), | |
headers: { | |
"Content-Type": "application/json", | |
}, | |
}); | |
if (response.ok) { | |
const successEntry = { | |
sender: "B", | |
message: `Successfully added ${dataTypes[sourceName]}!`, | |
}; | |
setChats((prevChats) => [...prevChats, successEntry]); | |
} else { | |
const errorEntry = { | |
sender: "B", | |
message: `Failed to add ${dataTypes[sourceName]}. Please try again.`, | |
}; | |
setChats((prevChats) => [...prevChats, errorEntry]); | |
} | |
setSourceName(""); | |
setIsLoading(false); | |
setSelectChat(true); | |
}; | |
return ( | |
<> | |
<div className="w-fit"> | |
<button | |
type="button" | |
onClick={() => setIsDropdownOpen(!isDropdownOpen)} | |
className="w-fit p-2.5 rounded-xl text-white bg-black hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300" | |
> | |
<PlusIcon className="w-6 h-6" /> | |
</button> | |
{isDropdownOpen && ( | |
<div className="absolute left-0 bottom-full bg-white border border-gray-300 rounded-lg shadow-lg mb-2"> | |
<ul className="py-1"> | |
<li | |
className="block px-4 py-2 text-sm text-black cursor-pointer hover:bg-gray-200" | |
onClick={handleDropdownClose} | |
> | |
<span className="flex items-center text-red-600"> | |
<CrossIcon className="w-5 h-5 mr-3" /> | |
Close | |
</span> | |
</li> | |
{Object.entries(dataTypes).map(([key, value]) => ( | |
<li | |
key={key} | |
className="block px-4 py-2 text-sm text-black cursor-pointer hover:bg-gray-200" | |
onClick={() => handleDropdownSelect(key)} | |
> | |
<span className="flex items-center"> | |
{dataIcons[key]} | |
{value} | |
</span> | |
</li> | |
))} | |
</ul> | |
</div> | |
)} | |
</div> | |
{sourceName && ( | |
<form | |
onSubmit={handleAddDataSource} | |
className="w-full flex flex-col sm:flex-row gap-y-2 gap-x-2 items-center" | |
> | |
<div className="w-full"> | |
<input | |
type="text" | |
placeholder="Enter URL, Data or File path here..." | |
className="text-sm w-full border-2 border-black rounded-xl focus:outline-none focus:border-blue-800 sm:pl-4 h-11" | |
required | |
value={sourceValue} | |
onChange={(e) => setSourceValue(e.target.value)} | |
/> | |
</div> | |
<div className="w-full sm:w-fit"> | |
<button | |
type="submit" | |
disabled={isLoading} | |
className={`${ | |
isLoading ? "opacity-60" : "" | |
} w-full bg-black hover:bg-blue-800 rounded-xl text-lg text-white px-6 h-11`} | |
> | |
Send | |
</button> | |
</div> | |
</form> | |
)} | |
</> | |
); | |
} | |