Last active
June 8, 2021 20:03
-
-
Save batazo/242a21bc078f624aadf2dbee5cc32149 to your computer and use it in GitHub Desktop.
UserSystem-Dashboard (Frontend for UserSystem Backend)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| input { | |
| padding: 5px; | |
| background: #30302d14; | |
| outline: none; | |
| font-size: 18px; | |
| border-radius: 8px; | |
| box-shadow: inset 2px 2px 7px -1px grey; | |
| } | |
| button { | |
| outline: none; | |
| } | |
| input:focus { | |
| outline: none; | |
| } | |
| .hidden { | |
| display: none; | |
| } | |
| #container { | |
| border: black 1px solid; | |
| padding: 10px; | |
| border-radius: 6px; | |
| box-shadow: 4px 4px 40px -10px grey; | |
| -webkit-touch-callout: none; /* iOS Safari */ | |
| -webkit-user-select: none; /* Safari */ | |
| -khtml-user-select: none; /* Konqueror HTML */ | |
| -moz-user-select: none; /* Old versions of Firefox */ | |
| -ms-user-select: none; /* Internet Explorer/Edge */ | |
| user-select: none; /* Non-prefixed version, currently | |
| supported by Chrome, Edge, Opera and Firefox */ | |
| } | |
| #loadingContainer { | |
| text-align: center; | |
| } | |
| .errorBox { | |
| margin-top: 5px; | |
| padding: 3px; | |
| background: #f7c8c8; | |
| width: 97%; | |
| heigth: 20px; | |
| border: red 1px solid; | |
| border-radius: 3px; | |
| color: red; | |
| } | |
| .progressBox { | |
| background: #d6eaf8; | |
| margin-bottom: 10px; | |
| color: blue; | |
| border: blue 1px solid; | |
| padding: 5px; | |
| border-radius: 3px; | |
| } | |
| .successBox { | |
| background: #97ec57; | |
| margin-top: 10px; | |
| color: green; | |
| border: green 1px solid; | |
| padding: 5px; | |
| border-radius: 3px; | |
| } | |
| .conwidth { | |
| width: 97%; | |
| } | |
| .actionbuttons { | |
| padding-top: 15px; | |
| padding-bottom: 15px; | |
| padding-left: 30px; | |
| padding-right: 30px; | |
| font-size: 20px; | |
| background: #0040ffb3; | |
| color: white; | |
| border-radius: 7px; | |
| border: none; | |
| box-shadow: 4px 4px 4px 0px grey; | |
| } | |
| .actionbuttons:active { | |
| transform: translateY(4px); | |
| background: #0040ffdb; | |
| box-shadow: 4px 0px 4px -1px grey; | |
| } | |
| .actionbuttons:focus { | |
| background: grey; | |
| } | |
| .actionbuttons:hover { | |
| background: #0040ffdb; | |
| } | |
| .buttoncontainer { | |
| width: 100%; | |
| text-align: center; | |
| } | |
| .linkbuttons { | |
| padding-top: 15px; | |
| padding-bottom: 15px; | |
| padding-left: 30px; | |
| padding-right: 30px; | |
| font-size: 16px; | |
| background: #ff0000ad; | |
| color: white; | |
| border-radius: 7px; | |
| border: none; | |
| box-shadow: 4px 4px 4px 0px grey; | |
| } | |
| .linkbuttons:active { | |
| transform: translateY(4px); | |
| background: #ff0000cc; | |
| box-shadow: 4px 0px 4px -1px grey; | |
| } | |
| .linkbuttons:hover { | |
| background: #ff0000cc; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <html> | |
| <head> | |
| <title>USER DASBOARD</title> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <link rel="stylesheet" href="dashboard.css"> | |
| </head> | |
| <body> | |
| <!-- START --> | |
| <div id="container"> | |
| <div id="loadingContainer"> | |
| <svg xmlns="http://www.w3.org/2000/svg" width="300" viewBox="0 0 300 300" enable-background="new 0 0 300 300" class="dfm-load"> | |
| <style type="text/css"> | |
| <![CDATA[ | |
| svg.dfm-load .c1, | |
| svg.dfm-load .c2, | |
| svg.dfm-load .c3 { | |
| -webkit-animation: dfmload 1s infinite ease; | |
| animation: dfmload 1s infinite ease; | |
| -webkit-transform-origin: center; | |
| transform-origin: center; | |
| } | |
| svg.dfm-load .c2 { | |
| -webkit-animation-delay: .2s; | |
| animation-delay: .2s; | |
| } | |
| svg.dfm-load .c3 { | |
| -webkit-animation-delay: .4s; | |
| animation-delay: .4s; | |
| } | |
| @-webkit-keyframes dfmload { | |
| 0% { | |
| -webkit-transform: rotate(0deg); | |
| transform: rotate(0deg); | |
| } | |
| 10% { | |
| opacity: .25; | |
| } | |
| 50% { | |
| -webkit-transform: rotate(360deg); | |
| transform: rotate(360deg); | |
| opacity: 1; | |
| } | |
| 100% { | |
| -webkit-transform: rotate(360deg); | |
| transform: rotate(360deg); | |
| } | |
| } | |
| @keyframes dfmload { | |
| 0% { | |
| -webkit-transform: rotate(0deg); | |
| transform: rotate(0deg); | |
| } | |
| 10% { | |
| opacity: .25; | |
| } | |
| 40% { | |
| -webkit-transform: rotate(360deg); | |
| transform: rotate(360deg); | |
| opacity: 1; | |
| } | |
| 100% { | |
| -webkit-transform: rotate(360deg); | |
| transform: rotate(360deg); | |
| } | |
| } | |
| ]]> | |
| </style> | |
| <g class="c3"> | |
| <path fill="#4d79ff" d="m206.672 101.133c2.957 4.104 2.957 9.339-.695 13.217-2.052 1.357-3.878 2.052-6.14 2.052-2.294 0-5.009-1.131-6.835-2.731-10.244-11.844-25.95-17.984-43.046-17.984-17.305 0-32.801 6.14-42.819 17.984-3.409 3.652-9.129 3.878-12.975.695-4.088-3.878-4.339-9.113-.695-13.217 13.67-15.027 33.949-24.14 56.489-24.14 22.088-.009 43.046 9.096 56.716 24.124z" /> | |
| <circle cx="150" cy="150" r="64.886" fill="none" /> | |
| </g> | |
| <g class="c2"> | |
| <path fill="#4d79ff" d="m149.948 64.235c-24.593 0-46.455 9.113-61.514 24.835-3.878 3.878-9.784 4.104-13.201.452-3.409-3.409-3.409-9.566 0-13.201 18.21-18.905 45.34-29.618 74.716-29.618 29.141 0 56.715 10.697 74.926 29.618 2.957 3.636 2.957 9.792-.444 13.201-2.052 2.052-4.339 2.731-6.617 2.731s-5.001-.695-6.593-3.183c-14.357-15.722-36.898-24.835-61.273-24.835z" /> | |
| <circle cx="150" cy="150" r="96.191" fill="none" /> | |
| </g> | |
| <g class="c1"> | |
| <path fill="#4d79ff" d="m60.658 64.461c-3.636-3.636-3.878-9.339-.226-12.975 20.707-22.783 54.203-35.758 89.509-35.758s67.865 12.991 89.743 35.758c3.636 3.652 3.175 9.339-.452 12.975-1.6 1.6-3.878 2.505-6.156 2.505-2.488 0-4.557-.905-6.609-2.731-18.226-19.358-46.229-30.054-76.517-30.054-30.087 0-58.525 10.697-76.525 30.054-3.202 3.644-9.124 3.644-12.767.226z" /> | |
| <circle cx="150" cy="150" r="125" fill="none" /> | |
| </g> | |
| </svg> | |
| </div> | |
| <div id="formsDiv" class="hidden"> | |
| <form id="loginForm" name="loginForm" action=""> | |
| <h2>LOGIN</h2> | |
| <label for="nameField"><strong>Username:</strong></label></br> | |
| <input type="text" id="nameField" class="conwidth" name="nameField" autocomplete="on" required> | |
| <div id="errorBoxName" class="errorBox hidden"></div> | |
| <p> | |
| <label for="passField"><strong>Password</strong> (8 characters minimum):</label></br> | |
| <input type="password" id="passField" class="conwidth" name="passField" autocomplete="on" minlength="8" required> | |
| <div id="errorBoxPass" class="errorBox hidden"></div> | |
| </p> | |
| <p> | |
| <input type="checkbox" id="stayloggedcheck" name="stayloggedcheck"> | |
| <label for="stayloggedcheck">I want to stay logged in</label> | |
| </p> | |
| <p> | |
| <div class="buttoncontainer"> | |
| <div id="loginProgressBox" class="progressBox hidden">Login in progress ...<img src="https://bzozoo.github.io/UserSystem/public/Frontends/img/load.webp" width=18px /></div> | |
| <input class="actionbuttons" type="button" id="submitButton" name="submitButton" value="LOGIN"> | |
| </div> | |
| </p> | |
| <div id="errorBoxCommon" class="errorBox hidden"></div> | |
| </form> | |
| <br> | |
| <hr> | |
| <form id="regForm" name="regForm" autocomplete="off" action=""> | |
| <h2>REGISTER</h2> | |
| <label for="regNameField"><strong>Username:</strong></label></br> | |
| <input type="text" id="regNameField" class="conwidth" name="regNameField" autocomplete="new-password" required> | |
| <div id="errorBoxRegName" class="errorBox hidden"></div> | |
| <p> | |
| <label for="regPassField"><strong>Password</strong> (8 characters minimum):</label></br> | |
| <input type="password" id="regPassField" class="conwidth" name="regPassField" autocomplete="new-password" minlength="8" required> | |
| <div id="errorBoxRegPass" class="errorBox hidden"></div> | |
| </p> | |
| <p> | |
| <label for="regConfirmPassField"><strong>Confirm Password</strong> (8 characters minimum):</label></br> | |
| <input type="password" id="regConfirmPassField" class="conwidth" name="regConfirmPassField" autocomplete="new-password" minlength="8" required> | |
| <div id="errorBoxRegConfirmPass" class="errorBox hidden"></div> | |
| </p> | |
| <p> | |
| <div class="buttoncontainer"> | |
| <p>* By pressing the registration button, you agree that <u>we will record your IP address</u> for security reasons. </p> | |
| <div id="regProgressBox" class="progressBox hidden">Registration in progress ...<img src="https://bzozoo.github.io/UserSystem/public/Frontends/img/load.webp" width=18px /></div> | |
| <input class="actionbuttons" type="button" id="regSubmitButton" name="regSubmitButton" value="REGISTER"> | |
| <div id="regSuccessBox" class="successBox hidden">Registration success! You can Log In! </div> | |
| <div id="errorBoxReg" class="errorBox hidden"></div> | |
| </div> | |
| </p> | |
| </form> | |
| </div> | |
| <div id="profileCOntainer" class="hidden"> | |
| <!-- USER NOT LOGGED IN --> | |
| </div> | |
| </div> | |
| <!-- Mobile devtools NOW DISABLED | |
| <script src="//cdn.jsdelivr.net/npm/eruda"></script> | |
| <script>eruda.init();</script> | |
| --> | |
| <!-- STOP --> | |
| <script src="dashboard.js"></script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let version = 'v23-dev'; | |
| console.log(version) | |
| //API Endpoints | |
| const loginEndpoint = "https://usersystem.mysqhost.tk/api/login"; | |
| const regEndpoint = "https://usersystem.mysqhost.tk/api/register"; | |
| const memberEndpointJWT = "https://usersystem.mysqhost.tk/api/user"; | |
| const memberEndpointSes = "https://usersystem.mysqhost.tk/api/userprofile"; | |
| const userScoreEndpoint = "https://usersystem.mysqhost.tk/api/userscore"; | |
| //constanes and variables | |
| const errorBoxes = document.querySelectorAll(".errorBox"); | |
| const successBoxes = document.querySelectorAll(".successBox"); | |
| const regSuccessBox = document.querySelector("#regSuccessBox"); | |
| const inputBoxes = document.querySelectorAll("#container input"); | |
| const defaultAvatar = 'https://raw.githubusercontent.com/bzozoo/UserSystem/main/public/Frontends/img/avatar.png'; | |
| let storedConnectionResponse; | |
| let storedLoginDatas; //Used in: loginProcess() | |
| let storedRegisterDatas; //Used in: registerProcess() | |
| let getAutHeader; | |
| let identifier; | |
| let loadCounter = 0; | |
| ///INITIALIZATION | |
| init(); | |
| function init() { | |
| checkIdentifiers() | |
| if (checkUserCookiesExist()) { | |
| userLoggedIn(); | |
| } else { | |
| userLogOut(); | |
| } | |
| } | |
| ///INITIALIZATION END | |
| // Connections | |
| //Main connection | |
| async function connection(url, options) { | |
| const response = await fetch(url, options); | |
| storedConnectionResponse = response | |
| console.log('Actual response.status changed to ', storedConnectionResponse.status) | |
| let getAutHeaderAll = response.headers.get("authorization"); | |
| getAutHeader = getAutHeaderAll | |
| ? getAutHeaderAll.slice(7, getAutHeaderAll.length) | |
| : false; | |
| let responsedjson = await response.json(); | |
| return responsedjson; | |
| } | |
| async function connectForLogin() { | |
| var formData = new FormData(); | |
| formData.append("nameField", nameField.value); | |
| formData.append("passField", passField.value); | |
| let options = { | |
| method: "POST", | |
| credentials: "include", | |
| mode: "cors", | |
| body: formData | |
| }; | |
| return await connection(loginEndpoint, options); | |
| } | |
| async function connectForRegister() { | |
| var formData = new FormData(); | |
| formData.append("reguser", regNameField.value); | |
| formData.append("regpwd", regPassField.value); | |
| let options = { | |
| method: "POST", | |
| credentials: "include", | |
| mode: "cors", | |
| body: formData | |
| }; | |
| return await connection(regEndpoint, options); | |
| } | |
| async function connectForUserDatas() { | |
| checkIdentifiers() | |
| let postKEY = (identifier.Mode === 'UTOK')? 'jwtKEY' : 'sessid' | |
| let endpointForMember = (identifier.Mode === 'UTOK')? memberEndpointJWT : memberEndpointSes | |
| console.log('Identifier methods :') | |
| console.log(identifier.Type, postKEY, endpointForMember) | |
| let formData = new FormData(); | |
| formData.append(postKEY, identifier.Value); | |
| let options = { | |
| method: "POST", | |
| body: formData, | |
| credentials: "include", | |
| mode: "cors", | |
| cache: "no-cache" | |
| }; | |
| return await connection(endpointForMember, options); | |
| } | |
| // Connections END | |
| //PROCESSES | |
| async function loginProcess() { | |
| let checkedLoginDatas = checkLoginInputDatas(); | |
| if (checkedLoginDatas) { | |
| submitButton.disabled = true; | |
| loginProgressBox.classList.remove("hidden"); | |
| try { | |
| storedLoginDatas = await connectForLogin(); | |
| } catch (error) { | |
| console.error("Catch error" + error); | |
| storedLoginDatas = false; | |
| submitButton.disabled = false; | |
| loginProgressBox.classList.add("hidden"); | |
| errorBoxCommon.innerHTML = "Server connection error"; | |
| errorBoxCommon.classList.remove("hidden"); | |
| } | |
| console.log(storedLoginDatas); | |
| if (storedLoginDatas) { | |
| console.log("We got login datas.."); | |
| submitButton.disabled = false; | |
| loginProgressBox.classList.add("hidden"); | |
| if (storedLoginDatas.Login === "Failed" || storedConnectionResponse.status === 401) { | |
| console.log("Login failed"); | |
| showLoginFail(); | |
| } | |
| if (storedLoginDatas.Login === "Success" || storedConnectionResponse.status === 200) { | |
| console.log("Login Success"); | |
| createUserCookies(); | |
| removeAllMessages() | |
| init(); | |
| } | |
| } | |
| } | |
| } | |
| async function registerProcess() { | |
| console.log("Register process function..."); | |
| let checkRegData = checkRegInputDatas(); | |
| if (checkRegData) { | |
| console.log("Register input datas are okey..."); | |
| regSubmitButton.disabled = true; | |
| regProgressBox.classList.remove("hidden"); | |
| try { | |
| storedRegisterDatas = await connectForRegister(); | |
| } catch (error) { | |
| console.error("Catch error" + error); | |
| regSubmitButton.disabled = false; | |
| storedRegisterDatas = false; | |
| regProgressBox.classList.add("hidden"); | |
| errorBoxReg.innerHTML = "Server connection error"; | |
| errorBoxReg.classList.remove("hidden"); | |
| } | |
| if (storedRegisterDatas) { | |
| console.log("We got reg responses: "); | |
| console.log(storedRegisterDatas) | |
| regSubmitButton.disabled = false; | |
| regProgressBox.classList.add("hidden"); | |
| regFormMessages(storedRegisterDatas); | |
| } | |
| } | |
| } | |
| //PROCESSES END | |
| // CHECKERS | |
| //Login input checker and error message render. Used in: registerProcess() | |
| function checkLoginInputDatas() { | |
| if (nameField.value === "") { | |
| errorBoxName.innerHTML = "Name is empty"; | |
| errorBoxName.classList.remove("hidden"); | |
| } | |
| if (passField.value === "") { | |
| errorBoxPass.innerHTML = "Password is empty"; | |
| errorBoxPass.classList.remove("hidden"); | |
| } | |
| if (passField.value.length < 8) { | |
| errorBoxPass.innerHTML = "The password must be 8 characters long "; | |
| errorBoxPass.classList.remove("hidden"); | |
| } | |
| if(passField.value != "" && nameField.value != "" && passField.value.length >= 8){ | |
| return true; | |
| } | |
| } | |
| function checkRegInputDatas() { | |
| if (regPassField.value.length < 8) { | |
| errorBoxRegPass.innerHTML = "The register password must be 8 characters long"; | |
| errorBoxRegPass.classList.remove("hidden"); | |
| } | |
| if (regPassField.value != regConfirmPassField.value) { | |
| errorBoxRegConfirmPass.innerHTML = "The passwords do not match "; | |
| errorBoxRegConfirmPass.classList.remove("hidden"); | |
| } | |
| if (regNameField.value === "") { | |
| errorBoxRegName.innerHTML = "Name field is empty"; | |
| errorBoxRegName.classList.remove("hidden"); | |
| } | |
| if (regPassField.value === "") { | |
| errorBoxRegPass.innerHTML = "Password field is empty"; | |
| errorBoxRegPass.classList.remove("hidden"); | |
| } | |
| if (regConfirmPassField.value === "") { | |
| errorBoxRegConfirmPass.innerHTML = "Confirm Password field is empty"; | |
| errorBoxRegConfirmPass.classList.remove("hidden"); | |
| } | |
| if ( | |
| regPassField.value === regConfirmPassField.value && | |
| regNameField.value != "" && | |
| regPassField.value != "" && | |
| regPassField.value.length >= 8 | |
| ) { | |
| return true; | |
| } | |
| } | |
| function checkUserCookiesExist() { | |
| if (((document.cookie.indexOf("una=") === -1 || getCookie('una') === undefined) && sessionStorage.getItem('una') === null && localStorage.getItem('una') === null) || | |
| !checkIdentifiers() | |
| ) { | |
| return false; | |
| } else { | |
| console.log("User cookies exist."); | |
| return true; | |
| } | |
| } | |
| //Check and set identifier | |
| function checkIdentifiers(){ | |
| identifier = false | |
| if(document.cookie.indexOf("UTOK=") >= 10 || getCookie('UTOK') != undefined){ | |
| identifier = {'Type':'Cookie', 'Mode':'UTOK', 'Value': getCookie('UTOK')} | |
| } else if((localStorage.getItem("UTOK") != null)){ | |
| identifier = {'Type':'localStorage', 'Mode':'UTOK', 'Value': localStorage.getItem("UTOK")} | |
| } else if((sessionStorage.getItem("UTOK") != null)){ | |
| identifier = {'Type':'sessionStorage', 'Mode':'UTOK', 'Value': sessionStorage.getItem("UTOK")} | |
| } else if(document.cookie.indexOf("ses=") >= 10 || getCookie('ses') != undefined){ | |
| identifier = {'Type':'Cookie', 'Mode':'ses', 'Value': getCookie('ses')} | |
| } else if((localStorage.getItem("ses") != null)){ | |
| identifier = {'Type':'localStorage', 'Mode':'ses', 'Value': localStorage.getItem("ses")} | |
| } else if((sessionStorage.getItem("ses") != null)){ | |
| identifier = {'Type':'sessionStorage', 'Mode':'ses', 'Value': sessionStorage.getItem("ses")} | |
| } | |
| return identifier | |
| } | |
| // CHECKERS END | |
| //RENDER helpers | |
| //Used in: userLoggedIn(), init() | |
| function userLogOut() { | |
| console.log(identifier) | |
| profileCOntainer.classList.add("hidden"); | |
| loadingContainer.classList.add("hidden"); | |
| profileCOntainer.innerHTML = ""; | |
| deleteUserCookies(); | |
| formsDiv.classList.remove("hidden"); | |
| if(loadCounter != 1){console.log("User logged out ...")} | |
| } | |
| //Used in: loginProcess(), init() | |
| async function userLoggedIn() { | |
| let profile = await connectForUserDatas(); | |
| console.log("User Profile Datas : "); | |
| console.log(profile); | |
| if (profile.User === "DoesnotExist" && profile.UserName === "Failed") { | |
| errorBoxCommon.innerHTML = "User session expired! Login again"; | |
| errorBoxCommon.classList.remove("hidden"); | |
| profile = false; | |
| userLogOut(); | |
| return; | |
| } | |
| if (profile) { | |
| formsDiv.classList.add("hidden"); | |
| loadingContainer.classList.add("hidden"); | |
| regSuccessBox.classList.add("hidden"); | |
| profileCOntainer.innerHTML = ` | |
| <h1>WELCOME HERE <red style="color: red"><b> ${profile.UserName} </b></red> !</h1> | |
| <p><img src="${(profile.UserAvatar != null || profile.UserAvatar === 'undefined')?profile.UserAvatar:defaultAvatar}" title="${profile.UserName}'s avatar" alt="avatar" width="250" height="250"/></p> | |
| <p><b>Registed At :</b> ${profile.UserRegistredAt.replace(/-/g, ". ").splice(12, '.')}</p><!-- Splice helper!! --> | |
| <p><b>Logined At :</b> ${new Date(profile.CreatedTimeStamp * 1000).toLocaleString()}</p> | |
| <p><b>Login will be expired At :</b> ${new Date(profile.ExpiredTimeStamp * 1000).toLocaleString()}</p> | |
| <p><b>User Score :</b> ${profile.UserScore}</p> | |
| <p><a target="_blank" href="https://codepen.io/bzozoo/full/VwmKOVj"> | |
| <button class="linkbuttons">SCORE TABLE</button></a></p> | |
| <p><div class="buttoncontainer"> | |
| <input class="actionbuttons" id="logoutButton" name="logoutButton" type="button" value="LOGOUT" onclick="userLogOut()"> | |
| </div> | |
| </p>`; | |
| profileCOntainer.classList.remove("hidden"); | |
| console.log('Profile Container was generated') | |
| } | |
| } | |
| function showLoginFail() { | |
| errorBoxCommon.innerHTML = "Wrong username or password"; | |
| errorBoxCommon.classList.remove("hidden"); | |
| } | |
| function removeAllMessages() { | |
| errorBoxes.forEach(function (errorBox) { | |
| errorBox.innerHTML = ""; | |
| errorBox.classList.add("hidden"); | |
| }); | |
| successBoxes.forEach(function (successBox) { | |
| successBox.classList.add("hidden"); | |
| }); | |
| console.log('All error messages was deleted') | |
| } | |
| //Userd in: registerProcess() | |
| function regFormMessages(storedRegDatas){ | |
| if(storedRegDatas){ | |
| if(storedConnectionResponse.status === 409 || storedRegDatas.Registration === "Failed"){ | |
| let userexistMessage = (storedRegDatas.UserExisted === "YES")? 'User already exist!' : 'Something wrong!'; | |
| let regErrorMessage = 'Registration failed!' | |
| errorBoxReg.innerHTML = userexistMessage + ' ' + regErrorMessage | |
| errorBoxReg.classList.remove("hidden"); | |
| regProgressBox.classList.add("hidden"); | |
| regSuccessBox.classList.add("hidden"); | |
| } | |
| if (storedConnectionResponse.status === 201 && storedRegDatas.UserExisted === "NO" && storedRegDatas.Registration === "Success"){ | |
| console.log("Registration success!"); | |
| regSuccessBox.innerHTML = 'Registration Success! You can login!' | |
| errorBoxReg.classList.add("hidden"); | |
| regSuccessBox.classList.remove("hidden"); | |
| regProgressBox.classList.add("hidden"); | |
| } | |
| } | |
| } | |
| //RENDER helpers END | |
| //Cookie handlers | |
| function createUserCookies() { | |
| let stayloggedcheck = document.querySelector("#stayloggedcheck"); | |
| var now = new Date(); | |
| var time = now.getTime(); | |
| var expireTime = time + 30 * 24 * 60 * 60 *1000; | |
| now.setTime(expireTime); | |
| let expiration = stayloggedcheck.checked | |
| ? `expires=${now.toUTCString()};` | |
| : ""; | |
| console.log(`Cookie expirations : ${expiration}`); | |
| //Create cookies | |
| document.cookie = `una=${storedLoginDatas.UserName}; ${expiration} path=/; SameSite=None; Secure`; | |
| document.cookie = `UTOK=${storedLoginDatas.UTOK}; ${expiration} path=/; SameSite=None; Secure`; | |
| document.cookie = `ses=${storedLoginDatas.SessionId}; ${expiration} path=/; SameSite=None; Secure`; | |
| if(stayloggedcheck.checked){ | |
| document.cookie = `sescrea=${time}; ${expiration} path=/; SameSite=None; Secure`; | |
| document.cookie = `sesexp=${expiration}; ${expiration} path=/; SameSite=None; Secure`; | |
| } | |
| //Save to sessionStorage | |
| if(!stayloggedcheck.checked){ | |
| sessionStorage.setItem('una', storedLoginDatas.UserName) | |
| sessionStorage.setItem('UTOK', storedLoginDatas.UTOK) | |
| sessionStorage.setItem('ses', storedLoginDatas.SessionId) | |
| sessionStorage.setItem('ses-exp', expireTime) | |
| } | |
| //Save to localStorage | |
| if(stayloggedcheck.checked){ | |
| localStorage.setItem('una', storedLoginDatas.UserName) | |
| localStorage.setItem('UTOK', storedLoginDatas.UTOK) | |
| localStorage.setItem('ses', storedLoginDatas.SessionId) | |
| localStorage.setItem('ses-crea', time) | |
| localStorage.setItem('ses-exp', expireTime) | |
| } | |
| } | |
| //Used in: userLogOut() | |
| function deleteUserCookies() { | |
| //Cookies | |
| document.cookie = `PHPSESSID=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT; SameSite=None; Secure`; | |
| document.cookie = `una=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT; SameSite=None; Secure`; | |
| document.cookie = `UTOK=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT; SameSite=None; Secure`; | |
| document.cookie = `ses=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT; SameSite=None; Secure`; | |
| //sessionStorage-s | |
| sessionStorage.removeItem('una') | |
| sessionStorage.removeItem('UTOK') | |
| sessionStorage.removeItem('ses') | |
| //localStorage -s | |
| localStorage.removeItem('una') | |
| localStorage.removeItem('UTOK') | |
| localStorage.removeItem('ses') | |
| localStorage.removeItem('ses-crea') | |
| localStorage.removeItem('ses-exp') | |
| //Identifier init | |
| identifier = false | |
| loadCounter += 1 | |
| if(loadCounter != 1){console.log('All user cookies was deleted!')} | |
| } | |
| function getCookie(name) { | |
| const value = `; ${document.cookie}`; | |
| const parts = value.split(`; ${name}=`); | |
| if (parts.length === 2) return parts.pop().split(";").shift(); | |
| } | |
| //Cookie handlers END | |
| //GENERAL helpers | |
| // String splice helper | |
| if (String.prototype.splice === undefined) { | |
| /** | |
| * Splices text within a string. | |
| * @param {int} offset The position to insert the text at (before) | |
| * @param {string} text The text to insert | |
| * @param {int} [removeCount=0] An optional number of characters to overwrite | |
| * @returns {string} A modified string containing the spliced text. | |
| */ | |
| String.prototype.splice = function(offset, text, removeCount=0) { | |
| let calculatedOffset = offset < 0 ? this.length + offset : offset; | |
| return this.substring(0, calculatedOffset) + | |
| text + this.substring(calculatedOffset + removeCount); | |
| }; | |
| } | |
| function elementChildren(element) { | |
| var childNodes = element.childNodes, | |
| children = [], | |
| i = childNodes.length; | |
| while (i--) { | |
| if (childNodes[i].nodeType == 1) { | |
| children.unshift(childNodes[i]); | |
| } | |
| } | |
| return children; | |
| } | |
| //GENERAL helpers END | |
| // TEST functions | |
| function reqListener() { | |
| console.log(this.responseText); | |
| } | |
| function getMemberX() { | |
| var oReq = new XMLHttpRequest(); | |
| oReq.addEventListener("load", reqListener); | |
| oReq.open("GET", memberEndpoint); | |
| oReq.withCredentials = true; | |
| oReq.send(); | |
| } | |
| function loadXMLDoc(theURL) { | |
| if (window.XMLHttpRequest) { | |
| // code for IE7+, Firefox, Chrome, Opera, Safari, SeaMonkey | |
| xmlhttp = new XMLHttpRequest(); | |
| } else { | |
| // code for IE6, IE5 | |
| xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); | |
| } | |
| xmlhttp.onreadystatechange = function () { | |
| if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { | |
| alert(xmlhttp.responseText); | |
| } | |
| }; | |
| xmlhttp.open("GET", theURL, false); | |
| xmlhttp.send(); | |
| } | |
| // TEST functions END | |
| //EVENT listeners | |
| inputBoxes.forEach(function (inputBox) { | |
| inputBox.addEventListener("input", removeAllMessages); | |
| }); | |
| submitButton.addEventListener("click", loginProcess); | |
| regSubmitButton.addEventListener("click", registerProcess); | |
| //EVENT listeners END |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <html> | |
| <head> | |
| <title>SCDORE TABLE - Fetch API</title> | |
| <style> | |
| #scoreTable { | |
| font-family: arial, sans-serif; | |
| font-size: 20px; | |
| border-collapse: collapse; | |
| width: 100%; | |
| } | |
| #scoreTable td, #scoreTable th { | |
| border: 1px solid #dddddd; | |
| text-align: left; | |
| padding: 8px; | |
| } | |
| #scoreTable tr:nth-child(odd) { | |
| background: #ccffcc; | |
| } | |
| #scoreTable tr:nth-child(even) { | |
| background-color: #e6ffe6; | |
| } | |
| #scoreTable th { | |
| padding-top: 12px; | |
| padding-bottom: 12px; | |
| text-align: left; | |
| background-color: #4CAF50; | |
| color: white; | |
| cursor: pointer; | |
| } | |
| #scoreTable tr:hover {background-color: #ddd;} | |
| </style> | |
| </head> | |
| <body> | |
| <table id="scoreTable"> | |
| <tbody> | |
| <!-- Scores --> | |
| <tr> | |
| <th> Name </th> | |
| <th> Score </th> | |
| </tr> | |
| <!-- Js added scores --> | |
| </tbody> | |
| </table> | |
| <script> | |
| const scoreTable = document.querySelector("#scoreTable"); | |
| const url = "https://usersystem.mysqhost.tk/api/userscore"; | |
| let actualUser = "Bzozoo"; | |
| let storedDatas; | |
| let dataByScore; | |
| function init(url){ | |
| console.log(`Init script from : ${url}`) | |
| fetch(url, { method: "GET", mode: "cors", cache: "no-cache" }) | |
| .then((response) => response.json()) | |
| .then((data) => getData(data)) | |
| .catch((error) => serverError(error)) | |
| } | |
| init(url) | |
| function serverError(error){ | |
| console.log(error) | |
| printErrorToHTML(scoreTable.tBodies[0], error) | |
| } | |
| function printErrorToHTML(where, what){ | |
| removeErrorRow() | |
| where.innerHTML += ` | |
| <tr id="errorRow"> | |
| <td> SERVER CONNECTION ERROR </td> | |
| <td> ${what} <br><button onclick="init('${url}')">Please refresh page</button></td> | |
| </tr>`; | |
| } | |
| function removeErrorRow(){ | |
| let errorRow = document.querySelector("#errorRow"); | |
| if(errorRow){ errorRow.remove()} | |
| } | |
| function getData(data) { | |
| storedDatas = data; | |
| console.log(storedDatas); | |
| dataByScore = storedDatas.slice(0); | |
| dataByScore.sort(function (a, b) { | |
| return b.UserScore - a.UserScore; | |
| }); | |
| console.log("Data by Score"); | |
| console.log(dataByScore); | |
| printDataToHTML(scoreTable.tBodies[0], dataByScore); | |
| } | |
| function printDataToHTML(where, what) { | |
| removeErrorRow() | |
| what.forEach(function (element) { | |
| where.innerHTML += ` | |
| <tr> | |
| <td> ${element.UserName} </td> | |
| <td> ${element.UserScore} </td> | |
| </tr>`; | |
| }); | |
| sortTable() | |
| } | |
| function getUserScoreByName(name) { | |
| let z; | |
| storedDatas.forEach(function (element) { | |
| if (element.UserName === name) { | |
| z = element.UserScore; | |
| } | |
| }); | |
| return z; | |
| } | |
| function sortTable() { | |
| const getCellValue = (tr, idx) => | |
| tr.children[idx].innerText || tr.children[idx].textContent; | |
| const comparer = (idx, asc) => (a, b) => | |
| ((v1, v2) => | |
| v1 !== "" && v2 !== "" && !isNaN(v1) && !isNaN(v2) | |
| ? v1 - v2 | |
| : v1.toString().localeCompare(v2))( | |
| getCellValue(asc ? a : b, idx), | |
| getCellValue(asc ? b : a, idx) | |
| ); | |
| // do the work... | |
| document.querySelectorAll("th").forEach((th) => | |
| th.addEventListener("click", () => { | |
| const table = th.closest("table"); | |
| Array.from(table.querySelectorAll("tr:nth-child(n+2)")) | |
| .sort( | |
| comparer( | |
| Array.from(th.parentNode.children).indexOf(th), | |
| (this.asc = !this.asc) | |
| ) | |
| ) | |
| .forEach((tr) => table.appendChild(tr)); | |
| }) | |
| ); | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment