Copy the Code for components/Chatbot.tsx
// components/Chatbot.tsx
import { useState } from 'react';
interface ChatbotProps {
apiKey: string;
className?: string;
}
const Chatbot: React.FC<ChatbotProps> = ({ apiKey, className }) => {
const [question, setQuestion] = useState('');
const [response, setResponse] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false); // State for loading
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
setResponse('');
setLoading(true); // Set loading to true
try {
const userId = process.env.NEXT_PUBLIC_USER_ID;
if (!userId) {
throw new Error('User ID is not defined in the environment variables.');
}
// Validate question input
if (question.trim() === '') {
throw new Error('Question cannot be empty.');
}
const res = await fetch(`https://apish-nikhil-chopras-projects.vercel.app/api/${userId}/chatbot/${apiKey}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ question }),
});
if (!res.ok) {
const errorText = await res.json();
throw new Error(errorText.message || 'Unknown error occurred');
}
const data = await res.json();
setResponse(data.answer || 'No answer found.');
} catch (err) {
console.log(err);
const errorMsg = err instanceof Error ? err.message : 'An unexpected error occurred';
setError(errorMsg);
} finally {
setLoading(false); // Reset loading state
}
};
return (
<div className={`flex flex-col max-w-md mx-auto p-8 bg-white rounded shadow-md ${className}`}>
<form onSubmit={handleSubmit}>
<div className="mb-4">
<label htmlFor="question" className="block text-sm font-medium text-gray-700">
Ask a question:
</label>
<textarea
id="question"
value={question}
onChange={(e) => setQuestion(e.target.value)}
className="mt-1 p-2 text-gray-700 w-full border rounded shadow-sm"
placeholder="Type your question here"
required
/>
</div>
<button
type="submit"
className="w-full py-2 bg-blue-600 text-white rounded hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
disabled={loading} // Disable button when loading
>
{loading ? 'Submitting...' : 'Submit'} {/* Show loading state */}
</button>
</form>
{response && (
<div className="mt-4 p-4 bg-green-100 rounded shadow-md">
<h3 className="text-lg font-bold text-green-800">Answer:</h3>
<p className="text-green-600">{response}</p>
</div>
)}
{error && (
<div className="mt-4 p-4 bg-red-100 rounded shadow-md">
<h3 className="text-lg font-bold text-red-800">Error:</h3>
<p className="text-red-600">{error}</p>
</div>
)}
</div>
);
};
export default Chatbot;