Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import time | |
| import random | |
| import re | |
| from typing import List, Dict, Any | |
| import json | |
| def generate_website_code(description: str, complexity: str, color_scheme: str = "Blue", layout_style: str = "Modern") -> Dict[str, str]: | |
| """ | |
| Enhanced AI website generation with multiple customization options. | |
| """ | |
| start_time = time.time() | |
| # Generate HTML, CSS, and JS with new features | |
| description_lower = description.lower() | |
| # Smart template selection | |
| if "portfolio" in description_lower or "personal" in description_lower: | |
| html_code = generate_portfolio_site(description, color_scheme, layout_style) | |
| elif "business" in description_lower or "company" in description_lower: | |
| html_code = generate_business_site(description, color_scheme, layout_style) | |
| elif "blog" in description_lower: | |
| html_code = generate_blog_site(description, color_scheme, layout_style) | |
| elif "landing" in description_lower or "product" in description_lower: | |
| html_code = generate_landing_site(description, color_scheme, layout_style) | |
| elif "ecommerce" in description_lower or "shop" in description_lower or "store" in description_lower: | |
| html_code = generate_ecommerce_site(description, color_scheme, layout_style) | |
| else: | |
| html_code = generate_simple_site(description, color_scheme, layout_style) | |
| css_code = generate_enhanced_css(complexity, color_scheme, layout_style) | |
| js_code = generate_enhanced_javascript(complexity) | |
| # Add SEO and accessibility features | |
| html_code = enhance_html_with_seo_accessibility(html_code, description) | |
| # Code quality analysis | |
| quality_metrics = analyze_code_quality(html_code, css_code, js_code) | |
| generation_time = time.time() - start_time | |
| return { | |
| "html": html_code, | |
| "css": css_code, | |
| "javascript": js_code, | |
| "generation_time": f"{generation_time:.2f}s", | |
| "quality_score": f"{quality_metrics['score']}/100", | |
| "performance_tips": quality_metrics['tips'], | |
| "accessibility_score": f"{quality_metrics['accessibility']}/100", | |
| "seo_score": f"{quality_metrics['seo']}/100", | |
| "status": "β Website generated successfully!" if generation_time < 15 else "β οΈ Generation took longer than expected" | |
| } | |
| def generate_ecommerce_site(description: str, color_scheme: str, layout_style: str) -> str: | |
| """Generate an e-commerce website template""" | |
| return f'''<!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>E-Commerce Store - Generated Website</title> | |
| <link rel="stylesheet" href="style.css"> | |
| <meta name="description" content="Generated e-commerce store based on: {description}"> | |
| </head> | |
| <body> | |
| <header> | |
| <nav> | |
| <div class="logo">ShopNow</div> | |
| <div class="search-bar"> | |
| <input type="text" placeholder="Search products..." aria-label="Search products"> | |
| <button class="search-btn" aria-label="Search">π</button> | |
| </div> | |
| <div class="nav-icons"> | |
| <button class="icon-btn" aria-label="User account">π€</button> | |
| <button class="icon-btn cart-btn" aria-label="Shopping cart">π <span class="cart-count">0</span></button> | |
| </div> | |
| </nav> | |
| </header> | |
| <main> | |
| <section id="hero" class="hero ecommerce-hero"> | |
| <div class="hero-content"> | |
| <h1>Premium Quality Products</h1> | |
| <p>Generated for: "{description}"</p> | |
| <p>Discover amazing products at unbeatable prices!</p> | |
| <button class="cta-button">Shop Now</button> | |
| </div> | |
| </section> | |
| <section id="products" class="products"> | |
| <div class="container"> | |
| <h2>Featured Products</h2> | |
| <div class="product-grid"> | |
| <div class="product-card"> | |
| <div class="product-image"> | |
| <div class="placeholder-img">ποΈ</div> | |
| </div> | |
| <div class="product-info"> | |
| <h3>Product 1</h3> | |
| <p class="price">$29.99</p> | |
| <button class="add-to-cart">Add to Cart</button> | |
| </div> | |
| </div> | |
| <div class="product-card"> | |
| <div class="product-image"> | |
| <div class="placeholder-img">π</div> | |
| </div> | |
| <div class="product-info"> | |
| <h3>Product 2</h3> | |
| <p class="price">$49.99</p> | |
| <button class="add-to-cart">Add to Cart</button> | |
| </div> | |
| </div> | |
| <div class="product-card"> | |
| <div class="product-image"> | |
| <div class="placeholder-img">π</div> | |
| </div> | |
| <div class="product-info"> | |
| <h3>Product 3</h3> | |
| <p class="price">$79.99</p> | |
| <button class="add-to-cart">Add to Cart</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="categories" class="categories"> | |
| <div class="container"> | |
| <h2>Shop by Category</h2> | |
| <div class="category-grid"> | |
| <div class="category-card"> | |
| <div class="category-icon">π±</div> | |
| <h3>Electronics</h3> | |
| </div> | |
| <div class="category-card"> | |
| <div class="category-icon">π</div> | |
| <h3>Clothing</h3> | |
| </div> | |
| <div class="category-card"> | |
| <div class="category-icon">π </div> | |
| <h3>Home & Garden</h3> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| <footer> | |
| <div class="container"> | |
| <div class="footer-content"> | |
| <div class="footer-section"> | |
| <h3>Customer Service</h3> | |
| <ul> | |
| <li><a href="#">Contact Us</a></li> | |
| <li><a href="#">Shipping Info</a></li> | |
| <li><a href="#">Returns</a></li> | |
| </ul> | |
| </div> | |
| <div class="footer-section"> | |
| <h3>About Us</h3> | |
| <ul> | |
| <li><a href="#">Our Story</a></li> | |
| <li><a href="#">Careers</a></li> | |
| <li><a href="#">Press</a></li> | |
| </ul> | |
| </div> | |
| <div class="footer-section"> | |
| <h3>Connect</h3> | |
| <div class="social-links"> | |
| <a href="#" aria-label="Facebook">π</a> | |
| <a href="#" aria-label="Twitter">π¦</a> | |
| <a href="#" aria-label="Instagram">π·</a> | |
| </div> | |
| </div> | |
| </div> | |
| <p>© 2024 ShopNow. All rights reserved.</p> | |
| </div> | |
| </footer> | |
| <script src="script.js"></script> | |
| </body> | |
| </html>''' | |
| def generate_enhanced_css(complexity: str, color_scheme: str, layout_style: str) -> str: | |
| """Generate enhanced CSS with multiple themes and layouts""" | |
| # Color schemes | |
| color_schemes = { | |
| "Blue": { | |
| "primary": "#007bff", | |
| "secondary": "#0056b3", | |
| "accent": "#17a2b8", | |
| "background": "#f8f9fa", | |
| "text": "#333333" | |
| }, | |
| "Green": { | |
| "primary": "#28a745", | |
| "secondary": "#1e7e34", | |
| "accent": "#20c997", | |
| "background": "#f8fff8", | |
| "text": "#333333" | |
| }, | |
| "Purple": { | |
| "primary": "#6f42c1", | |
| "secondary": "#5a32a3", | |
| "accent": "#e83e8c", | |
| "background": "#faf8ff", | |
| "text": "#333333" | |
| }, | |
| "Orange": { | |
| "primary": "#fd7e14", | |
| "secondary": "#e8650e", | |
| "accent": "#ffc107", | |
| "background": "#fffbf5", | |
| "text": "#333333" | |
| } | |
| } | |
| colors = color_schemes.get(color_scheme, color_schemes["Blue"]) | |
| base_css = f''' | |
| /* Reset and base styles */ | |
| * {{ | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| :root {{ | |
| --primary-color: {colors['primary']}; | |
| --secondary-color: {colors['secondary']}; | |
| --accent-color: {colors['accent']}; | |
| --background-color: {colors['background']}; | |
| --text-color: {colors['text']}; | |
| --border-radius: 8px; | |
| --shadow: 0 2px 10px rgba(0,0,0,0.1); | |
| --transition: all 0.3s ease; | |
| body {{ | |
| font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| line-height: 1.6; | |
| color: var(--text-color); | |
| background-color: var(--background-color); | |
| .container {{ | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 0 20px; | |
| /* Enhanced header */ | |
| header {{ | |
| background: #fff; | |
| box-shadow: var(--shadow); | |
| position: fixed; | |
| width: 100%; | |
| top: 0; | |
| z-index: 1000; | |
| backdrop-filter: blur(10px); | |
| nav {{ | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 1rem 2rem; | |
| .logo {{ | |
| font-size: 1.5rem; | |
| font-weight: bold; | |
| color: var(--primary-color); | |
| transition: var(--transition); | |
| .logo:hover {{ | |
| color: var(--secondary-color); | |
| .search-bar {{ | |
| display: flex; | |
| flex: 1; | |
| max-width: 400px; | |
| margin: 0 2rem; | |
| .search-bar input {{ | |
| flex: 1; | |
| padding: 10px 15px; | |
| border: 2px solid #e0e0e0; | |
| border-radius: var(--border-radius) 0 0 var(--border-radius); | |
| font-size: 14px; | |
| transition: var(--transition); | |
| .search-bar input:focus {{ | |
| outline: none; | |
| border-color: var(--primary-color); | |
| .search-btn {{ | |
| padding: 10px 15px; | |
| background: var(--primary-color); | |
| color: white; | |
| border: none; | |
| border-radius: 0 var(--border-radius) var(--border-radius) 0; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| .search-btn:hover {{ | |
| background: var(--secondary-color); | |
| .nav-icons {{ | |
| display: flex; | |
| gap: 1rem; | |
| .icon-btn {{ | |
| background: none; | |
| border: none; | |
| font-size: 1.2rem; | |
| cursor: pointer; | |
| padding: 8px; | |
| border-radius: 50%; | |
| transition: var(--transition); | |
| position: relative; | |
| .icon-btn:hover {{ | |
| background: var(--background-color); | |
| .cart-count {{ | |
| position: absolute; | |
| top: -5px; | |
| right: -5px; | |
| background: var(--primary-color); | |
| color: white; | |
| border-radius: 50%; | |
| width: 18px; | |
| height: 18px; | |
| font-size: 10px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| .nav-links {{ | |
| display: flex; | |
| list-style: none; | |
| gap: 2rem; | |
| .nav-links a {{ | |
| text-decoration: none; | |
| color: var(--text-color); | |
| font-weight: 500; | |
| transition: var(--transition); | |
| position: relative; | |
| .nav-links a:hover {{ | |
| color: var(--primary-color); | |
| .nav-links a::after {{ | |
| content: ''; | |
| position: absolute; | |
| width: 0; | |
| height: 2px; | |
| bottom: -5px; | |
| left: 0; | |
| background: var(--primary-color); | |
| transition: var(--transition); | |
| .nav-links a:hover::after {{ | |
| width: 100%; | |
| /* Enhanced hero sections */ | |
| .hero {{ | |
| background: linear-gradient(135deg, var(--primary-color) 0%, var(--accent-color) 100%); | |
| color: white; | |
| text-align: center; | |
| padding: 150px 0 100px; | |
| margin-top: 80px; | |
| position: relative; | |
| overflow: hidden; | |
| .ecommerce-hero {{ | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| .landing-hero {{ | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| .hero::before {{ | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background: rgba(0,0,0,0.1); | |
| z-index: 1; | |
| .hero-content {{ | |
| position: relative; | |
| z-index: 2; | |
| .hero-content h1 {{ | |
| font-size: 3.5rem; | |
| margin-bottom: 1rem; | |
| font-weight: 700; | |
| animation: fadeInUp 0.8s ease; | |
| .hero-content p {{ | |
| font-size: 1.2rem; | |
| margin-bottom: 2rem; | |
| opacity: 0.9; | |
| animation: fadeInUp 0.8s ease 0.2s both; | |
| .hero-buttons {{ | |
| display: flex; | |
| gap: 1rem; | |
| justify-content: center; | |
| flex-wrap: wrap; | |
| animation: fadeInUp 0.8s ease 0.4s both; | |
| .cta-button {{ | |
| background: var(--primary-color); | |
| color: white; | |
| border: none; | |
| padding: 15px 35px; | |
| border-radius: var(--border-radius); | |
| font-size: 1rem; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| text-decoration: none; | |
| display: inline-block; | |
| position: relative; | |
| overflow: hidden; | |
| .cta-button::before {{ | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: -100%; | |
| width: 100%; | |
| height: 100%; | |
| background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); | |
| transition: var(--transition); | |
| .cta-button:hover::before {{ | |
| left: 100%; | |
| .cta-button:hover {{ | |
| background: var(--secondary-color); | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 20px rgba(0,0,0,0.2); | |
| .secondary-button {{ | |
| background: transparent; | |
| color: white; | |
| border: 2px solid white; | |
| padding: 13px 33px; | |
| border-radius: var(--border-radius); | |
| font-size: 1rem; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| text-decoration: none; | |
| display: inline-block; | |
| .secondary-button:hover {{ | |
| background: white; | |
| color: var(--primary-color); | |
| transform: translateY(-2px); | |
| /* Enhanced sections */ | |
| .features, .products, .services, .blog-posts, .categories {{ | |
| padding: 80px 0; | |
| .features {{ | |
| background: var(--background-color); | |
| .products {{ | |
| background: #fff; | |
| .categories {{ | |
| background: var(--background-color); | |
| .features h2, .products h2, .services h2, .blog-posts h2, .categories h2 {{ | |
| text-align: center; | |
| font-size: 2.5rem; | |
| margin-bottom: 3rem; | |
| color: var(--text-color); | |
| position: relative; | |
| .features h2::after, .products h2::after, .services h2::after, .blog-posts h2::after, .categories h2::after {{ | |
| content: ''; | |
| position: absolute; | |
| bottom: -10px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| width: 60px; | |
| height: 3px; | |
| background: var(--primary-color); | |
| border-radius: 2px; | |
| /* Enhanced grid layouts */ | |
| .feature-grid, .product-grid, .service-grid, .post-grid, .category-grid {{ | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
| gap: 2rem; | |
| margin-top: 3rem; | |
| .product-grid {{ | |
| grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); | |
| .category-grid {{ | |
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | |
| /* Enhanced cards */ | |
| .feature-card, .product-card, .service-card, .post-card, .category-card {{ | |
| background: white; | |
| padding: 2rem; | |
| border-radius: var(--border-radius); | |
| box-shadow: var(--shadow); | |
| transition: var(--transition); | |
| position: relative; | |
| overflow: hidden; | |
| .feature-card::before, .product-card::before, .service-card::before, .post-card::before, .category-card::before {{ | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| height: 4px; | |
| background: linear-gradient(90deg, var(--primary-color), var(--accent-color)); | |
| .feature-card:hover, .product-card:hover, .service-card:hover, .post-card:hover, .category-card:hover {{ | |
| transform: translateY(-10px); | |
| box-shadow: 0 20px 40px rgba(0,0,0,0.15); | |
| .product-card {{ | |
| text-align: center; | |
| .product-image {{ | |
| margin-bottom: 1rem; | |
| .placeholder-img {{ | |
| width: 100%; | |
| height: 200px; | |
| background: var(--background-color); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 3rem; | |
| border-radius: var(--border-radius); | |
| .product-info h3 {{ | |
| margin-bottom: 0.5rem; | |
| color: var(--text-color); | |
| .price {{ | |
| font-size: 1.5rem; | |
| font-weight: bold; | |
| color: var(--primary-color); | |
| margin-bottom: 1rem; | |
| .add-to-cart {{ | |
| background: var(--primary-color); | |
| color: white; | |
| border: none; | |
| padding: 10px 20px; | |
| border-radius: var(--border-radius); | |
| cursor: pointer; | |
| transition: var(--transition); | |
| .add-to-cart:hover {{ | |
| background: var(--secondary-color); | |
| transform: translateY(-2px); | |
| .category-card {{ | |
| text-align: center; | |
| padding: 3rem 2rem; | |
| .category-icon {{ | |
| font-size: 3rem; | |
| margin-bottom: 1rem; | |
| .category-card h3 {{ | |
| color: var(--text-color); | |
| font-size: 1.3rem; | |
| /* Footer enhancements */ | |
| footer {{ | |
| background: var(--text-color); | |
| color: white; | |
| padding: 3rem 0 1rem; | |
| .footer-content {{ | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); | |
| gap: 2rem; | |
| margin-bottom: 2rem; | |
| .footer-section h3 {{ | |
| margin-bottom: 1rem; | |
| color: var(--accent-color); | |
| .footer-section ul {{ | |
| list-style: none; | |
| .footer-section li {{ | |
| margin-bottom: 0.5rem; | |
| .footer-section a {{ | |
| color: #ccc; | |
| text-decoration: none; | |
| transition: var(--transition); | |
| .footer-section a:hover {{ | |
| color: var(--accent-color); | |
| .social-links {{ | |
| display: flex; | |
| gap: 1rem; | |
| .social-links a {{ | |
| font-size: 1.5rem; | |
| transition: var(--transition); | |
| .social-links a:hover {{ | |
| transform: scale(1.2); | |
| /* Animations */ | |
| @keyframes fadeInUp {{ | |
| from {{ | |
| opacity: 0; | |
| transform: translateY(30px); | |
| to {{ | |
| opacity: 1; | |
| transform: translateY(0); | |
| @keyframes pulse {{ | |
| 0%, 100% {{ transform: scale(1); }} | |
| 50% {{ transform: scale(1.05); }} | |
| .pulse {{ | |
| animation: pulse 2s infinite; | |
| /* Responsive design */ | |
| @media (max-width: 768px) {{ | |
| .nav-links {{ | |
| display: none; | |
| .search-bar {{ | |
| margin: 0 1rem; | |
| .hero-content h1 {{ | |
| font-size: 2.5rem; | |
| .hero-content p {{ | |
| font-size: 1rem; | |
| .hero-buttons {{ | |
| flex-direction: column; | |
| align-items: center; | |
| .feature-grid, .product-grid, .service-grid, .post-grid, .category-grid {{ | |
| grid-template-columns: 1fr; | |
| .footer-content {{ | |
| grid-template-columns: 1fr; | |
| text-align: center; | |
| @media (max-width: 480px) {{ | |
| nav {{ | |
| padding: 1rem; | |
| .search-bar {{ | |
| display: none; | |
| .hero-content h1 {{ | |
| font-size: 2rem; | |
| .container {{ | |
| padding: 0 15px; | |
| ''' | |
| if complexity == "Advanced": | |
| base_css += ''' | |
| /* Advanced styling additions */ | |
| .hero { | |
| background-attachment: fixed; | |
| } | |
| .feature-card:nth-child(1) { border-left: 4px solid #e74c3c; } | |
| .feature-card:nth-child(2) { border-left: 4px solid #3498db; } | |
| .feature-card:nth-child(3) { border-left: 4px solid #2ecc71; } | |
| .post-excerpt { | |
| color: #666; | |
| margin-bottom: 1rem; | |
| line-height: 1.6; | |
| } | |
| /* Glass morphism effects */ | |
| .glass { | |
| background: rgba(255, 255, 255, 0.1); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| } | |
| /* Gradient text */ | |
| .gradient-text { | |
| background: linear-gradient(45deg, var(--primary-color), var(--accent-color)); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| } | |
| /* Advanced hover effects */ | |
| .hover-lift:hover { | |
| transform: translateY(-8px) scale(1.02); | |
| box-shadow: 0 25px 50px rgba(0,0,0,0.15); | |
| } | |
| /* Loading animations */ | |
| .loading { | |
| display: inline-block; | |
| width: 20px; | |
| height: 20px; | |
| border: 3px solid rgba(255,255,255,.3); | |
| border-radius: 50%; | |
| border-top-color: #fff; | |
| animation: spin 1s ease-in-out infinite; | |
| } | |
| @keyframes spin { | |
| to { transform: rotate(360deg); } | |
| } | |
| /* Enhanced mobile menu */ | |
| @media (max-width: 768px) { | |
| .mobile-menu-toggle { | |
| display: block; | |
| background: none; | |
| border: none; | |
| font-size: 1.5rem; | |
| cursor: pointer; | |
| color: var(--primary-color); | |
| } | |
| .nav-links.active { | |
| display: flex; | |
| flex-direction: column; | |
| position: absolute; | |
| top: 100%; | |
| left: 0; | |
| right: 0; | |
| background: white; | |
| box-shadow: var(--shadow); | |
| padding: 1rem; | |
| } | |
| } | |
| .mobile-menu-toggle { | |
| display: none; | |
| } | |
| ''' | |
| return base_css | |
| def generate_enhanced_javascript(complexity: str) -> str: | |
| """Generate enhanced JavaScript with advanced functionality""" | |
| base_js = ''' | |
| // Enhanced functionality for AI Web Coder | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Initialize all components | |
| initializeNavigation(); | |
| initializeButtons(); | |
| initializeCards(); | |
| initializeCart(); | |
| initializeSearch(); | |
| initializeAnimations(); | |
| function initializeNavigation() { | |
| // Smooth scrolling for navigation links | |
| const navLinks = document.querySelectorAll('.nav-links a'); | |
| navLinks.forEach(link => { | |
| link.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| const targetId = this.getAttribute('href').substring(1); | |
| const targetSection = document.getElementById(targetId); | |
| if (targetSection) { | |
| const headerHeight = document.querySelector('header').offsetHeight; | |
| const targetPosition = targetSection.offsetTop - headerHeight; | |
| window.scrollTo({ | |
| top: targetPosition, | |
| behavior: 'smooth' | |
| }); | |
| } | |
| }); | |
| }); | |
| // Mobile menu toggle | |
| const mobileMenuToggle = document.querySelector('.mobile-menu-toggle'); | |
| const navLinks = document.querySelector('.nav-links'); | |
| if (mobileMenuToggle && navLinks) { | |
| mobileMenuToggle.addEventListener('click', function() { | |
| navLinks.classList.toggle('active'); | |
| }); | |
| } | |
| } | |
| function initializeButtons() { | |
| // Enhanced CTA button functionality | |
| const ctaButtons = document.querySelectorAll('.cta-button'); | |
| ctaButtons.forEach(button => { | |
| button.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| // Add loading state | |
| const originalText = this.textContent; | |
| this.innerHTML = '<span class="loading"></span> Processing...'; | |
| this.disabled = true; | |
| // Simulate processing | |
| setTimeout(() => { | |
| this.textContent = originalText; | |
| this.disabled = false; | |
| // Show success message | |
| showNotification('Thank you! This would redirect to the next step.', 'success'); | |
| }, 2000); | |
| }); | |
| }); | |
| // Add to cart functionality | |
| const addToCartButtons = document.querySelectorAll('.add-to-cart'); | |
| addToCartButtons.forEach(button => { | |
| button.addEventListener('click', function() { | |
| const productName = this.closest('.product-card').querySelector('h3').textContent; | |
| addToCart(productName); | |
| // Visual feedback | |
| this.textContent = 'Added! β'; | |
| this.style.background = '#28a745'; | |
| setTimeout(() => { | |
| this.textContent = 'Add to Cart'; | |
| this.style.background = ''; | |
| }, 2000); | |
| }); | |
| }); | |
| } | |
| function initializeCart() { | |
| let cartCount = 0; | |
| window.addToCart = function(productName) { | |
| cartCount++; | |
| const cartCountElement = document.querySelector('.cart-count'); | |
| if (cartCountElement) { | |
| cartCountElement.textContent = cartCount; | |
| cartCountElement.style.display = 'block'; | |
| // Animate cart count | |
| cartCountElement.style.transform = 'scale(1.3)'; | |
| setTimeout(() => { | |
| cartCountElement.style.transform = 'scale(1)'; | |
| }, 200); | |
| } | |
| showNotification(`${productName} added to cart!`, 'info'); | |
| }; | |
| } | |
| function initializeSearch() { | |
| const searchInput = document.querySelector('.search-bar input'); | |
| const searchBtn = document.querySelector('.search-btn'); | |
| if (searchInput && searchBtn) { | |
| function performSearch() { | |
| const query = searchInput.value.trim(); | |
| if (query) { | |
| showNotification(`Searching for: "${query}"`, 'info'); | |
| // In a real app, this would perform the actual search | |
| } | |
| } | |
| searchBtn.addEventListener('click', performSearch); | |
| searchInput.addEventListener('keypress', function(e) { | |
| if (e.key === 'Enter') { | |
| performSearch(); | |
| } | |
| }); | |
| } | |
| } | |
| function initializeCards() { | |
| // Enhanced card animations with intersection observer | |
| const cards = document.querySelectorAll('.feature-card, .project-card, .service-card, .post-card, .product-card, .category-card'); | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach((entry, index) => { | |
| if (entry.isIntersecting) { | |
| setTimeout(() => { | |
| entry.target.style.opacity = '1'; | |
| entry.target.style.transform = 'translateY(0)'; | |
| }, index * 100); // Staggered animation | |
| } | |
| }); | |
| }, { | |
| threshold: 0.1, | |
| rootMargin: '0px 0px -50px 0px' | |
| }); | |
| cards.forEach((card, index) => { | |
| card.style.opacity = '0'; | |
| card.style.transform = 'translateY(30px)'; | |
| card.style.transition = `opacity 0.6s ease ${index * 0.1}s, transform 0.6s ease ${index * 0.1}s`; | |
| observer.observe(card); | |
| }); | |
| } | |
| function initializeAnimations() { | |
| // Parallax effect for hero section | |
| window.addEventListener('scroll', function() { | |
| const scrolled = window.pageYOffset; | |
| const hero = document.querySelector('.hero'); | |
| if (hero) { | |
| const rate = scrolled * -0.5; | |
| hero.style.transform = `translateY(${rate}px)`; | |
| } | |
| }); | |
| // Add typing effect to hero text | |
| const heroHeading = document.querySelector('.hero-content h1'); | |
| if (heroHeading && heroHeading.textContent.length > 20) { | |
| const originalText = heroHeading.textContent; | |
| heroHeading.textContent = ''; | |
| setTimeout(() => { | |
| typeWriter(heroHeading, originalText, 100); | |
| }, 500); | |
| } | |
| // Add counter animations for prices | |
| const priceElements = document.querySelectorAll('.price'); | |
| const priceObserver = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| const priceText = entry.target.textContent; | |
| const priceNumber = parseFloat(priceText.replace(/[^0-9.]/g, '')); | |
| animateCounter(entry.target, priceNumber); | |
| priceObserver.unobserve(entry.target); | |
| } | |
| }); | |
| }); | |
| priceElements.forEach(price => { | |
| priceObserver.observe(price); | |
| }); | |
| } | |
| // Utility functions | |
| function typeWriter(element, text, speed = 50) { | |
| let i = 0; | |
| element.innerHTML = ''; | |
| function type() { | |
| if (i < text.length) { | |
| element.innerHTML += text.charAt(i); | |
| i++; | |
| setTimeout(type, speed); | |
| } | |
| } | |
| type(); | |
| } | |
| function animateCounter(element, target, duration = 2000) { | |
| let start = 0; | |
| const increment = target / (duration / 16); | |
| function updateCounter() { | |
| start += increment; | |
| if (start < target) { | |
| element.textContent = '$' + Math.floor(start).toFixed(2); | |
| requestAnimationFrame(updateCounter); | |
| } else { | |
| element.textContent = '$' + target.toFixed(2); | |
| } | |
| } | |
| updateCounter(); | |
| } | |
| function showNotification(message, type = 'info') { | |
| // Create notification element | |
| const notification = document.createElement('div'); | |
| notification.className = `notification notification-${type}`; | |
| notification.textContent = message; | |
| // Style the notification | |
| Object.assign(notification.style, { | |
| position: 'fixed', | |
| top: '20px', | |
| right: '20px', | |
| padding: '15px 20px', | |
| borderRadius: '8px', | |
| color: 'white', | |
| fontWeight: '500', | |
| zIndex: '10000', | |
| transform: 'translateX(100%)', | |
| transition: 'transform 0.3s ease', | |
| maxWidth: '300px' | |
| }); | |
| // Set colors based on type | |
| const colors = { | |
| success: '#28a745', | |
| error: '#dc3545', | |
| info: '#007bff', | |
| warning: '#ffc107' | |
| }; | |
| notification.style.backgroundColor = colors[type] || colors.info; | |
| // Add to document | |
| document.body.appendChild(notification); | |
| // Animate in | |
| setTimeout(() => { | |
| notification.style.transform = 'translateX(0)'; | |
| }, 100); | |
| // Remove after delay | |
| setTimeout(() => { | |
| notification.style.transform = 'translateX(100%)'; | |
| setTimeout(() => { | |
| if (notification.parentNode) { | |
| notification.parentNode.removeChild(notification); | |
| } | |
| }, 300); | |
| }, 3000); | |
| } | |
| // Performance monitoring | |
| if (typeof window.performance !== 'undefined') { | |
| window.addEventListener('load', function() { | |
| setTimeout(() => { | |
| const perfData = window.performance.timing; | |
| const loadTime = perfData.loadEventEnd - perfData.navigationStart; | |
| console.log(`Page load time: ${loadTime}ms`); | |
| }, 0); | |
| }); | |
| } | |
| }); | |
| ''' | |
| if complexity == "Advanced": | |
| base_js += ''' | |
| // Advanced JavaScript features | |
| class AdvancedFeatures { | |
| constructor() { | |
| this.init(); | |
| } | |
| init() { | |
| this.initWebGL(); | |
| this.initServiceWorker(); | |
| this.initAnalytics(); | |
| this.initAccessibility(); | |
| } | |
| initWebGL() { | |
| // Simple WebGL demo for advanced features | |
| const canvas = document.createElement('canvas'); | |
| canvas.style.cssText = 'position: absolute; top: 0; left: 0; z-index: -1; opacity: 0.1;'; | |
| document.body.appendChild(canvas); | |
| if (canvas.getContext) { | |
| this.initParticles(canvas); | |
| } | |
| } | |
| initParticles(canvas) { | |
| const ctx = canvas.getContext('2d'); | |
| canvas.width = window.innerWidth; | |
| canvas.height = window.innerHeight; | |
| const particles = []; | |
| for (let i = 0; i < 50; i++) { | |
| particles.push({ | |
| x: Math.random() * canvas.width, | |
| y: Math.random() * canvas.height, | |
| vx: (Math.random() - 0.5) * 0.5, | |
| vy: (Math.random() - 0.5) * 0.5 | |
| }); | |
| } | |
| const animate = () => { | |
| ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| particles.forEach(particle => { | |
| particle.x += particle.vx; | |
| particle.y += particle.vy; | |
| if (particle.x < 0 || particle.x > canvas.width) particle.vx *= -1; | |
| if (particle.y < 0 || particle.y > canvas.height) particle.vy *= -1; | |
| ctx.beginPath(); | |
| ctx.arc(particle.x, particle.y, 1, 0, Math.PI * 2); | |
| ctx.fillStyle = 'rgba(0, 123, 255, 0.5)'; | |
| ctx.fill(); | |
| }); | |
| requestAnimationFrame(animate); | |
| }; | |
| animate(); | |
| window.addEventListener('resize', () => { | |
| canvas.width = window.innerWidth; | |
| canvas.height = window.innerHeight; | |
| }); | |
| } | |
| initServiceWorker() { | |
| if ('serviceWorker' in navigator) { | |
| // Register service worker for PWA functionality | |
| navigator.serviceWorker.register('/sw.js').then(registration => { | |
| console.log('SW registered: ', registration); | |
| }).catch(registrationError => { | |
| console.log('SW registration failed: ', registrationError); | |
| }); | |
| } | |
| } | |
| initAnalytics() { | |
| // Simple analytics tracking | |
| this.trackUserInteractions(); | |
| } | |
| trackUserInteractions() { | |
| document.addEventListener('click', function(e) { | |
| if (e.target.tagName === 'BUTTON') { | |
| console.log('Button clicked:', e.target.textContent); | |
| // In a real app, send to analytics service | |
| } | |
| }); | |
| } | |
| initAccessibility() { | |
| // Enhance keyboard navigation | |
| document.addEventListener('keydown', function(e) { | |
| if (e.key === 'Tab') { | |
| document.body.classList.add('keyboard-navigation'); | |
| } | |
| }); | |
| document.addEventListener('mousedown', function() { | |
| document.body.classList.remove('keyboard-navigation'); | |
| }); | |
| } | |
| } | |
| // Initialize advanced features | |
| new AdvancedFeatures(); | |
| // Add keyboard shortcuts | |
| document.addEventListener('keydown', function(e) { | |
| // Ctrl/Cmd + K for search | |
| if ((e.ctrlKey || e.metaKey) && e.key === 'k') { | |
| e.preventDefault(); | |
| const searchInput = document.querySelector('.search-bar input'); | |
| if (searchInput) { | |
| searchInput.focus(); | |
| } | |
| } | |
| }); | |
| // Progressive enhancement | |
| if ('IntersectionObserver' in window) { | |
| // Lazy loading for images (if any were added) | |
| const imageObserver = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| const img = entry.target; | |
| if (img.dataset.src) { | |
| img.src = img.dataset.src; | |
| img.removeAttribute('data-src'); | |
| imageObserver.unobserve(img); | |
| } | |
| } | |
| }); | |
| }); | |
| document.querySelectorAll('img[data-src]').forEach(img => { | |
| imageObserver.observe(img); | |
| }); | |
| } | |
| ''' | |
| return base_js | |
| def enhance_html_with_seo_accessibility(html_code: str, description: str) -> str: | |
| """Add SEO and accessibility improvements to HTML""" | |
| # Add meta tags for SEO | |
| seo_meta = f''' | |
| <meta name="description" content="Generated website based on: {description}"> | |
| <meta name="keywords" content="{description.split()[:10]}"> | |
| <meta name="author" content="AI Web Coder"> | |
| <meta property="og:title" content="Generated Website"> | |
| <meta property="og:description" content="Generated website based on: {description}"> | |
| <meta property="og:type" content="website"> | |
| <meta name="twitter:card" content="summary"> | |
| <meta name="twitter:title" content="Generated Website"> | |
| <meta name="twitter:description" content="Generated website based on: {description}"> | |
| <link rel="canonical" href="#"> | |
| ''' | |
| # Add accessibility improvements | |
| accessibility_fixes = ''' | |
| <meta name="theme-color" content="#007bff"> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> | |
| ''' | |
| # Insert meta tags after the existing charset meta tag | |
| html_code = html_code.replace( | |
| '<meta charset="UTF-8">', | |
| '<meta charset="UTF-8">\n ' + seo_meta.strip() + '\n ' + accessibility_fixes.strip() | |
| ) | |
| # Add skip link for accessibility | |
| skip_link = ''' <a href="#main" class="skip-link">Skip to main content</a>''' | |
| html_code = html_code.replace('<body>', '<body>\n' + skip_link) | |
| # Add ARIA labels and improve accessibility | |
| html_code = html_code.replace('<nav>', '<nav role="navigation" aria-label="Main navigation">') | |
| return html_code | |
| def analyze_code_quality(html_code: str, css_code: str, js_code: str) -> Dict[str, Any]: | |
| """Analyze code quality and provide metrics""" | |
| score = 0 | |
| tips = [] | |
| accessibility_score = 0 | |
| seo_score = 0 | |
| # HTML Quality Checks | |
| if '<!DOCTYPE html>' in html_code: | |
| score += 5 | |
| if 'lang="en"' in html_code: | |
| score += 5 | |
| accessibility_score += 10 | |
| if 'viewport' in html_code: | |
| score += 5 | |
| seo_score += 10 | |
| if 'aria-label' in html_code or 'alt=' in html_code: | |
| accessibility_score += 15 | |
| if '<meta name="description"' in html_code: | |
| seo_score += 15 | |
| # CSS Quality Checks | |
| if ':root' in css_code or 'var(' in css_code: | |
| score += 10 | |
| if '@media' in css_code: | |
| score += 10 | |
| accessibility_score += 10 | |
| if 'transition' in css_code: | |
| score += 5 | |
| if 'flexbox' in css_code or 'grid' in css_code: | |
| score += 5 | |
| # JavaScript Quality Checks | |
| if 'addEventListener' in js_code: | |
| score += 10 | |
| if 'DOMContentLoaded' in js_code: | |
| score += 10 | |
| if 'const ' in js_code or 'let ' in js_code: | |
| score += 5 | |
| if 'async' in js_code or 'await' in js_code: | |
| score += 5 | |
| # Accessibility Score (max 100) | |
| accessibility_score = min(accessibility_score, 100) | |
| # SEO Score (max 100) | |
| seo_score = min(seo_score, 100) | |
| # Generate tips | |
| if score < 50: | |
| tips.append("Consider adding more semantic HTML elements") | |
| if accessibility_score < 70: | |
| tips.append("Add more ARIA labels and alt text for images") | |
| if seo_score < 70: | |
| tips.append("Include meta descriptions and proper heading structure") | |
| if ':root' not in css_code: | |
| tips.append("Use CSS custom properties for better maintainability") | |
| if '@media' not in css_code: | |
| tips.append("Add responsive design with media queries") | |
| if 'addEventListener' not in js_code: | |
| tips.append("Use modern JavaScript event handling") | |
| if not tips: | |
| tips.append("Great code quality! Your website follows modern best practices.") | |
| return { | |
| 'score': min(score, 100), | |
| 'tips': tips, | |
| 'accessibility': accessibility_score, | |
| 'seo': seo_score | |
| } | |
| def save_project(project_name: str, description: str, complexity: str, html_code: str, css_code: str, js_code: str) -> str: | |
| """Save project data (simulated)""" | |
| project_data = { | |
| "name": project_name, | |
| "description": description, | |
| "complexity": complexity, | |
| "html": html_code, | |
| "css": css_code, | |
| "js": js_code, | |
| "timestamp": time.time() | |
| } | |
| # In a real implementation, this would save to a database | |
| return f"Project '{project_name}' saved successfully! (Simulated - would save to database)" | |
| def load_projects() -> List[str]: | |
| """Load saved projects (simulated)""" | |
| # In a real implementation, this would load from a database | |
| return [ | |
| "Portfolio Site", | |
| "Business Landing Page", | |
| "E-commerce Store", | |
| "Blog Template" | |
| ] | |
| # Enhanced theme with better styling | |
| enhanced_theme = gr.themes.Soft( | |
| primary_hue="blue", | |
| secondary_hue="indigo", | |
| neutral_hue="slate", | |
| font=gr.themes.GoogleFont("Inter"), | |
| text_size="lg", | |
| spacing_size="lg", | |
| radius_size="md" | |
| ).set( | |
| button_primary_background_fill="*primary |