import React, { useState, useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import Arrow2 from './assets/dropdown-arrow.svg'; import ArrowLeft from './assets/arrow-left.svg'; import ArrowRight from './assets/arrow-right.svg'; import Trash from './assets/trash.svg'; import { selectPrompt, setPrompt, selectSourceDocs, } from './preferences/preferenceSlice'; import { Doc } from './preferences/preferenceApi'; type PromptProps = { prompts: { name: string; id: string; type: string }[]; selectedPrompt: { name: string; id: string }; onSelectPrompt: (name: string, id: string) => void; onAddPrompt: (name: string) => void; newPromptName: string; onNewPromptNameChange: (name: string) => void; isAddPromptModalOpen: boolean; onToggleAddPromptModal: () => void; onDeletePrompt: (name: string, id: string) => void; }; const Setting: React.FC = () => { const tabs = ['General', 'Prompts', 'Documents']; //const tabs = ['General', 'Prompts', 'Documents', 'Widgets']; const [activeTab, setActiveTab] = useState('General'); const [prompts, setPrompts] = useState< { name: string; id: string; type: string }[] >([]); const selectedPrompt = useSelector(selectPrompt); const [newPromptName, setNewPromptName] = useState(''); const [isAddPromptModalOpen, setAddPromptModalOpen] = useState(false); const documents = useSelector(selectSourceDocs); const [isAddDocumentModalOpen, setAddDocumentModalOpen] = useState(false); const [newDocument, setNewDocument] = useState({ name: '', vectorDate: '', vectorLocation: '', }); const dispatch = useDispatch(); const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; const [widgetScreenshot, setWidgetScreenshot] = useState(null); const updateWidgetScreenshot = (screenshot: File | null) => { setWidgetScreenshot(screenshot); }; // Function to toggle the Add Document modal const toggleAddDocumentModal = () => { setAddDocumentModalOpen(!isAddDocumentModalOpen); }; useEffect(() => { const fetchPrompts = async () => { try { const response = await fetch(`${apiHost}/api/get_prompts`); if (!response.ok) { throw new Error('Failed to fetch prompts'); } const promptsData = await response.json(); setPrompts(promptsData); } catch (error) { console.error(error); } }; fetchPrompts(); }, []); const onDeletePrompt = (name: string, id: string) => { setPrompts(prompts.filter((prompt) => prompt.id !== id)); fetch(`${apiHost}/api/delete_prompt`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, // send id in body only body: JSON.stringify({ id: id }), }) .then((response) => { if (!response.ok) { throw new Error('Failed to delete prompt'); } }) .catch((error) => { console.error(error); }); }; const handleDeleteClick = (index: number, doc: Doc) => { const docPath = 'indexes/' + 'local' + '/' + doc.name; fetch(`${apiHost}/api/delete_old?path=${docPath}`, { method: 'GET', }) .then(() => { // remove the image element from the DOM const imageElement = document.querySelector( `#img-${index}`, ) as HTMLElement; const parentElement = imageElement.parentNode as HTMLElement; parentElement.parentNode?.removeChild(parentElement); }) .catch((error) => console.error(error)); }; return (

Settings

{tabs.map((tab, index) => ( ))}
{renderActiveTab()} {/* {activeTab === 'Widgets' && ( )} */}
); function scrollTabs(direction: number) { const container = document.querySelector('.flex-nowrap'); if (container) { container.scrollLeft += direction * 100; // Adjust the scroll amount as needed } } function renderActiveTab() { switch (activeTab) { case 'General': return ; case 'Prompts': return ( dispatch(setPrompt({ name: name, id: id })) } onAddPrompt={addPrompt} newPromptName={''} onNewPromptNameChange={function (name: string): void { throw new Error('Function not implemented.'); }} isAddPromptModalOpen={false} onToggleAddPromptModal={function (): void { throw new Error('Function not implemented.'); }} onDeletePrompt={onDeletePrompt} /> ); case 'Documents': return ( ); case 'Widgets': return ( ); default: return null; } } function addPrompt(name: string) { if (name) { setNewPromptName(''); toggleAddPromptModal(); } } function toggleAddPromptModal() { setAddPromptModalOpen(!isAddPromptModalOpen); } }; const General: React.FC = () => { const themes = ['Light']; const languages = ['English']; const [selectedTheme, setSelectedTheme] = useState(themes[0]); const [selectedLanguage, setSelectedLanguage] = useState(languages[0]); return (

Select Theme

Select Language

); }; export default Setting; const Prompts: React.FC = ({ prompts, selectedPrompt, onSelectPrompt, onAddPrompt, onDeletePrompt, }) => { const [isAddPromptModalOpen, setAddPromptModalOpen] = useState(false); const [newPromptName, setNewPromptName] = useState(''); const openAddPromptModal = () => { setAddPromptModalOpen(true); }; const closeAddPromptModal = () => { setAddPromptModalOpen(false); }; const handleSelectPrompt = (name: string) => { const selected = prompts.find((prompt) => prompt.name === name); if (selected) { onSelectPrompt(selected.name, selected.id); } }; const handleDeletePrompt = (name: string) => { const selected = prompts.find((prompt) => prompt.name === name); if (selected) { onDeletePrompt(selected.name, selected.id); } }; return (

Active Prompt

{/*
*/} {isAddPromptModalOpen && ( { onAddPrompt(newPromptName); closeAddPromptModal(); }} onClose={closeAddPromptModal} /> )}
); }; function DropdownPrompt({ options, selectedValue, onSelect, showDelete, onDelete, }: { options: { name: string; id: string; type: string }[]; selectedValue: string; onSelect: (value: string) => void; showDelete?: boolean; onDelete: (value: string) => void; }) { const [isOpen, setIsOpen] = useState(false); return (
{isOpen && (
{options.map((option, index) => (
{ onSelect(option.name); setIsOpen(false); }} className="ml-2 flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap py-3" > {option.name} {showDelete && option.type === 'private' && ( )}
))}
)}
); } function Dropdown({ options, selectedValue, onSelect, showDelete, onDelete, }: { options: string[]; selectedValue: string; onSelect: (value: string) => void; showDelete?: boolean; // optional onDelete?: (value: string) => void; // optional }) { const [isOpen, setIsOpen] = useState(false); return (
{isOpen && (
{options.map((option, index) => (
{ onSelect(option); setIsOpen(false); }} className="ml-2 flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap py-3" > {option} {showDelete && onDelete && ( )}
))}
)}
); } type AddPromptModalProps = { newPromptName: string; onNewPromptNameChange: (name: string) => void; onAddPrompt: () => void; onClose: () => void; }; const AddPromptModal: React.FC = ({ newPromptName, onNewPromptNameChange, onAddPrompt, onClose, }) => { return (

Add New Prompt

onNewPromptNameChange(e.target.value)} className="mb-4 w-full rounded-3xl border-2 p-2" />
); }; type DocumentsProps = { documents: Doc[] | null; handleDeleteDocument: (index: number, document: Doc) => void; }; const Documents: React.FC = ({ documents, handleDeleteDocument, }) => { return (
{/*

Documents

*/}
{documents && documents.map((document, index) => ( ))}
Document Name Vector Date Type
{document.name} {document.date} {document.location === 'remote' ? 'Pre-loaded' : 'Private'} {document.location !== 'remote' && ( Delete { event.stopPropagation(); handleDeleteDocument(index, document); }} /> )}
{/* */}
{/* {isAddDocumentModalOpen && ( )} */}
); }; type Document = { name: string; vectorDate: string; vectorLocation: string; }; // Modal for adding a new document type AddDocumentModalProps = { newDocument: Document; onNewDocumentChange: (document: Document) => void; onAddDocument: () => void; onClose: () => void; }; const AddDocumentModal: React.FC = ({ newDocument, onNewDocumentChange, onAddDocument, onClose, }) => { return (

Add New Document

onNewDocumentChange({ ...newDocument, name: e.target.value }) } className="mb-4 w-full rounded-lg border-2 p-2" /> onNewDocumentChange({ ...newDocument, vectorDate: e.target.value }) } className="mb-4 w-full rounded-lg border-2 p-2" /> onNewDocumentChange({ ...newDocument, vectorLocation: e.target.value, }) } className="mb-4 w-full rounded-lg border-2 p-2" />
); }; const Widgets: React.FC<{ widgetScreenshot: File | null; onWidgetScreenshotChange: (screenshot: File | null) => void; }> = ({ widgetScreenshot, onWidgetScreenshotChange }) => { const widgetSources = ['Source 1', 'Source 2', 'Source 3']; const widgetMethods = ['Method 1', 'Method 2', 'Method 3']; const widgetTypes = ['Type 1', 'Type 2', 'Type 3']; const [selectedWidgetSource, setSelectedWidgetSource] = useState( widgetSources[0], ); const [selectedWidgetMethod, setSelectedWidgetMethod] = useState( widgetMethods[0], ); const [selectedWidgetType, setSelectedWidgetType] = useState(widgetTypes[0]); // const [widgetScreenshot, setWidgetScreenshot] = useState(null); const [widgetCode, setWidgetCode] = useState(''); // Your widget code state const handleScreenshotChange = ( event: React.ChangeEvent, ) => { const files = event.target.files; if (files && files.length > 0) { const selectedScreenshot = files[0]; onWidgetScreenshotChange(selectedScreenshot); // Update the screenshot in the parent component } }; const handleCopyToClipboard = () => { // Create a new textarea element to select the text const textArea = document.createElement('textarea'); textArea.value = widgetCode; document.body.appendChild(textArea); // Select and copy the text textArea.select(); document.execCommand('copy'); // Clean up the textarea element document.body.removeChild(textArea); }; return (

Widget Source

Widget Method

Widget Type

Widget Code Snippet