Add our first view via Next.js for Agents (#817)

Initialize our migration to use Next.js for front-end views via Agents. This includes setup for getting authenticated users, reading in available agents, setting up a pop-up modal when you're clicking on an agent, and allowing users to start new conversations with agents.

Best attempt at an in-place migration, though there are some noticeable differences.

Also adds view for chat that are not being used, but in experimental phase.
This commit is contained in:
sabaimran
2024-06-27 01:26:16 -07:00
committed by GitHub
parent 8c12a69570
commit 3b7a9358c3
22 changed files with 1900 additions and 24 deletions

View File

@@ -0,0 +1,106 @@
'use client'
import styles from './chat.module.css';
import React, { Suspense, useEffect, useState } from 'react';
import SuggestionCard from '../components/suggestions/suggestionCard';
import SidePanel from '../components/sidePanel/chatHistorySidePanel';
import ChatHistory from '../components/chatHistory/chatHistory';
import { SingleChatMessage } from '../components/chatMessage/chatMessage';
import NavMenu from '../components/navMenu/navMenu';
import { useSearchParams } from 'next/navigation'
import ReferencePanel, { hasValidReferences } from '../components/referencePanel/referencePanel';
import 'katex/dist/katex.min.css';
interface ChatOptions {
[key: string]: string
}
const styleClassOptions = ['pink', 'blue', 'green', 'yellow', 'purple'];
function ChatBodyData({ chatOptionsData }: { chatOptionsData: ChatOptions | null }) {
const searchParams = useSearchParams();
const conversationId = searchParams.get('conversationId');
const [showReferencePanel, setShowReferencePanel] = useState(true);
const [referencePanelData, setReferencePanelData] = useState<SingleChatMessage | null>(null);
if (!conversationId) {
return (
<div className={styles.suggestions}>
{chatOptionsData && Object.entries(chatOptionsData).map(([key, value]) => (
<SuggestionCard
key={key}
title={`/${key}`}
body={value}
link='#' // replace with actual link if available
styleClass={styleClassOptions[Math.floor(Math.random() * styleClassOptions.length)]}
/>
))}
</div>
);
}
return(
<div className={(hasValidReferences(referencePanelData) && showReferencePanel) ? styles.chatBody : styles.chatBodyFull}>
<ChatHistory conversationId={conversationId} setReferencePanelData={setReferencePanelData} setShowReferencePanel={setShowReferencePanel} />
{
(hasValidReferences(referencePanelData) && showReferencePanel) &&
<ReferencePanel referencePanelData={referencePanelData} setShowReferencePanel={setShowReferencePanel} />
}
</div>
);
}
function Loading() {
return <h2>🌀 Loading...</h2>;
}
function handleChatInput(e: React.FormEvent<HTMLInputElement>) {
const target = e.target as HTMLInputElement;
}
export default function Chat() {
const [chatOptionsData, setChatOptionsData] = useState<ChatOptions | null>(null);
const [isLoading, setLoading] = useState(true)
useEffect(() => {
fetch('/api/chat/options')
.then(response => response.json())
.then((data: ChatOptions) => {
setLoading(false);
// Render chat options, if any
if (data) {
setChatOptionsData(data);
}
})
.catch(err => {
console.error(err);
return;
});
}, []);
return (
<div className={styles.main + " " + styles.chatLayout}>
<div className={styles.sidePanel}>
<SidePanel />
</div>
<div className={styles.chatBox}>
<title>
Khoj AI - Chat
</title>
<NavMenu selected="Chat" />
<div>
<Suspense fallback={<Loading />}>
<ChatBodyData chatOptionsData={chatOptionsData} />
</Suspense>
</div>
<div className={styles.inputBox}>
<input className={styles.inputBox} type="text" placeholder="Type here..." onInput={(e) => handleChatInput(e)} />
<button className={styles.inputBox}>Send</button>
</div>
</div>
</div>
)
}