Skip to content

Commit f2cb298

Browse files
DEVT-37: updated chat ui (#52)
Co-authored-by: austint-code <austintan2006@gmail.com>
1 parent 6d8e067 commit f2cb298

File tree

11 files changed

+735
-86
lines changed

11 files changed

+735
-86
lines changed
Lines changed: 76 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,114 @@
11
"use client";
22
import { useState } from "react";
3+
import {
4+
ChatBubble,
5+
ChatBubbleAvatar,
6+
ChatBubbleMessage,
7+
} from "@shared/components/ui/chat/chat-bubble";
8+
import { ChatMessageList } from "@shared/components/ui/chat/chat-message-list";
9+
import { ChatInput } from "@shared/components/ui/chat/chat-input";
10+
import { Button } from "@/shared/components/ui/button";
11+
312
import {
413
ChatClientWithSession,
514
RagFlowMessage,
615
RagFlowMessages,
716
sendMessage,
817
} from "@shared/lib/ragflow/chat/chat-client";
918
import { toast } from "@shared/hooks/use-toast";
19+
import LogoComponent from "@/shared/components/Logo";
20+
import { SendIcon } from "lucide-react";
1021

11-
function MessageBox(props: {
22+
interface MessageBoxProps {
1223
chatClient: ChatClientWithSession;
1324
messageHistory: RagFlowMessages | null;
14-
}) {
15-
const [value, setValue] = useState("");
25+
}
1626

17-
const [messages, setMessage] = useState<RagFlowMessages>(
18-
props.messageHistory ? props.messageHistory : []
27+
export default function MessageBox({
28+
chatClient,
29+
messageHistory,
30+
}: MessageBoxProps) {
31+
const [value, setValue] = useState("");
32+
const [messages, setMessages] = useState<RagFlowMessages>(
33+
messageHistory || []
1934
);
35+
const [isLoading, setIsLoading] = useState(false);
2036

21-
async function handle() {
22-
const ownMessage = { role: "user", content: value } as RagFlowMessage;
23-
24-
setMessage((oldArray) => [...oldArray, ownMessage]);
37+
async function handleSend() {
38+
if (!value.trim()) return;
2539

40+
const userMessage: RagFlowMessage = { role: "user", content: value };
41+
setMessages((prev) => [...prev, userMessage]);
2642
setValue("");
43+
setIsLoading(true);
44+
const response = await sendMessage(chatClient, value);
45+
setIsLoading(false);
2746

28-
const messageResponse = await sendMessage(props.chatClient, value);
29-
30-
if (!messageResponse.ragflowCallSuccess) {
47+
if (!response.ragflowCallSuccess) {
3148
toast({
3249
title: "Error sending message",
33-
description: `Please try refreshing the page`,
50+
description: "Please try refreshing the page",
3451
duration: 10000,
3552
variant: "destructive",
3653
});
3754
return;
3855
}
3956

40-
const messageData = {
57+
const assistantMessage: RagFlowMessage = {
4158
role: "assistant",
42-
content: messageResponse.response,
43-
} as RagFlowMessage;
44-
45-
setMessage((oldArray) => [...oldArray, messageData]);
46-
// console.log("response thingy2", messages);
59+
content: response.response,
60+
};
61+
setMessages((prev) => [...prev, assistantMessage]);
4762
}
4863

4964
return (
50-
<div className="min-h-screen w-1/2 flex-col justify-self-center p-4 text-gray-800 dark:text-white">
51-
<h1 className="mb-4 text-2xl font-bold">Chat:</h1>
52-
53-
<div className="flex-col rounded-t-lg bg-gray-100 p-3">
54-
{messages.map((aMessage, idx) => (
55-
<div
56-
key={idx}
57-
className={`my-2 max-w-md rounded-lg p-3 shadow-md ${
58-
aMessage.role != "assistant"
59-
? "justify-self-end bg-green-200 hover:bg-green-300"
60-
: "justify-self-start bg-blue-200 hover:bg-blue-300"
61-
}`}
62-
>
63-
<p className="font-medium text-gray-800">{aMessage.content}</p>
64-
</div>
65-
))}
65+
<div className="flex h-[600px] w-11/12 flex-col place-self-center rounded border p-4 text-gray-800 shadow dark:text-white">
66+
<LogoComponent
67+
className={"size-24 place-self-center stroke-black stroke-[10px]"}
68+
/>
69+
{/* doesn't seem like 400 px does much */}
70+
<div className="h-[400px] flex-1 overflow-auto">
71+
<ChatMessageList smooth>
72+
{messages.map((msg, index) => (
73+
<ChatBubble
74+
key={index}
75+
variant={msg.role === "assistant" ? "received" : "sent"}
76+
>
77+
{msg.role === "assistant" ? (
78+
<ChatBubbleAvatar fallback="AI" />
79+
) : (
80+
<ChatBubbleAvatar fallback="Me" />
81+
)}
82+
<ChatBubbleMessage
83+
variant={msg.role === "assistant" ? "received" : "sent"}
84+
className="p-2"
85+
>
86+
{msg.content}
87+
</ChatBubbleMessage>
88+
</ChatBubble>
89+
))}
90+
{isLoading && (
91+
<ChatBubble variant="received">
92+
<ChatBubbleAvatar fallback="AI" />
93+
<ChatBubbleMessage isLoading variant="received" />
94+
</ChatBubble>
95+
)}
96+
</ChatMessageList>
6697
</div>
67-
{/* <div className="justify-self-end"> */}
68-
<div className="flex items-center rounded-b-lg bg-gray-200 px-4 py-2 dark:bg-gray-700">
69-
<textarea
70-
id="chat"
71-
rows={1}
72-
className="mx-2 block w-full rounded-lg border border-gray-300 bg-white p-2.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-800 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
73-
placeholder="Your message..."
98+
<div className="relative mt-4">
99+
<ChatInput
74100
value={value}
75-
onChange={(e) => {
76-
setValue(e.target.value);
77-
}}
78-
></textarea>
79-
<button
80-
onClick={handle}
81-
className="inline-flex cursor-pointer justify-center rounded-full p-2 text-blue-600 hover:bg-blue-100 dark:text-blue-500 dark:hover:bg-gray-600"
82-
>
83-
<svg
84-
className="h-5 w-5 rotate-90 rtl:-rotate-90"
85-
aria-hidden="true"
86-
xmlns="http://www.w3.org/2000/svg"
87-
fill="currentColor"
88-
viewBox="0 0 18 20"
89-
>
90-
<path d="m17.914 18.594-8-18a1 1 0 0 0-1.828 0l-8 18a1 1 0 0 0 1.157 1.376L8 18.281V9a1 1 0 0 1 2 0v9.281l6.758 1.689a1 1 0 0 0 1.156-1.376Z" />
91-
</svg>
92-
<span className="sr-only">Send message</span>
93-
</button>
94-
95-
{/* <input
96-
type="text"
97-
placeholder="Type your message here..."
98-
className="w-100 rounded-md border border-gray-300 p-2 dark:bg-gray-700 dark:text-white"
99-
value={value}
100-
onChange={(e) => {
101-
setValue(e.target.value);
102-
}}
101+
onChange={(e) => setValue(e.target.value)}
102+
placeholder="Type your message..."
103103
/>
104-
105-
<button
106-
className="ml-4 mt-2 rounded-md bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"
107-
onClick={handle}
104+
<Button
105+
onClick={handleSend}
106+
size="default"
107+
className="absolute right-2 top-1/2 -translate-y-1/2"
108108
>
109-
Send
110-
</button> */}
109+
Send <SendIcon />
110+
</Button>
111111
</div>
112112
</div>
113113
);
114114
}
115-
116-
export default MessageBox;

app/classroom/[classroomId]/chat/page.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from "@shared/lib/ragflow/chat/chat-client";
1010
import { personalChatConfigTemplate } from "@shared/lib/ragflow/chat/chat-configs";
1111
import { Button } from "@shared/components/ui/button";
12-
import { Upload } from "lucide-react";
12+
import { SpeechIcon, Upload } from "lucide-react";
1313

1414
export default async function ChatPage({
1515
params,
@@ -30,7 +30,7 @@ export default async function ChatPage({
3030
const { classroomId } = await params;
3131
const classroomIdNum = Number(classroomId);
3232
const user = userAndClassData.userData;
33-
const username = user.user_metadata?.full_name ?? "User Name";
33+
// const username = user.user_metadata?.full_name ?? "User Name";
3434

3535
const classroomInfo = userAndClassData.classroomsData.find(
3636
(x) => x.id === classroomIdNum
@@ -150,7 +150,7 @@ export default async function ChatPage({
150150
<strong>Chat Assistant ID:</strong> {chatAssistantId} <br></br>
151151
<strong>Chat Session ID:</strong> {chatSessionId}
152152
</p> */}
153-
<p>
153+
{/* <p>
154154
<strong>Welcome to: </strong>
155155
{classroomInfo.name}, <strong>{username}</strong> <br />
156156
<strong>Ragflow Dataset ID:</strong> {datasetClient.client.datasetId}{" "}
@@ -159,7 +159,13 @@ export default async function ChatPage({
159159
<br />
160160
<strong>Chat Session ID:</strong>{" "}
161161
{(chatClient.client as ChatClientWithSession).sessionId}
162-
</p>
162+
</p> */}
163+
<h2 className="text-3xl font-bold tracking-tight">
164+
{classroomInfo.name}
165+
</h2>
166+
<h1 className="flex flex-row gap-4 text-2xl font-medium tracking-tight text-muted-foreground">
167+
<SpeechIcon className="mb-8 self-center" /> Personal Assistant
168+
</h1>
163169

164170
<MessageBox
165171
chatClient={chatClient.client as ChatClientWithSession}

shared/components/Logo.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const LogoComponent = ({ className }: { className: string }) => (
77
viewBox="0 0 892.69 723.06"
88
className={className}
99
>
10-
<path d="m773.83 446.71-.12.12v-.12h.12zM382.15 419.42c-1.54 0-3.1-.17-4.64-.51-5.51-1.23-10.21-4.53-13.23-9.29l-27.94-43.98c-3.02-4.76-4.02-10.41-2.79-15.92 1.23-5.5 4.53-10.2 9.29-13.23l187.12-118.86c9.83-6.25 22.91-3.32 29.15 6.51l27.94 43.99a20.95 20.95 0 0 1 2.79 15.92c-1.23 5.5-4.53 10.2-9.29 13.23L393.43 416.14c-3.43 2.18-7.32 3.3-11.28 3.3Zm159.14-184.69c-.14 0-.27.04-.39.11L353.79 353.7c-.06.04-.25.16-.32.46-.07.29.06.48.1.54l27.94 43.99c.04.06.16.26.45.32.28.06.49-.06.55-.1l187.12-118.86c.06-.04.25-.16.32-.46.07-.29-.06-.48-.1-.54s-27.94-43.99-27.94-43.99a.733.733 0 0 0-.61-.34Z" />
10+
<path d="m 546 215 z M 382.15 419.42 c -1.54 0 -3.1 -0.17 -4.64 -0.51 c -5.51 -1.23 -10.21 -4.53 -13.23 -9.29 l -27.94 -43.98 c -3.02 -4.76 -4.02 -10.41 -2.79 -15.92 c 1.23 -5.5 4.53 -10.2 9.29 -13.23 l 187.12 -118.86 c 9.83 -6.25 22.91 -3.32 29.15 6.51 l 27.94 43.99 a 20.95 20.95 0 0 1 2.79 15.92 c -1.23 5.5 -4.53 10.2 -9.29 13.23 L 393.43 416.14 c -3.43 2.18 -7.32 3.3 -11.28 3.3 Z m 159.14 -184.69 c -0.14 0 -0.27 0.04 -0.39 0.11 L 353.79 353.7 c -0.06 0.04 -0.25 0.16 -0.32 0.46 c -0.07 0.29 0.06 0.48 0.1 0.54 l 27.94 43.99 c 0.04 0.06 0.16 0.26 0.45 0.32 c 0.28 0.06 0.49 -0.06 0.55 -0.1 l 187.12 -118.86 c 0.06 -0.04 0.25 -0.16 0.32 -0.46 c 0.07 -0.29 -0.06 -0.48 -0.1 -0.54 s -27.94 -43.99 -27.94 -43.99 a 0.733 0.733 0 0 0 -0.61 -0.34 Z" />{" "}
1111
<path d="M305.24 435.71c-6.62 0-12.81-3.33-16.5-9.13-4.46-7.03-4.09-15.84.96-22.46l46.56-61.07 16.22 12.36-45.35 59.49 73.12-15.77 6.55 20.29-77.31 15.83c-1.42.31-2.84.45-4.24.45Z" />
1212
<path d="M291.2 641.83h-.03c-10.97 0-20.65-6.94-25.27-18.08l-30.01-72.33h-45.94c-47.9 0-86.87-45.85-86.87-102.2V215.03c0-56.35 38.97-102.2 86.87-102.2h479.17c47.9 0 86.87 45.85 86.87 102.2H735.6c0-45.11-29.82-81.81-66.48-81.81H189.95c-36.66 0-66.48 36.7-66.48 81.81v234.19c0 45.11 29.82 81.81 66.48 81.81h59.56l35.23 84.91c1.42 3.44 3.84 5.5 6.46 5.5 2.63 0 5.06-2.06 6.5-5.51l35.22-84.9h120.61v20.39h-107l-30.01 72.33c-4.65 11.16-14.35 18.08-25.32 18.08Z" />
1313
<path d="M745.8 311.93c-27.28 0-49.48-22.2-49.48-49.48s22.2-49.48 49.48-49.48 49.48 22.2 49.48 49.48-22.2 49.48-49.48 49.48Zm0-78.57c-16.04 0-29.09 13.05-29.09 29.09s13.05 29.09 29.09 29.09 29.09-13.05 29.09-29.09-13.05-29.09-29.09-29.09ZM468.73 446.72h24.22v106.19h-24.22z" />

0 commit comments

Comments
 (0)