Form Login V4.0 database content

form login v4.0


#Version 4.0

Apa yang baru ?

- lock pakai database.
- player video(coming soon). 
- new style.
- tidak lagi popup.
- Profile header.

Apa yang dihapus ?
- lock encrypt 
- Role Staff,Modder 
- form login popup
- encrypt label
 

Catatan:


Kode ini direlease agar ada tujuan untuk pengembangan versi premium, sekaligus sebagai test kode premium yang perlu disempurnakan.


check Demo: tidak tersedia
Video Thumbnail
Cara Post Demo(tidak tersedia)

Config SDK Firebase

Letakan dibawah head

jangan lupa pasang config sdk milik kamu didalam kode ini


<script src='https://www.gstatic.com/firebasejs/8.6.8/firebase-app.js'/>
  <script src='https://www.gstatic.com/firebasejs/8.6.8/firebase-auth.js'/>
  <script src='https://www.gstatic.com/firebasejs/8.6.8/firebase-firestore.js'/>
  <script src='https://www.gstatic.com/firebasejs/8.6.8/firebase-database.js'/>
  <script src='https://www.gstatic.com/firebasejs/8.6.8/firebase-storage.js'/>
  <script>
    /*<![CDATA[*/
    const config2 = {
       config sdk kamu  disini 
       
    };
    firebase.initializeApp(config2);
    const dbrl = firebase.database();
    const auth = firebase.auth();
    const storagedb = firebase.storage();
    const db = firebase.firestore();
/*]]>*/
   </script>

Rule Firebase

Firestore

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // Izinkan pencarian email
    match /users/{userId} {
      allow read: if request.auth == null || resource.data.email == request.auth.token.email;
      allow create, update, delete: if request.auth != null && request.auth.uid == userId;
      
      // Izinkan akses ke semua field dalam dokumen users setelah login
      match /users/{userId} {
        allow read, write: if request.auth != null && request.auth.uid == userId;
      }
    }

  match /profiles_publik/{document=**} {
      allow read: if true;
      allow write: if request.auth != null && (get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role in ['User', 'Member', 'Staff', 'Modder']);
    }


    // Pengecualian untuk pengguna dengan role "Admin" agar mendapat akses ke semua data
    match /{document=**} {
      allow read, write: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'Admin';
    }
  }
}
Realtime database (Update: 17/08/2024 4:00PM)
    Channge Log
  • Add Rule Kontent
  • Fixed Rule Series

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "auth != null && auth.uid === $uid",
        ".write": "auth != null && auth.uid === $uid"
      }
    },
    
"riwayat_baca": {
      "$userId": {
        ".read": "$userId === auth.uid",
        ".write": "$userId === auth.uid",
        "$postId": {
          ".validate": "newData.hasChildren(['imgcover', 'title', 'url', 'initialtime','latesttimeread','count_read'])"
        },
        ".indexOn": ["initialtime"]
      }
    },
 "kontent": {
    ".read": "auth != null",
    ".write": "auth != null"
   },   
   "series": {
        ".read": "auth != null || !data.child('linksPremium').exists()",
        ".write": "auth != null",
        "episodes": {
          "$episodeId": {
            ".read": "auth != null || !data.child('linksPremium').exists()",
            ".write": "auth != null"
          }
        }
    },
    "$other": {
      ".read": "auth != null",
      ".write": "root.child('users/' + auth.uid + '/role').val() == 'Admin'"
    }
  }
}
Storage

service firebase.storage {
  match /b/{bucket}/o {
    match /profile_photos/{allPaths=**} {
      allow read: if true;
      allow write: if request.auth != null;
    }
  }
}


Profile Header

letakan diheader


<img class="profilePicture" src="" alt="Profile Picture" style="width:30px; height:30px; border-radius:50%;"/>

<span class="username">Guest</span>
<span class="userRole"></span>
<span class="userExp"></span>
<span class="userEmail"></span>

<a href='/p/register.html' class='registerLink'>Register</a>
<a href='/p/login.html' class='loginLink'>Login</a>
<a href='/p/profile.html' class='profileLink'>Profile</a>
<a href='/p/reset-password.html' class='resetPasswordLink'>Reset Password</a>
<a href='#' class='logoutLink' onclick='logoutUser()' style='display:none;'>Logout</a>

<script>
/*<![CDATA[*/
function runprofile_Header(user) {
    const registerLink = document.querySelector(".registerLink");
    const loginLink = document.querySelector(".loginLink");
    const profileLink = document.querySelector(".profileLink");
    const resetPasswordLink = document.querySelector(".resetPasswordLink");
    const logoutLink = document.querySelector(".logoutLink");

    if (user) {
        profileLink.style.display = "inline";
        resetPasswordLink.style.display = "none";
        registerLink.style.display = "none";
        loginLink.style.display = "none";
        logoutLink.style.display = "inline";
    } else {
        registerLink.style.display = "inline";
        loginLink.style.display = "inline";
        profileLink.style.display = "none";
        resetPasswordLink.style.display = "inline";
        logoutLink.style.display = "none";
    }
}

function get_datauser(userId) {
    const user_doc = db.collection("users").doc(userId);
    return user_doc.get().then((doc) => {
        if (doc.exists) {
            return doc.data();
        } else {
  console.warn("No data.");
            return;
        }
    }).catch((error) => {
        console.error("Error:", error);
        return;
    });
}

function displayUserProfile(user, data_user) {
    const profile_Avatar = document.querySelector(".profilePicture");
    const username = document.querySelector(".username");
    const userRole = document.querySelector(".userRole");
    const userExp = document.querySelector(".userExp");
    const userEmail = document.querySelector(".userEmail");

    if (user.photoURL) {
        profile_Avatar.src = user.photoURL;
    }

    // username, role, EXP role, dan email

    username.textContent = data_user.username || "Guest";
    userRole.textContent = data_user.role ? `Role: ${data_user.role}` : "Role: N/A";
    userExp.textContent = data_user.exp ? `EXP role: ${data_user.exp}` : "EXP role: N/A";
    userEmail.textContent = data_user.email ? `Email: ${data_user.email}` : "Email: N/A";
}

function logoutUser() {
    auth.signOut().then(() => {
        window.location.href = '/p/login.html';
    }).catch((error) => {
        console.error("Error logging out:", error);
    });
}

auth.onAuthStateChanged(function(user) {
    runprofile_Header(user);
    if (user) {
    get_datauser(user.uid).then((data_user) => {
         displayUserProfile(user, data_user);
        });
    } else {
        displayUserProfile(null,null);
    }
});
/*]]>*/
</script>

Login - register - profile - change password

Ke empat kode ini harap letakan di halaman blog kalian, bebas kasih nama apa.

Login

