Spaces:
Running
Running
| ```typescript | |
| import React, { useState, useRef, useEffect } from 'react'; | |
| import { Send, Settings, Sparkles, Loader2 } from 'lucide-react'; | |
| import { HeaderProps } from '../types'; | |
| const Header: React.FC<HeaderProps> = ({ | |
| prompt, | |
| setPrompt, | |
| onGenerate, | |
| loading, | |
| onSettingsClick | |
| }) => { | |
| const textareaRef = useRef<HTMLTextAreaElement>(null); | |
| const [isExpanded, setIsExpanded] = useState(false); | |
| // Auto-resize textarea | |
| useEffect(() => { | |
| const textarea = textareaRef.current; | |
| if (textarea) { | |
| textarea.style.height = 'auto'; | |
| textarea.style.height = Math.min(textarea.scrollHeight, 120) + 'px'; | |
| } | |
| }, [prompt]); | |
| const handleSubmit = (e: React.FormEvent) => { | |
| e.preventDefault(); | |
| if (!loading && prompt.trim()) { | |
| onGenerate(); | |
| } | |
| }; | |
| const handleKeyDown = (e: React.KeyboardEvent) => { | |
| if (e.key === 'Enter' && !e.shiftKey) { | |
| e.preventDefault(); | |
| handleSubmit(e); | |
| } | |
| }; | |
| const suggestedPrompts = [ | |
| "Create a modern landing page with hero section and features", | |
| "Build a portfolio website with dark theme", | |
| "Generate a responsive e-commerce product page", | |
| "Make a blog with modern typography", | |
| "Create a dashboard with charts and analytics" | |
| ]; | |
| return ( | |
| <header className="header"> | |
| <div className="header-content"> | |
| {/* Logo and Title */} | |
| <div className="logo-section"> | |
| <div className="logo-icon"> | |
| <Sparkles className="w-8 h-8 text-white" /> | |
| </div> | |
| <div className="logo-text"> | |
| <h1 className="text-2xl font-bold text-white">DeepSite</h1> | |
| <p className="text-white/80 text-sm">AI-Powered Website Builder</p> | |
| </div> | |
| </div> | |
| {/* Main Input */} | |
| <form onSubmit={handleSubmit} className="input-section"> | |
| <div className="input-container"> | |
| <div className="input-wrapper"> | |
| <textarea | |
| ref={textareaRef} | |
| value={prompt} | |
| onChange={(e) => setPrompt(e.target.value)} | |
| onKeyDown={handleKeyDown} | |
| onFocus={() => setIsExpanded(true)} | |
| onBlur={() => setIsExpanded(false)} | |
| placeholder="Describe the website you want to create... (e.g., 'Create a modern portfolio with dark theme and smooth animations')" | |
| className="main-input" | |
| rows={1} | |
| disabled={loading} | |
| /> | |
| <button | |
| type="submit" | |
| disabled={loading || !prompt.trim()} | |
| className="submit-button" | |
| title="Generate Website (⌘+Enter)" | |
| > | |
| {loading ? ( | |
| <Loader2 className="w-5 h-5 animate-spin" /> | |
| ) : ( | |
| <Send className="w-5 h-5" /> | |
| )} | |
| </button> | |
| </div> | |
| {/* Suggested Prompts */} | |
| {isExpanded && ( | |
| <div className="suggestions fade-in"> | |
| <div className="suggestions-header"> | |
| <span className="text-sm text-white/60">Try these:</span> | |
| </div> | |
| <div className="suggestions-grid"> | |
| {suggestedPrompts.map((suggestion, index) => ( | |
| <button | |
| key={index} | |
| type="button" | |
| onClick={() => setPrompt(suggestion)} | |
| className="suggestion-chip" | |
| disabled={loading} | |
| > | |
| {suggestion} | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| )} | |
| </div> | |
| </form> | |
| {/* Settings Button */} | |
| <button | |
| onClick={onSettingsClick} | |
| className="settings-button" | |
| title="Settings" | |
| > | |
| <Settings className="w-5 h-5" /> | |
| </button> | |
| </div> | |
| {/* Quick Stats */} | |
| <div className="header-stats"> | |
| <div className="stat-item"> | |
| <span className="stat-number">∞</span> | |
| <span className="stat-label">AI Models</span> | |
| </div> | |
| <div className="stat-item"> | |
| <span className="stat-number">100%</span> | |
| <span className="stat-label">Free</span> | |
| </div> | |
| <div className="stat-item"> | |
| <span className="stat-number">⚡</span> | |
| <span className="stat-label">Fast</span> | |
| </div> | |
| </div> | |
| </header> | |
| ); | |
| }; | |
| export default Header; | |
| ``` |