// Age verification modal functions function confirmAge() { console.log('โœ… Age confirmed - setting cookie and closing modal'); // Set age verification cookie for 30 days const expirationDate = new Date(); expirationDate.setTime(expirationDate.getTime() + (30 * 24 * 60 * 60 * 1000)); document.cookie = `ageVerified=true; expires=${expirationDate.toUTCString()}; path=/; SameSite=Lax`; // Also store in localStorage as backup localStorage.setItem('ageVerified', 'true'); localStorage.setItem('ageVerifiedDate', new Date().toISOString()); // Close modal const modal = document.getElementById('ageModal'); if (modal) { modal.style.display = 'none'; } } // Check if age verification is needed function checkAgeVerification() { // Check cookie first const cookies = document.cookie.split(';'); const ageVerifiedCookie = cookies.find(cookie => cookie.trim().startsWith('ageVerified=')); if (ageVerifiedCookie && ageVerifiedCookie.includes('true')) { console.log('โœ… Age verified via cookie'); return true; } // Check localStorage as backup const ageVerified = localStorage.getItem('ageVerified'); const ageVerifiedDate = localStorage.getItem('ageVerifiedDate'); if (ageVerified === 'true' && ageVerifiedDate) { const verifiedDate = new Date(ageVerifiedDate); const now = new Date(); const daysDiff = (now - verifiedDate) / (1000 * 60 * 60 * 24); if (daysDiff < 30) { console.log('โœ… Age verified via localStorage'); // Restore cookie const expirationDate = new Date(); expirationDate.setTime(expirationDate.getTime() + (30 * 24 * 60 * 60 * 1000)); document.cookie = `ageVerified=true; expires=${expirationDate.toUTCString()}; path=/; SameSite=Lax`; return true; } } console.log('โŒ Age verification required'); return false; } function toggleModalLanguageDropdown() { console.log('๐ŸŒ Modal language dropdown toggled'); const dropdown = document.getElementById('modalLanguageDropdown'); if (dropdown) { const isVisible = dropdown.style.display === 'block'; dropdown.style.display = isVisible ? 'none' : 'block'; } } function selectModalLanguage(lang) { console.log('๐ŸŒ Modal language selected:', lang); const languageData = { 'en': { flag: 'https://flagcdn.com/w20/us.png', alt: 'US', name: 'English' }, 'tr': { flag: 'https://flagcdn.com/w20/tr.png', alt: 'TR', name: 'English' }, 'fr': { flag: 'https://flagcdn.com/w20/fr.png', alt: 'FR', name: 'Franรงais' }, 'de': { flag: 'https://flagcdn.com/w20/de.png', alt: 'DE', name: 'Deutsch' }, 'it': { flag: 'https://flagcdn.com/w20/it.png', alt: 'IT', name: 'Italiano' }, 'nl': { flag: 'https://flagcdn.com/w20/nl.png', alt: 'NL', name: 'Nederlands' } }; // Update current language display const currentFlag = document.getElementById('modalCurrentFlag'); const currentText = document.getElementById('modalLanguageText'); if (currentFlag && currentText && languageData[lang]) { currentFlag.src = languageData[lang].flag; currentFlag.alt = languageData[lang].alt; currentText.textContent = languageData[lang].name; } // Update global language window.DETECTED_LANGUAGE = lang; // Update modal content with new language updateAgeModalContent(lang); // Close dropdown const dropdown = document.getElementById('modalLanguageDropdown'); if (dropdown) { dropdown.style.display = 'none'; } // Update active state document.querySelectorAll('#modalLanguageDropdown .language-option').forEach(opt => { opt.classList.remove('active'); }); const activeOption = document.querySelector(`#modalLanguageDropdown [data-lang="${lang}"]`); if (activeOption) { activeOption.classList.add('active'); } } function loginFromModal() { console.log('๐Ÿ” Login button clicked from modal - redirecting to /login'); // Don't close the modal, just redirect to login // The age verification will be checked again when they return window.location.href = '/login'; } function updateAgeModalContent(lang) { const translations = { 'en': { title: 'This site is for adults only!', description: 'By entering this website, I confirm that I am 18 years of age or older and I agree to the Terms of Service.', language: 'English', login: 'Login', confirm: 'I am 18 or older' }, 'tr': { title: 'This site is for adults only!', description: 'Bu web sitesine girerek 18 yaลŸฤฑnda veya daha bรผyรผk olduฤŸumu kabul ediyor ve Hizmet ลžartlarฤฑnฤฑ kabul ediyorum.', language: 'English', login: 'Login', confirm: 'I am 18 or older' }, 'fr': { title: 'Ce site est rรฉservรฉ aux adultes!', description: 'En entrant sur ce site, je confirme que j\'ai 18 ans ou plus et que j\'accepte les Conditions d\'utilisation.', language: 'Franรงais', login: 'Connexion', confirm: 'J\'ai 18 ans ou plus' }, 'de': { title: 'Diese Seite ist nur fรผr Erwachsene!', description: 'Mit dem Betreten dieser Website bestรคtige ich, dass ich 18 Jahre oder รคlter bin und die Nutzungsbedingungen akzeptiere.', language: 'Deutsch', login: 'Anmelden', confirm: 'Ich bin 18 oder รคlter' }, 'it': { title: 'Questo sito รจ solo per adulti!', description: 'Entrando in questo sito, confermo di avere 18 anni o piรน e di accettare i Termini di servizio.', language: 'Italiano', login: 'Accesso', confirm: 'Ho 18 anni o piรน' }, 'nl': { title: 'Deze site is alleen voor volwassenen!', description: 'Door deze website te betreden, bevestig ik dat ik 18 jaar of ouder ben en akkoord ga met de Servicevoorwaarden.', language: 'Nederlands', login: 'Inloggen', confirm: 'Ik ben 18 of ouder' } }; const t = translations[lang] || translations['en']; // Update modal content const modal = document.querySelector('#ageModal .modal-content'); if (modal) { modal.innerHTML = `