<style>
.btn_login,.frinput{font-size:16px;width:100%}.border-wrp,.notif{align-items:center}.loginHiru{background:#f4f4f4;padding:20px;border-radius:8px;box-shadow:0 10px 30px rgba(0,0,0,.1);max-width:400px;width:100%;text-align:center}.login-form h3{font-size:24px;margin-bottom:20px;color:#333}.group_login{position:relative;margin-bottom:20px}.frinput{padding:10px 10px 10px 0;display:block;border:none;border-bottom:2px solid #333;background:0 0;color:#333;outline:0}.frinput::placeholder{color:#999}.group_login label{color:#333;font-size:14px;position:absolute;top:-20px;left:0}.bar_login{position:absolute;bottom:0;left:0;height:2px;width:100%;background:#333;transition:transform .3s;transform:scaleX(0)}.frinput:focus~.bar_login{transform:scaleX(1)}.icon_lock_pass_login{position:absolute;right:10px;top:10px;cursor:pointer}.btn_login{background-color:#000;color:#fff;padding:10px;border:none;border-radius:4px;cursor:pointer;transition:background-color .3s}.btn_login:hover{background-color:#333}.message{margin:15px 0 0;font-size:14px;color:#333}.message a{color:#000;text-decoration:none;font-weight:700}.border-wrp{display:flex;justify-content:center;margin:20px 0}.border-bts{height:1px;width:100%;background:#333}.spanor{padding:0 10px;font-weight:700;color:#333}.icon_lock_pass_login svg{width:24px;height:24px}.hiddeniconpass_login{display:none}@media (max-width:500px){.loginHiru{padding:15px}.login-form h3{font-size:20px}}.notif{position:fixed;top:20px;right:20px;background-color:#222;color:#fff;padding:20px;border-radius:8px;box-shadow:0 4px 8px rgba(0,0,0,.2);z-index:99999999;display:flex;transition:opacity .3s,visibility .3s}.notif.hiddeniconpass_login{opacity:0;visibility:hidden}.notif-content{display:flex;align-items:center}.notif-content h4{margin:0 10px;font-size:18px}.notif-content p{margin:0}.notif.success{border-left:4px solid #4caf50}.notif.error{border-left:4px solid #f44336}.notif.warning{border-left:4px solid #ff9800}#notifIcon{font-size:24px;margin-right:10px}@keyframes slideInRight{from{transform:translateX(100%)}to{transform:translateX(0)}}@keyframes slideOutRight{from{transform:translateX(0)}to{transform:translateX(100%)}}
</style>
<div class='loginHiru'>
  <!-- Form Login -->
  <form class='login-form' id='formlogin'>
   <h3>Welcome Back!</h3> 
  <div class='group_login'>
  <input class='frinput' id='login_email' placeholder='name@gmail.com' required='required' type='email'/>
     <span class='bar_login'></span>
      <label>EMAIL ADDRESS</label>
      </div>
   <div class='group_login'>
   <input class='frinput Validpass1' id='login_password' placeholder='Password' required='required' type='password'/>
  <span class='bar_login'></span>
<label>PASSWORD</label>
<span class='icon_lock_pass_login' id='clickShowpass_login'>
<svg class='showPas icon1' viewBox='0 0 24 24'><path d='M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z' fill='#bbb'/></svg>
<svg class='showPas icon2 hiddeniconpass_login' viewBox='0 0 24 24'>
<path d='M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z' fill='#bbb'/></svg>
</span> 
      </div>
<div class='boxbutton'>        
   <button class='btn_login' type='submit'>Sign-in</button>
      </div>  
   <p class='message'>
   <a class='reoverPassword'>Forgot Password?</a>
    </p>
    <div class="border-wrp">
<div class="border-bts"></div>
<span class="spanor">Hirutshuji</span>
<div class="border-bts"></div>
</div>
  <p class='message'>Don&#39;t have an account? <a class='createAccount'>Register</a>
    </p>   
    </form> 
    </div>   
<div id="loginNotif" class="notif hiddeniconpass_login">
  <div class="notif-content">
    <span id="notifIcon"></span>
    <h4 id="notifTitle"></h4>
    <p id="notifText"></p>
  </div>
</div> 
<script>
 /*<![CDATA[*/
    const pesanLogin = {
   berhasilLogin: {
        judul: "Berhasil Login!",
        pesan: "kamu berhasil masuk ke akun kamu."
        },
   emailBelumTervertifikasi: {
        judul: "Email Belum Terverifikasi",
        pesan: "Pastikan kamu telah melakukan verifikasi email sebelum mencoba login.",
        ya: "Mengerti"
        },
   kirimEmailVertifikasi:{
        judul: "Kirim Vertifikasi email",
        pesan:"Apakah kamu ingin Vertifikasi email sekarang?",
        ya: "ya,kirim",
        tidak: "batal"
        },
    vertifyTerkirim:{
      judul:"verifikasi terkirim",
      pesan:"Email verifikasi telah dikirim ke",
      pesan2:"Silahkan cek inbox pesan kamu"
        },
    ijinLogin:{
      judul:"warning",
      pesan:"Maaf, kamu tidak diizinkan untuk melakukan operasi autentikasi di luar domain yang terdaftar."
       },
     loaderLogin:{
      judul:"sabar bro",
      pesan:"Mengecek data kamu dulu"
      },
     errorLog: {
       judul: "Gagal Login",
       pesan: "Terjadi kesalahan saat login. Silakan coba lagi nanti."
        },
     userTidakDitemukan: {
      judul: "Gagal Login",
        pesan: "Email tidak ditemukan. Silakan daftar terlebih dahulu.",
        ya:"Tutup"
        },
     emailSalah: {
      judul: "Gagal Login",
        pesan: "Email yang kamu masukan salah. Silakan masukan email benar",
        ya:"Tutup"
        },
     passwordSalah: {
        judul: "Gagal Login",
        pesan: "Kata sandi salah. Silakan coba lagi."
        },
    loginLimit: {
        judul: "Gagal Login",
        pesan :"Terlalu banyak percobaan masuk. Silakan coba lagi nanti."
       },
    gagalVertifypassword: {
        judul: "Gagal Login",
        pesan: "Verifikasi password gagal. harap masukan password yang benar."
        }
    };
    

 let iconSukses = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="green" d="m9 20.42l-6.21-6.21l2.83-2.83L9 14.77l9.88-9.89l2.83 2.83z"/></svg>`; 
  
 let iconGagal = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="red" d="M6.4 19L5 17.6l5.6-5.6L5 6.4L6.4 5l5.6 5.6L17.6 5L19 6.4L13.4 12l5.6 5.6l-1.4 1.4l-5.6-5.6z"/></svg>`;
 let iconInfo = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="#ffff00" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 6v8m.05 4v.1h-.1V18z"/></svg>`;
 let iconWarning= `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512"><path fill="none" stroke="#ffd43b" stroke-linecap="round" stroke-miterlimit="10" stroke-width="15" d="m381 340.1l-52.8-97.3l-51-94.2a24 24 0 0 0-42.4 0l-51 94.2l-52.8 97.3a24.3 24.3 0 0 0 21.2 35.9h207.7a24.2 24.2 0 0 0 21.1-35.9Z"/><path fill="#ffd43b" d="M243 216.6q1.5-1.3 5.5-1.3h15.3c2.7 0 4.5.4 5.6 1.3s1.5 2.4 1.4 4.7l-3 71.8c-.1 2.3-.7 3.8-1.6 4.6s-2.7 1.3-5.4 1.3h-9.4c-2.6 0-4.4-.5-5.3-1.3s-1.5-2.3-1.6-4.6l-2.9-71.9c0-2.2.4-3.8 1.4-4.6m29 107.6q0 7-3 9.5c-2 1.8-5.6 2.7-11 2.7h-4c-5.4 0-9-1-11-2.6s-3-5-3-9.6v-2.9q0-7 3-9.6c2-1.7 5.6-2.5 11-2.5h4c5.4 0 9 .8 11 2.5s3 5 3 9.6Z"/></svg>`;
 let iconLoader = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#ffff00" d="M12,23a9.63,9.63,0,0,1-8-9.5,9.51,9.51,0,0,1,6.79-9.1A1.66,1.66,0,0,0,12,2.81h0a1.67,1.67,0,0,0-1.94-1.64A11,11,0,0,0,12,23Z"><animateTransform attributeName="transform" dur="0.75s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></svg>`;
 let iconTanya = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 64 64"><path fill="#be212f" d="M31.03 51.23q-2.854 0-4.872 1.809c-1.344 1.204-2.02 2.662-2.02 4.381q0 2.905 2.038 4.563c1.362 1.106 2.948 1.664 4.761 1.664c1.843 0 3.451-.55 4.827-1.641q2.062-1.642 2.062-4.587q0-2.577-1.972-4.381c-1.315-1.203-2.921-1.808-4.827-1.808M50.458 8.617c-1.75-2.656-4.251-4.78-7.438-6.319C39.851.773 36.16 0 32.046 0c-4.429 0-8.371.926-11.711 2.753c-3.344 1.83-5.928 4.178-7.68 6.978C10.895 12.545 10 15.375 10 18.145c0 1.477.616 2.856 1.824 4.096c1.214 1.248 2.724 1.879 4.488 1.879c3.01 0 5.061-1.766 6.105-5.23c.951-2.865 2.124-5.05 3.48-6.498c1.276-1.364 3.346-2.056 6.149-2.056c2.418 0 4.326.678 5.84 2.075c1.491 1.378 2.217 3.02 2.217 5.02c0 1.01-.236 1.917-.709 2.775c-.503.9-1.13 1.727-1.863 2.463c-.775.776-2.054 1.941-3.802 3.473c-2.036 1.785-3.679 3.348-4.875 4.646c-1.25 1.349-2.263 2.935-3.02 4.712c-.756 1.789-1.14 3.924-1.14 6.349c0 2.069.577 3.671 1.717 4.762c1.128 1.08 2.533 1.63 4.178 1.63c3.145 0 5.121-1.719 5.709-4.935q.448-2.006.674-2.802c.136-.483.333-.979.586-1.474c.246-.482.635-1.028 1.16-1.625c.547-.631 1.286-1.371 2.192-2.198c3.389-3.03 5.78-5.222 7.106-6.52c1.368-1.337 2.561-2.946 3.546-4.778c1.014-1.875 1.528-4.084 1.528-6.559c.002-3.131-.887-6.072-2.637-8.737"/></svg>`;

   // isi opsi redirect
    const RedirectOpsiHalaman_lHiru= {
        custom_url: "https://datakodehiru.blogspot.com",
        homepage_url: window.location.hostname
    };
  

 //redirect yang dipilih 
let redirectOpsi_loginHiru = "Customurl";
/*ada tiga opsi "Customurl","Homepage","Reload" */

let waktuTunda_lHiru = 1000;// 1detik sebelum redirect dilakukan

let waktuTundaNotif = 3000; //3detik notif berhasil login muncul
/*]]>*/
</script>  
<script defer='defer'>
/*<![CDATA[*/ 
 let idPassword = '#login_password';
function showpasslogin() {
 var pshowLogin = document.querySelector(idPassword);
 pshowLogin.setAttribute('type', 'text'); 
var loginpassshowicon = document.querySelector('.icon1'); loginpassshowicon.classList.add("hiddeniconpass_login");
 var loginpassshowicon2 = document.querySelector('.icon2'); loginpassshowicon2.classList.remove("hiddeniconpass_login");
}
function hidepasslogin() {
 var hidepassLogin = document.querySelector(idPassword);
 hidepassLogin.setAttribute('type', 'password');

 var hideniconpasslogin = document.querySelector('.icon1'); hideniconpasslogin.classList.remove("hiddeniconpass_login");
 var hideniconpasslogin2 = document.querySelector('.icon2'); hideniconpasslogin2.classList.add("hiddeniconpass_login");
}


var pwShownLogin = 0;
document.getElementById("clickShowpass_login").addEventListener("click", function () {
if (pwShownLogin == 0) {
 pwShownLogin = 1;
showpasslogin();
}
else {
 pwShownLogin = 0;
hidepasslogin();
}}, false);
function encryptPassword(password) {
  return btoa(password);
}
function decryptPassword(encryptedPassword) {
  return atob(encryptedPassword);
}
function simpanHistoryLoginTerakhir(email, password) {
  const ceklog = encryptPassword(password);
  localStorage.setItem('lastLoginEmail', email);
  localStorage.setItem('lastLoginPassword',ceklog);
}
function getLastLoginHistory() {
  const lastLoginEmail = localStorage.getItem('lastLoginEmail');
  const ceklog = localStorage.getItem('lastLoginPassword');
  return { email: lastLoginEmail, password: ceklog };
}
function showLastLoginHistory() {
  const { email, password } = getLastLoginHistory();
  if (email) {
    document.getElementById('login_email').value = email;
  }
  if (password) {
    const decryptedPassword = decryptPassword(password);
    document.getElementById('login_password').value = decryptedPassword;
  }
}
window.onload = function() {
  showLastLoginHistory();}
 /*]]>*/
   </script>
Register

<style>
.registerHiru{max-width:400px;margin:20px auto;padding:30px;background-color:#fff;border-radius:8px;box-shadow:0 4px 10px rgba(0,0,0,.1)}.registerHiru h3{text-align:center;margin-bottom:20px;font-size:1.8rem;color:#333}.group_register{position:relative;margin-bottom:25px}.group_register input{font-size:16px;padding:10px;display:block;width:100%;border:none;border-bottom:2px solid #ccc;background:0 0;outline:0;color:#333}.group_register input:focus{border-bottom:2px solid #007bff}.bar_register{position:absolute;bottom:0;left:0;height:2px;width:0;background-color:#007bff;transition:width .3s}.group_register input:focus~.bar_register{width:100%}.group_register label{position:absolute;top:-15px;left:0;font-size:14px;color:#999;pointer-events:none;transition:.2s}.btn_register,.notif-buttons button{background-color:#000;cursor:pointer;transition:background-color .3s}.group_register input:focus~label,.group_register input:valid~label{top:-15px;left:0;color:#007bff;font-size:12px}.icon_lock_pass_register{position:absolute;top:50%;right:10px;transform:translateY(-50%);cursor:pointer}.icon_lock_pass_register svg{width:20px;height:20px}.error-message{color:red;font-size:12px;margin-top:5px;display:none}.btn_register{display:block;width:100%;padding:10px;border:none;color:#fff;font-size:16px;border-radius:4px}.btn_register:hover,.notif-buttons button:hover{background-color:#0056b3}.inforegister,.message_register{text-align:center;margin-top:15px;font-size:14px}.message_register a{color:#007bff;text-decoration:none}.message_register a:hover{text-decoration:underline}.brd_r{margin:0 5px;color:#ccc}@media (max-width:500px){.registerHiru{padding:20px}.btn_register,.group_register input{font-size:14px}}.hiddeniconpass_registers{display:none} .notifregister_main{position:fixed;top:10px;right:20px;width:300px;padding:15px;border-radius:5px;box-shadow:0 2px 5px rgba(0,0,0,.2);display:flex;align-items:center;background-color:#222;color:#fff;font-size:12px; z-index:9999999;transition:opacity .5s,transform .5s}.notifkonfirmasi{top:30%;right:20px}.notifregister_main.hiddenregister_notif{opacity:0;transform:translateY(-200px)}.notif-icon{font-size:24px;margin-right:10px}.notif-content{flex:1}.notif-title{font-weight:700;margin-bottom:5px}.notif-text{font-size:14px}.notif-buttons{margin-top:10px}.notif-buttons button{color:#fff;border:none;padding:8px 16px;border-radius:4px;margin-right:10px}.success{border-left:5px solid #28a745}.error{border-left:5px solid #dc3545}.warning{border-left:5px solid #ffc107}.info{border-left:5px solid #17a2b8}
  </style>

<div class='registerHiru'>
<!-- Form Register -->
<form name="form_register" class='register-form' id='register-form'>
    <h3>Create Account</h3>
<div class='group_register'>
<input name="name" id='register-username' placeholder='Name' required='required' type='text' autocomplete="off"/>
    <span class='bar_register'></span>
     <label>YOUR NAME</label>
     </div>
<div class='group_register'>
 <input name="email" id='register-email' pattern='[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$' placeholder='name@gmail.com' required='required' value="youremail@gmail.com" type='email' autocomplete="off"/>
 <span class='bar_register'></span>
 <label>EMAIL ADDRESS</label>       </div>

<div class='group_register'>
 <input name="password" class='Validpass2' id='register-password' placeholder='Password' required='required' type='password' autocomplete="off"/> 
   <span class='bar_register'></span>
  <label>PASSWORD</label>
<span class='icon_lock_pass_register' id='showpass2'>
<svg class='showPas icon3' viewBox='0 0 24 24'><path d='M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z' fill='var(--color-svg-input)'/></svg>
<svg class='showPas icon4 hiddeniconpass_registers' viewBox='0 0 24 24'>
<path d='M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z' fill='var(--color-svg-input)'/></svg>
</span>
    </div>  
  <div class='group_register'>
    <input name="password" id='register-confirm-password' placeholder='Confirm Password' required='required' type='password' autocomplete="off"/>
<span id="passTidaksama" class="error-message"></span>
    <span class='bar_register'></span>
    <label>CONFIRM PASSWORD</label>
</div>
  <button class='btn_register' type='submit'>Sign-up</button>
<div class='inforegister'>
<p class='message_register'>Baca kebijakan kami disini</p><p class='message_register'><span class='brd_r'></span><a href='#' class='readnow'>Read Now</a><span class='brd_r'></span></p>
</div>
<p class='message_register'>Have an account?<a class='signIn' href='#'>Sign-in</a></p>
    </form>       
    
      </div>
      
      <!-- Notifikasi Pendaftaran -->
<div id="registerNotif" class="notifregister_main hiddenregister_notif">
    <div class="notif-icon" id="notifIcon_register"></div>
    <div class="notif-content">
        <div class="notif-title" id="notifTitle_register"></div>
        <div class="notif-text" id="notifText_register"></div>
    </div>
</div>

<!-- Notifikasi Konfirmasi -->
<div id="confirmRegisterNotif" class="notifkonfirmasi warning notifregister_main hiddenregister_notif">
    <div class="notif-icon">⚠️</div>
    <div class="notif-content">
        <div class="notif-title">Konfirmasi Pendaftaran</div>
        <div class="notif-text">Apakah Anda yakin ingin mendaftar?</div>
        <div class="notif-buttons">
            <button id="confirmYes">tentu</button>
            <button id="confirmNo">batal</button>
        </div>
    </div>
</div>

 <script defer='defer'>
/*<![CDATA[*/ 
const pesanNotifregister = {
    registerBerhasil: {
        judul: "Berhasil Register!",
        pesan: "Silakan periksa email Kamu untuk memverifikasi akunmu"
    },
    konfimasiRegister: {
        judul: "Apakah kamu yakin ingin register?",
        pesan: "kamu akan membuat akun dengan email ini ",
        pesan2:" Jika kamu click 'tentu' maka kami anggap bahwa kamu sudah membaca dan setuju dengan kebijakan kami. ",
    },
    emailTerdaftar: {
        judul: "Email terdaftar",
        pesan:"Email sudah digunakan. Silakan gunakan email lain."
    },
    errorRegister:{
     judul:"Gagal register",
     pesan: "Registrasi gagal. "
    },
  
    loaderSaatRegister:{
     judul:"Proses register",
     pesan:"Sabar...sedang diproses"
    },
  
    konfimasiVertifyemail:{
     judul:"Email verifikasi",
     pesan:"kami akan mengirim verifikasi ke emailmu untuk memverifikasi akunmu, click 'Oke' untuk mendapatkan pesan vertifikasi",
    },
  
    vertifyEmailterkirim:{
     judul:"verifikasi berhasil terkirim",
     pesan:"Email verifikasi telah dikirim, silahkan cek inbox pesan kamu."
    },
    infoRulevertify:{
     judul:"Pemberitahuan",
     pesan:"Beberapa fitur tidak dapat diakses sampai email verifikasi dikonfimasi."
    },

ijinRegister:{
     judul:"warning",
     pesan:"Maaf, kamu tidak diizinkan untuk melakukan operasi autentikasi di luar domain yang terdaftar."
    },
};

// isi opsi redirect
    const RedirectOpsiHalaman_rgHiru= {
        custom_url: "https://datakodehiru.blogspot.com",
        homepage_url: window.location.hostname
    };
 //redirect yang dipilih 
let redirectOpsi_rgHiru = "Customurl";
/*ada tiga opsi "Customurl","Homepage","Reload" */

let waktuTunda_rgHiru = 0;// 0detik sebelum redirect dilakukan
   
 let iconSukses = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="green" d="m9 20.42l-6.21-6.21l2.83-2.83L9 14.77l9.88-9.89l2.83 2.83z"/></svg>`; 
  
 let iconGagal = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="red" d="M6.4 19L5 17.6l5.6-5.6L5 6.4L6.4 5l5.6 5.6L17.6 5L19 6.4L13.4 12l5.6 5.6l-1.4 1.4l-5.6-5.6z"/></svg>`;
 let iconInfo = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="#ffff00" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 6v8m.05 4v.1h-.1V18z"/></svg>`;
 let iconWarning= `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512"><path fill="none" stroke="#ffd43b" stroke-linecap="round" stroke-miterlimit="10" stroke-width="15" d="m381 340.1l-52.8-97.3l-51-94.2a24 24 0 0 0-42.4 0l-51 94.2l-52.8 97.3a24.3 24.3 0 0 0 21.2 35.9h207.7a24.2 24.2 0 0 0 21.1-35.9Z"/><path fill="#ffd43b" d="M243 216.6q1.5-1.3 5.5-1.3h15.3c2.7 0 4.5.4 5.6 1.3s1.5 2.4 1.4 4.7l-3 71.8c-.1 2.3-.7 3.8-1.6 4.6s-2.7 1.3-5.4 1.3h-9.4c-2.6 0-4.4-.5-5.3-1.3s-1.5-2.3-1.6-4.6l-2.9-71.9c0-2.2.4-3.8 1.4-4.6m29 107.6q0 7-3 9.5c-2 1.8-5.6 2.7-11 2.7h-4c-5.4 0-9-1-11-2.6s-3-5-3-9.6v-2.9q0-7 3-9.6c2-1.7 5.6-2.5 11-2.5h4c5.4 0 9 .8 11 2.5s3 5 3 9.6Z"/></svg>`;

/*]]>*/
  </script>     
<script defer='defer'>
/*<![CDATA[*/ 
function showpassregister() {
 var pshowRegister = document.querySelector('#register-password');
 pshowRegister.setAttribute('type', 'text'); 
var registerpassshowicon = document.querySelector('.icon3'); registerpassshowicon.classList.add("hiddeniconpass_registers");
 var registerpassshowicon2 = document.querySelector('.icon4'); registerpassshowicon2.classList.remove("hiddeniconpass_registers");
}

function hidepassregister() {
 var hidepassregister = document.querySelector('#register-password');
 hidepassregister.setAttribute('type', 'password');

 var hideiconpassregister = document.querySelector('.icon3'); hideiconpassregister.classList.remove("hiddeniconpass_registers");

var hideiconpassregister2 = document.querySelector('.icon4'); hideiconpassregister2.classList.add("hiddeniconpass_registers");
 }
 
 var pwShownRegister = 0;
document.getElementById("showpass2").addEventListener("click", function () {
    if (pwShownRegister == 0) {
        pwShownRegister = 1;
        showpassregister();
    } else {
        pwShownRegister = 0;
        hidepassregister();
    }
}, false);
function validatePassword() {
    var password = document.getElementById("register-password");
    var confirm_password = document.getElementById("register-confirm-password");
    var error_message = document.getElementById("passTidaksama");

    if (password.value === "" || password.value !== confirm_password.value) {
        confirm_password.style.border = "thin solid red";
        error_message.innerHTML = "password is not the same";
    } else {
 confirm_password.style.border = ""; 
 error_message.innerHTML = "password correct";
    }
}
document.getElementById("register-password").addEventListener("input", validatePassword);
document.getElementById("register-confirm-password").addEventListener("input", validatePassword);
/*]]>*/
  </script>     
Profile

<style>
.ProfileX {
    width: 100%;
    max-width: 600px;
    margin: 0 auto;
    padding: 10px;
    background-color: #333;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}

.ProfileX h1 {
    text-align: center;
    margin-bottom: 20px;
}

.profile_data_0,
.profile_data_1,
.profile_data_2 {
    margin-bottom: 20px;
}

.fotoprofile {
    display: flex;
    align-items: center;
    margin-bottom: 10px;
}

.logoprofile {
    margin-right: 10px;
}

#userPhoto {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    object-fit: cover;
}

input[type="file"] {
    display: none;
}

label {
    cursor: pointer;
    color: #007bff;
    text-decoration: underline;
}

#updateprofile_hr {
    background-color: #222;
    color: white;
    padding: 5px 10px;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    margin-left: 10px;
}

.data-user {
    display: flex;
    align-items: center;
    margin-bottom: 10px;
}

.Ndata {
    font-weight: bold;
    margin-right: 5px;
}

.username_edit {
    display: flex;
    align-items: center;
}

.edit_Nama {
    background: none;
    border: none;
    cursor: pointer;
    color: #007bff;
    font-size: 20px;
    margin-left: 10px;
}

.btn_opsi_profile {
    display: flex;
    justify-content: space-between;
}

.btn_opsi_profile button {
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 16px;
    color:#fff;
    margin: 5px;
}

.DeleteAccount {
    background-color: #242424;
}

.Logout {
    background-color: #242424;
}

.notif-container {
    position: fixed;
    top: 20px;
    right: 20px;
    width: 300px;
    padding: 15px;
    border-radius: 5px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
    display: flex;
    align-items: center;
    background-color: #222;
    color:#fff;
    z-index: 999999;
    transition: opacity 0.5s ease, transform 0.5s ease;
}

.notif-container.hiddenprofile_notif {
    opacity: 0;
    transform: translateY(-200px);
}

.notif-icon {
    font-size: 24px;
    margin-right: 10px;
}

.notif-content {
    flex: 1;
}

.notif-title {
    font-weight: bold;
    margin-bottom: 5px;
}

.notif-text {
    font-size: 14px;
}

.notif-buttons {
    margin-top: 10px;
}

.notif-buttons button {
    background-color: #242424;
    color: #fff;
    border: none;
    padding: 8px 16px;
    border-radius: 4px;
    margin-right: 10px;
    cursor: pointer;
    transition: background-color 0.3s ease;
}

.notif-buttons button:hover {
    background-color: #0056b3;
}

.success {
    border-left: 5px solid #28a745;
}

.error {
    border-left: 5px solid #dc3545;
}

.warning {
    border-left: 5px solid #ffc107;
}

.info {
    border-left: 5px solid #17a2b8;
}
  
.loader_delete_akun {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 9999;
}

.loader_delete_akun::after {
    content: '';
    border: 8px solid #f3f3f3;
    border-radius: 50%;
    border-top: 8px solid #242424;
    width: 50px;
    height: 50px;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}
  
</style>

<!-- Form Profile -->
<div class='ProfileX form' id='profile_hr'>
 <h1>Profile</h1>
<div class='profile_data_0'>
<span class='fotoprofile'>
<span class='logoprofile' id='cc_profile' style="display:none;">
<img  id="userPhoto" src="" alt="User Photo">
</span>  
<input type="file" id="uploadprofile_hr" accept="image/*" style="display:none;">
<label for="uploadprofile_hr" style="cursor: pointer;">Pilih Foto</label>
<script>
  const input = document.getElementById('uploadprofile_hr');
  const userPhoto = document.getElementById('userPhoto');
  input.addEventListener('change', function(event) {
    const file = event.target.files[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = function(e) {
     userPhoto.src = e.target.result;
      };
      reader.readAsDataURL(file);
    }
  });
</script>
<span id="updateprofile_hr">Update</span>
</span>  
<div class='profile_data_1'>
   <span class='data-user'>
    <span class='Ndata'>Uid:</span>
  <span id='profile-uid'></span>
     </span>
 <span class='data-user'>
   <span class='Ndata'>Role: 
  </span>
    <span id='profile-role'>
    </span> 
    </span>
   <span class='data-user'>
 <span class='Ndata'>Exp: 
    </span>
    <span id='exp-role'></span>
   </span> 
   
    </div>
</div> 
 <div class='profile_data_2'>          
<span class='data-user username_edit'>
    <span class='Ndata'>Username:</span>
   <span id='profile-username'></span> 
    <button id="UpdateUsername" class='edit_Nama'><svg height='20' viewBox='0 0 32 32' width='20' xmlns='http://www.w3.org/2000/svg'><path d='M13 3c-3.855 0-7 3.145-7 7c0 2.41 1.23 4.55 3.094 5.813C5.527 17.343 3 20.883 3 25h2c0-4.43 3.57-8 8-8c2.145 0 4.063.879 5.5 2.25l-4.719 4.719l-.062.312l-.688 3.532l-.312 1.468l1.469-.312l3.53-.688l.313-.062l10.094-10.094c1.16-1.16 1.16-3.09 0-4.25a3.018 3.018 0 0 0-4.219-.031l-3.968 3.969a10.103 10.103 0 0 0-3.032-2A7.024 7.024 0 0 0 20 10c0-3.855-3.145-7-7-7zm0 2c2.773 0 5 2.227 5 5s-2.227 5-5 5s-5-2.227-5-5s2.227-5 5-5zm13 10c.254 0 .52.082.719.281a.977.977 0 0 1 0 1.406l-9.688 9.688l-1.781.375l.375-1.781l9.688-9.688A.934.934 0 0 1 26 15z' fill='currentColor'/></svg></button>
    </span>
  <span class='data-user'>
    <span class='Ndata'>Email:</span>
  <span id='profile-email'></span>
    </span>  
  <div class='btn_opsi_profile'>
  <!-- Loader delete -->
<div id="loader_delete_akun" class="loader_delete_akun" style="display: none;"></div>
<button id='deleteAccount' class='DeleteAccount'>Delete Account?</button>  
  <button class='Logout' id='logoutButton'>logout?</button>  
   </div>
	</div>
</div>   


<div id="notifContainer" class="notif-container hiddenprofile_notif">
    <div id="notifIcon" class="notif-icon"></div>
    <div class="notif-content">
        <div id="notifTitle" class="notif-title"></div>
        <div id="notifText" class="notif-text"></div>
    </div>
    <div id="notifButtons" class="notif-buttons">
        <button id="notifConfirm">OK</button>
        <button id="notifCancel" class="hiddenprofile_notif">Cancel</button>
    </div>
</div>

<script>
 /*<![CDATA[*/
  const pesanNotif = {
    logout: {
        judul: "Berhasil logout!",
        pesan: "Akun Telah berhasil Logout"
    },
    belumLogin: {
        judul: "Kamu belum Login",
        pesan: "Kamu harus Login terlebih dahulu dan pastikan sudah vertifikasi email kamu sebelum kesini"
    },
    belumTervertifikasi:{
      judul: "Kamu belum Tervertifikasi",
      pesan: "Email Kamu harus Tervertifikasi dahulu dan pastikan sudah vertifikasi email kamu sebelum kesini"
    },    
    konfirmasiPenghapusan: {
        judul:"Konfirmasi",
        pesan:  "Akun yang sudah dihapus tidak bisa dikembalikan. password dibutuhkan sebagai konfirmasi",
    },
    berhasilmenghapusAkun: {
        judul: "Berhasil Dihapus",
        pesan: "Akun kamu sudah berhasil dihapus"
    },
    autentikasiGagal: {
        judul: "Gagal dihapus",
        pesan: "Mohon Periksa kata sandi kamu dengan benar"
    },
    updateUsername: {
        judul: "Masukan Username",
        pesan:"Silahkan masukan Username yang baru",
        ya:"Update",
        tidak:"batal"
    },
    berhasilUpdateUsername: {
        judul: "username Diubah",
        pesan: "Username berhasil diubah"
    },
   updateUsernametelegram: {
        judul: "Masukan Username",
        pesan:"Silahkan masukan Username yang baru",
        ya:"Update",
        tidak:"batal"
    },
    updateprofilephoto:{
     judul:"Update Foto Profil",
     pesan:"Apakah kamu yakin ingin memperbarui foto profil kamu?",
     ya:"Update",
     tidak: "Batal"
    },
    suksesUpdatePhoto:{
      judul:'berhasil Update',
     pesan:"Profile Telah diupdate"
    },    
    wrnUpdatePhoto:{
      judul:'berhasil Update',
     pesan:"Profile Telah diupdate"
    },
    gagalUpdatePhoto:{
     judul:'gagal Update',
    },
    loaderupdatephoto:{
     judul:"Mengunggah Foto Profil",
     pesan:"Sabar...sedang diproses"
    },
    ijinProfile:{
     judul:"warning",
     pesan:"Maaf, kamu tidak diizinkan untuk melakukan menggunakan fitur ini di luar domain yang terdaftar."
    }
};
 var urlGambarcustom ="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQGqKEDe_BLCrykvvwKY5QNFVOe-s0C67nRcDJZW_PNHZTOUskqLu2z43OX&s=10";
 
// isi opsi redirect
    const RedirectOpsiHalaman_pHiru= {
        custom_url: "https://datakodehiru.blogspot.com",
        homepage_url: window.location.hostname
    };
 //redirect yang dipilih 
let redirectOpsi_pHiru = "Customurl";
/*ada tiga opsi "Customurl","Homepage","Reload" */

let waktuTunda_pHiru = 0;// 0detik sebelum redirect dilakukan
  
let iconSukses = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="green" d="m9 20.42l-6.21-6.21l2.83-2.83L9 14.77l9.88-9.89l2.83 2.83z"/></svg>`; 
  
 let iconGagal = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="red" d="M6.4 19L5 17.6l5.6-5.6L5 6.4L6.4 5l5.6 5.6L17.6 5L19 6.4L13.4 12l5.6 5.6l-1.4 1.4l-5.6-5.6z"/></svg>`;
  
 let iconInfo = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="#ffff00" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 6v8m.05 4v.1h-.1V18z"/></svg>`;
 
 let iconWarning= `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512"><path fill="none" stroke="#ffd43b" stroke-linecap="round" stroke-miterlimit="10" stroke-width="15" d="m381 340.1l-52.8-97.3l-51-94.2a24 24 0 0 0-42.4 0l-51 94.2l-52.8 97.3a24.3 24.3 0 0 0 21.2 35.9h207.7a24.2 24.2 0 0 0 21.1-35.9Z"/><path fill="#ffd43b" d="M243 216.6q1.5-1.3 5.5-1.3h15.3c2.7 0 4.5.4 5.6 1.3s1.5 2.4 1.4 4.7l-3 71.8c-.1 2.3-.7 3.8-1.6 4.6s-2.7 1.3-5.4 1.3h-9.4c-2.6 0-4.4-.5-5.3-1.3s-1.5-2.3-1.6-4.6l-2.9-71.9c0-2.2.4-3.8 1.4-4.6m29 107.6q0 7-3 9.5c-2 1.8-5.6 2.7-11 2.7h-4c-5.4 0-9-1-11-2.6s-3-5-3-9.6v-2.9q0-7 3-9.6c2-1.7 5.6-2.5 11-2.5h4c5.4 0 9 .8 11 2.5s3 5 3 9.6Z"/></svg>`;
/*]]>*/  
</script>
Change password

<style>
.resetpasswordHiru{max-width:400px;margin:0 auto;padding:20px;background-color:#f9f9f9;border-radius:8px;box-shadow:0 4px 8px rgba(0,0,0,.1)}.resetpassword-form{display:flex;flex-direction:column}.group_resetpassword{position:relative;margin-bottom:20px}.group_resetpassword input{width:100%;padding:10px;border:1px solid #ddd;border-radius:4px;font-size:16px}.group_resetpassword input:focus{border-color:#007bff;outline:0}.group_resetpassword .bar_resetpassword{position:absolute;bottom:0;left:0;width:100%;height:2px;background:#222;transform:scaleX(0);transition:transform .3s}.group_resetpassword input:focus~.bar_resetpassword{transform:scaleX(1)}.group_resetpassword label{position:absolute;top:-20px;left:10px;font-size:14px;color:#222;pointer-events:none;transition:.3s}.btn_resetpassword,.notif-buttons button{background-color:#222;cursor:pointer;transition:background-color .3s}.btn_resetpassword{padding:10px;border:none;border-radius:4px;color:#fff;font-size:16px}.btn_resetpassword:hover,.notif-buttons button:hover{background-color:#0056b3}.message_resetpassword{margin-top:20px;text-align:center}.message_resetpassword a{color:#222;text-decoration:none;font-size:14px;display:flex;align-items:center;justify-content:center}.message_resetpassword a:hover{text-decoration:underline}.message_resetpassword svg{margin-right:5px}.notif-container{position:fixed;top:20px;right:20px;width:300px;padding:15px;border-radius:5px;box-shadow:0 2px 5px rgba(0,0,0,.2);display:flex;align-items:center;background-color:#222;color:#fff;z-index:9999999;transition:opacity .5s,transform .5s}.notif-container.hiddenresetpassword_notif{opacity:0;transform:translateY(-200px)}.notif-icon{font-size:24px;margin-right:10px}.notif-content{flex:1}.notif-title{font-weight:700;margin-bottom:5px}.notif-text{font-size:14px}.notif-buttons{margin-top:10px}.notif-buttons button{color:#fff;border:none;padding:8px 16px;border-radius:4px;margin-right:10px}.success{border-left:5px solid #28a745}.error{border-left:5px solid #dc3545}.warning{border-left:5px solid #ffc107}.info{border-left:5px solid #17a2b8}
</style>
   
<div class='resetpasswordHiru'>
<form class='resetpassword-form' id='resetPasswordForm'>   
<div class='group_resetpassword'>
 <input id='resetEmail' pattern='[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$' placeholder='name@gmail.com' required='required' type='email' value='yourEmail@gmail.com'/>
  <span class='bar_resetpassword'></span>
     <label>EMAIL ADDRESS</label>
     </div>
      <button id='resetPasswordForm' class='btn_resetpassword' type='submit'>Sumbit</button>
   <p class='message_resetpassword'><a class='backToLogin'> Back to Sign-in</a></p>
    </form>     
    </div>
<div id="notifContainer" class="notif-container hiddenresetpassword_notif">
    <div id="notifIcon" class="notif-icon"></div>
    <div class="notif-content">
        <div id="notifTitle" class="notif-title"></div>
        <div id="notifText" class="notif-text"></div>
    </div>
    <div id="notifButtons" class="notif-buttons">
        <button id="notifConfirm">OK</button>
        <button id="notifCancel" class="hiddenresetpassword_notif">Cancel</button>
    </div>
</div>
 
 
 
<script defer='defer'>
/*<![CDATA[*/ 
const pesanNotifresetpass = {
   konfirmasiresetpass: {
        judul: "Apakah kamu yakin?",
        pesan: "kamu akan mereset password kamu ke yang baru, pada akun yang terhubung dengan email ini",
   },   
    ijinResetpass:{
     judul:"warning",
     pesan:"Maaf, kamu tidak diizinkan untuk melakukan operasi autentikasi di luar domain yang terdaftar."
    },
    mengirimResetpass:{
      judul:"Berhasil terkirim",
      pesan: "Email reset ulang kata sandi berhasil terkirim. Periksa pesan masuk diemail kamu"
    },
    errorResetpass:{
      judul:"Gagal Reset password",
      pesan: "Harap lapor pada admin jika kamu masih mengalami kendalah error ini"
    }
};
  
  let iconSukses = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="green" d="m9 20.42l-6.21-6.21l2.83-2.83L9 14.77l9.88-9.89l2.83 2.83z"/></svg>`; 
  
 let iconGagal = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="red" d="M6.4 19L5 17.6l5.6-5.6L5 6.4L6.4 5l5.6 5.6L17.6 5L19 6.4L13.4 12l5.6 5.6l-1.4 1.4l-5.6-5.6z"/></svg>`;
 let iconInfo = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="#ffff00" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 6v8m.05 4v.1h-.1V18z"/></svg>`;
 let iconWarning= `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512"><path fill="none" stroke="#ffd43b" stroke-linecap="round" stroke-miterlimit="10" stroke-width="15" d="m381 340.1l-52.8-97.3l-51-94.2a24 24 0 0 0-42.4 0l-51 94.2l-52.8 97.3a24.3 24.3 0 0 0 21.2 35.9h207.7a24.2 24.2 0 0 0 21.1-35.9Z"/><path fill="#ffd43b" d="M243 216.6q1.5-1.3 5.5-1.3h15.3c2.7 0 4.5.4 5.6 1.3s1.5 2.4 1.4 4.7l-3 71.8c-.1 2.3-.7 3.8-1.6 4.6s-2.7 1.3-5.4 1.3h-9.4c-2.6 0-4.4-.5-5.3-1.3s-1.5-2.3-1.6-4.6l-2.9-71.9c0-2.2.4-3.8 1.4-4.6m29 107.6q0 7-3 9.5c-2 1.8-5.6 2.7-11 2.7h-4c-5.4 0-9-1-11-2.6s-3-5-3-9.6v-2.9q0-7 3-9.6c2-1.7 5.6-2.5 11-2.5h4c5.4 0 9 .8 11 2.5s3 5 3 9.6Z"/></svg>`;
/*]]>*/
  </script>
<script>
   /*<![CDATA[*/
const _0x41c266=_0xf025;function _0x4c40(){const _0x40cf72=['resetEmail','Kode\x20dijalankan\x20karena\x20lisensi\x20valid.','pesan','classList','catch','remove','onclick','message','987678GjbfzR','getElementById','submit','judul','2817822mxlzSQ','notif-container\x20success','680110XmpSZd','notifCancel','notifConfirm','log','add','1250091mFYGDP','notifIcon','3492990JMQvir','konfirmasiresetpass','notifTitle','className','resetPasswordForm','notif-container\x20error','success','notif-container\x20warning','sendPasswordResetEmail','hiddenresetpassword_notif','textContent','notifText','cancel\x20reset\x20password','3WbdpDU','warning','8sNGsYP','111537gCKJLt','mengirimResetpass','preventDefault','innerHTML','value','271340HqVELv','notifContainer','20TggrTu'];_0x4c40=function(){return _0x40cf72;};return _0x4c40();}(function(_0x487046,_0x5daf2){const _0x286621=_0xf025,_0x3046e1=_0x487046();while(!![]){try{const _0x579860=-parseInt(_0x286621(0xd6))/0x1+-parseInt(_0x286621(0xec))/0x2*(-parseInt(_0x286621(0x100))/0x3)+-parseInt(_0x286621(0xdb))/0x4*(parseInt(_0x286621(0xdd))/0x5)+parseInt(_0x286621(0xe6))/0x6+-parseInt(_0x286621(0xea))/0x7+parseInt(_0x286621(0x102))/0x8*(parseInt(_0x286621(0xf1))/0x9)+parseInt(_0x286621(0xf3))/0xa;if(_0x579860===_0x5daf2)break;else _0x3046e1['push'](_0x3046e1['shift']());}catch(_0x407835){_0x3046e1['push'](_0x3046e1['shift']());}}}(_0x4c40,0x32a53),document[_0x41c266(0xe7)](_0x41c266(0xf7))['addEventListener'](_0x41c266(0xe8),function(_0x349a85){const _0x2f542b=_0x41c266;_0x349a85[_0x2f542b(0xd8)](),checkLisensi_hr(cur_blog_id_hr,function(_0x2b9ced){const _0x288cf1=_0x2f542b;_0x2b9ced&&(resetPassword_hr(),console['log'](_0x288cf1(0xdf)));});}));function resetPassword_hr(){const _0x177065=_0x41c266,_0x4e9a50=document[_0x177065(0xe7)](_0x177065(0xde))[_0x177065(0xda)];showNoti_resetpassword('warning',pesanNotifresetpass['konfirmasiresetpass'][_0x177065(0xe9)],pesanNotifresetpass[_0x177065(0xf4)][_0x177065(0xe0)]+':\x20'+_0x4e9a50,!![],()=>{const _0x2476d5=_0x177065;auth[_0x2476d5(0xfb)](_0x4e9a50)['then'](()=>{const _0x6569c3=_0x2476d5;showSweetAlertResetpass(pesanNotifresetpass[_0x6569c3(0xd7)][_0x6569c3(0xe9)],pesanNotifresetpass['mengirimResetpass']['pesan'],_0x6569c3(0xf9));})[_0x2476d5(0xe2)](_0x223b0b=>{const _0x373458=_0x2476d5;showSweetAlertResetpass(''+pesanNotifresetpass['errorResetpass'][_0x373458(0xe9)],pesanNotifresetpass['errorResetpass'][_0x373458(0xe0)]+':\x20'+_0x223b0b[_0x373458(0xe5)],'error');});},()=>{const _0x4c978c=_0x177065;console[_0x4c978c(0xef)](_0x4c978c(0xff));});}function showSweetAlertResetpass(_0x12f254,_0x5c7bc9,_0x385ccc){showNoti_resetpassword(_0x385ccc,_0x12f254,_0x5c7bc9,![]);}function _0xf025(_0x2094c6,_0xf5b8ba){const _0x4c40e6=_0x4c40();return _0xf025=function(_0xf0259c,_0x247ca6){_0xf0259c=_0xf0259c-0xd6;let _0xc5821b=_0x4c40e6[_0xf0259c];return _0xc5821b;},_0xf025(_0x2094c6,_0xf5b8ba);}function showNoti_resetpassword(_0x2b30b6,_0x31a03f,_0x34ef5b,_0x281637=![],_0x92bb31=null,_0x9d36b1=null){const _0x4f25e8=_0x41c266,_0x2bdbcf=document['getElementById'](_0x4f25e8(0xdc)),_0xa36397=document[_0x4f25e8(0xe7)](_0x4f25e8(0xf2)),_0x5c52a7=document[_0x4f25e8(0xe7)](_0x4f25e8(0xf5)),_0x55ccbd=document[_0x4f25e8(0xe7)](_0x4f25e8(0xfe)),_0x17e792=document[_0x4f25e8(0xe7)](_0x4f25e8(0xee)),_0x112302=document[_0x4f25e8(0xe7)](_0x4f25e8(0xed));switch(_0x2b30b6){case'success':_0xa36397[_0x4f25e8(0xd9)]=iconSukses,_0x2bdbcf[_0x4f25e8(0xf6)]=_0x4f25e8(0xeb);break;case'error':_0xa36397[_0x4f25e8(0xd9)]=iconGagal,_0x2bdbcf['className']=_0x4f25e8(0xf8);break;case _0x4f25e8(0x101):_0xa36397[_0x4f25e8(0xd9)]=iconWarning,_0x2bdbcf['className']=_0x4f25e8(0xfa);break;default:_0xa36397[_0x4f25e8(0xd9)]=iconInfo,_0x2bdbcf[_0x4f25e8(0xf6)]='notif-container\x20info';break;}_0x5c52a7[_0x4f25e8(0xfd)]=_0x31a03f,_0x55ccbd['textContent']=_0x34ef5b,_0x281637?_0x112302[_0x4f25e8(0xe1)][_0x4f25e8(0xe3)]('hiddenresetpassword_notif'):_0x112302['classList'][_0x4f25e8(0xf0)](_0x4f25e8(0xfc)),_0x2bdbcf['classList'][_0x4f25e8(0xe3)](_0x4f25e8(0xfc)),_0x17e792[_0x4f25e8(0xe4)]=()=>{const _0x1e4dff=_0x4f25e8;_0x2bdbcf[_0x1e4dff(0xe1)][_0x1e4dff(0xf0)]('hiddenresetpassword_notif');if(_0x92bb31)_0x92bb31();},_0x112302['onclick']=()=>{const _0x1d4179=_0x4f25e8;_0x2bdbcf[_0x1d4179(0xe1)][_0x1d4179(0xf0)](_0x1d4179(0xfc));if(_0x9d36b1)_0x9d36b1();},!_0x281637&&setTimeout(()=>{const _0x45ab36=_0x4f25e8;_0x2bdbcf[_0x45ab36(0xe1)][_0x45ab36(0xf0)](_0x45ab36(0xfc));},0x1388);}
   /*]]>*/
   </script>


Lock kontent

Kode ini buat mengunci kontent kalian, bagian javascript harap diletakan diatas </body>

dan untuk bagian html silahkan letakan dipost lalu ganti idpost dan roleKT dengan id post dan role kontent tersebut yang kamu buat didasboard


letakan dipostingan Chapter


<div idpost="Id post disini" roleKT="Role disini" class="premiumK"></div>

Letakan diatas </body>


 <script>
/*<![CDATA[*/
// Lisensi for protect code.
const lisensi_hr = [
  {
    lisensi: 'DAgGFB8cDBACAC0RBRUVCgQLAQ0BGwc=',
    ownerLisensi: 'Hirutshuji',
  }
];

var locknologin = '<div class="warning">Konten terkunci. Harap masuk untuk melihat konten ini.</div>';
   
 var lockKontent = '<div class="warning">Tidak ada konten yang tersedia atau akses tidak diberikan oleh admin.</div>';
    
var loaderKontent = 'Loading...';
    
    
function aksesrole(userRole, aksesKontent) {
      const ijinrole = {
        "Admin": ["Admin","Member", "User"],
        "Member": ["Member", "User"],
        "User": ["User"],
      };
return ijinrole[userRole].includes(aksesKontent);
    }
    
let hariWrn = 2; //peringatan membership akan habis dalam 2 hari lagi

let notifwrn_membership = "Membership Anda akan habis dalam {hari} hari lagi.";

let notifwrn_membership_habis1 = "Membership Anda habis besok hari.";

let notifwrn_membership_habis2 = "Membership kamu telah habis.";

function showntf(message, autoClose, closeTime = 5000) {
  const notifDiv = document.createElement("div");
  notifDiv.innerHTML = `
    <div style="position: fixed; top: 10px; right: 10px; background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; border-radius: 5px; padding: 10px; z-index: 99999999;">
      <p>${message}</p>
      <a href="#" style="border:none;" onclick="this.parentElement.style.display='none';">Tutup</a>
    </div>
  `;
  document.body.appendChild(notifDiv);
  if (autoClose) {
    setTimeout(() => {
      notifDiv.style.display = 'none';
    }, closeTime);
  }
}
 /*]]>*/
</script>
    <script src='https://cdn.jsdelivr.net/gh/MagicReincarnation/codeHirutshuji@main/codebyhirutshuji_lite/logincode_litex_v4.0.js'/>  
 <script src='https://cdn.jsdelivr.net/gh/MagicReincarnation/codeHirutshuji@main/codebyhirutshuji_lite/lisensiCodeLogin_lite.js'/> 


Dasboard Kontent

Letakan juga dihalaman blog, tapi ingat jangan sampai ketahuan orang lain


<style>
    .toast {
      display: inline-block;
      padding: 20px;
      border-radius: 4px;
      position: relative;
      margin-bottom: 10px;
      color: #fff;
      background-color: #333;
      max-width: 500px;
      margin: 10px auto;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
    }

    .toast--pending {
      background-color: #f0ad4e;
    }

    .toast--success {
      background-color: #5bc0de;
    }

    .toast--error {
      background-color: #d9534f;
    }

    .toast__close {
      cursor: pointer;
    }
    
    .toast__close svg {
      width: 15px;
      height: 15px;
      fill: #fff;
    }
    
    #toast-container {
      position: fixed;
      top: 10px;
      right: 10px;
      z-index: 1000;
    }
    #edit-form {
      display: none;
      margin: 20px 0;
    }      
