Skip to content

Instantly share code, notes, and snippets.

@dzakyputra
Last active April 6, 2025 13:25
Show Gist options
  • Select an option

  • Save dzakyputra/7c2f1b36f806cbf62ae05deb4b55c8cc to your computer and use it in GitHub Desktop.

Select an option

Save dzakyputra/7c2f1b36f806cbf62ae05deb4b55c8cc to your computer and use it in GitHub Desktop.
page.tsx
'use client';
import { useState } from 'react';
interface Message {
role: 'user' | 'assistant';
content: string;
}
export default function Home() {
const [messages, setMessages] = useState<Message[]>([]);
const [input, setInput] = useState('');
const [isLoading, setIsLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (!input.trim() || isLoading) return;
const userMessage = input.trim();
setInput('');
setIsLoading(true);
setMessages(prev => [...prev, { role: 'user', content: userMessage }]);
try {
const response = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
prompt: userMessage,
}),
});
if (!response.ok) {
throw new Error('Failed to fetch response');
}
const data = await response.json();
setMessages(prev => [...prev, { role: 'assistant', content: data.content }]);
} catch (error) {
console.error('Error:', error);
setMessages(prev => [...prev, { role: 'assistant', content: 'Sorry, there was an error processing your request.' }]);
} finally {
setIsLoading(false);
}
};
return (
<main className="min-h-screen bg-gray-800 p-4 relative">
<div className="max-w-2xl mx-auto h-full">
<div className="bg-gray-900 rounded-lg min-h-[500px] p-4 flex flex-col h-[calc(100vh-2rem)]">
<div className="flex-1 overflow-y-auto space-y-4 mb-4">
{messages.map((message, index) => (
<div key={index} className={`flex ${message.role === 'user' ? 'justify-end' : 'justify-start'}`}>
<div className={`max-w-[80%] rounded-lg p-3 ${
message.role === 'user'
? 'bg-blue-600 text-white'
: 'bg-gray-700 text-gray-100'
}`}>
{message.content}
</div>
</div>
))}
</div>
<form onSubmit={handleSubmit} className="sticky bottom-0 bg-gray-900 pt-2">
<div className="flex gap-2">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Send a message..."
className="flex-1 p-2 rounded bg-gray-700 text-white placeholder-gray-400 focus:outline-none"
/>
<button
type="submit"
disabled={isLoading || !input.trim()}
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
>
{isLoading ? '...' : 'Send'}
</button>
</div>
</form>
</div>
</div>
</main>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment