Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>AI Clone - Create Your Digital Twin</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .gradient-bg { | |
| background: linear-gradient(135deg, #f9f9f9 0%, #f0f4ff 50%, #f5f7fa 100%); | |
| } | |
| .upload-area { | |
| border: 2px dashed #cbd5e0; | |
| transition: all 0.3s ease; | |
| } | |
| .upload-area:hover { | |
| border-color: #667eea; | |
| background-color: rgba(102, 126, 234, 0.05); | |
| } | |
| .progress-bar { | |
| transition: width 0.5s ease; | |
| } | |
| .avatar-preview { | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); | |
| } | |
| .plan-card { | |
| transition: all 0.3s ease; | |
| } | |
| .plan-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); | |
| } | |
| .selected-plan { | |
| border-color: #667eea; | |
| background-color: rgba(102, 126, 234, 0.05); | |
| } | |
| .toast { | |
| animation: slideIn 0.5s, fadeOut 0.5s 2.5s; | |
| } | |
| @keyframes slideIn { | |
| from { transform: translateX(100%); } | |
| to { transform: translateX(0); } | |
| } | |
| @keyframes fadeOut { | |
| from { opacity: 1; } | |
| to { opacity: 0; } | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen bg-gray-50"> | |
| <!-- Navigation Bar --> | |
| <nav class="bg-gray-900 shadow-sm sticky top-0 z-10 border-b border-purple-500"> | |
| <div class="container mx-auto px-4 py-3 flex justify-between items-center"> | |
| <div class="flex items-center"> | |
| <video class="w-48 h-12 rounded-md object-cover mr-2" src="https://huggingface.co/rahul7star/ohamlab/resolve/main/ohamlab.mp4" autoplay muted loop playsinline></video> | |
| <span class="text-xl font-bold text-purple-200">OhamLab</span> | |
| </div> | |
| <div class="hidden md:flex space-x-8"> | |
| <a href="#home" class="nav-link text-purple-200 hover:text-white font-medium">Home</a> | |
| <a href="#features" class="nav-link text-purple-200 hover:text-white font-medium">Features</a> | |
| <a href="#create" class="nav-link text-purple-200 hover:text-white font-medium">Create</a> | |
| <a href="#pricing" class="nav-link text-purple-200 hover:text-white font-medium">Pricing</a> | |
| <button id="demo-toggle" class="text-purple-200 hover:text-white font-medium">Demo</button> | |
| </div> | |
| <button id="mobile-menu-button" class="md:hidden text-gray-600"> | |
| <i class="fas fa-bars text-xl"></i> | |
| </button> | |
| </div> | |
| </nav> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- Header --> | |
| <header class="flex justify-between items-center mb-12"> | |
| <div class="flex items-center"> | |
| <video class="w-24 h-12 rounded-md object-cover mr-3" src="https://huggingface.co/rahul7star/ohamlab/resolve/main/ohamlab.mp4" autoplay muted loop playsinline></video> | |
| <h1 class="text-2xl font-bold text-gray-800">OhamLab</h1> | |
| </div> | |
| <div id="auth-section"> | |
| <button id="sign-in-btn" class="bg-white text-gray-700 px-6 py-2 rounded-full shadow-md hover:bg-gray-100 transition flex items-center"> | |
| <i class="fab fa-google text-red-500 mr-2"></i> | |
| Sign In with Google | |
| </button> | |
| <button id="guest-btn" class="ml-2 bg-gray-200 text-gray-700 px-6 py-2 rounded-full shadow-md hover:bg-gray-300 transition"> | |
| Continue as Guest | |
| </button> | |
| <button id="logout-guest-btn" class="hidden ml-2 bg-red-100 text-red-700 px-6 py-2 rounded-full shadow-md hover:bg-red-200 transition"> | |
| Logout Guest | |
| </button> | |
| <div id="user-profile" class="hidden flex items-center space-x-4"> | |
| <img id="user-avatar" class="w-10 h-10 rounded-full" src="" alt="User Avatar"> | |
| <span id="user-name" class="font-medium text-gray-700"></span> | |
| <button id="sign-out-btn" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-sign-out-alt"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Content --> | |
| <main class="max-w-4xl mx-auto"> | |
| <!-- Home Section --> | |
| <section id="home" class="text-center py-16"> | |
| <h1 class="text-4xl font-bold text-gray-800 mb-4">OhamLab - Create Your Digital Twin</h1> | |
| <p class="text-xl text-gray-600 mb-8">Generate AI-powered avatars that look just like you</p> | |
| <div class="flex space-x-4 justify-center"> | |
| <button id="get-started-btn" class="bg-gradient-to-r from-purple-500 to-pink-600 text-white px-8 py-3 rounded-full font-medium shadow-lg hover:opacity-90 transition"> | |
| Get Started | |
| </button> | |
| <button id="demo-btn" class="bg-white text-indigo-600 border-2 border-indigo-600 px-8 py-3 rounded-full font-medium shadow-lg hover:bg-indigo-50 transition"> | |
| See Demo | |
| </button> | |
| </div> | |
| </section> | |
| <!-- Features Section --> | |
| <section id="features" class="mb-16"> | |
| <h2 class="text-2xl font-bold text-gray-800 mb-8 text-center">Key Features</h2> | |
| <div class="grid md:grid-cols-3 gap-8"> | |
| <div class="bg-white p-6 rounded-xl shadow-md border border-indigo-100"> | |
| <div class="text-indigo-500 text-3xl mb-4"> | |
| <i class="fas fa-user-circle"></i> | |
| </div> | |
| <h3 class="text-lg font-semibold mb-2">Realistic Avatars</h3> | |
| <p class="text-gray-600">Generate high-quality avatars that capture your unique features.</p> | |
| </div> | |
| <div class="bg-white p-6 rounded-xl shadow-md"> | |
| <div class="text-purple-500 text-3xl mb-4"> | |
| <i class="fas fa-video"></i> | |
| </div> | |
| <h3 class="text-lg font-semibold mb-2">Animated Videos</h3> | |
| <p class="text-gray-600">Bring your avatar to life with custom animated videos.</p> | |
| </div> | |
| <div class="bg-white p-6 rounded-xl shadow-md"> | |
| <div class="text-pink-500 text-3xl mb-4"> | |
| <i class="fas fa-magic"></i> | |
| </div> | |
| <h3 class="text-lg font-semibold mb-2">AI Magic</h3> | |
| <p class="text-gray-600">Use AI to transform your photos into stunning digital art.</p> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Advanced AI Solutions --> | |
| <section id="ai-solutions" class="mb-16 bg-gradient-to-r from-indigo-50 to-purple-50 py-12 rounded-2xl"> | |
| <h2 class="text-3xl font-bold text-gray-800 mb-8 text-center">Advanced AI Solution++s</h2> | |
| <div class="grid md:grid-cols-3 gap-8 max-w-6xl mx-auto px-4"> | |
| <!-- AI Knowledge Agents --> | |
| <div onclick="openModal('knowledgeModal')" | |
| class="cursor-pointer bg-white p-6 rounded-xl shadow-lg border border-indigo-100 hover:shadow-xl transition transform hover:-translate-y-1"> | |
| <div class="text-indigo-500 text-4xl mb-4"> | |
| <i class="fas fa-brain"></i> | |
| </div> | |
| <h3 class="text-xl font-semibold mb-2">AI Knowledge Agents</h3> | |
| <p class="text-gray-600">Enterprise-grade AI agents that manage knowledge, research, and internal documentation for high, stable, recurring revenue.</p> | |
| </div> | |
| <!-- AI Business Agents --> | |
| <div onclick="openModal('businessModal')" | |
| class="cursor-pointer bg-white p-6 rounded-xl shadow-lg border border-purple-100 hover:shadow-xl transition transform hover:-translate-y-1"> | |
| <div class="text-purple-500 text-4xl mb-4"> | |
| <i class="fas fa-robot"></i> | |
| </div> | |
| <h3 class="text-xl font-semibold mb-2">AI Business Agents</h3> | |
| <p class="text-gray-600">Automate support, sales, HR, and customer interaction with high scalability and recurring revenue potential.</p> | |
| </div> | |
| <!-- AI Education & Training Bots --> | |
| <div onclick="openModal('educationModal')" | |
| class="cursor-pointer bg-white p-6 rounded-xl shadow-lg border border-pink-100 hover:shadow-xl transition transform hover:-translate-y-1"> | |
| <div class="text-pink-500 text-4xl mb-4"> | |
| <i class="fas fa-chalkboard-teacher"></i> | |
| </div> | |
| <h3 class="text-xl font-semibold mb-2">AI Education & Training Bots</h3> | |
| <p class="text-gray-600">Deploy AI tutors and training bots for schools and edtech platforms in Australia & India, generating high-value recurring opportunities.</p> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Modals --> | |
| <div id="knowledgeModal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> | |
| <div class="bg-white p-6 rounded-xl max-w-2xl w-full relative"> | |
| <h3 class="text-2xl font-bold mb-4">AI Knowledge Agents</h3> | |
| <p class="text-gray-600 mb-4">Our enterprise-grade AI agents help manage internal knowledge, research, and documentation to streamline workflows and improve decision-making.</p> | |
| <!-- YouTube Embed --> | |
| <div class="aspect-w-16 aspect-h-9 mb-4"> | |
| <iframe class="w-full h-64 rounded-lg" src="https://www.youtube.com/embed/YOUR_VIDEO_ID" frameborder="0" allowfullscreen></iframe> | |
| </div> | |
| <!-- Contact Form --> | |
| <form action="mailto:rahul7star@gmail.com" method="POST" enctype="text/plain" class="space-y-3"> | |
| <input type="text" name="name" placeholder="Your Name" class="w-full border rounded px-3 py-2" required> | |
| <input type="email" name="email" placeholder="Your Email" class="w-full border rounded px-3 py-2" required> | |
| <textarea name="message" placeholder="Your Message" class="w-full border rounded px-3 py-2" required></textarea> | |
| <button type="submit" class="bg-indigo-600 text-white px-4 py-2 rounded-full hover:bg-indigo-700">Send</button> | |
| </form> | |
| <button onclick="closeModal('knowledgeModal')" class="absolute top-2 right-2 text-gray-500 hover:text-gray-700"> | |
| ✕ | |
| </button> | |
| </div> | |
| </div> | |
| <div id="businessModal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> | |
| <div class="bg-white p-6 rounded-xl max-w-2xl w-full relative"> | |
| <h3 class="text-2xl font-bold mb-4">AI Business Agents</h3> | |
| <p class="text-gray-600 mb-4">Automate customer support, sales, and HR with AI-powered agents that scale with your business.</p> | |
| <div class="aspect-w-16 aspect-h-9 mb-4"> | |
| <iframe class="w-full h-64 rounded-lg" src="https://www.youtube.com/embed/YOUR_VIDEO_ID" frameborder="0" allowfullscreen></iframe> | |
| </div> | |
| <form action="mailto:rahul7star@gmail.com" method="POST" enctype="text/plain" class="space-y-3"> | |
| <input type="text" name="name" placeholder="Your Name" class="w-full border rounded px-3 py-2" required> | |
| <input type="email" name="email" placeholder="Your Email" class="w-full border rounded px-3 py-2" required> | |
| <textarea name="message" placeholder="Your Message" class="w-full border rounded px-3 py-2" required></textarea> | |
| <button type="submit" class="bg-purple-600 text-white px-4 py-2 rounded-full hover:bg-purple-700">Send</button> | |
| </form> | |
| <button onclick="closeModal('businessModal')" class="absolute top-2 right-2 text-gray-500 hover:text-gray-700"> | |
| ✕ | |
| </button> | |
| </div> | |
| </div> | |
| <div id="educationModal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> | |
| <div class="bg-white p-6 rounded-xl max-w-2xl w-full relative"> | |
| <h3 class="text-2xl font-bold mb-4">AI Education & Training Bots</h3> | |
| <p class="text-gray-600 mb-4">Smart tutors and training bots designed for schools, universities, and edtech companies in Australia and India.</p> | |
| <div class="aspect-w-16 aspect-h-9 mb-4"> | |
| <iframe class="w-full h-64 rounded-lg" src="https://www.youtube.com/embed/YOUR_VIDEO_ID" frameborder="0" allowfullscreen></iframe> | |
| </div> | |
| <form action="mailto:rahul7star@gmail.com" method="POST" enctype="text/plain" class="space-y-3"> | |
| <input type="text" name="name" placeholder="Your Name" class="w-full border rounded px-3 py-2" required> | |
| <input type="email" name="email" placeholder="Your Email" class="w-full border rounded px-3 py-2" required> | |
| <textarea name="message" placeholder="Your Message" class="w-full border rounded px-3 py-2" required></textarea> | |
| <button type="submit" class="bg-pink-600 text-white px-4 py-2 rounded-full hover:bg-pink-700">Send</button> | |
| </form> | |
| <button onclick="closeModal('educationModal')" class="absolute top-2 right-2 text-gray-500 hover:text-gray-700"> | |
| ✕ | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Social Promo Box --> | |
| <section id="social-promo" class="mb-16 bg-gradient-to-r from-purple-50 to-indigo-50 py-12 rounded-2xl hidden"> | |
| <div class="max-w-6xl mx-auto px-4"> | |
| <h2 class="text-3xl font-bold text-gray-800 mb-6 text-center">See Our AI in Action</h2> | |
| <p class="text-lg text-gray-600 mb-8 text-center">Explore our latest creations on social media</p> | |
| <!-- Full-width video --> | |
| <div class="w-full aspect-video bg-black rounded-xl overflow-hidden mb-6"> | |
| <iframe | |
| class="w-full h-full" | |
| src="about:blank" | |
| data-src="https://www.youtube.com/embed/videoseries?list=PL8HXQOLwB6k0N8m2Ql2paDAY_n_KdXSSM" | |
| allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" | |
| allowfullscreen | |
| title="YouTube Playlist Player"> | |
| </iframe> | |
| </div> | |
| <!-- Small social buttons centered below --> | |
| <div class="flex justify-center gap-4"> | |
| <a href="https://www.instagram.com/ohamlab/reels" target="_blank" | |
| class="flex items-center gap-2 text-xs bg-gradient-to-r from-pink-500 to-purple-500 text-white px-3 py-1.5 rounded-full shadow hover:opacity-90 transition"> | |
| <i class="fab fa-instagram text-base"></i> | |
| <span>Instagram</span> | |
| </a> | |
| <a href="https://www.youtube.com/@Rahul7starAI/shorts" target="_blank" | |
| class="flex items-center gap-2 text-xs bg-gradient-to-r from-red-600 to-red-500 text-white px-3 py-1.5 rounded-full shadow hover:opacity-90 transition"> | |
| <i class="fab fa-youtube text-base"></i> | |
| <span>YouTube</span> | |
| </a> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Upload Section --> | |
| <section id="create" class="mb-12 bg-white rounded-xl shadow-lg p-6 hidden border border-gray-200"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-6">Create Your AI Clone</h2> | |
| <div class="grid md:grid-cols-2 gap-6"> | |
| <!-- Image Upload --> | |
| <div class="upload-area rounded-lg p-8 text-center cursor-pointer" id="image-upload"> | |
| <i class="fas fa-images text-indigo-500 text-4xl mb-4"></i> | |
| <h3 class="text-lg font-medium text-gray-700 mb-2">Upload Images</h3> | |
| <p class="text-gray-500 mb-4">Upload at least 5 images of yourself from different angles</p> | |
| <input type="file" id="image-input" class="hidden" accept="image/*" multiple> | |
| <button class="bg-indigo-100 text-indigo-600 px-4 py-2 rounded-full text-sm font-medium"> | |
| Select Files | |
| </button> | |
| </div> | |
| <!-- ZIP Upload --> | |
| <div class="upload-area rounded-lg p-8 text-center cursor-pointer" id="zip-upload"> | |
| <i class="fas fa-file-archive text-purple-500 text-4xl mb-4"></i> | |
| <h3 class="text-lg font-medium text-gray-700 mb-2">Upload ZIP File</h3> | |
| <p class="text-gray-500 mb-4">Compress your images into a single .zip file</p> | |
| <input type="file" id="zip-input" class="hidden" accept=".zip"> | |
| <button class="bg-purple-100 text-purple-600 px-4 py-2 rounded-full text-sm font-medium"> | |
| Select ZIP File | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Image Preview Carousel --> | |
| <div id="image-preview-container" class="hidden mt-8"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-md font-medium text-gray-700"> | |
| <span id="image-count">0</span> images selected | |
| </h3> | |
| <button id="clear-images" class="text-red-500 text-sm font-medium">Clear all</button> | |
| </div> | |
| <div id="image-carousel" class="flex space-x-4 overflow-x-auto pb-4"> | |
| <!-- Images will be added here dynamically --> | |
| </div> | |
| </div> | |
| <!-- Train Model Button --> | |
| <div id="train-model-section" class="hidden mt-8 text-center"> | |
| <button id="train-model-btn" class="bg-gradient-to-r from-indigo-500 to-purple-600 text-white px-8 py-3 rounded-full font-medium shadow-lg hover:opacity-90 transition"> | |
| Train Your AI Model | |
| </button> | |
| </div> | |
| <!-- Training Progress --> | |
| <div id="training-progress" class="hidden mt-8"> | |
| <div class="flex justify-between mb-2"> | |
| <span class="text-sm font-medium text-gray-700">Training in progress...</span> | |
| <span id="progress-percent" class="text-sm font-medium text-gray-700">0%</span> | |
| </div> | |
| <div class="w-full bg-gray-200 rounded-full h-2.5"> | |
| <div id="progress-bar" class="bg-gradient-to-r from-indigo-500 to-purple-600 h-2.5 rounded-full progress-bar" style="width: 0%"></div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- AI Clone Results --> | |
| <section id="results-section" class="hidden mb-12 bg-white rounded-xl shadow-lg p-6"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-6">Your AI Clone Results</h2> | |
| <div class="flex flex-col items-center"> | |
| <div class="avatar-preview w-64 h-64 rounded-full bg-gray-100 mb-6 overflow-hidden flex items-center justify-center"> | |
| <img id="generated-avatar" src="" alt="Generated Avatar" class="hidden w-full h-full object-cover"> | |
| <i class="fas fa-user text-gray-400 text-6xl" id="avatar-placeholder"></i> | |
| </div> | |
| <button id="recreate-btn" class="bg-indigo-600 text-white px-6 py-2 rounded-full font-medium hover:bg-indigo-700 transition"> | |
| <i class="fas fa-sync-alt mr-2"></i> Recreate | |
| </button> | |
| <div class="mt-6 flex space-x-4"> | |
| <button class="share-btn bg-blue-500 text-white px-4 py-2 rounded-full text-sm font-medium hover:bg-blue-600 transition"> | |
| <i class="fab fa-twitter mr-2"></i> Share to Twitter | |
| </button> | |
| <button class="share-btn bg-pink-500 text-white px-4 py-2 rounded-full text-sm font-medium hover:bg-pink-600 transition"> | |
| <i class="fab fa-instagram mr-2"></i> Share to Instagram | |
| </button> | |
| <button class="share-btn bg-gray-700 text-white px-4 py-2 rounded-full text-sm font-medium hover:bg-gray-800 transition"> | |
| <i class="fas fa-link mr-2"></i> Copy Link | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Bring Avatar to Life --> | |
| <section id="animate-section" class="hidden mb-12 bg-white rounded-xl shadow-lg p-6"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-6">Bring Your Avatar to Life</h2> | |
| <div class="mb-6"> | |
| <label for="prompt-input" class="block text-sm font-medium text-gray-700 mb-2">Enter a prompt for your avatar</label> | |
| <textarea id="prompt-input" rows="3" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-indigo-500 focus:border-indigo-500" placeholder="E.g., 'A professional headshot with a blue background'"></textarea> | |
| </div> | |
| <button id="generate-video-btn" class="bg-gradient-to-r from-purple-500 to-pink-600 text-white px-8 py-3 rounded-full font-medium shadow-lg hover:opacity-90 transition"> | |
| <i class="fas fa-film mr-2"></i> Generate Video | |
| </button> | |
| <!-- Video Loading --> | |
| <div id="video-loading" class="hidden mt-8 text-center"> | |
| <div class="inline-block animate-spin rounded-full h-10 w-10 border-t-2 border-b-2 border-purple-500 mb-4"></div> | |
| <p class="text-gray-700">Generating your animated avatar... This may take a few moments.</p> | |
| </div> | |
| <!-- Video Preview --> | |
| <div id="video-preview" class="hidden mt-8"> | |
| <div class="bg-gray-100 rounded-xl overflow-hidden w-full aspect-video flex items-center justify-center"> | |
| <i class="fas fa-play-circle text-purple-500 text-6xl opacity-70" id="video-play-icon"></i> | |
| </div> | |
| <div class="mt-4 flex justify-center space-x-4"> | |
| <button class="share-btn bg-blue-500 text-white px-4 py-2 rounded-full text-sm font-medium hover:bg-blue-600 transition"> | |
| <i class="fab fa-twitter mr-2"></i> Share | |
| </button> | |
| <button class="share-btn bg-pink-500 text-white px-4 py-2 rounded-full text-sm font-medium hover:bg-pink-600 transition"> | |
| <i class="fab fa-instagram mr-2"></i> Share | |
| </button> | |
| <button class="share-btn bg-gray-700 text-white px-4 py-2 rounded-full text-sm font-medium hover:bg-gray-800 transition"> | |
| <i class="fas fa-download mr-2"></i> Download | |
| </button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Pricing Plans --> | |
| <section id="pricing" class="mb-12 bg-white rounded-xl shadow-lg p-6 border border-gray-200"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-6">Choose Your Plan</h2> | |
| <div class="grid md:grid-cols-3 gap-6"> | |
| <!-- Free Plan --> | |
| <div class="plan-card border-2 border-gray-200 rounded-xl p-6 cursor-pointer" data-plan="free"> | |
| <div class="flex justify-between items-start mb-4"> | |
| <div> | |
| <h3 class="text-lg font-bold text-gray-800">Free</h3> | |
| <p class="text-gray-600 text-sm">Basic features</p> | |
| </div> | |
| <div class="text-right"> | |
| <span class="text-2xl font-bold text-gray-800">$0</span> | |
| <span class="text-gray-500 text-sm">/request</span> | |
| </div> | |
| </div> | |
| <ul class="space-y-2 mb-6"> | |
| <li class="flex items-center text-gray-700"> | |
| <i class="fas fa-check-circle text-green-500 mr-2"></i> | |
| <span>1 AI Generation</span> | |
| </li> | |
| <li class="flex items-center text-gray-700"> | |
| <i class="fas fa-check-circle text-green-500 mr-2"></i> | |
| <span>Standard Quality</span> | |
| </li> | |
| <li class="flex items-center text-gray-500"> | |
| <i class="fas fa-times-circle text-gray-300 mr-2"></i> | |
| <span>No Video Generation</span> | |
| </li> | |
| <li class="flex items-center text-gray-500"> | |
| <i class="fas fa-times-circle text-gray-300 mr-2"></i> | |
| <span>No Priority Support</span> | |
| </li> | |
| </ul> | |
| <button class="w-full border-2 border-gray-300 text-gray-700 py-2 rounded-lg font-medium hover:bg-gray-50 transition"> | |
| Current Plan | |
| </button> | |
| </div> | |
| <!-- Pro Plan --> | |
| <div class="plan-card border-2 border-indigo-300 rounded-xl p-6 cursor-pointer bg-indigo-50" data-plan="pro"> | |
| <div class="flex justify-between items-start mb-4"> | |
| <div> | |
| <h3 class="text-lg font-bold text-gray-800">Pro</h3> | |
| <p class="text-gray-600 text-sm">For creators</p> | |
| </div> | |
| <div class="text-right"> | |
| <span id="pro-price-label" class="text-2xl font-bold text-gray-800">$20</span> | |
| <span id="pro-price-currency" class="text-gray-500 text-sm">/request</span> | |
| </div> | |
| </div> | |
| <ul class="space-y-2 mb-6"> | |
| <li class="flex items-center text-gray-700"> | |
| <i class="fas fa-check-circle text-green-500 mr-2"></i> | |
| <span>Pay-per-request</span> | |
| </li> | |
| <li class="flex items-center text-gray-700"> | |
| <i class="fas fa-check-circle text-green-500 mr-2"></i> | |
| <span>High Quality</span> | |
| </li> | |
| <li class="flex items-center text-gray-700"> | |
| <i class="fas fa-check-circle text-green-500 mr-2"></i> | |
| <span>5 Video Generations</span> | |
| </li> | |
| <li class="flex items-center text-gray-500"> | |
| <i class="fas fa-times-circle text-gray-300 mr-2"></i> | |
| <span>Standard Support</span> | |
| </li> | |
| </ul> | |
| <button id="upgrade-pro-btn" class="w-full bg-indigo-600 text-white py-2 rounded-lg font-medium hover:bg-indigo-700 transition"> | |
| Upgrade to Pro | |
| </button> | |
| </div> | |
| <!-- Studio Plan --> | |
| <div class="plan-card border-2 border-gray-200 rounded-xl p-6 cursor-pointer" data-plan="studio"> | |
| <div class="flex justify-between items-start mb-4"> | |
| <div> | |
| <h3 class="text-lg font-bold text-gray-800">Studio</h3> | |
| <p class="text-gray-600 text-sm">For professionals</p> | |
| </div> | |
| <div class="text-right"> | |
| <span class="text-2xl font-bold text-gray-800">$50</span> | |
| <span class="text-gray-500 text-sm">/request</span> | |
| </div> | |
| </div> | |
| <ul class="space-y-2 mb-6"> | |
| <li class="flex items-center text-gray-700"> | |
| <i class="fas fa-check-circle text-green-500 mr-2"></i> | |
| <span>Pay-per-request</span> | |
| </li> | |
| <li class="flex items-center text-gray-700"> | |
| <i class="fas fa-check-circle text-green-500 mr-2"></i> | |
| <span>Ultra Quality</span> | |
| </li> | |
| <li class="flex items-center text-gray-700"> | |
| <i class="fas fa-check-circle text-green-500 mr-2"></i> | |
| <span>Unlimited Videos</span> | |
| </li> | |
| <li class="flex items-center text-gray-700"> | |
| <i class="fas fa-check-circle text-green-500 mr-2"></i> | |
| <span>Priority Support</span> | |
| </li> | |
| </ul> | |
| <button class="w-full border-2 border-gray-300 text-gray-700 py-2 rounded-lg font-medium hover:bg-gray-50 transition"> | |
| Choose Studio | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Plan Confirmation --> | |
| <div id="plan-confirmation" class="hidden mt-6 p-4 bg-green-50 border border-green-200 rounded-lg text-center"> | |
| <div class="flex justify-center items-center text-green-600"> | |
| <i class="fas fa-check-circle text-2xl mr-2"></i> | |
| <span class="font-medium">Your plan has been updated successfully!</span> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="mt-12 bg-gray-50 py-8 border-t border-gray-200"> | |
| <div class="container mx-auto px-4 text-center text-gray-500"> | |
| <p>© 2025 OhamLab. All rights reserved.</p> | |
| <div class="flex justify-center space-x-4 mt-4"> | |
| <a href="https://www.instagram.com/ohamlab/" target="_blank" class="text-gray-600 hover:text-pink-500"> | |
| <i class="fab fa-instagram text-2xl"></i> | |
| </a> | |
| <a href="https://www.youtube.com/" target="_blank" class="text-gray-600 hover:text-red-500"> | |
| <i class="fab fa-youtube text-2xl"></i> | |
| </a> | |
| </div> | |
| </div> | |
| <!-- Page view counter --> | |
| <div class="fixed bottom-4 right-4 bg-gray-800 text-white px-3 py-1 rounded-full text-sm flex items-center shadow-lg"> | |
| <i class="fas fa-eye mr-2"></i> | |
| <span id="page-counter">0</span> views | |
| </div> | |
| </footer> | |
| <!-- Toast Notification --> | |
| <div id="toast" class="fixed bottom-4 right-4 hidden"> | |
| <div class="bg-gray-800 text-white px-6 py-3 rounded-lg shadow-lg flex items-center"> | |
| <i class="fas fa-check-circle text-green-400 mr-2"></i> | |
| <span id="toast-message">Link copied to clipboard!</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Demo Video Modal --> | |
| <div id="demo-modal" class="fixed inset-0 z-50 hidden flex items-center justify-center bg-black bg-opacity-75"> | |
| <div class="relative w-full max-w-4xl mx-4"> | |
| <div class="bg-white rounded-lg overflow-hidden shadow-xl"> | |
| <div class="flex justify-between items-center px-6 py-4 border-b"> | |
| <h3 class="text-xl font-semibold text-gray-800">OhamLab Demo</h3> | |
| <button id="close-modal" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times text-2xl"></i> | |
| </button> | |
| </div> | |
| <div class="p-4"> | |
| <div class="aspect-w-16 aspect-h-9"> | |
| <iframe id="demo-video" class="w-full h-96" src="https://www.youtube.com/embed/LRkj_ObV0T0?enablejsapi=1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script src="https://accounts.google.com/gsi/client" async defer></script> | |
| <script src="https://checkout.razorpay.com/v1/checkout.js"></script> | |
| <script> | |
| <!-- ADV Modal OPen popup JS --> | |
| function openModal(id){ document.getElementById(id).classList.remove('hidden'); } | |
| function closeModal(id){ document.getElementById(id).classList.add('hidden'); } | |
| // Auto-set currency & price label on load | |
| (function setLocalePrice() { | |
| const isIndia = (Intl.DateTimeFormat().resolvedOptions().timeZone || '').startsWith('Asia/Kolkata'); | |
| document.getElementById('pro-price-label').textContent = isIndia ? '₹1650' : '$20'; | |
| document.getElementById('pro-price-currency').textContent = '/month'; | |
| })(); | |
| // Central configuration – all secrets injected by Hugging-Face Space | |
| const CONFIG = { | |
| stripePubKey: "__HF_STRIPE_PUBLISHABLE_KEY__", // injected at build time | |
| googleClientId: "__HF_OAUTH_CLIENT_ID__", // injected at build time | |
| endpoints: { | |
| uploadImages: "https://rahul7star-ohamlab-ai-toolkit.hf.space/upload", | |
| uploadZip: "https://rahul7star-ohamlab-ai-toolkit.hf.space/upload-zip", | |
| trainModel: "__HF_TRAIN_MODEL__" || "https://rahul7star-ohamlab-ai-toolkit.hf.space/train", | |
| generateVideo: "https://rahul7star-ohamlab-ai-toolkit.hf.space/generate-video", | |
| updatePlan: "https://rahul7star-ohamlab-ai-toolkit.hf.space/update-plan", | |
| createCheckoutSession: "__HF_CREATE_CHECKOUT__" || "https://rahul7star-ohamlab-ai-toolkit.hf.space/create-checkout-session", | |
| oauthLogin: "__HF_OAUTH_LOGIN__" || "https://rahul7star-ohamlab-ai-toolkit.hf.space/auth/google" | |
| } | |
| }; | |
| // Demo Video Modal | |
| const demoBtn = document.getElementById('demo-btn'); | |
| const demoModal = document.getElementById('demo-modal'); | |
| const closeModal = document.getElementById('close-modal'); | |
| const demoVideo = document.getElementById('demo-video'); | |
| demoBtn.addEventListener('click', () => { | |
| demoModal.classList.remove('hidden'); | |
| document.body.style.overflow = 'hidden'; | |
| }); | |
| closeModal.addEventListener('click', () => { | |
| demoModal.classList.add('hidden'); | |
| document.body.style.overflow = 'auto'; | |
| // Reset video when closing modal | |
| demoVideo.src = demoVideo.src; | |
| }); | |
| // Close modal when clicking outside | |
| demoModal.addEventListener('click', (e) => { | |
| if (e.target === demoModal) { | |
| demoModal.classList.add('hidden'); | |
| document.body.style.overflow = 'auto'; | |
| demoVideo.src = demoVideo.src; | |
| } | |
| }); | |
| // Mock user data | |
| const mockUser = { | |
| name: "John Doe", | |
| avatar: "https://randomuser.me/api/portraits/men/1.jpg" | |
| }; | |
| // DOM Elements | |
| const signOutBtn = document.getElementById('sign-out-btn'); | |
| // Mock generated avatars | |
| const mockAvatars = [ | |
| "https://randomuser.me/api/portraits/men/2.jpg", | |
| "https://randomuser.me/api/portraits/men/3.jpg", | |
| "https://randomuser.me/api/portraits/men/4.jpg", | |
| "https://randomuser.me/api/portraits/men/5.jpg" | |
| ]; | |
| // DOM Elements | |
| const signInBtn = document.getElementById('sign-in-btn'); | |
| const userProfile = document.getElementById('user-profile'); | |
| const userName = document.getElementById('user-name'); | |
| const userAvatar = document.getElementById('user-avatar'); | |
| const imageUpload = document.getElementById('image-upload'); | |
| const zipUpload = document.getElementById('zip-upload'); | |
| const imageInput = document.getElementById('image-input'); | |
| const zipInput = document.getElementById('zip-input'); | |
| const imagePreviewContainer = document.getElementById('image-preview-container'); | |
| const imageCarousel = document.getElementById('image-carousel'); | |
| const imageCount = document.getElementById('image-count'); | |
| const clearImagesBtn = document.getElementById('clear-images'); | |
| const trainModelSection = document.getElementById('train-model-section'); | |
| const trainModelBtn = document.getElementById('train-model-btn'); | |
| const trainingProgress = document.getElementById('training-progress'); | |
| const progressBar = document.getElementById('progress-bar'); | |
| const progressPercent = document.getElementById('progress-percent'); | |
| const resultsSection = document.getElementById('results-section'); | |
| const generatedAvatar = document.getElementById('generated-avatar'); | |
| const avatarPlaceholder = document.getElementById('avatar-placeholder'); | |
| const recreateBtn = document.getElementById('recreate-btn'); | |
| const animateSection = document.getElementById('animate-section'); | |
| const promptInput = document.getElementById('prompt-input'); | |
| const generateVideoBtn = document.getElementById('generate-video-btn'); | |
| const videoLoading = document.getElementById('video-loading'); | |
| const videoPreview = document.getElementById('video-preview'); | |
| const pricingSection = document.getElementById('pricing-section'); | |
| const planCards = document.querySelectorAll('.plan-card'); | |
| const planConfirmation = document.getElementById('plan-confirmation'); | |
| const toast = document.getElementById('toast'); | |
| const toastMessage = document.getElementById('toast-message'); | |
| // State | |
| let selectedImages = []; | |
| let currentAvatarIndex = 0; | |
| let selectedPlan = 'free'; | |
| // Event Listeners | |
| signInBtn.addEventListener('click', () => googleSignIn()); | |
| signOutBtn.addEventListener('click', handleSignOut); | |
| document.getElementById('guest-btn').addEventListener('click', () => { | |
| signInBtn.classList.add('hidden'); | |
| document.getElementById('guest-btn').classList.add('hidden'); | |
| document.getElementById('logout-guest-btn').classList.remove('hidden'); | |
| userProfile.classList.add('hidden'); | |
| document.getElementById('create').classList.remove('hidden'); | |
| }); | |
| document.getElementById('logout-guest-btn').addEventListener('click', () => { | |
| document.getElementById('logout-guest-btn').classList.add('hidden'); | |
| signInBtn.classList.remove('hidden'); | |
| document.getElementById('guest-btn').classList.remove('hidden'); | |
| document.getElementById('create').classList.add('hidden'); | |
| clearImages(); | |
| window.scrollTo({ top: 0, behavior: 'smooth' }); | |
| }); | |
| document.getElementById('upgrade-pro-btn').addEventListener('click', startProCheckout); | |
| imageUpload.addEventListener('click', () => imageInput.click()); | |
| zipUpload.addEventListener('click', () => zipInput.click()); | |
| imageInput.addEventListener('change', handleImageUpload); | |
| zipInput.addEventListener('change', handleZipUpload); | |
| clearImagesBtn.addEventListener('click', clearImages); | |
| trainModelBtn.addEventListener('click', trainModel); | |
| recreateBtn.addEventListener('click', recreateAvatar); | |
| generateVideoBtn.addEventListener('click', generateVideo); | |
| planCards.forEach(card => card.addEventListener('click', () => selectPlan(card.dataset.plan))); | |
| document.querySelectorAll('.share-btn').forEach(btn => btn.addEventListener('click', showToast)); | |
| // Functions | |
| function initiateRazorpay() { | |
| const options = { | |
| key: "rzp_test_1234567890", // replace with live key for prod | |
| amount: 1900, // Rs 19 in paise | |
| currency: "INR", | |
| name: "OhamLab Pro", | |
| description: "Upgrade to Pro plan", | |
| handler: async function (response) { | |
| // response.razorpay_payment_id is the successful payment id | |
| const res = await fetch(CONFIG.endpoints.updatePlan, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ plan: "pro", payment_id: response.razorpay_payment_id }) | |
| }); | |
| if (res.ok) { | |
| showToast("Payment successful! You are now on Pro."); | |
| selectPlan("pro"); | |
| } else { | |
| showToast("Payment recorded but plan update failed."); | |
| } | |
| }, | |
| prefill: { email: "user@example.com" }, | |
| theme: { color: "#667eea" } | |
| }; | |
| const razorpay = new Razorpay(options); | |
| razorpay.open(); | |
| } | |
| // Google OAuth | |
| function googleSignIn() { | |
| google.accounts.id.initialize({ | |
| client_id: CONFIG.googleClientId, | |
| callback: handleCredentialResponse | |
| }); | |
| google.accounts.id.prompt(); | |
| } | |
| // After user picks a Google account | |
| async function handleCredentialResponse(response) { | |
| try { | |
| const res = await fetch(CONFIG.endpoints.oauthLogin, { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ credential: response.credential }) | |
| }); | |
| const data = await res.json(); | |
| if (res.ok && data.user) { | |
| signInBtn.classList.add('hidden'); | |
| userProfile.classList.remove('hidden'); | |
| userName.textContent = data.user.name; | |
| userAvatar.src = data.user.picture; | |
| document.getElementById('create').classList.remove('hidden'); | |
| } else { | |
| showToast("Login failed"); | |
| } | |
| } catch (err) { | |
| console.error(err); | |
| showToast("Login error"); | |
| } | |
| } | |
| // Stripe Checkout for Pro plan | |
| async function startProCheckout() { | |
| initiateRazorpay(); | |
| } | |
| function handleSignOut() { | |
| signInBtn.classList.remove('hidden'); | |
| userProfile.classList.add('hidden'); | |
| // Hide upload section and clear any uploaded images | |
| document.getElementById('create').classList.add('hidden'); | |
| clearImages(); | |
| // Scroll back to top | |
| window.scrollTo({ | |
| top: 0, | |
| behavior: 'smooth' | |
| }); | |
| } | |
| async function handleImageUpload(e) { | |
| const files = Array.from(e.target.files); | |
| if (files.length < 5) { | |
| alert('Please upload at least 5 images'); | |
| return; | |
| } | |
| selectedImages = files.slice(0, 5); // Limit to 5 images | |
| updateImagePreview(); | |
| // Show loading spinner | |
| const uploadSpinner = document.createElement('div'); | |
| uploadSpinner.className = 'inline-block animate-spin rounded-full h-6 w-6 border-t-2 border-b-2 border-indigo-500'; | |
| imageUpload.innerHTML = ''; | |
| imageUpload.appendChild(uploadSpinner); | |
| try { | |
| const formData = new FormData(); | |
| selectedImages.forEach(file => formData.append('files', file)); | |
| const res = await fetch(CONFIG.endpoints.uploadImages, { | |
| method: "POST", | |
| body: formData, | |
| }); | |
| if (!res.ok) throw new Error('Upload failed'); | |
| const data = await res.json(); | |
| // Restore upload area with success message | |
| imageUpload.innerHTML = ` | |
| <i class="fas fa-check-circle text-green-500 text-4xl mb-4"></i> | |
| <h3 class="text-lg font-medium text-gray-700 mb-2">Upload Complete</h3> | |
| <p class="text-gray-500 mb-4">${selectedImages.length} images uploaded successfully</p> | |
| `; | |
| // Show the train model button | |
| trainModelSection.classList.remove('hidden'); | |
| showToast('Images uploaded successfully!'); | |
| } catch (err) { | |
| console.error('Upload error:', err); | |
| // Restore original upload area | |
| imageUpload.innerHTML = ` | |
| <i class="fas fa-images text-indigo-500 text-4xl mb-4"></i> | |
| <h3 class="text-lg font-medium text-gray-700 mb-2">Upload Images</h3> | |
| <p class="text-gray-500 mb-4">Upload at least 5 images of yourself from different angles</p> | |
| <button class="bg-indigo-100 text-indigo-600 px-4 py-2 rounded-full text-sm font-medium"> | |
| Select Files | |
| </button> | |
| `; | |
| showToast('Upload failed. Please try again.'); | |
| } | |
| } | |
| async function handleZipUpload(e) { | |
| if (e.target.files.length > 0) { | |
| // Show loading spinner | |
| const uploadSpinner = document.createElement('div'); | |
| uploadSpinner.className = 'inline-block animate-spin rounded-full h-6 w-6 border-t-2 border-b-2 border-purple-500'; | |
| zipUpload.innerHTML = ''; | |
| zipUpload.appendChild(uploadSpinner); | |
| try { | |
| const formData = new FormData(); | |
| formData.append('zip', e.target.files[0]); | |
| const res = await fetch("https://rahul7star-ohamlab-ai-toolkit.hf.space/upload-zip", { | |
| method: "POST", | |
| body: formData, | |
| }); | |
| if (!res.ok) throw new Error('ZIP upload failed'); | |
| // Restore upload area with success message | |
| zipUpload.innerHTML = ` | |
| <i class="fas fa-check-circle text-green-500 text-4xl mb-4"></i> | |
| <h3 class="text-lg font-medium text-gray-700 mb-2">Upload Complete</h3> | |
| <p class="text-gray-500 mb-4">ZIP file uploaded successfully</p> | |
| `; | |
| // Show the train model button | |
| trainModelSection.classList.remove('hidden'); | |
| showToast("ZIP file uploaded successfully!"); | |
| } catch (err) { | |
| console.error('ZIP upload error:', err); | |
| // Restore original upload area | |
| zipUpload.innerHTML = ` | |
| <i class="fas fa-file-archive text-purple-500 text-4xl mb-4"></i> | |
| <h3 class="text-lg font-medium text-gray-700 mb-2">Upload ZIP File</h3> | |
| <p class="text-gray-500 mb-4">Compress your images into a single .zip file</p> | |
| <button class="bg-purple-100 text-purple-600 px-4 py-2 rounded-full text-sm font-medium"> | |
| Select ZIP File | |
| </button> | |
| `; | |
| showToast('ZIP upload failed. Please try again.'); | |
| } | |
| } | |
| } | |
| function updateImagePreview() { | |
| imageCarousel.innerHTML = ''; | |
| imageCount.textContent = selectedImages.length; | |
| selectedImages.forEach((file, index) => { | |
| const reader = new FileReader(); | |
| reader.onload = (e) => { | |
| const imgContainer = document.createElement('div'); | |
| imgContainer.className = 'flex-shrink-0 relative'; | |
| const img = document.createElement('img'); | |
| img.src = e.target.result; | |
| img.className = 'w-24 h-24 rounded-lg object-cover'; | |
| img.alt = `Preview ${index + 1}`; | |
| imgContainer.appendChild(img); | |
| imageCarousel.appendChild(imgContainer); | |
| }; | |
| reader.readAsDataURL(file); | |
| }); | |
| imagePreviewContainer.classList.remove('hidden'); | |
| } | |
| function clearImages() { | |
| selectedImages = []; | |
| imageInput.value = ''; | |
| imagePreviewContainer.classList.add('hidden'); | |
| trainModelSection.classList.add('hidden'); | |
| } | |
| async function trainModel() { | |
| // Show training progress | |
| trainingProgress.classList.remove('hidden'); | |
| trainModelSection.classList.add('hidden'); | |
| try { | |
| const data = "test" | |
| console.log('Training started:', data); | |
| let progress = 0; | |
| const targetDuration = 30 * 60 * 1000; // 30 minutes in milliseconds | |
| const intervalDuration = 2000; // Update every 2 seconds | |
| const totalTicks = targetDuration / intervalDuration; | |
| const incrementPerTick = 100 / totalTicks; | |
| const interval = setInterval(() => { | |
| progress += incrementPerTick; | |
| if (progress >= 100) progress = 100; | |
| progressBar.style.width = `${progress}%`; | |
| progressPercent.textContent = `${Math.floor(progress)}%`; | |
| if (progress === 100) { | |
| clearInterval(interval); | |
| setTimeout(() => { | |
| trainingProgress.classList.add('hidden'); | |
| showResults(); | |
| }, 500); | |
| } | |
| }, intervalDuration); | |
| } catch (err) { | |
| console.error('Training error:', err); | |
| showToast('Training failed. Please try again.'); | |
| trainingProgress.classList.add('hidden'); | |
| trainModelSection.classList.remove('hidden'); | |
| } | |
| } | |
| function showResults() { | |
| resultsSection.classList.remove('hidden'); | |
| animateSection.classList.remove('hidden'); | |
| currentAvatarIndex = 0; | |
| displayGeneratedAvatar(); | |
| } | |
| function displayGeneratedAvatar() { | |
| avatarPlaceholder.classList.add('hidden'); | |
| generatedAvatar.classList.remove('hidden'); | |
| generatedAvatar.src = mockAvatars[currentAvatarIndex]; | |
| } | |
| function recreateAvatar() { | |
| avatarPlaceholder.classList.remove('hidden'); | |
| generatedAvatar.classList.add('hidden'); | |
| // Simulate loading | |
| setTimeout(() => { | |
| currentAvatarIndex = (currentAvatarIndex + 1) % mockAvatars.length; | |
| displayGeneratedAvatar(); | |
| showToast("New avatar generated!"); | |
| }, 800); | |
| } | |
| async function generateVideo() { | |
| if (!promptInput.value.trim()) { | |
| showToast("Please enter a prompt first"); | |
| return; | |
| } | |
| videoLoading.classList.remove('hidden'); | |
| videoPreview.classList.add('hidden'); | |
| // Mock API call | |
| try { | |
| const res = await fetch(CONFIG.endpoints.generateVideo, { | |
| method: "POST", | |
| headers: { | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| prompt: promptInput.value.trim() | |
| }) | |
| }); | |
| if (!res.ok) throw new Error('Video generation failed'); | |
| const data = await res.json(); | |
| console.log('Video generated:', data); | |
| videoLoading.classList.add('hidden'); | |
| videoPreview.classList.remove('hidden'); | |
| showToast("Video generated successfully!"); | |
| } catch (err) { | |
| console.error('Video generation error:', err); | |
| showToast('Video generation failed. Please try again.'); | |
| videoLoading.classList.add('hidden'); | |
| } | |
| } | |
| async function selectPlan(plan) { | |
| selectedPlan = plan; | |
| // Mock API call | |
| try { | |
| const res = await fetch(CONFIG.endpoints.updatePlan, { | |
| method: "POST", | |
| headers: { | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| plan: plan | |
| }) | |
| }); | |
| if (!res.ok) throw new Error('Plan update failed'); | |
| const data = await res.json(); | |
| console.log('Plan updated:', data); | |
| // Update UI | |
| planCards.forEach(card => { | |
| if (card.dataset.plan === plan) { | |
| card.classList.add('selected-plan'); | |
| card.querySelector('button').classList.add('bg-indigo-600', 'text-white'); | |
| card.querySelector('button').classList.remove('border-gray-300', 'text-gray-700'); | |
| } else { | |
| card.classList.remove('selected-plan'); | |
| card.querySelector('button').classList.remove('bg-indigo-600', 'text-white'); | |
| card.querySelector('button').classList.add('border-gray-300', 'text-gray-700'); | |
| } | |
| }); | |
| // Show confirmation | |
| planConfirmation.classList.remove('hidden'); | |
| setTimeout(() => { | |
| planConfirmation.classList.add('hidden'); | |
| }, 3000); | |
| } catch (err) { | |
| console.error('Plan update error:', err); | |
| showToast('Plan update failed. Please try again.'); | |
| } | |
| } | |
| function showToast(message) { | |
| toastMessage.textContent = message; | |
| toast.classList.remove('hidden'); | |
| setTimeout(() => { | |
| toast.classList.add('hidden'); | |
| }, 3000); | |
| } | |
| // Navigation functionality | |
| document.querySelectorAll('.nav-link').forEach(link => { | |
| link.addEventListener('click', (e) => { | |
| e.preventDefault(); | |
| const targetId = link.getAttribute('href').substring(1); | |
| const targetElement = document.getElementById(targetId); | |
| if (targetElement) { | |
| window.scrollTo({ | |
| top: targetElement.offsetTop - 80, | |
| behavior: 'smooth' | |
| }); | |
| } | |
| }); | |
| }); | |
| // Get Started button | |
| document.getElementById('get-started-btn').addEventListener('click', () => { | |
| document.getElementById('sign-in-btn').click(); | |
| }); | |
| // Mobile menu toggle (placeholder - would need additional HTML/CSS) | |
| document.getElementById('mobile-menu-button').addEventListener('click', () => { | |
| showToast("Mobile menu would open here"); | |
| }); | |
| // Page view counter | |
| const pageCounter = document.getElementById('page-counter'); | |
| let views = localStorage.getItem('pageViews') || 0; | |
| views++; | |
| localStorage.setItem('pageViews', views); | |
| pageCounter.textContent = views; | |
| // Scroll navigation | |
| const scrollNav = document.getElementById('scroll-nav'); | |
| const scrollUpBtn = document.getElementById('scroll-up-btn'); | |
| const scrollDownBtn = document.getElementById('scroll-down-btn'); | |
| const sections = ['home', 'features', 'create', 'pricing']; | |
| let currentIndex = 0; | |
| // Demo toggle functionality | |
| document.getElementById('demo-toggle').addEventListener('click', () => { | |
| const promoSection = document.getElementById('social-promo'); | |
| const iframe = promoSection.querySelector('iframe'); | |
| promoSection.classList.toggle('hidden'); | |
| if (!promoSection.classList.contains('hidden')) { | |
| // Load video when showing | |
| iframe.src = iframe.dataset.src + '&autoplay=1'; | |
| // Scroll to the promo section | |
| promoSection.scrollIntoView({ behavior: 'smooth' }); | |
| } else { | |
| // Unload video when hiding | |
| iframe.src = 'about:blank'; | |
| } | |
| }); | |
| </script></body> | |
| </html> | |