/* Form Styles */
.cc_form {
  background-color: #222;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  max-width: 800px;
  margin: auto;
}

.form-group {
  margin-bottom: 15px;
}

.form-group label {
  display: block;
  margin-bottom: 5px;
  color: #fff;
  font-weight: bold;
}

.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  padding: 10px;
  font-size: 16px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.form-group button {
  background-color: #333;
  color: #fff;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.form-group button:hover {
  background-color: #555;
}

#edit-form {
  margin-top: 30px;
  background-color: #222;
  padding: 15px;
  border-radius: 8px;
}

#edit-form h2 {
  margin-top: 0;
}

@media (max-width: 768px) {
  .cc_form {
    padding: 15px;
  }
  .form-group input,
  .form-group select,
  .form-group textarea {
    font-size: 14px;
  }
}

@media (max-width: 480px) {
  .cc_form {
    padding: 10px;
  }
  .form-group input,
  .form-group select,
  .form-group textarea {
    font-size: 13px;
  }
}

/* Table Styles */
.ccTabel {
  background-color: #222;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  max-width: 800px;
  margin: auto;
  overflow-x: auto;
}

#result-container {
  width: 100%;
  border-collapse: collapse;
  margin-top: 20px;
}

#result-container th,
#result-container td {
  padding: 10px;
  border: 1px solid #ccc;
  text-align: left;
  white-space: nowrap;
}