${t.title}

${t.description}

`; } } // Close dropdown when clicking outside document.addEventListener('click', function(event) { const selector = document.getElementById('modalLanguageSelector'); const dropdown = document.getElementById('modalLanguageDropdown'); if (selector && dropdown && !selector.contains(event.target)) { dropdown.style.display = 'none'; } }); // Authentication functions - redirect to login page instead of showing modal function showLoginModal() { console.log('๐Ÿ” Redirecting to login page instead of showing modal'); window.location.href = '/login'; } function closeLoginModal() { console.log('๐Ÿ” Closing login modal'); document.getElementById('loginModal').style.display = 'none'; // Clear form document.getElementById('quickLoginForm').reset(); document.getElementById('quickLoginError').style.display = 'none'; } // Quick login form handler document.addEventListener('DOMContentLoaded', () => { const quickLoginForm = document.getElementById('quickLoginForm'); if (quickLoginForm) { quickLoginForm.addEventListener('submit', async (e) => { e.preventDefault(); const btn = document.getElementById('quickLoginBtn'); const spinner = document.getElementById('quickLoginSpinner'); const text = document.getElementById('quickLoginText'); const errorDiv = document.getElementById('quickLoginError'); const identifier = document.getElementById('quickIdentifier').value.trim(); const password = document.getElementById('quickPassword').value; // Clear previous errors errorDiv.style.display = 'none'; if (!identifier || !password) { errorDiv.textContent = 'Please fill in all fields'; errorDiv.style.display = 'block'; return; } // Show loading btn.disabled = true; spinner.style.display = 'inline-block'; text.textContent = 'Signing in...'; try { const response = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ identifier, password }) }); const data = await response.json(); if (data.success) { // Store token and user data localStorage.setItem('authToken', data.data.token); localStorage.setItem('user', JSON.stringify(data.data.user)); console.log('โœ… Login successful'); // Close modal closeLoginModal(); // Update UI updateAuthUI(); // Show success message showNotification('Login successful!', 'success'); } else { errorDiv.textContent = data.message || 'Login failed'; errorDiv.style.display = 'block'; } } catch (error) { console.error('Login error:', error); errorDiv.textContent = 'Network error. Please try again.'; errorDiv.style.display = 'block'; } finally { btn.disabled = false; spinner.style.display = 'none'; text.textContent = 'Sign In'; } }); } }); // USER PROFILE FUNCTIONS function showProfile() { console.log('๐Ÿ“ฑ Profile clicked'); toggleUserDropdown(); // Close dropdown document.getElementById('profileModal').style.display = 'block'; loadUserProfile(); } function showSettings() { console.log('โš™๏ธ Settings clicked'); toggleUserDropdown(); // Close dropdown alert('Settings page coming soon!'); } function showPremium() { console.log('๐Ÿ‘‘ Premium clicked'); toggleUserDropdown(); // Close dropdown window.location.href = '/pricing'; } function logoutUser() { console.log('๐Ÿšช Logout clicked'); toggleUserDropdown(); // Close dropdown if (confirm('Are you sure you want to logout?')) { logout(); } } // Notification function function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 15px 20px; border-radius: 8px; color: white; font-weight: 500; z-index: 10000; animation: slideIn 0.3s ease; ${type === 'success' ? 'background: linear-gradient(135deg, #4CAF50, #45a049);' : 'background: linear-gradient(135deg, #4a90e2, #357abd);'} `; notification.innerHTML = ` ${message}`; document.body.appendChild(notification); setTimeout(() => { if (notification.parentNode) { notification.parentNode.removeChild(notification); } }, 3000); } function goToPricing() { window.location.href = '/pricing'; } async function logout() { try { const token = localStorage.getItem('authToken'); if (token) { await fetch('/api/auth/logout', { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); } } catch (error) { console.error('Logout error:', error); } finally { // Clear local storage localStorage.removeItem('authToken'); localStorage.removeItem('user'); // Update UI updateAuthUI(); // Redirect to home window.location.reload(); } } function updateAuthUI() { console.log('๐Ÿ”„ updateAuthUI called'); const loginIcon = document.getElementById('loginIcon'); const userProfile = document.getElementById('userProfile'); const token = localStorage.getItem('authToken'); console.log('๐Ÿ” Auth UI check:', { hasToken: !!token, loginIcon: !!loginIcon, userProfile: !!userProfile }); // Clear any invalid tokens first if (token && !isValidJWTFormat(token)) { console.log('โŒ Invalid token format, clearing auth data'); clearInvalidAuthData(); if (loginIcon) loginIcon.style.display = 'block'; if (userProfile) userProfile.style.display = 'none'; return; } const user = JSON.parse(localStorage.getItem('user') || '{}'); console.log('๐Ÿ‘ค User data:', user); if (token && isValidJWTFormat(token) && user.id) { console.log('โœ… User is authenticated, showing profile'); // User is logged in - show profile, hide login icon if (loginIcon) { loginIcon.style.display = 'none'; console.log('๐Ÿ”’ Login icon hidden'); } if (userProfile) { userProfile.style.display = 'block'; console.log('๐Ÿ‘ค User profile shown'); } // Update username in profile const usernameDisplay = document.getElementById('usernameDisplay'); if (usernameDisplay) { usernameDisplay.textContent = user.username || 'User'; console.log('๐Ÿ“ Username updated:', user.username); } // Update dropdown details const dropdownUsername = document.getElementById('dropdownUsername'); if (dropdownUsername) { dropdownUsername.textContent = user.username || 'User'; } const dropdownEmail = document.getElementById('dropdownEmail'); if (dropdownEmail) { dropdownEmail.textContent = user.email || 'user@example.com'; } console.log('โœ… User profile UI updated successfully'); } else { console.log('โŒ User not authenticated, showing login icon'); // User is not logged in - show login icon, hide profile if (loginIcon) loginIcon.style.display = 'block'; if (userProfile) userProfile.style.display = 'none'; } } function isValidJWTFormat(token) { if (!token || typeof token !== 'string') { return false; } const parts = token.split('.'); if (parts.length !== 3) { return false; } // Check if each part is base64-like (basic validation) for (let part of parts) { if (!part || part.length === 0) { return false; } } return true; } function clearInvalidAuthData() { console.log('Clearing invalid authentication data from localStorage'); localStorage.removeItem('authToken'); localStorage.removeItem('user'); localStorage.removeItem('refreshToken'); } async function loadUserProfile() { const token = localStorage.getItem('authToken'); if (!token) return; // Validate token format before making request if (!isValidJWTFormat(token)) { console.log('Invalid token format detected, clearing auth data'); clearInvalidAuthData(); updateAuthUI(); return; } try { const response = await fetch('/api/auth/profile', { headers: { 'Authorization': `Bearer ${token}` } }); if (response.ok) { const data = await response.json(); if (data.success) { // Update stored user data localStorage.setItem('user', JSON.stringify(data.data)); updateAuthUI(); // Update profile modal content updateProfileModal(data.data); } } else if (response.status === 401) { // Token is invalid, logout console.log('Token validation failed on server, clearing auth data'); clearInvalidAuthData(); updateAuthUI(); } } catch (error) { console.error('Failed to load user profile:', error); // If there's a network error and token is invalid format, clear it if (!isValidJWTFormat(token)) { clearInvalidAuthData(); updateAuthUI(); } } } function updateProfileModal(userData) { const profileBody = document.querySelector('.profile-body'); profileBody.innerHTML = `
${userData.username}
${userData.email} ${!userData.isEmailVerified ? '(Not verified)' : '(Verified)'}
${userData.premiumStatus.replace('_', ' ').toUpperCase()}
${userData.premiumExpires ? `
${new Date(userData.premiumExpires).toLocaleDateString()}
` : ''}
${new Date(userData.createdAt).toLocaleDateString()}
${!userData.isEmailVerified ? ` ` : ''} ${!userData.hasPremiumAccess ? ` ` : ''}
`; } async function resendVerificationEmail() { const user = JSON.parse(localStorage.getItem('user') || '{}'); if (!user.email) return; try { const response = await fetch('/api/auth/resend-verification', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: user.email }) }); const data = await response.json(); if (data.success) { alert('Verification email sent! Please check your inbox.'); } else { alert(data.message || 'Failed to send verification email'); } } catch (error) { console.error('Failed to resend verification email:', error); alert('Network error. Please try again.'); } } function closeProfileModal() { document.getElementById('profileModal').style.display = 'none'; } // Close login modal when clicking outside document.addEventListener('click', function(event) { const loginModal = document.getElementById('loginModal'); // Close login modal if clicking outside if (loginModal && event.target === loginModal) { closeLoginModal(); } }); // Add hover effect to login icon document.addEventListener('DOMContentLoaded', () => { const loginIcon = document.getElementById('loginIcon'); if (loginIcon) { const icon = loginIcon.querySelector('i'); loginIcon.addEventListener('mouseenter', () => { if (icon) icon.style.color = '#4a90e2'; }); loginIcon.addEventListener('mouseleave', () => { if (icon) icon.style.color = '#cccccc'; }); } }); // New dropdown functions function showLists() { alert('Lists feature coming soon!'); toggleUserDropdown(); } function showUndressAI() { alert('Undress AI feature coming soon!'); toggleUserDropdown(); } function showPacks() { alert('Packs feature coming soon!'); toggleUserDropdown(); } function showReferral() { alert('Referral program coming soon!'); toggleUserDropdown(); } function showSettings() { // Create settings modal const settingsModal = document.createElement('div'); settingsModal.className = 'modal'; settingsModal.style.display = 'block'; settingsModal.innerHTML = ` `; document.body.appendChild(settingsModal); toggleUserDropdown(); } function closeSettingsModal() { const modal = document.querySelector('.modal:last-child'); if (modal) { modal.remove(); } } function editEmail() { alert('Edit email feature coming soon!'); closeSettingsModal(); } function editPassword() { alert('Change password feature coming soon!'); closeSettingsModal(); } function managePayments() { alert('Payment management coming soon!'); closeSettingsModal(); } function viewBilling() { alert('Billing history coming soon!'); closeSettingsModal(); } function toggleTheme() { alert('Theme switching coming soon!'); closeSettingsModal(); } function claimAdMaven() { alert('AdMaven rewards coming soon!'); toggleUserDropdown(); } function openSupportChat() { alert('Support chat coming soon!'); toggleUserDropdown(); } function openTelegram() { window.location.href = 'https://t.me/leaksup'; toggleUserDropdown(); } function openHelpCenter() { alert('Help center coming soon!'); toggleUserDropdown(); } // Initialize auth UI on page load document.addEventListener('DOMContentLoaded', () => { console.log('๐Ÿš€ DOM Content Loaded - Initializing auth system'); // Clean up any invalid authentication data first const token = localStorage.getItem('authToken'); const user = localStorage.getItem('user'); console.log('๐Ÿ” Initial auth data check:', { hasToken: !!token, hasUser: !!user, tokenLength: token ? token.length : 0 }); // Validate token format if (token && !isValidJWTFormat(token)) { console.log('Found malformed token in localStorage, cleaning up...'); clearInvalidAuthData(); } // Validate user data if (user) { try { const parsedUser = JSON.parse(user); console.log('โœ… User data is valid JSON:', parsedUser); } catch (error) { console.log('Found malformed user data in localStorage, cleaning up...'); clearInvalidAuthData(); } } // If we have a token but no user data, or vice versa, clean up const cleanToken = localStorage.getItem('authToken'); const cleanUser = localStorage.getItem('user'); if ((cleanToken && !cleanUser) || (!cleanToken && cleanUser)) { console.log('Inconsistent auth data found, cleaning up...'); clearInvalidAuthData(); } // Force update auth UI setTimeout(() => { console.log('๐Ÿ”„ Forcing auth UI update after DOM load'); updateAuthUI(); }, 100); // Load user profile if logged in and token is valid const validToken = localStorage.getItem('authToken'); if (validToken && isValidJWTFormat(validToken)) { console.log('๐Ÿ”„ Loading user profile...'); loadUserProfile(); } else { // Force update UI for non-authenticated users updateAuthUI(); } console.log('โœ… Authentication system initialized'); }); // FORCE OVERRIDE - Redirect to login page instead of showing modal window.showLoginModal = function() { console.log('๐Ÿ” FORCE: Redirecting to login page instead of showing modal'); window.location.href = '/login'; }; window.closeLoginModal = function() { console.log('๐Ÿ” FORCE: Closing login modal'); const modal = document.getElementById('loginModal'); if (modal) { modal.style.display = 'none'; // Clear form const form = document.getElementById('quickLoginForm'); if (form) form.reset(); const error = document.getElementById('quickLoginError'); if (error) error.style.display = 'none'; console.log('โœ… FORCE: Login modal closed'); } }; // Force immediate setup document.addEventListener('DOMContentLoaded', function() { console.log('๐Ÿš€ FORCE: DOM loaded, setting up auth'); // Add click handler to login icon const loginIcon = document.getElementById('loginIcon'); if (loginIcon) { loginIcon.onclick = function() { console.log('๐Ÿ–ฑ๏ธ FORCE: Login icon clicked - redirecting to login'); window.location.href = '/login'; }; console.log('โœ… FORCE: Login icon handler added'); } // Add click handler to user profile const userProfile = document.getElementById('userProfile'); if (userProfile) { userProfile.onclick = function() { console.log('๐Ÿ–ฑ๏ธ FORCE: User profile clicked - redirecting to account'); window.location.href = '/account'; }; console.log('โœ… FORCE: User profile handler added'); } // Force auth UI update setTimeout(function() { const token = localStorage.getItem('authToken'); const user = JSON.parse(localStorage.getItem('user') || '{}'); console.log('๐Ÿ” FORCE: Auth check', { hasToken: !!token, hasUser: !!user.id }); if (token && user.id) { // Show user profile if (loginIcon) loginIcon.style.display = 'none'; if (userProfile) userProfile.style.display = 'block'; const username = document.getElementById('usernameDisplay'); if (username) username.textContent = user.username || 'User'; console.log('โœ… FORCE: User profile shown'); } else { // Show login icon if (loginIcon) loginIcon.style.display = 'block'; if (userProfile) userProfile.style.display = 'none'; console.log('โœ… FORCE: Login icon shown'); } }, 100); }); // Models button functionality function showModelsPage() { console.log('๐ŸŽญ Models button clicked'); // Check if user is logged in const token = localStorage.getItem('authToken'); const user = JSON.parse(localStorage.getItem('user') || '{}'); if (!token || !user.id) { console.log('โŒ User not logged in, redirecting to login'); window.location.href = '/login'; return; } // Check if user has premium access if (!user.hasPremiumAccess && user.premiumStatus !== 'active') { console.log('โŒ User does not have premium access, showing premium modal'); showPremiumModal(); return; } // User has access, redirect to models page console.log('โœ… User has access, redirecting to models page'); window.location.href = '/models'; } // Premium modal functions function showPremiumModal() { console.log('๐Ÿ‘‘ Showing premium modal'); const modal = document.getElementById('premiumModal'); if (modal) { modal.style.display = 'block'; } } function closePremiumModal() { console.log('๐Ÿ‘‘ Closing premium modal'); const modal = document.getElementById('premiumModal'); if (modal) { modal.style.display = 'none'; } } function upgradeToPremium(plan) { console.log('๐Ÿ‘‘ Upgrading to premium:', plan); // Redirect to pricing page with selected plan window.location.href = `/pricing?plan=${plan}`; } // Initialize age verification check on page load document.addEventListener('DOMContentLoaded', function() { console.log('๐Ÿ” Checking age verification status'); // Only show age modal if not verified if (!checkAgeVerification()) { console.log('๐Ÿ“‹ Showing age verification modal'); const ageModal = document.getElementById('ageModal'); if (ageModal) { ageModal.style.display = 'block'; } } else { console.log('โœ… Age already verified, hiding modal'); const ageModal = document.getElementById('ageModal'); if (ageModal) { ageModal.style.display = 'none'; } } }); // Tutorial Modal Functions function showTutorialModal() { console.log('๐ŸŽฌ Tutorial button clicked'); const modal = document.getElementById('tutorialModal'); if (modal) { modal.style.display = 'block'; } } function closeTutorialModal() { console.log('๐ŸŽฌ Closing tutorial modal'); const modal = document.getElementById('tutorialModal'); if (modal) { modal.style.display = 'none'; } } function playTutorial(type) { console.log('๐ŸŽฌ Playing tutorial:', type); const videoModal = document.getElementById('videoModal'); const video = document.getElementById('tutorialVideo'); const videoTitle = document.getElementById('videoTitle'); const videoSource = video.querySelector('source'); // Set video source and title if (type === 'pc') { videoSource.src = '/assets/pc.mp4'; videoTitle.textContent = 'PC Tutorial'; video.setAttribute('poster', ''); // Remove poster for immediate loading } else if (type === 'phone') { videoSource.src = '/assets/phone.mp4'; videoTitle.textContent = 'Phone Tutorial'; video.setAttribute('poster', ''); // Remove poster for immediate loading } // Enhanced loading with better error handling video.addEventListener('loadstart', function() { console.log('๐ŸŽฌ Video loading started'); }, { once: true }); video.addEventListener('loadedmetadata', function() { console.log('๐ŸŽฌ Video metadata loaded, duration:', video.duration); }, { once: true }); video.addEventListener('canplay', function() { console.log('๐ŸŽฌ Video can start playing'); // Auto-start video when ready if (video.paused) { video.play().catch(e => console.warn('Auto-play failed:', e)); } }, { once: true }); video.addEventListener('error', function(e) { console.error('๐ŸŽฌ Video loading error:', e); // Retry loading setTimeout(() => { video.load(); }, 1000); }, { once: true }); // Load the new video source video.load(); // Close tutorial modal and show video modal closeTutorialModal(); if (videoModal) { videoModal.style.display = 'block'; } } function closeVideoModal() { console.log('๐ŸŽฌ Closing video modal'); const modal = document.getElementById('videoModal'); const video = document.getElementById('tutorialVideo'); if (modal) { modal.style.display = 'none'; } // Pause the video when closing and reset if (video) { video.pause(); video.currentTime = 0; // Keep video loaded for faster reopening // video.src = ''; // Don't clear source to maintain cache } } // Close modals when clicking outside document.addEventListener('click', function(event) { const tutorialModal = document.getElementById('tutorialModal'); const videoModal = document.getElementById('videoModal'); // Close tutorial modal if clicking outside if (tutorialModal && event.target === tutorialModal) { closeTutorialModal(); } // Close video modal if clicking outside if (videoModal && event.target === videoModal) { closeVideoModal(); } });