Files
phaten-audio/en/docs/common/checklogin_form.md
2025-06-13 14:17:55 +08:00

16 KiB
Raw Blame History

<style> .login-modal { display: none !important; position: fixed !important; z-index: 100 !important; left: 0 !important; top: 0 !important; width: 100% !important; height: 100% !important; background-color: rgba(0,0,0,0.5) !important; } .login-modal[style*="block"] { display: block !important; } .login-content { background-color: #fefefe; margin: 10% auto; padding: 20px; border: 1px solid #888; width: 400px; border-radius: 15px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); } .login-content h2 { text-align: center; margin-bottom: 15px; color: #333; font-size: 22px; } .login-form .login-type { display: flex; justify-content: center; margin-bottom: 12px; } .login-form .login-type label { margin: 0 15px; cursor: pointer; font-size: 15px; display: flex; align-items: center; } .login-form .login-type input[type="radio"] { margin-right: 5px; width: auto; } .login-form input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ddd; border-radius: 8px; box-sizing: border-box; font-size: 15px; } .login-form .code-container { display: flex; gap: 10px; margin: 10px 0; } .login-form .hint-text { font-size: 12px; color: #666; margin-top: 3px; margin-bottom: 3px; text-align: left; } .login-form .code-input { flex: 3; padding: 10px; border: 1px solid #ddd; border-radius: 8px; box-sizing: border-box; font-size: 15px; } .login-form .send-code-btn { flex: 1; min-width: 95px; padding: 0 8px; background-color: #3498db; color: white; border: none; border-radius: 8px; cursor: pointer; font-size: 14px; transition: background-color 0.3s ease; white-space: nowrap; } .login-form .send-code-btn:hover { background-color: #2980b9; } .login-form .send-code-btn:disabled { background-color: #95a5a6; cursor: not-allowed; } .login-form button { width: 100%; padding: 10px; background-color: #3498db; color: white; border: none; border-radius: 8px; cursor: pointer; margin-top: 12px; font-size: 16px; transition: background-color 0.3s ease; } .login-form button:hover { background-color: #2980b9; } .close { float: right; cursor: pointer; font-size: 24px; color: #666; transition: color 0.3s ease; } .close:hover { color: #333; } /* Message modal styles */ .message-modal { display: none; position: fixed; z-index: 1001; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); } .message-content { background-color: #fefefe; margin: 15% auto; padding: 20px; border: 1px solid #888; width: 400px; border-radius: 15px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); text-align: center; } .message-content h3 { margin: 0 0 15px 0; color: #333; font-size: 18px; } .message-content p { margin: 15px 0; color: #666; line-height: 1.5; white-space: pre-line; } .message-content .success { color: #27ae60; } .message-content .error { color: #e74c3c; } .message-btn { background-color: #3498db; color: white; border: none; border-radius: 8px; padding: 10px 20px; cursor: pointer; font-size: 14px; margin-top: 10px; transition: background-color 0.3s ease; } .message-btn:hover { background-color: #2980b9; } .close-message { float: right; cursor: pointer; font-size: 24px; color: #666; transition: color 0.3s ease; } .close-message:hover { color: #333; } /* Download button styles */ .download-btn { font-size: 12px !important; padding: 6px 12px !important; min-height: auto !important; line-height: 1.2 !important; } .download-btn.loading { pointer-events: none; opacity: 0.7; position: relative; } .download-btn.loading::after { content: ""; position: absolute; width: 12px; height: 12px; top: 50%; left: 50%; margin-left: -6px; margin-top: -6px; border: 2px solid #ffffff; border-radius: 50%; border-top-color: transparent; animation: button-loading-spinner 1s ease infinite; } @keyframes button-loading-spinner { from { transform: rotate(0turn); } to { transform: rotate(1turn); } } </style>
×

Notice

OK
×

Phaten Cloud Login/Register

Send Code
(Auto register on first login)
Submit
<script> // Avoid duplicate declarations, use immediately invoked function to create scope (function() { 'use strict'; // Define API base URL const baseUrl = 'https://api.phaten-audio.com/api'; // Get modal elements const modal = document.getElementById("loginModal"); const loginForm = document.getElementById("loginForm"); const sendCodeBtn = document.getElementById("sendCodeBtn"); const emailInput = document.getElementById("email"); let countdownTimer; // Get message modal elements const messageModal = document.getElementById("messageModal"); const messageTitle = document.getElementById("messageTitle"); const messageText = document.getElementById("messageText"); const messageBtn = document.getElementById("messageBtn"); const closeMessage = document.getElementsByClassName("close-message")[0]; // Show custom message modal function showMessage(title, text, type = 'info') { messageTitle.textContent = title; messageText.textContent = text; // Set style based on type messageText.className = type === 'success' ? 'success' : (type === 'error' ? 'error' : ''); messageModal.style.display = "block"; } // Close message modal function closeMessageModal() { messageModal.style.display = "none"; } // Bind message modal close events closeMessage.onclick = closeMessageModal; messageBtn.onclick = closeMessageModal; // Add login modal close button function closeLoginModal() { console.log("User closed login modal"); modal.style.display = "none"; // Clear pending download URL since user cancelled login const pendingUrl = sessionStorage.getItem('pendingDownloadUrl'); if (pendingUrl) { console.log("Clear pending download URL:", pendingUrl); sessionStorage.removeItem('pendingDownloadUrl'); } // Restore download button state const downloadBtn = document.getElementById('designDownloadBtn'); if (downloadBtn) { downloadBtn.classList.remove('loading'); downloadBtn.innerHTML = 'Download'; console.log("Restore download button state"); } } // Click outside message modal to close (only close message modal, not login modal) window.addEventListener('click', function(event) { if (event.target == messageModal) { closeMessageModal(); } // Click outside login modal can also close it if (event.target == modal) { closeLoginModal(); } }); // Check if token exists in local storage function getLocalToken() { return localStorage.getItem('ftyToken'); } // Save token to local storage function saveToken(token) { localStorage.setItem('ftyToken', token); } // Clear token function clearToken() { localStorage.removeItem('ftyToken'); } // Validate if token is valid async function validateToken() { const token = getLocalToken(); console.log("validateToken function called, token:", token); if (!token) { console.log("No token, return false"); return false; } try { console.log("Sending token validation request..."); const response = await fetch(`${baseUrl}/fty/validateToken`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` } }); const data = await response.json(); console.log("Token validation server response:", data); const isValid = data.data && data.data.valid === true; console.log("Is token valid:", isValid); // If token is invalid, clear local storage if (!isValid) { console.log("Token invalid, clear local storage"); clearToken(); } return isValid; } catch (error) { console.error('Token validation error:', error); console.log("Token validation error, clear local storage"); clearToken(); return false; } } // Check login status async function checkLogin(downloadUrl = null) { // Get trigger button and add loading state const downloadBtn = document.getElementById('designDownloadBtn'); if (downloadBtn) { downloadBtn.classList.add('loading'); downloadBtn.innerHTML = '...'; } try { // Check if token is valid console.log("Start validating token..."); const token = getLocalToken(); console.log("Local token:", token); const isLoggedIn = await validateToken(); console.log("Validation result isLoggedIn:", isLoggedIn); if (!isLoggedIn) { // If not logged in, save download link and show login modal if (downloadUrl) { sessionStorage.setItem('pendingDownloadUrl', downloadUrl); if (modal) { modal.style.display = "block"; } else { console.error("Modal element not found!"); } } } else { // If logged in, start download directly if (downloadUrl) { if (downloadBtn) { downloadBtn.innerHTML = 'Downloading...'; } window.location.href = downloadUrl; } } } catch (error) { console.error("Login verification error:", error); } finally { // Restore button state (if not redirected) if (downloadBtn && !downloadBtn.innerHTML.includes('Downloading')) { setTimeout(() => { downloadBtn.classList.remove('loading'); downloadBtn.innerHTML = 'Download'; }, 500); } } } // Send verification code sendCodeBtn.onclick = function() { const contactValue = emailInput.value; if (!validateEmail(contactValue)) { showMessage('Input Error', 'Please enter a valid email address!', 'error'); return; } // Disable button and start countdown startCountdown(); // Send AJAX request to get verification code fetch(`${baseUrl}/fty/sendCode`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ type: "1", // Fixed as email type username: contactValue }) }) .then(response => response.json()) .then(data => { if (data.success) { showMessage('Send Success', 'Verification code has been sent to your email!', 'success'); } else { showMessage('Send Failed', data.msg || 'Failed to send verification code, please try again later!', 'error'); resetCountdown(); } }) .catch(error => { console.error('Error:', error); showMessage('Network Error', 'Failed to send verification code request, please try again later!', 'error'); resetCountdown(); }); } // Validate email format function validateEmail(email) { const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return re.test(String(email).toLowerCase()); } // Start countdown function startCountdown() { let countdown = 60; sendCodeBtn.disabled = true; sendCodeBtn.textContent = `Retry after ${countdown}s`; countdownTimer = setInterval(() => { countdown--; sendCodeBtn.textContent = `Retry after ${countdown}s`; if (countdown <= 0) { resetCountdown(); } }, 1000); } // Reset countdown function resetCountdown() { clearInterval(countdownTimer); sendCodeBtn.disabled = false; sendCodeBtn.textContent = 'Send Code'; } // Handle login form submission loginForm.onsubmit = function(e) { console.log("Form submitted"); e.preventDefault(); const verificationCode = document.getElementById("verificationCode").value; const contactValue = emailInput.value; // Send AJAX request fetch(`${baseUrl}/fty/login`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ type: "1", // Fixed as email type username: contactValue, code: verificationCode }) }) .then(response => response.json()) .then(data => { console.log("Login response", data); if (data.code==2000) { // Save token to local storage if (data.data.token) { saveToken(data.data.token); } showMessage('Login Success', 'Login successful!', 'success'); // Close modal after successful login modal.style.display = "none"; resetCountdown(); // Check if there's a pending download link const pendingDownloadUrl = sessionStorage.getItem('pendingDownloadUrl'); if (pendingDownloadUrl) { sessionStorage.removeItem('pendingDownloadUrl'); // Delay a bit before redirect to let user see success message setTimeout(() => { if (downloadBtn) { downloadBtn.innerHTML = 'Downloading...'; } window.location.href = pendingDownloadUrl; }, 1500); } } else { showMessage('Login Failed', data.msg || 'Login failed, please check email and verification code!', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('Network Error', 'Login request failed, please try again later!', 'error'); }); } // ESC key to close login modal document.addEventListener('keydown', function(event) { if (event.key === 'Escape' && modal.style.display === 'block') { console.log("User pressed ESC to close login modal"); closeLoginModal(); } }); // Auto validate token when page loads document.addEventListener('DOMContentLoaded', async function() { // Auto check login status (but don't auto show login modal) await validateToken(); // Additional check if modal element is correctly obtained console.log("Page loaded, modal element:", modal); }); // Expose globally accessible functions to window object window.checkLogin = checkLogin; window.closeLoginModal = closeLoginModal; })(); // End of immediately invoked function </script>