#result-container th {
  background-color: #333;
  color: white;
}

#result-container td a {
  color: #007BFF;
  text-decoration: none;
}

#result-container td a:hover {
  text-decoration: underline;
}
@media (max-width: 768px) {
  .table-container table,
  .table-container thead,
  .table-container tbody,
  .table-container th,
  .table-container td,
  .table-container tr {
    display: block;
  }

  .table-container thead {
    display: none;
  }

  .table-container tbody tr {
    margin-bottom: 15px;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 10px;
    background-color: #fff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }

  .table-container td {
    display: flex;
    justify-content: space-between;
    padding: 8px 10px;
    border: none;
    border-bottom: 1px solid #eee;
    position: relative;
  }

  .table-container td:last-child {
    border-bottom: none;
  }

  .table-container td::before {
    content: attr(data-label);
    font-weight: bold;
    text-transform: capitalize;
    color: #333;
  }

  .table-container td button {
    margin-right: 5px;
    padding: 6px 12px;
    font-size: 14px;
    background-color: #333;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
  }

  .table-container td button:hover {
    background-color: #555;
  }
}
@media (min-width: 769px) {
  .table-container td::before {
    display: none;
  }
}
</style>  
<div id="toast-container"></div>  
  <div class="cc_form">
  <div class="form-group">
    <label for="postIdInput">Post ID</label>
    <input type="number" id="postIdInput" class="form-control" placeholder="Enter post ID..." required>
  </div>
  <div class="form-group">
    <label for="titleInput">Title</label>
    <input type="text" id="titleInput" class="form-control" placeholder="Enter title...">
  </div>
  <div class="form-group">
    <label for="linkInput">Link</label>
    <input type="text" id="linkInput" class="form-control" placeholder="Enter link...">
  </div>
  <div class="form-group">
    <label for="contentInput">Content</label>
    <textarea id="contentInput" class="form-control" rows="10" placeholder="Enter content..." required></textarea>
  </div>
  <div class="form-group">
    <label for="roleSelect">Role</label>
    <select id="roleSelect" class="form-control">
      <option value="Member">Member</option>
      <option value="User">User</option>
    </select>
  </div>
  <div class="form-group">
    <button onclick="saveContent()">Save Content</button>
  </div>
  <div id="edit-form">
    <h2>Edit Content</h2>
    <div class="form-group">
      <label for="editPostIdInput">Post ID</label>
      <input type="number" id="editPostIdInput" class="form-control" placeholder="Post ID" required>
    </div>
    <div class="form-group">
      <label for="editTitleInput">Title</label>
      <input type="text" id="editTitleInput" class="form-control" placeholder="Title">
    </div>
    <div class="form-group">
      <label for="editLinkInput">Link</label>
      <input type="text" id="editLinkInput" class="form-control" placeholder="Link">
    </div>
    <div class="form-group">
      <label for="editContentInput">Content</label>
      <textarea id="editContentInput" class="form-control" rows="10" placeholder="Content" required></textarea>
    </div>
    <div class="form-group">
      <label for="editRoleSelect">Role</label>
      <select id="editRoleSelect" class="form-control">
        <option value="Admin">Admin</option>
        <option value="Member">Member</option>
        <option value="User">User</option>
      </select>
    </div>
    <div class="form-group">
      <button onclick="updateContent()">Update Content</button>
      <button onclick="cancelEdit()">Cancel</button>
    </div>
  </div></div>
  <h2>Content List</h2>
  <div class="ccTabel">
  <table id="result-container">
    <thead>
      <tr>
        <th>Post ID</th>
        <th>Title</th>
        <th>Link</th>
        <th>Role</th>
        <th>Actions</th>
      </tr>
    </thead>
    <tbody>
    </tbody>
  </table></div> 
<script>
function showToast(type, message) {
      const container = document.getElementById('toast-container');
      const toast = document.createElement('div');
      toast.className = `toast toast--${type}`;
      toast.innerHTML = `
        <span>${message}</span>
      `;
      container.appendChild(toast);
      setTimeout(() => {
        toast.style.transition = 'opacity 0.5s';
        toast.style.opacity = '0';
        setTimeout(() => toast.remove(), 500);
      }, 3000);
    }
function validatePassword(password) {
  return password === 'HR05082024';
}

function _0x3969(){const _0x56b22a=['block','kontent','getElementById','appendChild','contentInput','title','set','editPostIdInput','\x22\x20href=\x22','677340ryUmBE','exists','ref','editRoleSelect','message','link','error','oldRole','Error\x20deleting\x20content:\x20','</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td>','</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20onclick=\x22editContent(\x27','Error\x20saving\x20content:\x20','innerHTML','2152759YSSHNc','922270LoIcmL','60AdlqQi','pending','success','linkInput','429516ZhMSuy','edit-form','60759ScMtyk','Content\x20saved\x20successfully!','72BCeYND','\x27,\x20\x27','Post\x20ID,\x20Title,\x20and\x20Link\x20are\x20required.','value','All\x20fields\x20are\x20required.','roleSelect','kontent/','\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td>','Content\x20updated\x20successfully!','281132sOhGsz','\x27)\x22>Edit</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20onclick=\x22deleteContent(\x27','8BMafNn','editContentInput','style','catch','remove','Saving\x20content...','key','val','</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td><a\x20title=\x22','postIdInput','dataset','oldPostId','No\x20data\x20found\x20for\x20editing.','display','tbody','forEach','editLinkInput','Content\x20deleted\x20successfully!','then','once','6246eKeAAO','\x27)\x22>Delete</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'];_0x3969=function(){return _0x56b22a;};return _0x3969();}(function(_0x5f4e2d,_0xaebf81){const _0x9de19=_0x4e43,_0x27db80=_0x5f4e2d();while(!![]){try{const _0x3d68bc=-parseInt(_0x9de19(0x1e4))/0x1+parseInt(_0x9de19(0x1ae))/0x2+parseInt(_0x9de19(0x1c4))/0x3*(-parseInt(_0x9de19(0x1e6))/0x4)+parseInt(_0x9de19(0x1dd))/0x5+parseInt(_0x9de19(0x1e2))/0x6+parseInt(_0x9de19(0x1dc))/0x7*(parseInt(_0x9de19(0x1b0))/0x8)+-parseInt(_0x9de19(0x1cf))/0x9*(parseInt(_0x9de19(0x1de))/0xa);if(_0x3d68bc===_0xaebf81)break;else _0x27db80['push'](_0x27db80['shift']());}catch(_0x32b0ac){_0x27db80['push'](_0x27db80['shift']());}}}(_0x3969,0x25aec));function saveContent(){const _0x350825=_0x4e43,_0x55ee41=document[_0x350825(0x1c8)](_0x350825(0x1b9))[_0x350825(0x1e9)],_0xab11cf=document[_0x350825(0x1c8)]('titleInput')[_0x350825(0x1e9)],_0x4fb9be=document[_0x350825(0x1c8)](_0x350825(0x1e1))[_0x350825(0x1e9)],_0x367fc6=document[_0x350825(0x1c8)](_0x350825(0x1ca))[_0x350825(0x1e9)],_0x455172=document['getElementById'](_0x350825(0x1aa))[_0x350825(0x1e9)];if(!_0x55ee41||!_0xab11cf||!_0x4fb9be||!_0x367fc6){showToast(_0x350825(0x1d5),_0x350825(0x1a9));return;}showToast(_0x350825(0x1df),_0x350825(0x1b5));const _0x4e134d=dbrl['ref'](_0x350825(0x1ab)+_0x55ee41+'/'+_0x455172);_0x4e134d[_0x350825(0x1cc)]({'title':_0xab11cf,'link':_0x4fb9be,'kontent':_0x367fc6})['then'](()=>{const _0x4f36c6=_0x350825;showToast(_0x4f36c6(0x1e0),_0x4f36c6(0x1e5)),displayResult();})[_0x350825(0x1b3)](_0x26ca45=>{const _0x5b4d35=_0x350825;showToast('error',_0x5b4d35(0x1da)+_0x26ca45[_0x5b4d35(0x1d3)]);});}function displayResult(){const _0x259e94=_0x4e43,_0x410cda=document[_0x259e94(0x1c8)]('result-container')['getElementsByTagName'](_0x259e94(0x1be))[0x0];_0x410cda[_0x259e94(0x1db)]='',dbrl['ref'](_0x259e94(0x1c7))[_0x259e94(0x1c3)](_0x259e94(0x1e9))['then'](_0x13c22b=>{const _0x2d242d=_0x259e94;_0x13c22b[_0x2d242d(0x1bf)](_0xd3232=>{const _0x13788c=_0x2d242d,_0xa3e9a0=_0xd3232[_0x13788c(0x1b6)];_0xd3232['forEach'](_0x3ef0ae=>{const _0x30f8e4=_0x13788c,_0x297223=_0x3ef0ae[_0x30f8e4(0x1b6)],_0x4e769c=_0x3ef0ae[_0x30f8e4(0x1b7)](),_0x3454b6=document['createElement']('tr');_0x3454b6[_0x30f8e4(0x1db)]=_0x30f8e4(0x1ac)+_0xa3e9a0+_0x30f8e4(0x1d8)+(_0x4e769c[_0x30f8e4(0x1cb)]||'')+_0x30f8e4(0x1b8)+(_0x4e769c[_0x30f8e4(0x1cb)]||'')+_0x30f8e4(0x1ce)+(_0x4e769c[_0x30f8e4(0x1d4)]||'')+'\x22>link</a></td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td>'+_0x297223+_0x30f8e4(0x1d9)+_0xa3e9a0+_0x30f8e4(0x1e7)+_0x297223+_0x30f8e4(0x1af)+_0xa3e9a0+'\x27,\x20\x27'+_0x297223+_0x30f8e4(0x1c5),_0x410cda[_0x30f8e4(0x1c9)](_0x3454b6);});});})[_0x259e94(0x1b3)](_0x50a201=>{showToast('error','Error\x20fetching\x20content:\x20'+_0x50a201['message']);});}function _0x4e43(_0x8b6589,_0x1fc692){const _0x39693d=_0x3969();return _0x4e43=function(_0x4e4327,_0x54cb34){_0x4e4327=_0x4e4327-0x1a9;let _0x3c0c41=_0x39693d[_0x4e4327];return _0x3c0c41;},_0x4e43(_0x8b6589,_0x1fc692);}function updateContent(){const _0x3b44e9=_0x4e43,_0x2f63e7=document['getElementById']('editPostIdInput')[_0x3b44e9(0x1ba)][_0x3b44e9(0x1bb)],_0x1d8ce4=document[_0x3b44e9(0x1c8)]('editRoleSelect')[_0x3b44e9(0x1ba)]['oldRole'],_0x3bd9b1=document[_0x3b44e9(0x1c8)](_0x3b44e9(0x1cd))[_0x3b44e9(0x1e9)],_0x2f0a7e=document[_0x3b44e9(0x1c8)]('editTitleInput')[_0x3b44e9(0x1e9)],_0x3b273e=document[_0x3b44e9(0x1c8)]('editLinkInput')[_0x3b44e9(0x1e9)],_0x190368=document['getElementById']('editRoleSelect')[_0x3b44e9(0x1e9)];if(!_0x3bd9b1||!_0x2f0a7e||!_0x3b273e){showToast(_0x3b44e9(0x1d5),_0x3b44e9(0x1e8));return;}const _0x23be60=dbrl[_0x3b44e9(0x1d1)](_0x3b44e9(0x1ab)+_0x2f63e7+'/'+_0x1d8ce4);_0x23be60[_0x3b44e9(0x1b4)]()[_0x3b44e9(0x1c2)](()=>{const _0x59a592=_0x3b44e9,_0x531dcb=dbrl[_0x59a592(0x1d1)](_0x59a592(0x1ab)+_0x3bd9b1+'/'+_0x190368);return _0x531dcb[_0x59a592(0x1cc)]({'title':_0x2f0a7e,'link':_0x3b273e,'kontent':document['getElementById'](_0x59a592(0x1b1))['value']});})[_0x3b44e9(0x1c2)](()=>{const _0x576e8f=_0x3b44e9;showToast(_0x576e8f(0x1e0),_0x576e8f(0x1ad)),cancelEdit(),displayResult();})['catch'](_0x4792f6=>{const _0x1201ac=_0x3b44e9;showToast(_0x1201ac(0x1d5),'Error\x20updating\x20content:\x20'+_0x4792f6[_0x1201ac(0x1d3)]);});}function cancelEdit(){const _0x4ca602=_0x4e43;document[_0x4ca602(0x1c8)](_0x4ca602(0x1e3))[_0x4ca602(0x1b2)][_0x4ca602(0x1bd)]='none';}function editContent(_0x54f123,_0x38df3e){const _0x1967d4=_0x4e43,_0x3c6425=dbrl[_0x1967d4(0x1d1)](_0x1967d4(0x1ab)+_0x54f123+'/'+_0x38df3e);_0x3c6425[_0x1967d4(0x1c3)]('value')[_0x1967d4(0x1c2)](_0x349158=>{const _0x4e0d24=_0x1967d4;if(_0x349158[_0x4e0d24(0x1d0)]()){const _0x363af0=_0x349158[_0x4e0d24(0x1b7)]();document[_0x4e0d24(0x1c8)](_0x4e0d24(0x1cd))[_0x4e0d24(0x1e9)]=_0x54f123,document[_0x4e0d24(0x1c8)]('editPostIdInput')[_0x4e0d24(0x1ba)][_0x4e0d24(0x1bb)]=_0x54f123,document[_0x4e0d24(0x1c8)]('editRoleSelect')[_0x4e0d24(0x1e9)]=_0x38df3e,document[_0x4e0d24(0x1c8)](_0x4e0d24(0x1d2))[_0x4e0d24(0x1ba)][_0x4e0d24(0x1d6)]=_0x38df3e,document[_0x4e0d24(0x1c8)]('editTitleInput')[_0x4e0d24(0x1e9)]=_0x363af0[_0x4e0d24(0x1cb)]||'',document['getElementById'](_0x4e0d24(0x1c0))[_0x4e0d24(0x1e9)]=_0x363af0[_0x4e0d24(0x1d4)]||'',document[_0x4e0d24(0x1c8)](_0x4e0d24(0x1b1))[_0x4e0d24(0x1e9)]=_0x363af0[_0x4e0d24(0x1c7)]||'',document[_0x4e0d24(0x1c8)](_0x4e0d24(0x1e3))[_0x4e0d24(0x1b2)][_0x4e0d24(0x1bd)]=_0x4e0d24(0x1c6);}else showToast(_0x4e0d24(0x1d5),_0x4e0d24(0x1bc));})['catch'](_0xed02b9=>{const _0x5c9b29=_0x1967d4;showToast(_0x5c9b29(0x1d5),'Error\x20fetching\x20content\x20for\x20edit:\x20'+_0xed02b9[_0x5c9b29(0x1d3)]);});}function deleteContent(_0x1e1347,_0x2fe636){const _0x4402ae=_0x4e43,_0x5c9a01=prompt('Please\x20enter\x20password\x20to\x20confirm\x20deletion:');if(validatePassword(_0x5c9a01)){const _0x7e318f=dbrl[_0x4402ae(0x1d1)](_0x4402ae(0x1ab)+_0x1e1347+'/'+_0x2fe636);_0x7e318f[_0x4402ae(0x1b4)]()[_0x4402ae(0x1c2)](()=>{const _0x8196cb=_0x4402ae;showToast('success',_0x8196cb(0x1c1)),displayResult();})[_0x4402ae(0x1b3)](_0xdf0552=>{const _0x5040ab=_0x4402ae;showToast(_0x5040ab(0x1d5),_0x5040ab(0x1d7)+_0xdf0552['message']);});}else showToast(_0x4402ae(0x1d5),'Invalid\x20password.\x20Content\x20not\x20deleted.');}
displayResult();
  </script>

Update(4.0): dasboard admin,letakan dihalaman

<style>
  :root {
    --bg-datauser-dasboard: #1e2129;
    --color-dasboard: #0c70de;
    --color-text-dasboard: #fff;
  }

  .hidden1 { display: none; }

  ul#user-list {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  ul#user-list li.usersub::before {
    position: absolute;
    top: -35px;
    right: 0;
    font-size: 14px;
    border-radius: 5px;
    padding: 3px 7px;
    background: var(--color-dasboard);
    color: var(--color-text-dasboard);
    content: attr(index);
  }

  #user-list li {
    position: relative;
    margin: 55px 0 25px -20px;
    background: var(--bg-datauser-dasboard);
    color: var(--color-text-dasboard);
    height: auto;
    border-radius: 15px;
    font-size: 16px;
    float: left;
  }

  span.setting-user {
    display: flex;
    flex-direction: column;
  }

  span.setting-user > span {
    border: 1px solid var(--color-dasboard);
    border-radius: 5px;
    padding: 1px 10px;
    margin: 3px;
    overflow: hidden;
  }

  span.setting-user > span:hover {
    overflow: auto;
  }

  ul#user-list li button:first-child {
    background: var(--color-dasboard);
    color: var(--color-text-dasboard);
    border: none;
    border-radius: 5px;
    right: -5px;
    top: -25px;
  }

  ul#user-list li button:nth-child(2) {
    background: #0000;
    color: #fff;
    border-radius: 5px;
    border: 1px solid #eee;
    bottom: 13px;
    right: 16px;
  }

  ul#user-list li button:nth-child(3) {
    border: 1px solid var(--color-dasboard);
    border-radius: 5px;
    bottom: 0;
    left: 0;
  }

  div#set1 {
    display: flex;
    padding: 5px;
    margin: 5px;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    text-align: center;
  }

  input#checkTanggal {
    padding: 10px 15px;
    background: #1e2129ba;
    color: #fff;
    outline: none;
    border: none;
    border-radius: 5px;
    text-align: center;
  }

  input#checkTanggal::placeholder {
    color: #fff;
  }

  span#inputset1 {
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  #inputset1 button {
    background: var(--color-dasboard);
    color: #fff;
    border: none;
    border-radius: 15px;
    padding: 6px 20px;
    margin: 5px;
  }

  span#result_tanggal {
    position: relative;
    border-radius: 15px;
    background: #1e2129ba;
    color: #fff;
    padding: 3px;
    width: 50%;
    min-height: 60px;
    max-height: 100%;
    margin: 5px;
  }

  span#result_tanggal:before {
    content: "Output >";
    position: absolute;
    top: 0;
    left: -80px;
    background: #1e2129ba;
    color: #fff;
    padding: 3px 8px;
    border-radius: 16px;
  }
  .setting-dashboard {
    display: flex;
    padding: 5px;
    margin: 5px;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    text-align: center;
  }

  span.cariUser, .filterUser {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
  }

  input#search-input {
    width: 100%;
    padding: 10px 15px;
    background: #1e2129ba;
    color: #fff;
    outline: none;
    border: none;
    border-radius: 5px;
    text-align: center;
  }

  input#search-input::placeholder {
    color: #fff;
  }

  .cariUser button {
    background: var(--color-dasboard);
    color: #fff;
    border: none;
    border-radius: 15px;
    padding: 6px 20px;
    margin: 5px;
  }
  div#pagination {
    width: 100%;
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    padding: 3px;
  }

  div#pagination button {
    padding: 5px 8px;
    background: #0c70de;
    border-radius: 5px;
    border: none;
    color: #fff;
  }

  div#page-numbers {
    display: inline-flex;
    justify-content: center;
    align-items: center;
  }

  div#page-numbers span {
    margin: auto 5px;
    border: none;
    background: #0c70de;
    color: #eee;
    font-size: 16px;
    border-radius: 5px;
    padding: 3px 7px;
  }

  div#page-numbers span.current-page,
  div#pagination button:hover,
  div#page-numbers span:hover {
    background: #ff9a00;
    color: #1e2129;
  }
