{"id":9,"date":"2026-02-18T14:21:24","date_gmt":"2026-02-18T14:21:24","guid":{"rendered":"https:\/\/kwata.app\/health\/customer-login\/"},"modified":"2026-02-25T21:17:47","modified_gmt":"2026-02-25T20:17:47","slug":"customer-login","status":"publish","type":"page","link":"https:\/\/kwata.app\/health\/customer-login\/","title":{"rendered":"Customer Login"},"content":{"rendered":"\n    <div class=\"rwm-login-card\" role=\"region\" aria-label=\"Customer login\">\n                    <div class=\"rwm-login-logo\">\n                <img decoding=\"async\" src=\"https:\/\/kwata.app\/health\/wp-content\/uploads\/2026\/05\/Health-C-web-G.png\" alt=\"Kwata Health Centre\" \/>\n            <\/div>\n                <div class=\"rwm-header\">\n            <h2>Welcome back<\/h2>\n            <p>Sign in with your phone number<\/p>\n        <\/div>\n        <div class=\"rwm-body\">\n            \n            <form id=\"rwm-frontend-login-form\" class=\"rwm-frontend-login-form\" method=\"post\" action=\"https:\/\/kwata.app\/health\/wp-admin\/admin-post.php\"\n                autocomplete=\"on\">\n                <input type=\"hidden\" name=\"action\" value=\"rwm_frontend_login_handler\" \/>\n                <input type=\"hidden\" name=\"rwm_login_nonce\" value=\"ae2f6f4f94\" \/>\n                                <input type=\"hidden\" name=\"redirect_to\" value=\"https:\/\/kwata.app\/health\/wp-json\/wp\/v2\/pages\/9\" \/>\n                <input type=\"hidden\" name=\"origin_site_url\" value=\"https:\/\/kwata.app\/health\/\" \/>\n\n              <div id=\"rwm-phone-wrapper\" style=\"width: 100%; max-width: 100%;\">\n                    <input id=\"rwm_phone_field\" type=\"tel\" inputmode=\"numeric\" pattern=\"[0-9 ]*\" name=\"phone\"\n                        placeholder=\"Provide a valid phone number to proceed\" required aria-required=\"true\" style=\"width: 100% !important;\" \/>\n                <\/div>\n                <div id=\"rwm-phone-feedback\" class=\"rwm-phone-feedback\" aria-live=\"polite\"\n                    style=\"margin-top:8px;font-size:13px;min-height:18px\"><\/div>\n\n                <div id=\"rwm-login-ajax-status\" class=\"rwm-login-status\" aria-live=\"polite\"\n                    style=\"display:none;margin-top:8px\"><\/div>\n\n                <!-- OTP Verification Section (hidden by default) -->\n                <div id=\"rwm-otp-section\" style=\"display:none;\">\n                    <div class=\"rwm-otp-info\" style=\"background:#f0f9ff;border:1px solid #bfdbfe;border-radius:8px;padding:16px;margin-bottom:16px;\">\n                        <p style=\"margin:0;color:#1e40af;font-size:14px;\">\n                            <strong>\ud83d\udce7 Check your email!<\/strong><br>\n                            We've sent a verification code to <span id=\"rwm-masked-email\" style=\"font-weight:600;\"><\/span>\n                        <\/p>\n                    <\/div>\n                    <div style=\"margin-bottom:16px;\">\n                        <label for=\"rwm-otp-input\" style=\"display:block;margin-bottom:8px;font-weight:600;\">Enter Verification Code<\/label>\n                        <input type=\"text\" id=\"rwm-otp-input\" inputmode=\"numeric\" pattern=\"[0-9]{6}\" maxlength=\"6\" \n                               placeholder=\"000000\" style=\"width:100%;padding:12px;font-size:20px;letter-spacing:8px;text-align:center;border:2px solid #e5e7eb;border-radius:8px;\" \/>\n                    <\/div>\n                    <button type=\"button\" id=\"rwm-verify-otp-btn\" class=\"rwm-button rwm-button-primary\" style=\"width:100%;margin-bottom:12px;\">\n                        Verify & Login                    <\/button>\n                    <button type=\"button\" id=\"rwm-resend-otp-btn\" class=\"rwm-button rwm-button-secondary\" style=\"width:100%;margin-bottom:8px;\">\n                        Resend Code                    <\/button>\n                    <button type=\"button\" id=\"rwm-back-to-phone\" class=\"rwm-button rwm-button-secondary\" style=\"width:100%;\">\n                        \u2190 Back to Phone Login                    <\/button>\n                <\/div>\n\n                <div class=\"rwm-login-cta\" id=\"rwm-phone-section\">\n                    <button type=\"submit\" id=\"rwm-frontend-login-submit\"\n                        class=\"btn rwm-login-btn\">Continue<\/button>\n                <\/div>\n\n                <p class=\"rwm-login-note\">We will create an account for you if one does not exist.                 <\/p>\n            <\/form>\n\n            <!-- intl-tel-input CSS -->\n            <link rel=\"stylesheet\"\n                href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/intl-tel-input\/17.0.8\/css\/intlTelInput.min.css\" \/>\n\n            <!-- intl-tel-input and utils -->\n            <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/intl-tel-input\/17.0.8\/js\/intlTelInput.min.js\"><\/script>\n            <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/intl-tel-input\/17.0.8\/js\/utils.js\"><\/script>\n\n            <!-- IMask JS for input masking -->\n            <script src=\"https:\/\/unpkg.com\/imask\"><\/script>\n\n            <script>\n                (function () {\n                    var form = document.getElementById('rwm-frontend-login-form');\n                    if (!form) return;\n                    var phoneEl = document.getElementById('rwm_phone_field');\n                    var submitBtn = document.getElementById('rwm-frontend-login-submit');\n                    var status = document.getElementById('rwm-login-ajax-status');\n                    var feedback = document.getElementById('rwm-phone-feedback');\n\n                    \/\/ Initialize intl-tel-input if available\n                    var iti = null;\n                    if (window.intlTelInput) {\n                        iti = window.intlTelInput(phoneEl, {\n                            \/\/ Default to Cameroon (CM, +237). GeoIP can override if available.\n                            initialCountry: 'cm',\n                            nationalMode: false,\n                            separateDialCode: true,\n                            utilsScript: 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/intl-tel-input\/17.0.8\/js\/utils.js',\n                            geoIpLookup: function (callback) {\n                                fetch('https:\/\/ipapi.co\/json')\n                                    .then(function (res) { return res.json(); })\n                                    .then(function (data) { callback(data && data.country_code ? data.country_code : 'CM'); })\n                                    .catch(function () { callback('CM'); });\n                            }\n                        });\n\n                        \/\/ Force the displayed selected country to Cameroon (+237) after init to ensure UI shows CM\n                        try {\n                            if (iti && iti.setCountry) iti.setCountry('cm');\n                        } catch (e) { }\n                        \n                        \/\/ Ensure input stays visible and full width after initialization\n                        setTimeout(function() {\n                            phoneEl.style.display = 'block';\n                            phoneEl.style.visibility = 'visible';\n                            phoneEl.style.opacity = '1';\n                            phoneEl.style.width = '100%';\n                            \n                            \/\/ Force the intl-tel-input container to full width\n                            var itiContainer = phoneEl.closest('.intl-tel-input');\n                            if (itiContainer) {\n                                itiContainer.style.width = '100%';\n                                itiContainer.style.maxWidth = '100%';\n                            }\n                        }, 100);\n                    }\n\n                    \/\/ Apply IMask if available: digits only (intl-tel-input will still display dial code visually)\n                    try { if (window.IMask) IMask(phoneEl, { mask: \/^(?:\\d|\\s)*$\/ }); } catch (e) { }\n\n                    function setFeedback(text, good) {\n                        if (!feedback) return;\n                        feedback.textContent = text || '';\n                        feedback.style.color = good ? '#1b8f47' : '#c23b3b';\n                    }\n\n                    \/\/ Validation helper\n                    function validNumber() {\n                        if (iti && iti.isValidNumber) return iti.isValidNumber();\n                        var v = (phoneEl.value || '').replace(\/[^0-9+]\/g, '');\n                        var digits = v.replace(\/\\+\/g, '');\n                        return digits.length >= 7 && digits.length <= 15;\n                    }\n\n                    \/\/ Live feedback\n                    phoneEl.addEventListener('input', function () {\n                        if (validNumber()) setFeedback('Looks good', true);\n                        else setFeedback('Provide a valid phone number to proceed', false);\n                    });\n\n                    \/\/ Robust submit handler: run in capture so validation runs BEFORE delegated jQuery handlers\n                    var submitting = false;\n                    var currentUserId = null;\n                    form.addEventListener('submit', function (e) {\n                        \/\/ Prevent default for custom OTP flow check\n                        e.preventDefault();\n                        \n                        \/\/ If already submitting, return\n                        if (submitting) return false;\n\n                        \/\/ If invalid, stop\n                        if (!validNumber()) {\n                            setFeedback('Provide a valid phone number to proceed', false);\n                            phoneEl.focus();\n                            return false;\n                        }\n\n                        \/\/ Valid: normalize to digits-only\n                        var phoneValue = phoneEl.value;\n                        if (iti && iti.getNumber) {\n                            try {\n                                var full = iti.getNumber();\n                                if (full) {\n                                    phoneValue = full.replace(\/\\D\/g, '');\n                                }\n                            } catch (ignore) { }\n                        }\n\n                        \/\/ show loading UI\n                        if (submitBtn) {\n                            submitBtn.disabled = true;\n                            submitBtn.classList.add('loading');\n                            submitBtn.textContent = 'Checking account...';\n                        }\n\n                        submitting = true;\n                        status.style.display = 'block';\n                        status.textContent = 'Checking account...';\n\n                        \/\/ Check if user has recovery email via AJAX\n                        var formData = new FormData();\n                        formData.append('action', 'rwm_check_user_recovery');\n                        formData.append('phone', phoneValue);\n                        formData.append('nonce', 'bf4f90d7a1');\n\n                        fetch('https:\/\/kwata.app\/health\/wp-admin\/admin-ajax.php', {\n                            method: 'POST',\n                            body: formData\n                        })\n                        .then(r => r.json())\n                        .then(data => {\n                            if (data.success && data.data.has_recovery_email) {\n                                \/\/ User has recovery email - trigger OTP flow\n                                currentUserId = data.data.user_id;\n                                sendOTP(phoneValue);\n                            } else {\n                                \/\/ No recovery email - use normal phone login by submitting form\n                                phoneEl.value = phoneValue;\n                                submitting = false; \/\/ Allow resubmit\n                                form.submit();\n                            }\n                        })\n                        .catch(() => {\n                            \/\/ Error - fallback to normal submit\n                            phoneEl.value = phoneValue;\n                            submitting = false;\n                            form.submit();\n                        });\n\n                        return false;\n                    }, true);\n\n                    \/\/ OTP Functions\n                    function sendOTP(phone) {\n                        status.textContent = 'Sending verification code...';\n                        var formData = new FormData();\n                        formData.append('action', 'rwm_send_login_otp');\n                        formData.append('phone', phone);\n                        formData.append('nonce', 'bf4f90d7a1');\n\n                        fetch('https:\/\/kwata.app\/health\/wp-admin\/admin-ajax.php', {\n                            method: 'POST',\n                            body: formData\n                        })\n                        .then(r => r.json())\n                        .then(data => {\n                            if (data.success) {\n                                currentUserId = data.data.user_id;\n                                document.getElementById('rwm-masked-email').textContent = data.data.masked_email;\n                                document.getElementById('rwm-phone-section').style.display = 'none';\n                                document.getElementById('rwm-phone-wrapper').style.display = 'none';\n                                document.getElementById('rwm-phone-feedback').style.display = 'none';\n                                document.getElementById('rwm-otp-section').style.display = 'block';\n                                status.style.display = 'none';\n                                submitting = false;\n                                submitBtn.disabled = false;\n                                submitBtn.classList.remove('loading');\n                                submitBtn.textContent = 'Continue';\n                                document.getElementById('rwm-otp-input').focus();\n                            } else {\n                                status.textContent = data.data.message || 'Error sending code';\n                                submitting = false;\n                                submitBtn.disabled = false;\n                                submitBtn.classList.remove('loading');\n                                submitBtn.textContent = 'Continue';\n                            }\n                        })\n                        .catch(() => {\n                            status.textContent = 'Network error. Please try again.';\n                            submitting = false;\n                            submitBtn.disabled = false;\n                            submitBtn.classList.remove('loading');\n                            submitBtn.textContent = 'Continue';\n                        });\n                    }\n\n                    \/\/ Verify OTP\n                    document.getElementById('rwm-verify-otp-btn').addEventListener('click', function() {\n                        var otpInput = document.getElementById('rwm-otp-input');\n                        var otp = otpInput.value.trim();\n                        if (otp.length !== 6) {\n                            status.style.display = 'block';\n                            status.textContent = 'Please enter the 6-digit code';\n                            return;\n                        }\n\n                        this.disabled = true;\n                        this.textContent = 'Verifying...';\n                        status.style.display = 'block';\n                        status.textContent = 'Verifying code...';\n\n                        var formData = new FormData();\n                        formData.append('action', 'rwm_verify_login_otp');\n                        formData.append('user_id', currentUserId);\n                        formData.append('otp', otp);\n                        formData.append('nonce', 'bf4f90d7a1');\n                        \n                        \/\/ Send redirect URL for login page (venue pages don't send this, so they reload instead).\n                        \/\/ Prefer an explicit hidden input named `redirect_to` if provided on the form.\n                        var redirectInput = document.querySelector('input[name=\"redirect_to\"]');\n                        var redirectUrl = '';\n                        if (redirectInput && redirectInput.value) {\n                            redirectUrl = redirectInput.value;\n                        } else {\n                            \/\/ Fallback to the site's default post-login redirect (My Orders)\n                            redirectUrl = 'https:\/\/kwata.app\/health\/my-orders\/';\n                        }\n                        formData.append('redirect_url', redirectUrl);\n\n                        fetch('https:\/\/kwata.app\/health\/wp-admin\/admin-ajax.php', {\n                            method: 'POST',\n                            body: formData\n                        })\n                        .then(r => r.json())\n                        .then(data => {\n                            if (data.success) {\n                                status.textContent = data.data.message;\n                                setTimeout(() => {\n                                    \/\/ Use redirect from response, or fallback to default\n                                    window.location.href = data.data.redirect || redirectUrl;\n                                }, 500);\n                            } else {\n                                status.textContent = data.data.message || 'Invalid code';\n                                this.disabled = false;\n                                this.textContent = 'Verify &amp; Login';\n                                otpInput.value = '';\n                                otpInput.focus();\n                            }\n                        })\n                        .catch(() => {\n                            status.textContent = 'Network error. Please try again.';\n                            this.disabled = false;\n                            this.textContent = 'Verify &amp; Login';\n                        });\n                    });\n\n                    \/\/ Resend OTP\n                    document.getElementById('rwm-resend-otp-btn').addEventListener('click', function() {\n                        this.disabled = true;\n                        this.textContent = 'Sending...';\n\n                        var formData = new FormData();\n                        formData.append('action', 'rwm_resend_otp');\n                        formData.append('user_id', currentUserId);\n                        formData.append('nonce', 'bf4f90d7a1');\n\n                        fetch('https:\/\/kwata.app\/health\/wp-admin\/admin-ajax.php', {\n                            method: 'POST',\n                            body: formData\n                        })\n                        .then(r => r.json())\n                        .then(data => {\n                            status.style.display = 'block';\n                            status.textContent = data.data.message;\n                            this.disabled = false;\n                            this.textContent = 'Resend Code';\n                        })\n                        .catch(() => {\n                            status.textContent = 'Error resending code';\n                            this.disabled = false;\n                            this.textContent = 'Resend Code';\n                        });\n                    });\n\n                    \/\/ Back to phone login\n                    document.getElementById('rwm-back-to-phone').addEventListener('click', function() {\n                        document.getElementById('rwm-otp-section').style.display = 'none';\n                        document.getElementById('rwm-phone-section').style.display = 'block';\n                        document.getElementById('rwm-phone-wrapper').style.display = 'block';\n                        document.getElementById('rwm-phone-feedback').style.display = 'block';\n                        document.getElementById('rwm-otp-input').value = '';\n                        status.style.display = 'none';\n                        currentUserId = null;\n                        submitting = false;\n                        submitBtn.disabled = false;\n                        submitBtn.classList.remove('loading');\n                        submitBtn.textContent = 'Continue';\n                    });\n                })();\n            <\/script>\n\n            <!-- Styles loaded from assets\/css\/rwm-login.css -->\n        <\/div>\n    <\/div>\n    \n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-9","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/kwata.app\/health\/wp-json\/wp\/v2\/pages\/9","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kwata.app\/health\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/kwata.app\/health\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/kwata.app\/health\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kwata.app\/health\/wp-json\/wp\/v2\/comments?post=9"}],"version-history":[{"count":1,"href":"https:\/\/kwata.app\/health\/wp-json\/wp\/v2\/pages\/9\/revisions"}],"predecessor-version":[{"id":85,"href":"https:\/\/kwata.app\/health\/wp-json\/wp\/v2\/pages\/9\/revisions\/85"}],"wp:attachment":[{"href":"https:\/\/kwata.app\/health\/wp-json\/wp\/v2\/media?parent=9"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}