CoolFace
Apppublic

Labareda1945/ai-dev-tools-hub-explorer

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
script.js462 linesDownload Raw Back to root
1 2// Authentication functions3function signInWithGoogle() {4    // Simulate Google OAuth flow5    showNotification('Connecting to Google...', 'info');6    7    setTimeout(() => {8        // Mock successful Google sign in9        const mockGoogleUser = {10            email: 'user@gmail.com',11            displayName: 'Google User',12            photoURL: 'https://picsum.photos/seed/google-user/100/100.jpg',13            provider: 'google',14            credits: 500,15            plan: 'Free Plan',16            createdAt: new Date().toISOString()17        };18        19        localStorage.setItem('user', JSON.stringify(mockGoogleUser));20        showNotification('Successfully signed in with Google!', 'success');21        22        // Redirect to home page23        setTimeout(() => {24            window.location.href = 'index.html';25        }, 1500);26    }, 2000);27}28 29function handleLogin(event) {30    if (event) event.preventDefault();31    32    const email = document.getElementById('email')?.value;33    const password = document.getElementById('password')?.value;34    35    if (!email || !password) {36        showNotification('Please fill in all fields', 'error');37        return;38    }39    40    // Simulate login process41    showNotification('Signing in...', 'info');42    43    setTimeout(() => {44        // Mock successful login45        const mockUser = {46            email: email,47            displayName: email.split('@')[0],48            credits: 1000,49            plan: 'Pro Plan',50            createdAt: new Date().toISOString()51        };52        53        localStorage.setItem('user', JSON.stringify(mockUser));54        showNotification('Login successful! Welcome back.', 'success');55        56        // Redirect to home page57        setTimeout(() => {58            window.location.href = 'index.html';59        }, 1500);60    }, 1500);61}62 63function handleRegister(event) {64    if (event) event.preventDefault();65    66    const firstName = document.getElementById('firstName')?.value;67    const lastName = document.getElementById('lastName')?.value;68    const email = document.getElementById('email')?.value;69    const password = document.getElementById('password')?.value;70    const confirmPassword = document.getElementById('confirmPassword')?.value;71    72    if (!firstName || !lastName || !email || !password || !confirmPassword) {73        showNotification('Please fill in all fields', 'error');74        return;75    }76    77    if (password !== confirmPassword) {78        showNotification('Passwords do not match', 'error');79        return;80    }81    82    if (password.length < 8) {83        showNotification('Password must be at least 8 characters long', 'error');84        return;85    }86    87    // Simulate registration process88    showNotification('Creating your account...', 'info');89    90    setTimeout(() => {91        // Mock successful registration92        const mockUser = {93            email: email,94            displayName: `${firstName} ${lastName}`,95            credits: 500, // Welcome bonus96            plan: 'Free Plan',97            createdAt: new Date().toISOString()98        };99        100        localStorage.setItem('user', JSON.stringify(mockUser));101        showNotification('Account created successfully! Welcome to AI Muse Forge!', 'success');102        103        // Redirect to home page104        setTimeout(() => {105            window.location.href = 'index.html';106        }, 1500);107    }, 2000);108}109 110function handleLogout() {111    showNotification('Signing out...', 'info');112    113    setTimeout(() => {114        localStorage.removeItem('user');115        showNotification('You have been signed out successfully', 'success');116        117        // Redirect to login page118        setTimeout(() => {119            window.location.href = 'login.html';120        }, 1000);121    }, 1000);122}123 124function togglePassword() {125    const passwordInput = document.getElementById('password');126    const passwordToggleIcon = document.getElementById('password-toggle-icon');127    128    if (passwordInput && passwordToggleIcon) {129        if (passwordInput.type === 'password') {130            passwordInput.type = 'text';131            passwordToggleIcon.setAttribute('data-feather', 'eye-off');132        } else {133            passwordInput.type = 'password';134            passwordToggleIcon.setAttribute('data-feather', 'eye');135        }136        feather.replace();137    }138}139 140function toggleConfirmPassword() {141    const confirmPasswordInput = document.getElementById('confirmPassword');142    const confirmPasswordToggleIcon = document.getElementById('confirm-password-toggle-icon');143    144    if (confirmPasswordInput && confirmPasswordToggleIcon) {145        if (confirmPasswordInput.type === 'password') {146            confirmPasswordInput.type = 'text';147            confirmPasswordToggleIcon.setAttribute('data-feather', 'eye-off');148        } else {149            confirmPasswordInput.type = 'password';150            confirmPasswordToggleIcon.setAttribute('data-feather', 'eye');151        }152        feather.replace();153    }154}155 156// Check authentication status on page load157function checkAuthStatus() {158    const user = JSON.parse(localStorage.getItem('user') || 'null');159    const currentPath = window.location.pathname;160    161    // Redirect authenticated users away from auth pages162    if (user && (currentPath.includes('login.html') || currentPath.includes('register.html'))) {163        window.location.href = 'index.html';164        return false;165    }166    167    // Redirect unauthenticated users to login if needed (for protected pages)168    if (!user && currentPath.includes('dashboard.html')) {169        window.location.href = 'login.html';170        return false;171    }172    173    return true;174}175 176// Main application script177document.addEventListener('DOMContentLoaded', function() {178    // Check authentication status first179    if (!checkAuthStatus()) {180        return;181    }182// Initialize Feather Icons183    feather.replace();184    185    // Mock API data for demonstration186    const mockModels = [187        {188            id: 1,189            name: "Cyberpunk Samurai",190            type: "LORA",191            triggerWords: ["cyber_samurai", "neon_warrior"],192            image: "http://static.photos/technology/640x360/1",193            description: "Futuristic warrior with neon enhancements"194        },195        {196            id: 2,197            name: "Fantasy Elven Queen",198            type: "LORA",199            triggerWords: ["elven_queen", "fantasy_royalty"],200            image: "http://static.photos/fantasy/640x360/2",201            description: "Ethereal elven royalty with magical aura"202        },203        {204            id: 3,205            name: "Steampunk Inventor",206            type: "LORA",207            triggerWords: ["steampunk_inventor", "gear_master"],208            image: "http://static.photos/vintage/640x360/3",209            description: "Victorian-era inventor with mechanical enhancements"210        },211        {212            id: 4,213            name: "Astral Traveler",214            type: "CHECKPOINT",215            triggerWords: ["astral", "cosmic_wanderer"],216            image: "http://static.photos/abstract/640x360/4",217            description: "Cosmic being traversing dimensional planes"218        }219    ];220 221    const mockQueue = [222        { id: 7892, status: 'PROCESSING', progress: 75 },223        { id: 7891, status: 'PENDING', progress: 0 },224        { id: 7890, status: 'QUEUED', progress: 0 }225    ];226 227    // Load models gallery228    function loadModelsGallery() {229        const gallery = document.getElementById('models-gallery');230        if (!gallery) return;231 232        gallery.innerHTML = mockModels.map(model => `233            <div class="model-card bg-gray-800/50 backdrop-blur-sm rounded-xl overflow-hidden border border-gray-700 hover-lift">234                <div class="relative h-48 overflow-hidden">235                    <img src="${model.image}" alt="${model.name}" class="w-full h-full object-cover transition-transform duration-500 hover:scale-110">236                    <div class="absolute top-3 right-3">237                        <span class="status-badge ${model.type === 'LORA' ? 'bg-secondary-900/80' : 'bg-primary-900/80'} text-xs px-2 py-1 rounded">238                            ${model.type}239                        </span>240                    </div>241                </div>242                <div class="p-4">243                    <h3 class="font-bold text-lg mb-2">${model.name}</h3>244                    <p class="text-gray-400 text-sm mb-3">${model.description}</p>245                    <div class="flex flex-wrap gap-1 mb-4">246                        ${model.triggerWords.map(word => `247                            <span class="px-2 py-1 bg-gray-900/70 text-xs rounded">${word}</span>248                        `).join('')}249                    </div>250                    <button class="w-full px-4 py-2 bg-gray-700 hover:bg-gray-600 rounded-lg text-sm transition-colors flex items-center justify-center gap-2" onclick="selectModel(${model.id})">251                        <i data-feather="plus" class="w-4 h-4"></i>252                        Select Model253                    </button>254                </div>255            </div>256        `).join('');257 258        // Re-initialize feather icons for new content259        setTimeout(() => feather.replace(), 100);260    }261 262    // Update queue display263    function updateQueueDisplay() {264        const queueList = document.getElementById('queue-list');265        if (!queueList) return;266 267        queueList.innerHTML = mockQueue.map(job => `268            <div class="flex items-center justify-between p-3 bg-gray-900/50 rounded-lg hover:bg-gray-800/70 transition-colors">269                <div class="flex items-center gap-3">270                    <div class="w-2 h-2 rounded-full ${getStatusColor(job.status)} ${job.status === 'PROCESSING' ? 'animate-pulse' : ''}"></div>271                    <div>272                        <div class="font-medium">Job #${job.id}</div>273                        <div class="text-xs text-gray-400">${getStatusText(job.status)}</div>274                    </div>275                </div>276                <div class="flex items-center gap-3">277                    ${job.status === 'PROCESSING' ? `278                        <div class="w-24 h-2 bg-gray-700 rounded-full overflow-hidden">279                            <div class="h-full bg-primary-500 rounded-full" style="width: ${job.progress}%"></div>280                        </div>281                    ` : ''}282                    <span class="text-sm ${getStatusTextColor(job.status)}">${job.status}</span>283                </div>284            </div>285        `).join('');286    }287 288    // Helper functions for status display289    function getStatusColor(status) {290        switch(status) {291            case 'PROCESSING': return 'bg-green-500';292            case 'PENDING': return 'bg-yellow-500';293            case 'QUEUED': return 'bg-blue-500';294            case 'SUCCESS': return 'bg-green-500';295            case 'FAILED': return 'bg-red-500';296            default: return 'bg-gray-500';297        }298    }299 300    function getStatusText(status) {301        switch(status) {302            case 'PROCESSING': return 'Processing on GPU #3';303            case 'PENDING': return 'Awaiting GPU allocation';304            case 'QUEUED': return 'In queue position #2';305            case 'SUCCESS': return 'Completed successfully';306            case 'FAILED': return 'Generation failed';307            default: return status;308        }309    }310 311    function getStatusTextColor(status) {312        switch(status) {313            case 'PROCESSING': return 'text-green-400';314            case 'PENDING': return 'text-yellow-400';315            case 'QUEUED': return 'text-blue-400';316            case 'SUCCESS': return 'text-green-400';317            case 'FAILED': return 'text-red-400';318            default: return 'text-gray-400';319        }320    }321 322    // Update stats with random numbers for demo323    function updateStats() {324        const stats = {325            gpuCount: Math.floor(Math.random() * 5) + 10, // 10-15326            imagesCount: Math.floor(Math.random() * 1000) + 8000, // 8000-9000327            modelsCount: Math.floor(Math.random() * 50) + 150, // 150-200328            queueTime: Math.floor(Math.random() * 30) + 30 // 30-60 seconds329        };330 331        document.getElementById('gpu-count').textContent = stats.gpuCount;332        document.getElementById('images-count').textContent = stats.imagesCount.toLocaleString();333        document.getElementById('models-count').textContent = stats.modelsCount;334        document.getElementById('queue-time').textContent = `${stats.queueTime}s`;335 336        // Animate number counting337        animateCounter('gpu-count', stats.gpuCount);338        animateCounter('images-count', stats.imagesCount);339        animateCounter('models-count', stats.modelsCount);340    }341 342    function animateCounter(elementId, target) {343        const element = document.getElementById(elementId);344        if (!element) return;345 346        const current = parseInt(element.textContent.replace(/,/g, '')) || 0;347        const increment = (target - current) / 30; // 30 frames348        let currentValue = current;349 350        const timer = setInterval(() => {351            currentValue += increment;352            if ((increment > 0 && currentValue >= target) || (increment < 0 && currentValue <= target)) {353                currentValue = target;354                clearInterval(timer);355            }356            element.textContent = Math.round(currentValue).toLocaleString();357        }, 50);358    }359 360    // Simulate queue updates361    function simulateQueueUpdates() {362        setInterval(() => {363            mockQueue.forEach(job => {364                if (job.status === 'PROCESSING' && job.progress < 100) {365                    job.progress += Math.random() * 10;366                    if (job.progress >= 100) {367                        job.progress = 100;368                        job.status = 'SUCCESS';369                    }370                } else if (job.status === 'QUEUED') {371                    job.status = 'PENDING';372                } else if (job.status === 'PENDING') {373                    job.status = 'PROCESSING';374                    job.progress = 0;375                }376            });377            updateQueueDisplay();378        }, 3000);379    }380 381    // Initialize everything382    loadModelsGallery();383    updateQueueDisplay();384    updateStats();385    simulateQueueUpdates();386 387    // Add smooth scrolling for anchor links388    document.querySelectorAll('a[href^="#"]').forEach(anchor => {389        anchor.addEventListener('click', function (e) {390            e.preventDefault();391            const target = document.querySelector(this.getAttribute('href'));392            if (target) {393                target.scrollIntoView({394                    behavior: 'smooth',395                    block: 'start'396                });397            }398        });399    });400 401    // Add floating animation to hero section402    const heroTitle = document.querySelector('h1');403    if (heroTitle) {404        heroTitle.style.animation = 'float 6s ease-in-out infinite';405    }406});407 408// Global function for model selection409window.selectModel = function(modelId) {410    const model = mockModels.find(m => m.id === modelId);411    if (model) {412        // Show notification413        showNotification(`Selected model: ${model.name}`, 'success');414        415        // Update control panel trigger words416        const promptInput = document.querySelector('textarea[placeholder*="prompt"]');417        if (promptInput) {418            const triggerWord = model.triggerWords[0];419            if (!promptInput.value.includes(triggerWord)) {420                promptInput.value = `${promptInput.value} ${triggerWord}`.trim();421            }422        }423    }424};425 426// Notification system427function showNotification(message, type = 'info') {428    const notification = document.createElement('div');429    notification.className = `fixed top-4 right-4 z-50 px-6 py-3 rounded-lg shadow-lg transform translate-x-full transition-transform duration-300 ${430        type === 'success' ? 'bg-green-900/90 border border-green-700' : 431        type === 'error' ? 'bg-red-900/90 border border-red-700' : 432        'bg-primary-900/90 border border-primary-700'433    }`;434    notification.innerHTML = `435        <div class="flex items-center gap-3">436            <i data-feather="${type === 'success' ? 'check-circle' : type === 'error' ? 'alert-circle' : 'info'}" 437               class="w-5 h-5 ${type === 'success' ? 'text-green-400' : type === 'error' ? 'text-red-400' : 'text-primary-400'}"></i>438            <span>${message}</span>439        </div>440    `;441    442    document.body.appendChild(notification);443    feather.replace();444    445    // Animate in446    setTimeout(() => {447        notification.style.transform = 'translateX(0)';448    }, 10);449    450    // Remove after 3 seconds451    setTimeout(() => {452        notification.style.transform = 'translateX(100%)';453        setTimeout(() => {454            if (notification.parentNode) {455                notification.parentNode.removeChild(notification);456            }457        }, 300);458    }, 3000);459}460 461// Export functions for use in components462window.showNotification = showNotification;