</style>
  <div class="setting-dashboard">
    <span class="cariUser">
      <input type="text" id="search-input" placeholder="Cari berdasarkan UID"/>
      <button onclick="searchUsers()">Cari User</button>
    </span>
    <br/>
  </div>

<hr/>
<div id="admin-dashboard">
  <ul id="user-list"></ul>
</div>
 <hr/>
<div id="pagination">
    <button onclick="loadPreviousPage()">Prev</button>
    <div id="page-numbers"></div>
    <button onclick="loadNextPage()">Next</button>
  </div>


<script>
  const perhalaman = 15;
  function _0x48d4(_0x45442a,_0x42d7e4){const _0x3de2a1=_0x3de2();return _0x48d4=function(_0x48d4b6,_0x4ba678){_0x48d4b6=_0x48d4b6-0xe1;let _0x24320d=_0x3de2a1[_0x48d4b6];return _0x24320d;},_0x48d4(_0x45442a,_0x42d7e4);}const _0x4a5d92=_0x48d4;(function(_0x3b9fb8,_0x191415){const _0x33408e=_0x48d4,_0x58974d=_0x3b9fb8();while(!![]){try{const _0xa3ac1=-parseInt(_0x33408e(0xf3))/0x1*(-parseInt(_0x33408e(0x11f))/0x2)+-parseInt(_0x33408e(0xf6))/0x3+-parseInt(_0x33408e(0x10e))/0x4+-parseInt(_0x33408e(0x121))/0x5*(-parseInt(_0x33408e(0xfe))/0x6)+parseInt(_0x33408e(0x101))/0x7+parseInt(_0x33408e(0x11d))/0x8+parseInt(_0x33408e(0xe1))/0x9*(-parseInt(_0x33408e(0x119))/0xa);if(_0xa3ac1===_0x191415)break;else _0x58974d['push'](_0x58974d['shift']());}catch(_0x4cb6ff){_0x58974d['push'](_0x58974d['shift']());}}}(_0x3de2,0x51081));let currentPage=0x1;function setperhalaman(_0x17b9f6){perhalaman=_0x17b9f6,currentPage=0x1,loadUsers();}function loadUsers(){const _0x1a6666=_0x48d4,_0x2164d9=(currentPage-0x1)*perhalaman,_0x45358e=_0x2164d9+perhalaman;db['collection']('users')['get']()[_0x1a6666(0x105)](_0x481f7a=>{const _0xe310a7=_0x1a6666,_0x1558a8=[];_0x481f7a[_0xe310a7(0x11c)](_0x1298a0=>{_0x1558a8['push']({'id':_0x1298a0['id'],..._0x1298a0['data']()});});const _0x1ed369=_0x1558a8[_0xe310a7(0x107)](_0x2164d9,_0x45358e);showUserList(_0x1ed369),displayPageNumbers(_0x1558a8[_0xe310a7(0xee)]);});}function _0x3de2(){const _0x2f2d43=['value','createElement','202926LoDPsK','Admin','textContent','1865241zbRjhK','</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22exp-role\x22>Exp:\x20','numeric','setAttribute','then','email','slice','message','addEventListener','.editexp','Gagal\x20mengubah\x20Role\x20User:\x20','</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<details>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<summary>Info\x20Role</summary>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p>Hanya\x203\x20Role\x20yang\x20tersedia</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p>1:\x20Admin\x20=\x20membuka\x20Konten\x20User\x20&\x20Member\x20&\x20Admin</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p>2:\x20Member\x20=\x20membuka\x20Konten\x20User\x20&\x20Member</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p>3:\x20User\x20=\x20membuka\x20Konten\x20User</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</details>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<details>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<summary>Info\x20Aturan\x20Exp\x20Role</summary>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p>Hanya\x20Tanggal\x20angka\x20yang\x20diijinkan</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p>1.\x20dd/mm/yyyy:\x20harus\x20wajib\x20dua\x20angka\x20seperti\x20ini\x20[01/01/2023]\x20Angka\x20satu\x20punya\x20angka\x20nol</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p>2.\x20dd/mm/yyyy:\x20Dalam\x20Tanggal\x20kalian\x20tidak\x20boleh\x20memasukan\x20Huruf,\x20Hanya\x20angka\x20yang\x20diperbolehkan</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p>3.\x20dd/mm/yyyy:\x20Kalian\x20juga\x20tidak\x20boleh\x20memasukan\x20WIB\x20karena\x20itu\x20otomatis\x20akan\x20ada\x20dengan\x20sendirinya</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</details>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22role-user\x22>Role:\x20','role','2102108YOhRPd','exists','error','data','</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<details>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<summary>Info\x20Status\x20Email?</summary>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p>false\x20=\x20Belum\x20verifikasi\x20email\x20dan\x20belum\x20login\x20sama\x20sekali</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p>true\x20=\x20sudah\x20verifikasi\x20email\x20dan\x20sudah\x20login\x20sekali\x20(terdaftar)</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</details>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22email-user\x22>Email:\x20','split','toLowerCase','test','#page-numbers','Masukkan\x20tanggal\x20Exp\x20membership:\x20contoh\x20(30/12/2023)\x20tanpa\x20WIB:','#user-list','2890Hjollm','classList','getTime','forEach','4793624mwJqBO','Masukkan\x20Role\x20baru\x20untuk\x20User:','478cSlzSt','Asia/Jakarta','35DaJdzZ','collection','Format\x20tanggal\x20tidak\x20valid.\x20Gunakan\x20format\x20dd/mm/yyyy.','appendChild','querySelector','index','catch','Error\x20getting\x20user\x20data:','774VAhIll','users','includes','map','toLocaleDateString','filter','add','innerHTML','Gagal\x20mengambil\x20data\x20User:\x20','get','usersub','Error\x20getting\x20users:','current-page','length','Role\x20User\x20berhasil\x20diubah.','update','doc','\x0a\x20\x20\x20\x20\x20\x20<span\x20class=\x22setting-user\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20id=\x22uidcheck\x22\x20class=\x22username-user\x22>Uid:\x20','79mRaoSj','</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22email-status\x22>Status\x20Email:\x20','click','717024WfACYM','2-digit','span','#search-input','short','exp'];_0x3de2=function(){return _0x2f2d43;};return _0x3de2();}function loadPreviousPage(){currentPage>0x1&&(currentPage--,loadUsers());}function loadNextPage(){currentPage++,loadUsers();}function displayPageNumbers(_0x3228f2){const _0x3b677c=_0x48d4,_0x552cd4=Math['ceil'](_0x3228f2/perhalaman),_0x3d4e54=document[_0x3b677c(0x125)](_0x3b677c(0x116));_0x3d4e54['innerHTML']='';for(let _0x13f784=0x1;_0x13f784<=_0x552cd4;_0x13f784++){const _0x358d3f=document[_0x3b677c(0xfd)](_0x3b677c(0xf8));_0x358d3f[_0x3b677c(0x100)]=_0x13f784,_0x13f784===currentPage&&_0x358d3f[_0x3b677c(0x11a)][_0x3b677c(0xe7)](_0x3b677c(0xed)),_0x358d3f[_0x3b677c(0x109)](_0x3b677c(0xf5),()=>{currentPage=_0x13f784,loadUsers();}),_0x3d4e54[_0x3b677c(0x124)](_0x358d3f);}}function ExpRoleuser(_0x54ad62,_0xe99a44){const _0x4fc6ff=_0x48d4;if(!/^(\d{2})\/(\d{2})\/(\d{4})$/[_0x4fc6ff(0x115)](_0xe99a44)){alert('Format\x20tanggal\x20tidak\x20valid.\x20Gunakan\x20format\x20dd/mm/yyyy.');return;}db[_0x4fc6ff(0x122)]('users')[_0x4fc6ff(0xf1)](_0x54ad62)[_0x4fc6ff(0xea)]()[_0x4fc6ff(0x105)](_0x4e64ae=>{const _0x2fc6f0=_0x4fc6ff;if(_0x4e64ae[_0x2fc6f0(0x10f)]){const _0x2e09da=_0x4e64ae[_0x2fc6f0(0x111)]();if(_0x2e09da[_0x2fc6f0(0x10d)]==='Admin'){alert('Tidak\x20diizinkan\x20mengubah\x20tanggal\x20Exp\x20pada\x20user\x20dengan\x20Role\x20Admin.');return;}const [_0x144cd4,_0x5cc11e,_0x284c61]=_0xe99a44[_0x2fc6f0(0x113)]('/')[_0x2fc6f0(0xe4)](Number),_0x6e161a=new Date(_0x284c61,_0x5cc11e-0x1,_0x144cd4);if(isNaN(_0x6e161a[_0x2fc6f0(0x11b)]())){alert(_0x2fc6f0(0x123));return;}const _0xa1ed06=_0x6e161a[_0x2fc6f0(0xe5)]('id-ID',{'timeZone':_0x2fc6f0(0x120),'day':_0x2fc6f0(0xf7),'month':_0x2fc6f0(0xf7),'year':_0x2fc6f0(0x103),'timeZoneName':_0x2fc6f0(0xfa)});db['collection'](_0x2fc6f0(0xe2))[_0x2fc6f0(0xf1)](_0x54ad62)[_0x2fc6f0(0xf0)]({'exp':_0xa1ed06})[_0x2fc6f0(0x105)](()=>{alert('Tanggal\x20Exp\x20Role\x20User\x20berhasil\x20diubah.'),loadUsers();})[_0x2fc6f0(0x127)](_0x51d495=>{const _0x430b8e=_0x2fc6f0;alert('Gagal\x20mengubah\x20Tanggal\x20Exp\x20Role\x20User:\x20'+_0x51d495[_0x430b8e(0x108)]);});}})[_0x4fc6ff(0x127)](_0x1f698c=>{const _0x13a27a=_0x4fc6ff;console[_0x13a27a(0x110)](_0x13a27a(0x128),_0x1f698c);});}function changeUserRole(_0x1bb417,_0x45877b){const _0x715d89=_0x48d4;db[_0x715d89(0x122)](_0x715d89(0xe2))[_0x715d89(0xf1)](_0x1bb417)[_0x715d89(0xea)]()[_0x715d89(0x105)](_0x237143=>{const _0x2840e6=_0x715d89;if(_0x237143[_0x2840e6(0x10f)]){const _0xa26ef2=_0x237143[_0x2840e6(0x111)]();if(_0xa26ef2[_0x2840e6(0x10d)]===_0x2840e6(0xff)){alert('Tidak\x20diizinkan\x20mengubah\x20User\x20dengan\x20Role\x20Admin.');return;}db[_0x2840e6(0x122)]('users')[_0x2840e6(0xf1)](_0x1bb417)['update']({'role':_0x45877b})[_0x2840e6(0x105)](()=>{const _0x40bca4=_0x2840e6;alert(_0x40bca4(0xef)),loadUsers();})[_0x2840e6(0x127)](_0x31397b=>{const _0x2bf98d=_0x2840e6;alert(_0x2bf98d(0x10b)+_0x31397b['message']);});}})['catch'](_0x452c0c=>{const _0x59f728=_0x715d89;alert(_0x59f728(0xe9)+_0x452c0c[_0x59f728(0x108)]);});}function showUserList(_0x499ba4){const _0x2c9e3c=_0x48d4,_0xbb6114=document[_0x2c9e3c(0x125)](_0x2c9e3c(0x118));_0xbb6114[_0x2c9e3c(0xe8)]='',_0x499ba4[_0x2c9e3c(0x11c)]((_0x46fbb7,_0x3cca69)=>{const _0x35f61a=_0x2c9e3c,_0x3c80b1=document[_0x35f61a(0xfd)]('li');_0x3c80b1[_0x35f61a(0x11a)][_0x35f61a(0xe7)](_0x35f61a(0xeb)),_0x3c80b1[_0x35f61a(0x104)](_0x35f61a(0x126),_0x3cca69+0x1),_0x3c80b1['innerHTML']=_0x35f61a(0xf2)+_0x46fbb7['id']+'</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22username-user\x22>Nama:\x20'+_0x46fbb7['username']+_0x35f61a(0x112)+_0x46fbb7[_0x35f61a(0x106)]+_0x35f61a(0xf4)+_0x46fbb7['emailVerified']+_0x35f61a(0x10c)+_0x46fbb7['role']+_0x35f61a(0x102)+_0x46fbb7[_0x35f61a(0xfb)]+'</span>\x0a\x20\x20\x20\x20\x20\x20</span>\x0a\x20\x20\x20\x20\x20\x20<span\x20class=\x22btn-edit\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22editrole\x22>Edit\x20Role</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22editexp\x22>Edit\x20Tanggal\x20Exp</button>\x0a\x20\x20\x20\x20\x20\x20</span>\x0a\x20\x20\x20\x20',_0x3c80b1[_0x35f61a(0x125)]('.editrole')[_0x35f61a(0x109)](_0x35f61a(0xf5),()=>{const _0x59a556=_0x35f61a,_0x323234=prompt(_0x59a556(0x11e));_0x323234&&changeUserRole(_0x46fbb7['id'],_0x323234);}),_0x3c80b1[_0x35f61a(0x125)](_0x35f61a(0x10a))[_0x35f61a(0x109)](_0x35f61a(0xf5),()=>{const _0x4d7259=_0x35f61a,_0x3f950a=prompt(_0x4d7259(0x117));_0x3f950a&&ExpRoleuser(_0x46fbb7['id'],_0x3f950a);}),_0xbb6114[_0x35f61a(0x124)](_0x3c80b1);});}function searchUsers(){const _0x57b12b=_0x48d4,_0x5cbbcb=document[_0x57b12b(0x125)](_0x57b12b(0xf9))[_0x57b12b(0xfc)][_0x57b12b(0x114)]();db[_0x57b12b(0x122)](_0x57b12b(0xe2))[_0x57b12b(0xea)]()[_0x57b12b(0x105)](_0x33c15c=>{const _0x439631=_0x57b12b,_0x50dd64=[];_0x33c15c['forEach'](_0x370bba=>{const _0x2b26e7=_0x48d4;_0x50dd64['push']({'id':_0x370bba['id'],..._0x370bba[_0x2b26e7(0x111)]()});});const _0x2a74d8=_0x50dd64[_0x439631(0xe6)](_0x317cd5=>_0x317cd5['id'][_0x439631(0x114)]()[_0x439631(0xe3)](_0x5cbbcb));showUserList(_0x2a74d8),displayPageNumbers(_0x2a74d8['length']);})['catch'](_0x3a1ab9=>{const _0x55c061=_0x57b12b;console[_0x55c061(0x110)](_0x55c061(0xec),_0x3a1ab9);});}document[_0x4a5d92(0x109)]('DOMContentLoaded',()=>{loadUsers();});
  </script>

