Skip to content

Commit ea9119b

Browse files
Merge pull request #41 from DanielAgbeni/Updated-Chat-UI
fix: Updated te UI of The chat component and improved the UX
2 parents e4b820c + 14174a2 commit ea9119b

File tree

1 file changed

+100
-65
lines changed

1 file changed

+100
-65
lines changed
Lines changed: 100 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,112 @@
1-
"use client";
1+
'use client';
22

3-
import { PlaceholdersAndVanishInput } from "../ui/placeholders-and-vanish-input";
4-
import { useState } from "react";
5-
import axios from "axios";
3+
import { PlaceholdersAndVanishInput } from '../ui/placeholders-and-vanish-input';
4+
import { useState, useEffect, useRef } from 'react';
5+
import axios from 'axios';
6+
7+
interface Message {
8+
query: string;
9+
response: string;
10+
isLoading?: boolean;
11+
}
612

713
export function PlaceholdersAndVanishInputDemo() {
8-
const [messages, setMessages] = useState<Array<{ query: string; response: string }>>([]);
9-
const [isLoading, setIsLoading] = useState(false);
14+
const [messages, setMessages] = useState<Array<Message>>([]);
15+
const messagesEndRef = useRef<HTMLDivElement>(null);
16+
17+
const backendUrl =
18+
import.meta.env.VITE_BACKEND_URL || 'http://localhost:5000';
1019

11-
const backendUrl = import.meta.env.VITE_BACKEND_URL || 'http://localhost:5000';
20+
const placeholders = [
21+
'How to set up a React project with Vite?',
22+
'What is the difference between JavaScript and TypeScript?',
23+
'How to implement authentication in a Next.js app?',
24+
'What is a closure in JavaScript?',
25+
'How to optimize React app performance?',
26+
'Explain event delegation in JavaScript',
27+
];
1228

29+
const scrollToBottom = () => {
30+
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
31+
};
1332

14-
const placeholders = [
15-
"What's the first rule of Fight Club?",
16-
"Who is Tyler Durden?",
17-
"Where is Andrew Laeddis Hiding?",
18-
"Write a Javascript method to reverse a string",
19-
"How to assemble your own PC?",
20-
];
33+
useEffect(() => {
34+
scrollToBottom();
35+
}, [messages]);
2136

22-
const handleChange = () => {
23-
// You can add any additional logic here if needed
24-
};
37+
const handleChange = () => {
38+
// Additional logic can be added here
39+
};
2540

26-
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
27-
e.preventDefault();
28-
const query = e.currentTarget.querySelector('input')?.value;
29-
if (!query) return;
41+
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
42+
e.preventDefault();
43+
const query = e.currentTarget.querySelector('input')?.value;
44+
if (!query) return;
3045

31-
setIsLoading(true);
32-
try {
33-
const result = await axios.post(`${backendUrl}/chat`, { query });
34-
setMessages(prevMessages => [...prevMessages, { query, response: result.data.result }]);
35-
} catch (error) {
36-
console.error('Error querying the model:', error);
37-
setMessages(prevMessages => [...prevMessages, { query, response: "An error occurred while processing your request." }]);
38-
} finally {
39-
setIsLoading(false);
40-
}
41-
};
46+
setMessages((prevMessages) => [
47+
...prevMessages,
48+
{ query, response: '', isLoading: true },
49+
]);
4250

43-
return (
44-
<div className="h-[50rem] flex flex-col">
45-
<h2 className="mb-4 text-xl text-center sm:text-5xl dark:text-white text-black">
46-
Start Collaborating
47-
</h2>
48-
<div className="flex-grow overflow-y-auto px-4 flex flex-col items-center">
49-
{messages.map((message, index) => (
50-
<div key={index} className="mb-4 w-full max-w-[80%]">
51-
<div className="bg-zinc-100 dark:bg-zinc-800 p-2 rounded-lg mb-2">
52-
<p className="font-bold">You:</p>
53-
<p>{message.query}</p>
54-
</div>
55-
<div className="bg-zinc-200 dark:bg-zinc-700 p-2 rounded-lg">
56-
<p className="font-bold">AI:</p>
57-
<p>{message.response}</p>
58-
</div>
59-
</div>
60-
))}
61-
</div>
62-
{isLoading && (
63-
<div className="flex justify-center items-center p-4">
64-
<p>Loading...</p>
65-
</div>
66-
)}
67-
<div className="p-4 mt-4">
68-
<PlaceholdersAndVanishInput
69-
placeholders={placeholders}
51+
try {
52+
const result = await axios.post(`${backendUrl}/chat`, { query });
53+
setMessages((prevMessages) => {
54+
const newMessages = [...prevMessages];
55+
const lastMessage = newMessages[newMessages.length - 1];
56+
lastMessage.response = result.data.result;
57+
lastMessage.isLoading = false;
58+
return newMessages;
59+
});
60+
} catch (error) {
61+
console.error('Error querying the model:', error);
62+
setMessages((prevMessages) => {
63+
const newMessages = [...prevMessages];
64+
const lastMessage = newMessages[newMessages.length - 1];
65+
lastMessage.response =
66+
'An error occurred while processing your request.';
67+
lastMessage.isLoading = false;
68+
return newMessages;
69+
});
70+
}
71+
};
7072

71-
onChange={handleChange}
72-
onSubmit={onSubmit}
73-
/>
74-
</div>
75-
</div>
76-
);
73+
return (
74+
<div className='h-screen md:w-[60%] w-full mx-auto justify-center flex flex-col'>
75+
<h2 className='mb-4 text-xl text-center sm:text-5xl dark:text-white text-black mt-5'>
76+
Start Collaborating
77+
</h2>
78+
<div className='flex-grow overflow-y-auto px-4'>
79+
{messages.map((message, index) => (
80+
<div
81+
key={index}
82+
className='mb-4'>
83+
<div className='flex justify-end mb-2'>
84+
<div className='bg-zinc-100 dark:bg-zinc-800 p-3 rounded-lg max-w-[80%]'>
85+
<p className='font-bold'>You:</p>
86+
<p>{message.query}</p>
87+
</div>
88+
</div>
89+
<div className='flex justify-start'>
90+
<div className='bg-zinc-200 dark:bg-zinc-700 p-3 rounded-lg max-w-[80%]'>
91+
<p className='font-bold'>AI:</p>
92+
{message.isLoading ? (
93+
<p>Loading...</p>
94+
) : (
95+
<p>{message.response}</p>
96+
)}
97+
</div>
98+
</div>
99+
</div>
100+
))}
101+
<div ref={messagesEndRef} />
102+
</div>
103+
<div className='p-4 mb-auto'>
104+
<PlaceholdersAndVanishInput
105+
placeholders={placeholders}
106+
onChange={handleChange}
107+
onSubmit={onSubmit}
108+
/>
109+
</div>
110+
</div>
111+
);
77112
}

0 commit comments

Comments
 (0)