fastcode-landingpage/src/components/ChatInterface.tsx
gpt-engineer-app[bot] 069ca8f7f7 feat: Implement landing page and chatbot interface
Create a minimal, high-end landing page with a chatbot-like interface, including dark/light mode, prewritten prompts, and animated sidebar. Design should be black and white with glassmorphism and subtle gradients.
2025-06-18 07:20:12 +00:00

156 lines
5.9 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import TypingAnimation from './TypingAnimation';
import { getPromptContent } from '../utils/promptContent';
interface ChatInterfaceProps {
onPromptSelect: (prompt: string, content: any) => void;
isExpanded: boolean;
}
const prompts = [
"What can you help me with?",
"What is MCP?",
"Who is this for?",
"Show me how I can earn"
];
const ChatInterface: React.FC<ChatInterfaceProps> = ({ onPromptSelect, isExpanded }) => {
const [messages, setMessages] = useState<Array<{ text: string; isUser: boolean; isTyping?: boolean }>>([]);
const [inputValue, setInputValue] = useState('');
const [isThinking, setIsThinking] = useState(false);
const handlePromptClick = (prompt: string) => {
setMessages(prev => [...prev, { text: prompt, isUser: true }]);
setIsThinking(true);
setTimeout(() => {
setIsThinking(false);
setMessages(prev => [...prev, { text: `Let me show you detailed information about "${prompt}"`, isUser: false, isTyping: true }]);
setTimeout(() => {
const content = getPromptContent(prompt);
onPromptSelect(prompt, content);
}, 1500);
}, 1000);
};
const handleSendMessage = () => {
if (!inputValue.trim()) return;
const prompt = inputValue;
setInputValue('');
handlePromptClick(prompt);
};
const handleKeyPress = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
handleSendMessage();
}
};
return (
<div className="flex flex-col h-full p-6">
{/* Hero Section */}
{messages.length === 0 && (
<div className={`flex-1 flex flex-col justify-center items-center text-center transition-all duration-500 ${
isExpanded ? 'max-w-4xl mx-auto' : 'max-w-2xl mx-auto'
}`}>
<div className="mb-8">
<h1 className="text-4xl md:text-6xl font-bold text-gray-900 dark:text-white mb-6 leading-tight">
Build an MCP server and become part of the new world
</h1>
<p className="text-xl text-gray-600 dark:text-gray-300 mb-8">
Where AI chatbots are the modern interface
</p>
</div>
{/* Glassmorphism card with prompts */}
<div className="w-full max-w-2xl p-8 rounded-3xl border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-xl bg-white/10 dark:bg-black/10 shadow-2xl">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-6">
How can I help you today?
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{prompts.map((prompt, index) => (
<Button
key={index}
variant="ghost"
onClick={() => handlePromptClick(prompt)}
className="p-4 h-auto text-left justify-start border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-sm bg-white/5 dark:bg-black/5 hover:bg-white/10 dark:hover:bg-black/10 rounded-xl transition-all duration-300 hover:scale-105"
>
<span className="text-gray-700 dark:text-gray-300">{prompt}</span>
</Button>
))}
</div>
</div>
</div>
)}
{/* Chat Messages */}
{messages.length > 0 && (
<div className="flex-1 overflow-y-auto space-y-4 mb-6">
{messages.map((message, index) => (
<div
key={index}
className={`flex ${message.isUser ? 'justify-end' : 'justify-start'}`}
>
<div
className={`max-w-xs lg:max-w-md px-4 py-3 rounded-2xl ${
message.isUser
? 'bg-blue-500 text-white'
: 'border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-xl bg-white/10 dark:bg-black/10 text-gray-900 dark:text-white'
}`}
>
{message.isTyping ? (
<TypingAnimation text={message.text} />
) : (
message.text
)}
</div>
</div>
))}
{isThinking && (
<div className="flex justify-start">
<div className="max-w-xs lg:max-w-md px-4 py-3 rounded-2xl border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-xl bg-white/10 dark:bg-black/10 text-gray-900 dark:text-white">
<div className="flex items-center space-x-2">
<div className="flex space-x-1">
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div>
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.1s' }}></div>
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.2s' }}></div>
</div>
<span className="text-sm">AI is thinking...</span>
</div>
</div>
</div>
)}
</div>
)}
{/* Input Area */}
<div className="border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-xl bg-white/10 dark:bg-black/10 rounded-2xl p-4">
<div className="flex space-x-4">
<Input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyPress={handleKeyPress}
placeholder="Ask me anything about MCP..."
className="flex-1 border-0 bg-transparent focus:ring-0 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400"
/>
<Button
onClick={handleSendMessage}
disabled={!inputValue.trim()}
className="bg-blue-500 hover:bg-blue-600 text-white rounded-xl px-6"
>
Send
</Button>
</div>
</div>
</div>
);
};
export default ChatInterface;