bingung cara pasangnya?

tanya admin langsung, ke group/komen aja dibawah

Group Telegram

Posting Komentar:

166 Komentar

  1. #Question...
    Anonymous
    I like it but I wish we can edit the register option.
  2. #Reply... Anonim
    MAGIC Reincarnated
    If you understand javascript, then you can edit it yourself, with what you want.

    Can you give me an example? What do you want to edit?,Maybe that example can be useful when I update this login code
  3. #Reply... Anonim
    Anonymous
    Done editing. I didn't see it. Btw, I've tried to login but this happens https://im.ge/i/Screenshot-2023-08-15-015717.j4tkTJ
  4. #Reply... Anonim
    Didanim
    how to activate the firestore database? I don't know what document ID is.
  5. #Reply... Anonim
    MAGIC Reincarnated
    @dmcscans
    It's already in the video.
    As long as you follow the tutorial it will work.
    Firebase database Will be active when you have opened the section "firebase database" And start setting the rules.
  6. #Question...
    MAGIC Reincarnated
    @Anonim
    That's because you didn't delete the part in the javascript,
    The element you removed has a class/id Try searching for class/id In javascript and delete if you have found it
  7. #Reply... Anonim
    Didanim
    Followed the video but you didn't show how you make the firebase database.
  8. #Reply... Anonim
    MAGIC Reincarnated
    It's on the video, in the first video (Min 2:35) there I created the Firestore database, it's the database I'm using, not a real-time database.
    The document ID that you said is a User ID, the user ID is randomly generated when you register In form register.

    Maybe I misunderstood what you meant, if possible please give me a screenshot to make it clearer.
  9. #Reply... Anonim
    Didanim
    How about similar to this style? Is it difficult? https://drive.google.com/file/d/1LYYg_I6BFvJU8TkDCl38GIhnibpd8rtB/view?usp=sharing
  10. #Question...
    Chocolate con leche
    Is it possible to use this in other template?
  11. #Reply... Anonim
    MAGIC Reincarnated
    Btw Your style is very good, may I use it to use in the next code update?
  12. MAGIC Reincarnated
    Of course it can be done,
    You have to find the element used to enclose the article and just add a div with class "lck".
    And skip step 4 and 5 because this step only for ZeistmangaV5
    I want to ask, What theme do you use?
  13. #Reply... Anonim
    Didanim
    sure, you can.
  14. #Reply... Anonim
    MAGIC Reincarnated
    I've done it, I'll upload it later after successfully installing it on ZeistmangaV5
  15. #Question...
    Anonymous
  16. #Question...
    선생님
    i like the style min. when is the update?
  17. #Reply... 선생님
    MAGIC Reincarnated
    after I finished making the video tutorial
  18. #Question...
    Wernayasa
    Ada demonya.
    Di tunggu tutorialnya.
  19. #Reply... 선생님
    선생님
    Hi nim, how to remove this effect? https://im.ge/i/wNoF2x
  20. #Reply... 선생님
    MAGIC Reincarnated
    .group input:focus ~ label, .group input:valid ~ label { left:0;
    top: -25px;
    font-size: 14px;}

    this is the css section that creates the effect
  21. #Reply... Wernayasa
    MAGIC Reincarnated
    Sudah ku upload.
    Agak lama karena internetnya cuman 2Mb
  22. #Question...
    Anonymous
    Min kenapa selalu gagal begini yah? Padahal udah ngikutin seperti yang di video

    Login: https://ibb.co/SKrJ2rs
    Register: https://ibb.co/gS9H400
  23. #Reply... Anonim
    MAGIC Reincarnated
    Kamu Sudah ganti configformlogin ini belum,
    Ganti ini dengan punya kamu sendiri.

    <script>/*<![CDATA[*/
    const configformlogin={

    apiKey: "AIzaSyCDUKoueS66e77qvqGbrc1Clb0eFJWi2JU",
    authDomain: "formlogin-6e176.firebaseapp.com",
    projectId: "formlogin-6e176",
    storageBucket: "formlogin-6e176.appspot.com",
    messagingSenderId: "197923569691",
    appId: "1:197923569691:web:db39447bcd0f6d7bd6f8be",
    measurementId: "G-9RHRPYQXVQ"

    };
    /*]]>*/
    </script>


  24. #Reply... Anonim
    MAGIC Reincarnated
    Komentar ini telah dihapus oleh pengarang.
  25. #Question...
    Anonymous
    is there a way to hide the profile if the user is not logged? And when I tried to register or login, the message is very delayed. It took a minute to appear.
  26. 선생님
    Hi min, could you please provide the original code instead of the minified version? It's challenging for me to make edits.
  27. Anonymous
    Udah bisa ternyata dari rules firestorenya. Kedepannya apakah ada update min?
  28. #Reply... Anonim
    MAGIC Reincarnated
    There's a way.
    I'll make a tutorial later on Thursday, because I'm busy in the next two days.

    Work Stage: https://demokodehiru.blogspot.com/p/dasboard-admin-hiru.html
  29. #Reply... 선생님
    MAGIC Reincarnated
    sorry but Unmified Code is not share,
    That's early stage code, for my development.
    And only a few web developers can get it.
    If you still want, Go Trakteer Link , it's not expensive, only 0,33$ dollar (for support development).
    If there is an update to the code, you will still get the Unminified code.
  30. #Reply... Anonim
    MAGIC Reincarnated
    baguslah kalau sudah benar.
    Yep..Code Bakal Terus diupdate sampai benar-benar memberikan Kemanan ketat, karena targetku adalah Encrypt Kontent...Untuk Web Premium Yang sangat Butuh Ginian
  31. #Reply... Anonim
    MAGIC Reincarnated
    contoh dasar encrypt kontent yang aku maksud Link
  32. Anonymous
    Mantap min dan semoga yang ini juga ada update karna masih bisa diakalin dengan cara inspect element
  33. #Reply... Anonim
    MAGIC Reincarnated
    Mungkin Next Update, Soalnya next Update aku gak mau terburu-buru, Cari cara dulu biar aman kontentnya.
    Update kali ini cuman bug kecil.
  34. Anonymous
    Siap min jangan buru2
  35. #Question...
    Azathoth13x
    work with Zm v6?
  36. #Reply... Azathoth13x
    MAGIC Reincarnated
    This works on any theme, as long as you know the data:post.body location of the content you want to lock (step 6).
  37. #Question...
    Anonymous
  38. #Question...
    Novel & Manga
    Komentar ini telah dihapus oleh pengarang.
  39. #Question...
    Novel & Manga
    https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfEVDy85u6aVrQmHuSK-__kToJ0c4tk6z40Npm3r9CBocl0ztvPcJTnOZGS1E1YyQ4wd2cbYv5bC7e17XDZ4vBZg_7AFROhu6AIr_lArUfx8_0OG9-xKbpWTpbGwYtWkqYjtileR-5Q4OL1lAjFVm3o3vkWXBxdPOF2J8JPed2bZP9jSLJbSX2VZV1lDE0/s320/Screenshot_20230916-082420_Chrome.jpg
  40. Anonymous
    Min untuk next update apakah bisa tambahkan fitur countdown waktu untuk mengembalikan Role 'Member' Ke role 'User', misal diatur ke 10 hari maka dalam 10 hari role 'Member' akan berubah menjadi role 'user' dan di profile user akan ada countdown nya, jadi seperti membership gitu
  41. #Reply... Unknown
    MAGIC Reincarnated
  42. #Reply... Novel & Manga
    MAGIC Reincarnated
    Ada banyak Kesalahan Saat kamu meletakan kodenya, Kamu pakai tema apa?,kalau zeistmangav5 tinggal ikuti video tutorialnya, kalau zeistmangav6 nanti aku buat tutorialnya
  43. #Reply... Anonim
    MAGIC Reincarnated
    entah bisa atau gak, Soalnya Bingung Ambil data tanggal dan mencocokannya dengan tanggal saat ini itu gimana caranya.
    akan kucoba targetkan fitur itu.Otw cari di stackoverflow
  44. Novel & Manga
  45. Novel & Manga
  46. #Reply... Anonim
    MAGIC Reincarnated
    Sudah Berhasil buat fitur exp Role, Next update bakal ada...
  47. #Reply... Novel & Manga
    MAGIC Reincarnated
    Coba Gunakan Kode ini, Ini sama dengan yang ada di demo.
    Link
    <!--Menu Login/Register-->
    <div class='dropdown-opsi'>
    <button class='dropdown-btn-opsi menu-login'>
    <span class='sm:dn'>Login</span></button>
    <div class='dropdown-content-opsi'>
    <button class='dropdown-item-opsi' disabled='disabled' id='profiletab-button' onclick='document.getElementById(&quot;contentx&quot;).style.display=&quot;flex&quot;;' type='button'><svg height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='M12 4a8 8 0 0 0-6.96 11.947A4.99 4.99 0 0 1 9 14h6a4.99 4.99 0 0 1 3.96 1.947A8 8 0 0 0 12 4Zm7.943 14.076A9.959 9.959 0 0 0 22 12c0-5.523-4.477-10-10-10S2 6.477 2 12a9.958 9.958 0 0 0 2.057 6.076l-.005.018l.355.413A9.98 9.98 0 0 0 12 22a9.947 9.947 0 0 0 5.675-1.765a10.055 10.055 0 0 0 1.918-1.728l.355-.413l-.005-.018ZM12 6a3 3 0 1 0 0 6a3 3 0 0 0 0-6Z' fill='currentColor' fill-rule='evenodd'/></svg>Profile</button>
    <button class='dropdown-item-opsi' onclick='document.getElementById(&quot;login-register-form&quot;).style.display=&quot;&quot;;'><svg height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M4 22q-.825 0-1.413-.588T2 20V9q0-.825.588-1.413T4 7h5V4q0-.825.588-1.413T11 2h2q.825 0 1.413.588T15 4v3h5q.825 0 1.413.588T22 9v11q0 .825-.588 1.413T20 22H4Zm0-2h16V9h-5q0 .825-.588 1.413T13 11h-2q-.825 0-1.413-.588T9 9H4v11Zm2-2h6v-.45q0-.425-.238-.788T11.1 16.2q-.5-.225-1.012-.338T9 15.75q-.575 0-1.088.113T6.9 16.2q-.425.2-.663.563T6 17.55V18Zm8-1.5h4V15h-4v1.5ZM9 15q.625 0 1.063-.438T10.5 13.5q0-.625-.438-1.063T9 12q-.625 0-1.063.438T7.5 13.5q0 .625.438 1.063T9 15Zm5-1.5h4V12h-4v1.5ZM11 9h2V4h-2v5Zm1 5.5Z' fill='currentColor'/></svg>Login/Register</button>
    </div>
    </div>
    <script>
    /*<![CDATA[*/
    const dropdownButton = document.querySelector('.dropdown-btn-opsi');
    const dropdownContent = document.querySelector('.dropdown-content-opsi'); dropdownButton.addEventListener('click', () => { dropdownContent.classList.toggle('show-opsi');
    });
    window.addEventListener('click', (event) => {
    if (!event.target.matches('.dropdown-btn-opsi')) {
    if (dropdownContent.classList.contains('show-opsi')) {
    dropdownContent.classList.remove('show-opsi');
    }
    }
    });
    /*]]>*/
    </script>
    <!--Menu Login/Register-->
  48. Anonymous
    Wahh mantap min, ditunggu next updatenya
  49. #Reply... Anonim
    MAGIC Reincarnated
    Kayak gini kan, exp role yang kamu maksud
    Screenshot
    Link video test

    dikarenakan timer coutdown realtime gak mungkin bisa dibuat olehku.
    Tapi kalau tanggal exp Member di Profile bisa aja, jadi ketika sudah Habis Waktunya maka Role Membernya akan balik ke User
  50. Anonymous
    Nah iya begitu min, tanpa countdown juga udah mantap, kira2 untuk next update apakah masih lama min?
  51. #Reply... Anonim
    MAGIC Reincarnated
    Aku Lagi kena demam, Mungkin Minggu depan, Kalau demamku hilang sebelum hari kamis, Ya.. berarti kamis Updatenya
  52. Wernayasa
    Gk usah di paksain, santai aj.
    Moga cepat sembuh.
  53. Anonymous
    Semoga sembuh min
  54. #Reply... Wernayasa
    MAGIC Reincarnated
    Makasih bang, Lumayan agak mendingan setelah minum banyak obat.
  55. #Reply... Anonim
    MAGIC Reincarnated
  56. #Question...
    Anonymous
    Min next update apa bisa tambahkan fitur search di dashboard karna nanti jika user lumayan banyak nyari user nya agak susah
  57. #Reply... Anonim
    MAGIC Reincarnated
    kalau dashboard Admin Diupdate Secarah terpisah..
    Itu Udah dibuat Cuman Belum direlease, soalnya belum ada stylenya dan stuck di button delete , Video.
  58. #Question...
    Anonymous
    can I add another role?
  59. #Reply... Anonim
    MAGIC Reincarnated
    Other role could be added, but it would be too complicated to explain.
    The point is you have to connect and add logic to the function checkUserRole(e),
    place the new code for the New Role check Logic condition in if else


    newRole1 = document.querySelectorAll(".guest");

    else if ("User" === s) { newRole1[0].classList.remove("guest", "hidden");
    console.log("Role User");
    }
  60. #Reply... Anonim
    MAGIC Reincarnated
    If you want to add another role, just write a comment here, I'll add it for the next update.
  61. Anonymous
    I want to add the role Staff or Mod. Any of this two.
  62. Anonymous
    Wahh makin mantap min, semoga hari ini jadi udapte
  63. #Reply... Anonim
    MAGIC Reincarnated
    OK, I'll add that role
  64. #Reply... Anonim
    MAGIC Reincarnated
    minggu... soalnya tinggal cssnya doang (ada dua versi style,style ke2 pakai gambar anime Screenshot) dan upload video baru, wifi lemot jadi harus pakai kuota buat uploadnya, minggu baru ada kuota.
  65. Anonymous
    Siap min, ditunggu updatenya
  66. Anonymous
    Makasih min untuk updatenya, tapi kok di aku error yah
    Screenshot,
    Sama info usernya tidak muncul
    Screenshot

    Dan juga pas login dengan akun admin chapter yang terkunci tetap tidak terbuka
  67. #Reply... Anonim
    Anonymous
    Ss 1: https://ibb.co/7XFR1nX
    Ss 2: https://ibb.co/C6HmrT2
  68. #Reply... Anonim
    MAGIC Reincarnated
    Ah... itu salahku, kamu Langsung Ngambil kodenya waktu aku lagi (proses) ubah Kode lama ke yang baru, itu kode step 4 lama, sekarang ganti ke yang baru, sudah aku upload
  69. #Reply... Anonim
    MAGIC Reincarnated
    Lakukan pemasangan ulang pada step 4
  70. Anonymous
    Berhasil min, terima kasih untuk updatenya
  71. #Question...
    MAGIC Reincarnated
  72. #Question...
    Azathoth13x
    Thank for updated but still "Unknown runtime binding: includable in widget" in ZMv6
  73. #Reply... Azathoth13x
    MAGIC Reincarnated
    can you include a screenshot or video?, Someone has already installed this form in zmv6 and it worked, I have also tried it, so I don't understand what the error is.
  74. #Question...
    Anonymous
    When entering the password, it can changed like this?
    <style>
    /* Style all input fields */
    input {
    width: 100%;
    padding: 12px;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
    margin-top: 6px;
    margin-bottom: 16px;
    }

    /* Style the submit button */
    input[type=submit] {
    background-color: #04AA6D;
    color: white;
    }

    /* Style the container for inputs */
    .container {
    background-color: #f1f1f1;
    padding: 20px;
    }

    /* The message box is shown when the user clicks on the password field */
    #message {
    display:none;
    background: #f1f1f1;
    color: #000;
    position: relative;
    padding: 20px;
    margin-top: 10px;
    }

    #message p {
    padding: 10px 35px;
    font-size: 18px;
    }

    /* Add a green text color and a checkmark when the requirements are right */
    .valid {
    color: green;
    }

    .valid:before {
    position: relative;
    left: -35px;
    content: "✔";
    }

    /* Add a red text color and an "x" when the requirements are wrong */
    .invalid {
    color: red;
    }

    .invalid:before {
    position: relative;
    left: -35px;
    content: "✖";
    }
    </style>
    </head>
    <body>

    <h3>Password Validation</h3>
    <p>Try to submit the form.</p>

    <div class="container">
    <form action="/action_page.php">
    <label for="usrname">Username</label>
    <input type="text" id="usrname" name="usrname" required>

    <label for="psw">Password</label>
    <input type="password" id="psw" name="psw" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" title="Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters" required>

    <input type="submit" value="Submit">
    </form>
    </div>

    <div id="message">
    <h3>Password must contain the following:</h3>
    <p id="letter" class="invalid">A <b>lowercase</b> letter</p>
    <p id="capital" class="invalid">A <b>capital (uppercase)</b> letter</p>
    <p id="number" class="invalid">A <b>number</b></p>
    <p id="length" class="invalid">Minimum <b>8 characters</b></p>
    </div>

    <script>
    var myInput = document.getElementById("psw");
    var letter = document.getElementById("letter");
    var capital = document.getElementById("capital");
    var number = document.getElementById("number");
    var length = document.getElementById("length");

    // When the user clicks on the password field, show the message box
    myInput.onfocus = function() {
    document.getElementById("message").style.display = "block";
    }

    // When the user clicks outside of the password field, hide the message box
    myInput.onblur = function() {
    document.getElementById("message").style.display = "none";
    }

    // When the user starts to type something inside the password field
    myInput.onkeyup = function() {
    // Validate lowercase letters
    var lowerCaseLetters = /[a-z]/g;
    if(myInput.value.match(lowerCaseLetters)) {
    letter.classList.remove("invalid");
    letter.classList.add("valid");
    } else {
    letter.classList.remove("valid");
    letter.classList.add("invalid");
    }

    // Validate capital letters
    var upperCaseLetters = /[A-Z]/g;
    if(myInput.value.match(upperCaseLetters)) {
    capital.classList.remove("invalid");
    capital.classList.add("valid");
    } else {
    capital.classList.remove("valid");
    capital.classList.add("invalid");
    }

    // Validate numbers
    var numbers = /[0-9]/g;
    if(myInput.value.match(numbers)) {
    number.classList.remove("invalid");
    number.classList.add("valid");
    } else {
    number.classList.remove("valid");
    number.classList.add("invalid");
    }

    // Validate length
    if(myInput.value.length >= 8) {
    length.classList.remove("invalid");
    length.classList.add("valid");
    } else {
    length.classList.remove("valid");
    length.classList.add("invalid");
    }
    }
    </script>
  75. #Reply... Anonim
    MAGIC Reincarnated
    yes it can.
    I'll make a tutorial on installing it tomorrow
  76. #Reply... Anonim
    MAGIC Reincarnated
    This is a tutorial for installing password validation

    Video : Link


    file: Link
  77. #Question...
    Anonymous
    i found your site recently. But where's the code admin?
  78. #Reply... Anonim
    MAGIC Reincarnated
    After logging in to my account, don't forget to refresh the website
  79. #Reply... Anonim
    MAGIC Reincarnated
    I will open it for two day.
    you see the gift menu above the header,
    open the gift and enter the account
    username: hiru
    password : lumatina

    [ account exp: 01/10/2023 ]
  80. Anonymous
    it's empty tho?
  81. #Reply... Anonim
    MAGIC Reincarnated
    What's empty?.
    Check this video : Link
  82. Anonymous
    Okay, I understand. In Step 6, this
    Chapter Terkunci
    Chapter Ini terkunci, Silahkan login terlebih dahulu Sesuai Role
    Unlock with Role:
    Member
    it keeps disappearing, and when the user's role is 'Member the content isn't showing..
  83. #Question...
    Blackberry
    Admin can you help me? I can't find the code "Forma email verification V2", I'm doing the firebase tutorial in tyour Zeistmanga 1.2 theme and it's not in that template. How can I continue?
  84. #Reply... Anonim
    MAGIC Reincarnated
    if nothing is changed in the code then it will work fine.
    did you change the label? or class name?
    It's hard for me to know because the code worked fine when I tested it.

    and for role notification issues
    Chapter Terkunci
    Chapter Ini terkunci, Silahkan login terlebih dahulu Sesuai Role
    Unlock with Role:
    Member

    which often disappears, that's because I set it using setTimeout 5 seconds,

    in step 4... more precisely in function checkUserRole, there is this code
    setTimeout(()=>{s===r||s!==r?t.forEach(e=>{e.classList.add("hidden")}):t.forEach(e=>{e.classList.remove("hidden")})},5e3)
    Just replace the 5 seconds, with the seconds you want...

    5e3

    5000= 5e3 = 5sec
    10000 10e4 = 10 seconds
    60000 = 6e4 = 60 seconds
    3600000 = 36e5 = 1 hour
  85. #Reply... Blackberry
    MAGIC Reincarnated
    "Form email verification V2" is old code, now it's "v3.2".

    do you mean zeistmaid v1.2?,
    it is very difficult to install form login v3.2 into Zeistmaid v1.2, because code count bookmark.

    code form login v3.2: Link

    Contact me if you have any problems.
    I will help you install it
    https://t.me/webhiru
  86. #Question...
    Azathoth13x
    Thanks for ur hard work
  87. #Reply... Azathoth13x
    MAGIC Reincarnated
    yeah u're welcome
  88. #Question...
    Azathoth13x
    Screenshot

    My profile not appear and How to give role? Did I skip look?
  89. #Reply... Azathoth13x
    MAGIC Reincarnated
    Don't forget the Firestore rules
    , replace using this rule
    rules_version = '2';
    service cloud.firestore {
    match /databases/{database}/documents {
    match /{document=**} {
    allow read, write: if request.auth != null;
    }
    }
    }


    how to give role: Link
  90. Anonymous
    Why is there a timeout? Why not it will not appear if the user has the role?
  91. #Reply... Anonim
    MAGIC Reincarnated
    because I didn't have enough time when creating the code.. that's why I used setTimeout , I have fixed this, where it will only disappear if the content is already open.
    I'll make a tutorial tonight
  92. Anonymous
    wow thank you.
  93. #Reply... Anonim
    MAGIC Reincarnated
    This tutorial removes setTimeout and makes the role notification only disappear when the content is opened
    Link video
  94. Anonymous
    btw, I can't edit the style? Because when I edit it, it's not working anymore.
  95. #Reply... Anonim
    MAGIC Reincarnated
    You can edit the style, as long as you don't change the class name and ID or the html structure
  96. Anonymous
    I didn't change the class name, I just changed the height and width here. #fixedform{position:fixed;top:0;right:0;left:0;display:grid;place-items:center;z-index:9999;overflow:auto;height:100%;width:100%;justify-content: center;}
  97. #Reply... Anonim
    MAGIC Reincarnated
    it's the container that makes the form float....if you change max-height to height and max-width to width then the container will cover the screen

    just try putting it on
    background:#222; then the whole screen goes dark, the reason why it doesn't work is because the container covers the whole screen so what you click is the container and nothing else
  98. Anonymous
    I'm trying to center the container where the register, login, and profile options are located.
  99. #Question...
    Didanim
    Can you check what's wrong? Even my role is Member the content is not showing. Link
  100. #Reply... Anonim
    MAGIC Reincarnated
    that's difficult, because I don't use the add class to display the popup form.
    When I have free time I will make a tutorial
  101. #Reply... Didanim
    MAGIC Reincarnated
    Give my account the role "Member", so I can check
  102. #Reply... Didanim
    Didanim
    and also this when Login failed. Screenshot
  103. #Reply... Didanim
    MAGIC Reincarnated
    delete your account in authentication and firestore database then re-register,
    I've logged in there and it's normal, it's just a "member" problem that I haven't checked
  104. Didanim
    I've already done it, but it only happens when you enter the wrong password. Perhaps I made a mistake while changing the language in id='jsfrm' to English?
  105. #Reply... Didanim
    MAGIC Reincarnated
    If you enter the password incorrectly, there will be a notification "Login failed . The password is invalid or the user does not have a password."

    Check it out
    Firestore rules Have you replaced it?
  106. #Reply... Didanim
    MAGIC Reincarnated
    If there is an error in the line of code then the code will not run, so the problem is not id='jsfrm', but firebase
  107. Didanim
    Yes, this? rules_version = '2';
    service cloud.firestore {
    match /databases/{database}/documents {
    match /{document=**} {
    allow read, write: if request.auth != null;
    }
    }
    }
  108. #Reply... Didanim
    MAGIC Reincarnated
    yes, that's correct.
  109. #Reply... Didanim
    MAGIC Reincarnated
    I found a little problem, your content is trapped by the canvas script so it doesn't display anything because the canvas script doesn't work.

    To make it work... maybe you should put the function canvas in code function checkUserRole
  110. Didanim
    Yes, that's the problem but how?
  111. #Reply... Didanim
    MAGIC Reincarnated
    give me the code snippet const img <data:post.body/>
  112. #Question...
    Anonymous
    can we hide/disable the click of the login button if they access the profile/logged in?
  113. Didanim
    Here window.addEventListener(`load`, function () {
    const imgTags = `<data:post.body.cssEscaped/>`;
    ImageManager.loadImages(imgTags);
    });
  114. #Reply... Anonim
    MAGIC Reincarnated
    could you please provide a little more detail?
    I don't quite understand what you mean and what it's for
  115. #Reply... Didanim
    MAGIC Reincarnated

    function loadImg () {
    const imgTags = `<data:post.body.cssEscaped/>`;
    ImageManager.loadImages(imgTags);
    }


    put this function " loadImg () " under unlockUser() in the function checkUserRole

    like this
    "Member"===t?(n[0].classList.remove("member","guest","hidden","hidden1"),checkMembershipExp(),unlockMember(),unlockUser(),loadImg (),console.log("Role Member"))
  116. Anonymous
    the same with profile you can't click it if you haven't logged it.
  117. Didanim
    Hi, I now understand the error. When I set it to Production Mode, "Login failed" appears, but it works correctly in Test Mode. Here's the demo image Screenshot
  118. Didanim
    Is this correct? function checkMembershipExp(){let e=document.getElementById("profile-uid"),r=document.querySelector("#exp-role");if(e&&r){let t=e.textContent,l=r.textContent.trim(),i=l.split(", ");if(2===i.length){let o=i[0];i[1];let n=o.split("/");if(3===n.length){let a=parseInt(n[0],10),s=parseInt(n[1],10)-1,d=parseInt(n[2],10),m=new Date(d,s,a);if(!isNaN(m.getTime())){let c=new Date;(c==m||c>=m||c>m)&&db.collection("users").doc(t).update({role:"User",exp:"Membership has expired"}).then(()=>{alert("Your 'Member' role membership has expired, so we will change your role back to 'User'. Please renew if you want to remain a 'Member'. Have a great day!"),location.reload()}).catch(e=>{console.error("Failed to change user role:",e)})}}}}}function checkUserRole(e){db.collection("users").doc(e).onSnapshot(e=>{if(e.exists){let r=e.data().role,l=document.querySelectorAll(".admin"),i=document.querySelectorAll(".member"),o=document.querySelectorAll(".modder"),n=document.querySelectorAll(".staff"),a=document.querySelectorAll(".guest");"Admin"===r?(l[0].classList.remove("admin","member","staff","modder","guest","hidden","hidden1"),checkMembershipExp(),unlockAdmin(),unlockModder(),unlockStaff(),unlockMember(),unlockUser(),notiRole(),loadImg(),console.log("Role Admin")):"Modder"===r?(o[0].classList.remove("modder","member","staff","guest","hidden","hidden1"),checkMembershipExp(),unlockModder(),unlockStaff(),unlockMember(),unlockUser(),loadImg(),console.log("Role Moddertor")):"Staff"===r?(n[0].classList.remove("staff","member","modder","guest","hidden","hidden1"),checkMembershipExp(),unlockModder(),unlockStaff(),unlockMember(),unlockUser(),notiRole(),loadImg(),console.log("Role Staff")):"Member"===r?(i[0].classList.remove("member","guest","hidden","hidden1"),checkMembershipExp(),unlockMember(),unlockUser(),notiRole(),loadImg(),console.log("Role Member")):"User"===r&&(a[0].classList.remove("guest","hidden"),checkMembershipExp(),unlockUser(),notiRole(),loadImg(),console.log("Role User"))}})}auth.onAuthStateChanged(e=>{e&&e.emailVerified?(showContent(),showProfile(e.uid),checkUserRole(e.uid)):hideContent()});
    function notiRole(){let t=document.querySelectorAll(".notifchapter");t?t.forEach(e=>{e.classList.add("hidden")}): t.forEach(e=>{e.classList.remove("hidden")})}
    function loadImg () {
    const imgTags = `<data:post.body.cssEscaped/>`;
    ImageManager.loadImages(imgTags);
    }
  119. #Reply... Didanim
    MAGIC Reincarnated
    Delete this code (This code shouldn't be there )
    function loadImg () {
    const imgTags = `<data:post.body.cssEscaped/>`;
    ImageManager.loadImages(imgTags);
    }



    And look for a code like this then replace it
    window.addEventListener(`load`, function () {
    const imgTags = `<data:post.body.cssEscaped/>`;
    ImageManager.loadImages(imgTags);
    });

    With this code
    function loadImg () {
    const imgTags = `<data:post.body.cssEscaped/>`;
    ImageManager.loadImages(imgTags);
    }

  120. #Reply... Didanim
    MAGIC Reincarnated
    yes I know that, have you changed the Firestore database rules? as I suggested.
  121. Didanim
    Yes, I did. But why is it working well only in test mode? Screenshot
  122. #Reply... Didanim
    MAGIC Reincarnated
    There are two reasons
    1 Because the rules of the two modes are different, that's why I suggest changing the rules.
    2 There is no database with the name "users"
  123. Didanim
    I don't know what's wrong, I followed your tutorial video Screenshot
  124. #Reply... Didanim
    MAGIC Reincarnated
    try using custom error.
    find this code
    find this code in jsfrm

    loginMessage.textContent = "login failed. " + e.message;


    replace with this


    if (e.code === "auth/user-not-found") {
    loginMessage.textContent = "Email not found. Please register";
    } else if (e.code === "auth/wrong-password") {
    loginMessage.textContent = "Wrong password. Please try again.";
    } else {
    loginMessage.textContent = "Login Failed. There is an error: " + e.message;
    }
  125. #Question...
    Anonymous
    min, this appear after I add the code, can we remove it? Screenshot
  126. #Reply... Anonim
    MAGIC Reincarnated
    I don't know what it is. can you send the full picture?
  127. Anonymous
  128. #Reply... Anonim
    MAGIC Reincarnated
    Maybe it's the login session token URL, if it's really a login token then it can't be hidden.
  129. Anonymous
    but I saw the example in zeistmaid. It wasn't like this: blogspot.com/2023/10/chapter-1.html?zx=a6a20ec91630d7d9
  130. #Reply... Anonim
    MAGIC Reincarnated
    yeah in zeistmaid it doesn't happen like that, because the code is a little different.

    Does the form you use on the Zeistmaid theme use the same code as this post?
    then in the login section, register and profile or open content... is it all working normally?
  131. #Question...
    Azathoth13x
    Screenshot

    ZMv6 Search Bookmark Setting not work
  132. #Reply... Azathoth13x
    MAGIC Reincarnated
    delete class .hidden in this css
    .hidden,.hidden1,.form .register-fr,.form .reset-fr,.icon1.hidden,.icon2.hidden,.options li:first-child{display:none}
    example like this
    .hidden1,.form .register-fr,.form .reset-fr,.icon1.hidden,.icon2.hidden,.options li:first-child{display:none}
  133. #Question...
    Azathoth13x
  134. #Reply... Azathoth13x
    MAGIC Reincarnated
  135. #Reply...
    MAGIC Reincarnated
    I will make a video tutorial
  136. #Question...
    Azathoth13x
    Thank u have kofi?
  137. #Reply... Azathoth13x
    MAGIC Reincarnated
    yeah I have Kofi Link kofi.

    this is the video tutorial Link video
  138. Azathoth13x
    kodenumber can enter any number right?
  139. Azathoth13x
    One more how to popup profile change to page? It maybe better than popup
  140. #Question...
    Azathoth13x
    <b:if cond='data:post.labels any (l =&gt; l.name == &quot;Admin&quot; || l.name == &quot;User&quot; || l.name == &quot;MemberA1&quot; || l.name == &quot;MemberA2&quot; || l.name == &quot;MemberA3&quot; || l.name == &quot;MemberA4&quot; || l.name == &quot;MemberA5&quot; || l.name == &quot;Modder&quot; || l.name == &quot;Staff&quot;)'>

    9 labels can be used if more there will be error
  141. #Reply... Azathoth13x
    MAGIC Reincarnated
    Yes, but also no, sometimes there can be an error if there are more than 100, so I recommend just 1-50.
  142. #Reply... Azathoth13x
    MAGIC Reincarnated
    You can't, because the javascript is still fetching the data that appears in the profile.
  143. #Reply... Azathoth13x
    MAGIC Reincarnated
    try this
    <b:if cond='data:post.labels any (labelLock => labelLock.name in ["MemberA1", "MemberA2","MemberA3","MemberA4","MemberA5","Admin","Staff","Modder","User","Member"])'>
  144. #Question...
    Azathoth13x
    Can login but cant create account
  145. #Reply... Azathoth13x
    MAGIC Reincarnated
    Code "other roles" is not the cause of the register error code.

    I don't know where the error is because I don't know what changes you made to the jsfrm code.

    screenshot code jsfrm and record console.log when you register
  146. Azathoth13x
    I fixed it that my wrong
  147. #Question...
    S David Prince
    😌 hehehe I also want to contribute ; I know I'm not on you guys level tho but I finally see something I can add
  148. #Question...
    S David Prince
    rules_version = '3';
    service cloud.firestore {
    match /databases/{database}/documents {
    // Allow read access for authenticated users.
    match /{document=**} {
    allow read: if request.auth != null;

    // Allow write access only for authenticated users from a specific domain and subdomains.
    allow write: if request.auth != null &&
    request.auth.token.email.matches(".*@yourdomain.com");
    }
    }
    }
  149. MAGIC Reincarnated
    that's good, it gave me the idea to develop this login form so that it can only be accessed on registered domains.
  150. S David Prince
    Eish my bad thats a wrong. the previous code only give write access to the custom domain email address
    service cloud.firestore {
    match /databases/{database}/documents {
    match /{document=**} {
    allow read: if request.auth != null;

    // Allow write access only for authenticated users with the custom claim 'domain' set to 'sdacvip.com'.
    allow write: if request.auth != null &&
    request.auth.token.domain == 'domain.com';
    }
    }
    }

    I think this worked
  151. #Question...
    Anonymous
    Harus ada lisense bang,??
  152. #Reply... Anonim
    MAGIC Reincarnated
    gak, itu lisensi langsung dariku.. buat protect code aja, jangan diubah lisensinya.
  153. #Question...
    Anonymous
    what's the difference between the premium?
  154. #Reply... Anonim
    MAGIC Reincarnated
    Not much different, because this is the original code version of premium... when I was still developing it at the beginning, before the current premium was released.

    Most different in the level of code complexity, this version is not flexible in setting roles or content... While premium is more flexible in setting roles, coins, content, notifications, And other features that will be created can be directly installed and used without any hassle.
  155. #Question...
    Anonymous
    Halo, saya nggak ada dasar coding sama sekali mau tanya itu dapet config sdk firebase kita dari mana ya?
  156. #Reply... Anonim
    MAGIC Reincarnated
    buat akun firebase disini Link.

    setelah itu
    saat membuat project pada Firebase, disitu setelah selesai setup bakal diperlihatkan config Sdk ..

    Config Sdk dimenit 1:47 - 2:07
    Video,
    jika sudah terlanjur membuat project maka bisa dilihat dibagian menu settingVideo
  157. #Question...
    Anix Realm
    hello min , i want to know can i connect 1 firebase account to 2 login forms ?
  158. #Reply... Anix Realm
    MAGIC Reincarnated
    Yes, u can use 1 Firebase account for 2 login form codes.
  159. Anix Realm
    thanks bro ! hello hiru bro , the profile header is not toggling on my theme .
    please help
    https://private-user-images.githubusercontent.com/121334995/381080804-ea578750-38c5-4ade-83ab-241622a283b6.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzAyNjMyNjgsIm5iZiI6MTczMDI2Mjk2OCwicGF0aCI6Ii8xMjEzMzQ5OTUvMzgxMDgwODA0LWVhNTc4NzUwLTM4YzUtNGFkZS04M2FiLTI0MTYyMmEyODNiNi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQxMDMwJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MTAzMFQwNDM2MDhaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1mOTNkODliMzI0YTg0ODlmZjUwNWY2YWNmMmVkMGQ0OWU2OTg2ZTA1ZTA0NWU5M2IwMzNiNmM5NGNkYTM0ZTVmJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.Ca3-59AJl6-iYYV_ipooBX4PVq1_elV3bi4FStyDY6s
  160. #Reply... Anix Realm
    MAGIC Reincarnated
    ? code is just a URL link and user data, make sure pages URL are linked in tag link.

    Can u resend the image link?, The image can't be opened.
  161. Anix Realm
    The pages are linked but the user button is the toggling when hovered or clicked .

    screenshot : https://ibb.co/PcQX5pt

    console screenshot : https://ibb.co/KDz58pR
  162. #Reply... Anix Realm
    MAGIC Reincarnated
    Do you mean the popup when you click on the Avatar profile in the header?, If yes, it must be created by yourself, because the header profile code only displays data without a popup or drawer.
  163. Anix Realm
    got it bro . thanks btw there is a register issue in the login form :

    screenshot : https://ibb.co/CvNTzKD
  164. #Reply... Anix Realm
    MAGIC Reincarnated
    Your Firebase config sdk is not found, maybe you haven't installed the Firebase config sdk,
    Make sure you have installed it here
    const config2 = {
    your sdk config is here
    };

  165. #Question...
    DeadLyBro
    Demo video is broken, can you renew?
  166. #Reply... DeadLyBro
    MAGIC Reincarnated
    I will update the demo later..
    Also releasing the raw code without encryption.
Tinggalkan komentar Jika suka dengan kontent ini
Masukkan URL Gambar (imgbb) / (im.ge) atau Potongan Kode, atau Quote, lalu klik tombol yang kamu inginkan untuk di-parse. Salin hasil parse lalu paste ke kolom komentar.


image quote pre code