🚀 Styling

This commit is contained in:
Asim Shrestha
2023-04-07 21:48:53 -07:00
parent e4588d9606
commit dd9cb41d46
3 changed files with 65 additions and 28 deletions

View File

@@ -1,6 +1,7 @@
import cx from "classnames"; import cx from "classnames";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import React, { useEffect, useRef } from "react"; import React, { useEffect, useRef } from "react";
import { FaBrain, FaListAlt, FaPlayCircle, FaStar } from "react-icons/fa";
interface ChatWindowProps { interface ChatWindowProps {
children?: ReactNode; children?: ReactNode;
@@ -34,6 +35,8 @@ const ChatWindow = ({ messages, children, className }: ChatWindowProps) => {
<ChatMessage key={`${index}-${message.type}`} message={message} /> <ChatMessage key={`${index}-${message.type}`} message={message} />
))} ))}
{children} {children}
<ChatMessage message={{ type: "thinking", value: "" }} />
</div> </div>
</div> </div>
); );
@@ -53,16 +56,42 @@ const MacWindowHeader = () => {
const ChatMessage = ({ message }: { message: Message }) => { const ChatMessage = ({ message }: { message: Message }) => {
return ( return (
<div className="mx-4 my-1 rounded-lg border-[1px] border-transparent bg-white/20 p-3 font-mono hover:border-[#1E88E5]"> <div className="mx-4 my-1 rounded-lg border-[2px] border-white/10 bg-white/20 p-3 font-mono hover:border-[#1E88E5]">
<span> <div className="mr-2 inline-block h-[0.9em]">
{message.type === "goal" ? "🌟 Embarking on a new goal: " : ""} {getMessageIcon(message)}
{message.type === "task" ? "📝 Adding task: " : ""} </div>
</span> <span className="mr-2 font-bold">{getMessagePrefix(message)}</span>
<span className="font-black">{message.value}</span> <span>{message.value}</span>
</div> </div>
); );
}; };
const getMessageIcon = (message: Message) => {
switch (message.type) {
case "goal":
return <FaStar />;
case "task":
return <FaListAlt />;
case "thinking":
return <FaBrain className="mt-[0.1em]" />;
case "action":
return <FaPlayCircle />;
}
};
const getMessagePrefix = (message: Message) => {
switch (message.type) {
case "goal":
return "Embarking on a new goal:";
case "task":
return "Added task:";
case "thinking":
return "Thinking...";
case "action":
return "Executing action:";
}
};
export interface Message { export interface Message {
type: "goal" | "thinking" | "task" | "action"; type: "goal" | "thinking" | "task" | "action";
value: string; value: string;

View File

@@ -5,9 +5,16 @@ interface InputProps {
value: string; value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void; onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
placeholder?: string; placeholder?: string;
disabled?: boolean;
} }
const Input = ({ placeholder, left, value, onChange }: InputProps) => { const Input = ({
placeholder,
left,
value,
onChange,
disabled,
}: InputProps) => {
return ( return (
<div className="flex w-full items-center rounded-xl bg-[#3a3a3a] font-mono text-lg text-white/75 shadow-2xl"> <div className="flex w-full items-center rounded-xl bg-[#3a3a3a] font-mono text-lg text-white/75 shadow-2xl">
{left != null ? ( {left != null ? (
@@ -16,11 +23,15 @@ const Input = ({ placeholder, left, value, onChange }: InputProps) => {
</div> </div>
) : null} ) : null}
<input <input
className="border:black delay-50 w-full rounded-xl rounded-l-none border-[2px] border-white/10 bg-transparent px-2 py-3 tracking-wider outline-0 transition-all placeholder:text-white/20 hover:border-[#1E88E5]/25 focus:border-[#1E88E5]" className={
"border:black delay-50 w-full rounded-xl rounded-l-none border-[2px] border-white/10 bg-transparent px-2 py-3 tracking-wider outline-0 transition-all placeholder:text-white/20 hover:border-[#1E88E5]/25 focus:border-[#1E88E5]" +
(disabled ? " cursor-not-allowed hover:border-white/10" : "")
}
placeholder={placeholder} placeholder={placeholder}
type="text" type="text"
value={value} value={value}
onChange={onChange} onChange={onChange}
disabled={disabled}
/> />
</div> </div>
); );

View File

@@ -4,7 +4,6 @@ import DefaultLayout from "../layout/default";
import React from "react"; import React from "react";
import type { Message } from "../components/ChatWindow"; import type { Message } from "../components/ChatWindow";
import ChatWindow, { import ChatWindow, {
ChatMessage,
CreateGoalMessage, CreateGoalMessage,
CreateTaskMessage, CreateTaskMessage,
} from "../components/ChatWindow"; } from "../components/ChatWindow";
@@ -13,29 +12,24 @@ import Drawer from "../components/Drawer";
import Input from "../components/Input"; import Input from "../components/Input";
import Button from "../components/Button"; import Button from "../components/Button";
import { FaRobot, FaStar } from "react-icons/fa"; import { FaRobot, FaStar } from "react-icons/fa";
import { VscLoading } from "react-icons/vsc";
import type AutonomousAgent from "../components/AutonomousAgent";
const Home: NextPage = () => { const Home: NextPage = () => {
const [loading, setLoading] = React.useState<boolean>(false);
const [name, setName] = React.useState<string>(""); const [name, setName] = React.useState<string>("");
const [goalInput, setGoalInput] = React.useState<string>(""); const [goalInput, setGoalInput] = React.useState<string>("");
const [agent, setAgent] = React.useState<AutonomousAgent | null>(null);
const [messages, setMessages] = React.useState<Message[]>([]); const [messages, setMessages] = React.useState<Message[]>([]);
const [goal, setGoal] = React.useState<string>("");
const handleNewGoal = async () => { const handleNewGoal = async () => {
setLoading(true);
setGoal(goalInput);
setMessages([...messages, CreateGoalMessage(goalInput)]); setMessages([...messages, CreateGoalMessage(goalInput)]);
const res = await axios.post( const res = await axios.post(`/api/chain`, { prompt: goalInput });
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`${process.env.NEXT_PUBLIC_BACKEND_URL}/api/chain?prompt=test`,
{ prompt: goalInput }
);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-member-access // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-member-access
const tasks: string[] = JSON.parse(res.data.tasks); const tasks: string[] = JSON.parse(res.data.tasks);
setMessages((prev) => [...prev, ...tasks.map(CreateTaskMessage)]); setMessages((prev) => [...prev, ...tasks.map(CreateTaskMessage)]);
setLoading(false);
}; };
return ( return (
@@ -62,13 +56,7 @@ const Home: NextPage = () => {
</div> </div>
</div> </div>
<ChatWindow className="m-10" messages={messages}> <ChatWindow className="m-10" messages={messages} />
{loading ? (
<ChatMessage
message={{ type: "action", value: "🧠 Thinking..." }}
/>
) : null}
</ChatWindow>
<Input <Input
left={ left={
@@ -78,6 +66,7 @@ const Home: NextPage = () => {
</> </>
} }
value={name} value={name}
disabled={agent != null}
onChange={(e) => setName(e.target.value)} onChange={(e) => setName(e.target.value)}
placeholder="AgentGPT (Note: this field doesn't do anything right now)" placeholder="AgentGPT (Note: this field doesn't do anything right now)"
/> />
@@ -89,17 +78,25 @@ const Home: NextPage = () => {
<span className="ml-2">Goal:</span> <span className="ml-2">Goal:</span>
</> </>
} }
disabled={agent != null}
value={goalInput} value={goalInput}
onChange={(e) => setGoalInput(e.target.value)} onChange={(e) => setGoalInput(e.target.value)}
placeholder="Make the world a better place." placeholder="Make the world a better place."
/> />
<Button <Button
disabled={goalInput === ""} disabled={agent != null || name === "" || goalInput === ""}
onClick={() => void handleNewGoal()} onClick={() => void handleNewGoal()}
className="mt-10" className="mt-10"
> >
Deploy Agent {agent == null ? (
"Deploy Agent"
) : (
<>
<VscLoading className="animate-spin" size={20} />
<span className="ml-2">Agent running</span>
</>
)}
</Button> </Button>
</div> </div>
</div> </div>