{"id":994,"date":"2023-10-24T19:43:08","date_gmt":"2023-10-24T19:43:08","guid":{"rendered":"https:\/\/vrai-dev.johnabbott.qc.ca\/?page_id=994"},"modified":"2024-12-10T16:31:26","modified_gmt":"2024-12-10T20:31:26","slug":"login","status":"publish","type":"page","link":"https:\/\/vrai.johnabbott.qc.ca\/zh\/login\/","title":{"rendered":"\u767b\u5f55"},"content":{"rendered":"<div style=\"height:16px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<style>\n    .login-form {\n        border-radius: 12px;\n        padding: 1.8em;\n        margin: 0 auto;\n        width: 50%;\n        border: 1px solid black;\n        box-shadow: 0px 13px 18px -3px rgba(0, 0, 0, 0.1);\n    }\n\n    .login-title {\n        font-weight: bold;\n        font-size: 24px;\n    }\n\n    .login-form input[type=\"text\"],\n    .login-form input[type=\"password\"] {\n        color: black;\n        background-color: #f0f0f0;\n        border-radius: 8px;\n        width: 100%;\n        padding: 0.5em;\n        margin-bottom: 1em;\n    }\n\n    .login-form input[type=\"submit\"] {\n        font-weight: bold;\n        width: 100%;\n        font-size: 18px;\n        border-radius: 8px;\n        background-color: #4472C4;\n        color: white;\n        border: none;\n        padding: 0.7em;\n    }\n\n    .error {\n        color: #ff3860;\n        font-size: 12px;\n        margin-top: -0.8em;\n        margin-bottom: 1em;\n    }\n\n    .login-success-message,\n    .login-error-message {\n        display: none;\n        margin: 0 auto;\n        padding: 10px;\n        border-radius: 8px;\n        margin-top: 20px;\n        text-align: center;\n    }\n\n    .login-success-message {\n        background-color: #09C372;\n        color: white;\n    }\n\n    .login-error-message {\n        background-color: #ff3860;\n        color: white;\n    }\n<\/style>\n\n<body>\n    <form class=\"login-form\" id=\"login-form\" action=\"\">\n        <p class=\"login-title\">\u767b\u5f55<\/p>\n\n        <div class=\"input-control\">\n            <input id=\"username\" type=\"text\" name=\"username\" placeholder=\"\u7528\u6237\u540d\" \/>\n            <div class=\"error\" id=\"username-error\"><\/div>\n        <\/div>\n\n        <div class=\"input-control\">\n            <input type=\"password\" id=\"password\" name=\"password\" placeholder=\"\u5bc6\u7801\" \/>\n            <div class=\"error\" id=\"password-error\"><\/div>\n        <\/div>\n\n        <p class=\"forgot-password\"><a href=\"\/zh\/forgot-password\/\" class=\"anchor-2\">\u5fd8\u8bb0\u5bc6\u7801\uff1f<\/a><\/p>\n\n        <div id=\"login-success-message\" class=\"login-success-message\">Login successful! Redirecting to your account&#8230;<\/div>\n        <div id=\"login-error-message\" class=\"login-error-message\"><\/div>\n\n        <p class=\"login-btn\"><input type=\"submit\" value=\"\u767b\u5f55\" \/><\/p>\n    <input type=\"hidden\" name=\"trp-form-language\" value=\"zh\"\/><\/form>\n\n    <script>\n        const form = document.querySelector('#login-form');\n        const username = document.querySelector('#username');\n        const password = document.querySelector('#password');\n        const loginSuccessMessage = document.querySelector('#login-success-message');\n        const loginErrorMessage = document.querySelector('#login-error-message');\n\n        form.addEventListener('submit', async (event) => {\n            event.preventDefault();\n\n            \/\/ Validate inputs\n            if (validateInputs()) {\n                try {\n                    \/\/ Submit form data\n                    const response = await fetch(`${API_URL}\/auth\/login`, {\n                        method: 'POST',\n                        headers: {\n                            'Content-Type': 'application\/json',\n                        },\n                        body: JSON.stringify({\n                            username: username.value.trim(),\n                            password: password.value.trim() || null,\n                            passwordMandatory : true\n                        }),\n                    });\n\n                    const data = await response.json();\n\n                    if (data.token) {\n                        form.reset();\n                        localStorage.setItem('authToken', data.token);\n\n                        loginSuccessMessage.style.display = 'block';\n                        setTimeout(() => {\n                            loginSuccessMessage.style.display = 'none';\n                            window.location.href = '\/account';\n                        }, 3000);\n                    } else {\n                        displayError(loginErrorMessage, data.message || 'Login failed.');\n                    }\n                } catch (error) {\n                    displayError(loginErrorMessage, `Error during login: ${error.message}`);\n                }\n            }\n        });\n\n        const displayError = (element, message) => {\n            element.style.display = 'block';\n            element.innerText = message;\n            setTimeout(() => {\n                element.style.display = 'none';\n            }, 3000);\n        };\n\n        const validateInputs = () => {\n            let isValid = true;\n\n            if (!username.value.trim()) {\n                setError(username, 'Username is required.');\n                isValid = false;\n            } else {\n                clearError(username);\n            }\n\n            \/\/ Password is optional; no validation needed unless required in the future.\n\n            return isValid;\n        };\n\n        const setError = (input, message) => {\n            const errorDiv = document.querySelector(`#${input.id}-error`);\n            errorDiv.innerText = message;\n            input.classList.add('error-border');\n        };\n\n        const clearError = (input) => {\n            const errorDiv = document.querySelector(`#${input.id}-error`);\n            errorDiv.innerText = '';\n            input.classList.remove('error-border');\n        };\n    <\/script>\n<\/body>\n\n\n\n<div style=\"height:74px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>","protected":false},"excerpt":{"rendered":"<p>Login Forgot password? Login successful! Redirecting to your account&#8230;<\/p>","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"wp-custom-template-page-banner-removed","meta":{"footnotes":""},"class_list":["post-994","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/vrai.johnabbott.qc.ca\/zh\/wp-json\/wp\/v2\/pages\/994","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vrai.johnabbott.qc.ca\/zh\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/vrai.johnabbott.qc.ca\/zh\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/vrai.johnabbott.qc.ca\/zh\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/vrai.johnabbott.qc.ca\/zh\/wp-json\/wp\/v2\/comments?post=994"}],"version-history":[{"count":86,"href":"https:\/\/vrai.johnabbott.qc.ca\/zh\/wp-json\/wp\/v2\/pages\/994\/revisions"}],"predecessor-version":[{"id":3869,"href":"https:\/\/vrai.johnabbott.qc.ca\/zh\/wp-json\/wp\/v2\/pages\/994\/revisions\/3869"}],"wp:attachment":[{"href":"https:\/\/vrai.johnabbott.qc.ca\/zh\/wp-json\/wp\/v2\/media?parent=994"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}