import { useState, useRef, useEffect, FormEvent, KeyboardEvent} from "react"; import Head from "next/head"; import styles from "../styles/Home.module.css"; import Image from "next/image"; import ReactMarkdown from "react-markdown"; import CircularProgress from "@mui/material/CircularProgress"; import Link from "next/link"; export default function Home() { const [userInput, setUserInput] = useState(""); const [loading, setLoading] = useState(false); const [messages, setMessages] = useState([ { role: "assistant", content: "Hi there! How can I help?" }, ]); const messageListRef = useRef(null); const textAreaRef = useRef(null); // Auto scroll chat to bottom useEffect(() => { if (messageListRef.current) { const messageList = messageListRef.current; messageList.scrollTop = messageList.scrollHeight; } }, [messages]); // Focus on input field useEffect(() => { if (textAreaRef.current) { textAreaRef.current.focus(); } }, []); // Handle errors const handleError = () => { setMessages((prevMessages) => [ ...prevMessages, { role: "assistant", content: "Oops! There seems to be an error. Please try again.", }, ]); setLoading(false); setUserInput(""); }; // Handle form submission const handleSubmit = async (e: FormEvent) => { e.preventDefault(); if (userInput.trim() === "") { return; } setLoading(true); const context = [...messages, { role: "user", content: userInput }]; setMessages(context); // Send chat history to API const response = await fetch("/api/chat", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ messages: context }), }); // Reset user input setUserInput(""); const data = await response.json(); if (!data) { handleError(); return; } setMessages((prevMessages) => [ ...prevMessages, { role: "assistant", content: data.result.content }, ]); setLoading(false); }; // Prevent blank submissions and allow for multiline input const handleEnter = (e: KeyboardEvent) => { if (e.key === "Enter" && userInput) { if (!e.shiftKey && userInput) { handleSubmit(e); } } else if (e.key === "Enter") { e.preventDefault(); } }; return ( <> Willow Sage
{messages.map((message, index) => { return ( // The latest message sent by the user will be animated while waiting for a response
{/* Display the correct icon depending on the message type */} {message.role === "assistant" ? ( AI ) : ( Me )}
{/* Messages are being rendered in Markdown format */} {message.content}
); })}