{"id":474,"date":"2025-11-12T14:06:39","date_gmt":"2025-11-12T06:06:39","guid":{"rendered":"https:\/\/xingshengcardindustry.com\/index.php\/account\/"},"modified":"2025-11-14T18:18:22","modified_gmt":"2025-11-14T10:18:22","slug":"account","status":"publish","type":"page","link":"https:\/\/staging.xingshengcardindustry.com\/account\/","title":{"rendered":"Account access"},"content":{"rendered":"<style>\n.otp-wrap{max-width:560px;margin:40px auto;padding:24px;border:1px solid #e5e7eb;border-radius:12px;background:#fff;box-shadow:0 8px 28px rgba(0,0,0,.08);font-family:system-ui,-apple-system,Segoe UI,Roboto}\n.otp-tabs{display:flex;border-bottom:1px solid #eee;margin-bottom:16px}\n.otp-tab{flex:1;text-align:center;padding:12px;cursor:pointer;font-weight:700;color:#6b7280}\n.otp-tab.active{color:#4f46e5;border-bottom:3px solid #4f46e5}\n.otp-pane{display:none}\n.otp-pane.active{display:block}\n.otp-field{margin-bottom:12px}\n.otp-field label{display:block;font-size:14px;margin-bottom:6px}\n.otp-input{width:100%;padding:12px;border:1px solid #d1d5db;border-radius:8px}\n.otp-row{display:flex;gap:8px}\n.otp-btn{width:100%;padding:12px;border:none;border-radius:8px;background:#4f46e5;color:#fff;font-weight:700;cursor:pointer}\n.otp-btn[disabled]{opacity:.6;cursor:not-allowed}\n.otp-link{color:#4f46e5;text-decoration:none;font-size:13px}\n.otp-msg{margin-bottom:12px;border-radius:8px;padding:10px 12px}\n.otp-error{background:#fee2e2;border:1px solid #fecaca;color:#991b1b}\n.otp-success{background:#dcfce7;border:1px solid #bbf7d0;color:#166534}\n.otp-tip{font-size:12px;color:#6b7280;margin-top:4px}\n@media (max-width:560px){.otp-wrap{margin:16px;padding:16px}}\n<\/style>\n\n<div class=\"otp-wrap\">\n<div class=\"otp-tabs\">\n<div class=\"otp-tab active\" data-tab=\"reg\">Register \/ Login<\/div>\n<div class=\"otp-tab\" data-tab=\"password\">Password Login<\/div>\n<div class=\"otp-tab\" data-tab=\"reset\">Forgot Password<\/div>\n<\/div>\n\n<!-- Register\/Login: invite + username + password + (email code if email) -->\n<div class=\"otp-pane active\" id=\"pane-reg\">\n<div id=\"msg-reg\"><\/div>\n<div class=\"otp-field\">\n<label>Phone or Email<\/label>\n<input type=\"text\" id=\"reg-login\" class=\"otp-input\" placeholder=\"+234123456789 or your@email.com\">\n<\/div>\n<div class=\"otp-field\">\n<label>Invite code (optional)<\/label>\n<input type=\"text\" id=\"reg-ref\" class=\"otp-input\" placeholder=\"e.g. 12345\/123456\">\n<\/div>\n<div class=\"otp-field\">\n<label>Username (required)<\/label>\n<input type=\"text\" id=\"reg-username\" class=\"otp-input\" placeholder=\"Letters\/numbers\/underscore, 3-30 chars\">\n<\/div>\n<div class=\"otp-field\">\n<label>Password (at least 6 characters)<\/label>\n<input type=\"password\" id=\"reg-password\" class=\"otp-input\">\n<\/div>\n\n<!-- NEW: Email verification code (only when login is an email) -->\n<div class=\"otp-field\" id=\"reg-code-wrap\" style=\"display:none\">\n  <label>Email verification code<\/label>\n  <div class=\"otp-row\">\n    <input type=\"text\" id=\"reg-code\" class=\"otp-input\" placeholder=\"6 digits\">\n    <button class=\"otp-btn\" id=\"btn-reg-send\">Get Code<\/button>\n  <\/div>\n  <div class=\"otp-tip\">We will send a 6\u2011digit code to the email above. Valid for 10 minutes.<\/div>\n<\/div>\n\n<button class=\"otp-btn\" id=\"btn-reg-login\" style=\"margin-top:8px\">Login \/ Register<\/button>\n<p class=\"otp-tip\" style=\"margin-top:10px\">\nAlready have an account? You can also log in via \"Password Login\" using phone\/email\/username + password.\n<\/p>\n<\/div>\n\n<!-- Password Login -->\n<div class=\"otp-pane\" id=\"pane-password\">\n<div id=\"msg-pass\"><\/div>\n<div class=\"otp-field\">\n<label>Phone \/ Email \/ Username<\/label>\n<input type=\"text\" id=\"pass-login\" class=\"otp-input\">\n<\/div>\n<div class=\"otp-field\">\n<label>Password<\/label>\n<input type=\"password\" id=\"pass-password\" class=\"otp-input\">\n<\/div>\n<button class=\"otp-btn\" id=\"btn-password-login\">Login<\/button>\n<p style=\"margin-top:10px\"><a href=\"#\" class=\"otp-link\" data-jump=\"reset\">Forgot password? Reset with email code<\/a><\/p>\n<\/div>\n\n<!-- Forgot Password (email code only) -->\n<div class=\"otp-pane\" id=\"pane-reset\">\n<div id=\"msg-reset\"><\/div>\n<div class=\"otp-field\">\n<label>Email<\/label>\n<input type=\"email\" id=\"reset-email\" class=\"otp-input\" placeholder=\"Enter your registered email\">\n<\/div>\n<div class=\"otp-field\">\n<label>Email Verification Code<\/label>\n<div class=\"otp-row\">\n<input type=\"text\" id=\"reset-code\" class=\"otp-input\" placeholder=\"6 digits\">\n<button class=\"otp-btn\" id=\"btn-reset-send\">Get Code<\/button>\n<\/div>\n<\/div>\n<div class=\"otp-field\">\n<label>New Password (at least 6 characters)<\/label>\n<input type=\"password\" id=\"reset-pass\" class=\"otp-input\">\n<\/div>\n<button class=\"otp-btn\" id=\"btn-reset-do\">Reset Password<\/button>\n<\/div>\n<\/div>\n\n<script>\n(function(){\nconst tabs = document.querySelectorAll('.otp-tab');\ntabs.forEach(t => t.addEventListener('click', () => {\ntabs.forEach(x=>x.classList.remove('active')); t.classList.add('active');\ndocument.querySelectorAll('.otp-pane').forEach(p=>p.classList.remove('active'));\ndocument.getElementById('pane-'+t.dataset.tab).classList.add('active');\n}));\ndocument.querySelectorAll('[data-jump]').forEach(a=>{\na.addEventListener('click', (e)=>{e.preventDefault(); document.querySelector('.otp-tab[data-tab=\"'+a.dataset.jump+'\"]').click();});\n});\n\n\/\/ URL ?r= \u81ea\u52a8\u586b\u5145\u9080\u8bf7\u7801\nconst urlParams = new URLSearchParams(location.search);\nif (urlParams.get('r')) {\nconst ref = urlParams.get('r').replace(\/[^0-9]\/g,'');\nif (ref) document.getElementById('reg-ref').value = ref;\n}\n\nconst ajax = (action, data) => {\ndata.append('action', action);\ndata.append('nonce', '0cb80e082e');\nreturn fetch('https:\/\/staging.xingshengcardindustry.com\/wp-admin\/admin-ajax.php', { method:'POST', body:data, credentials:'same-origin' }).then(r=>r.json());\n};\nconst show = (id, ok, text) => {\nconst box = document.getElementById(id);\nbox.innerHTML = '<div class=\"otp-msg '+(ok?'otp-success':'otp-error')+'\">'+text+'<\/div>';\n};\n\nconst isEmail = v => \/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/.test(v||'');\n\n\/\/ Show\/hide email code UI based on login input\nconst regLogin = document.getElementById('reg-login');\nconst codeWrap = document.getElementById('reg-code-wrap');\nfunction toggleCodeUI(){\n  const on = isEmail(regLogin.value.trim());\n  codeWrap.style.display = on ? 'block' : 'none';\n}\nregLogin.addEventListener('input', toggleCodeUI);\nregLogin.addEventListener('blur', toggleCodeUI);\ntoggleCodeUI();\n\n\/\/ Send registration email code\nconst btnRegSend = document.getElementById('btn-reg-send');\nbtnRegSend.addEventListener('click', () => {\n  const login = regLogin.value.trim();\n  if(!isEmail(login)){ show('msg-reg', false, 'Please enter a valid email'); return; }\n  const fd = new FormData(); fd.append('login', login);\n  const btn = btnRegSend; btn.disabled=true; btn.textContent='Sending...';\n  ajax('nggc_send_reg_code', fd).then(res=>{\n      if(res && res.success) show('msg-reg', true, 'Verification code sent. It is valid for 10 minutes.');\n      else show('msg-reg', false, (res && res.data && res.data.message) ? res.data.message : 'Failed to send');\n      btn.disabled=false; btn.textContent='Get Code';\n  }).catch(()=>{ show('msg-reg', false, 'Network error'); btn.disabled=false; btn.textContent='Get Code'; });\n});\n\n\/\/ Register \/ Login (email new registration requires code)\ndocument.getElementById('btn-reg-login').addEventListener('click', () => {\nconst login = document.getElementById('reg-login').value.trim();\nconst uname = document.getElementById('reg-username').value.trim();\nconst pass  = document.getElementById('reg-password').value;\nconst ref   = document.getElementById('reg-ref').value.trim();\nconst code  = document.getElementById('reg-code').value.trim();\nif(!login || !uname || pass.length<6){ show('msg-reg', false, 'Please enter phone or email, username, and a password of at least 6 characters'); return; }\nif (isEmail(login)) {\n  if (!\/^\\d{6}$\/.test(code)) { show('msg-reg', false, 'Please enter the 6\u2011digit email verification code'); return; }\n}\nconst fd = new FormData(); fd.append('login', login); fd.append('username', uname); fd.append('password', pass); if(ref) fd.append('ref', ref);\nif (isEmail(login)) fd.append('code', code);\nconst btn = document.getElementById('btn-reg-login'); btn.disabled=true; btn.textContent='Submitting...';\najax('nggc_register_or_login', fd).then(res=>{\nif(res && res.success){\nshow('msg-reg', true, res.data.message || 'Success, redirecting...');\nsetTimeout(()=>location.href=res.data.redirect, 350);\n} else {\nshow('msg-reg', false, (res && res.data && res.data.message) ? res.data.message : 'Operation failed');\nbtn.disabled=false; btn.textContent='Login \/ Register';\n}\n}).catch(()=>{ show('msg-reg', false, 'Network error'); btn.disabled=false; btn.textContent='Login \/ Register'; });\n});\n\n\/\/ Password Login\ndocument.getElementById('btn-password-login').addEventListener('click', () => {\nconst login = document.getElementById('pass-login').value.trim();\nconst pass = document.getElementById('pass-password').value;\nif(!login || !pass){ show('msg-pass', false, 'Please enter account and password'); return; }\nconst fd = new FormData(); fd.append('login', login); fd.append('password', pass);\nconst btn = document.getElementById('btn-password-login'); btn.disabled=true; btn.textContent='Logging in...';\najax('nggc_password_login', fd).then(res=>{\nif(res && res.success){ show('msg-pass', true, 'Login successful, redirecting...'); setTimeout(()=>location.href=res.data.redirect, 300); }\nelse { show('msg-pass', false, (res && res.data && res.data.message) ? res.data.message : 'Login failed'); btn.disabled=false; btn.textContent='Login'; }\n}).catch(()=>{ show('msg-pass', false, 'Network error'); btn.disabled=false; btn.textContent='Login'; });\n});\n\n\/\/ Send email code (password reset)\ndocument.getElementById('btn-reset-send').addEventListener('click', () => {\nconst email = document.getElementById('reset-email').value.trim();\nif(!email){ show('msg-reset', false, 'Please enter your email'); return; }\nconst fd = new FormData(); fd.append('login', email); fd.append('purpose','reset');\nconst btn = document.getElementById('btn-reset-send'); btn.disabled=true; btn.textContent='Sending...';\najax('nggc_send_code', fd).then(res=>{\nif(res && res.success) show('msg-reset', true, 'Verification code has been sent to your email. Please use it within 10 minutes');\nelse show('msg-reset', false, (res && res.data && res.data.message) ? res.data.message : 'Failed to send');\nbtn.disabled=false; btn.textContent='Get Code';\n}).catch(()=>{ show('msg-reset', false, 'Network error'); btn.disabled=false; btn.textContent='Get Code'; });\n});\n\n\/\/ Reset password\ndocument.getElementById('btn-reset-do').addEventListener('click', () => {\nconst email = document.getElementById('reset-email').value.trim();\nconst code = document.getElementById('reset-code').value.trim();\nconst pass = document.getElementById('reset-pass').value;\nif(!email || !code || pass.length<6){ show('msg-reset', false, 'Incomplete information. Password must be at least 6 characters'); return; }\nconst fd = new FormData(); fd.append('login', email); fd.append('code', code); fd.append('password', pass);\nconst btn = document.getElementById('btn-reset-do'); btn.disabled=true; btn.textContent='Submitting...';\najax('nggc_reset_with_code', fd).then(res=>{\nif(res && res.success){ show('msg-reset', true, 'Password has been reset. Please log in with your new password'); setTimeout(()=>document.querySelector('.otp-tab[data-tab=\"password\"]').click(), 600); }\nelse { show('msg-reset', false, (res && res.data && res.data.message) ? res.data.message : 'Reset failed'); btn.disabled=false; btn.textContent='Reset Password'; }\n}).catch(()=>{ show('msg-reset', false, 'Network error'); btn.disabled=false; btn.textContent='Reset Password'; });\n});\n})();\n<\/script>\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":"","meta":{"_acf_changed":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-474","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/staging.xingshengcardindustry.com\/wp-json\/wp\/v2\/pages\/474","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/staging.xingshengcardindustry.com\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/staging.xingshengcardindustry.com\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/staging.xingshengcardindustry.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/staging.xingshengcardindustry.com\/wp-json\/wp\/v2\/comments?post=474"}],"version-history":[{"count":3,"href":"https:\/\/staging.xingshengcardindustry.com\/wp-json\/wp\/v2\/pages\/474\/revisions"}],"predecessor-version":[{"id":495,"href":"https:\/\/staging.xingshengcardindustry.com\/wp-json\/wp\/v2\/pages\/474\/revisions\/495"}],"wp:attachment":[{"href":"https:\/\/staging.xingshengcardindustry.com\/wp-json\/wp\/v2\/media?parent=474"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}