-
Notifications
You must be signed in to change notification settings - Fork 5k
/
Copy pathChat.tsx
104 lines (96 loc) · 3.73 KB
/
Chat.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { useState } from "react";
import { useParams } from "react-router-dom";
import { useMutation } from "@tanstack/react-query";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import "./App.css";
type TextResponse = {
text: string;
user: string;
};
export default function Chat() {
const { agentId } = useParams();
const [input, setInput] = useState("");
const [messages, setMessages] = useState<TextResponse[]>([]);
const mutation = useMutation({
mutationFn: async (text: string) => {
const res = await fetch(`/api/${agentId}/message`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
text,
userId: "user",
roomId: `default-room-${agentId}`,
}),
});
return res.json() as Promise<TextResponse[]>;
},
onSuccess: (data) => {
setMessages((prev) => [...prev, ...data]);
},
});
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!input.trim()) return;
// Add user message immediately to state
const userMessage: TextResponse = {
text: input,
user: "user",
};
setMessages((prev) => [...prev, userMessage]);
mutation.mutate(input);
setInput("");
};
return (
<div className="flex flex-col h-screen max-h-screen w-full">
<div className="flex-1 min-h-0 overflow-y-auto p-4">
<div className="max-w-3xl mx-auto space-y-4">
{messages.length > 0 ? (
messages.map((message, index) => (
<div
key={index}
className={`flex ${
message.user === "user"
? "justify-end"
: "justify-start"
}`}
>
<div
className={`max-w-[80%] rounded-lg px-4 py-2 ${
message.user === "user"
? "bg-primary text-primary-foreground"
: "bg-muted"
}`}
>
{message.text}
</div>
</div>
))
) : (
<div className="text-center text-muted-foreground">
No messages yet. Start a conversation!
</div>
)}
</div>
</div>
<div className="border-t p-4 bg-background">
<div className="max-w-3xl mx-auto">
<form onSubmit={handleSubmit} className="flex gap-2">
<Input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type a message..."
className="flex-1"
disabled={mutation.isPending}
/>
<Button type="submit" disabled={mutation.isPending}>
{mutation.isPending ? "..." : "Send"}
</Button>
</form>
</div>
</div>
</div>
);
}