From c450950cb008ddc2ff4376f5d1792228804760b1 Mon Sep 17 00:00:00 2001 From: Gabriel Copat <copatg@cardiff.ac.uk> Date: Sun, 3 Dec 2023 16:26:05 +0000 Subject: [PATCH] Added client-side validation for log-in --- src/main/resources/static/css/userProfile.css | 55 ++++++++++++++++--- src/main/resources/static/scripts/login.js | 49 +++++++++++++++++ .../resources/templates/rewards/login.html | 22 ++++++-- .../templates/rewards/userProfile.html | 10 +--- 4 files changed, 117 insertions(+), 19 deletions(-) create mode 100644 src/main/resources/static/scripts/login.js diff --git a/src/main/resources/static/css/userProfile.css b/src/main/resources/static/css/userProfile.css index 7047dc43..3cc42919 100644 --- a/src/main/resources/static/css/userProfile.css +++ b/src/main/resources/static/css/userProfile.css @@ -39,8 +39,11 @@ } body { - background: linear-gradient(135deg, #d295e9, #53166a); + background: linear-gradient(135deg, #f7e8fd, #9914d1); height: 100svh; + display: flex; + flex-direction: column; + justify-content: space-evenly; } main { background: linear-gradient(to bottom, #1e1e1e 10%, darkgoldenrod 50%, #1e1e1e 90%); @@ -52,6 +55,8 @@ main { margin-top: 6em; padding-inline: 1vw; box-shadow: rgba(0, 0, 0, 0.7) 0 0.5svh max(1vw, 1em); + + } .userInfo { display: flex; @@ -259,17 +264,16 @@ header .footerButton:hover { margin-block: 5svh; display: flex; text-align: center; - justify-content: left; - background: #c45cef; + justify-content: center; + background: rgba(196, 92, 239, 0.75); padding: 2em; - - width: auto; - height: auto; + flex: 0 0; border-radius: 1vw; box-shadow: rgba(0, 0, 0, 0.7) 0 0.5svh max(1vw, 1em); & h2 { - margin-left: 1vw; + margin-left: 0; margin-right: auto; + margin-bottom: 0.5em; } & form{ margin-block: auto; @@ -300,6 +304,8 @@ header .footerButton:hover { width: 40vw; border-radius: 0.2em; padding-inline: 0.4em; + border: transparent solid 0.1em; + margin-bottom: 1em; } & button { font-size: 1em; @@ -318,4 +324,39 @@ header .footerButton:hover { background-color: var(--accent-border); border: 0.1em solid var(--accent-colour); } +} +.label { + position: relative; +} +.invalid-tooltip { + color: red; + width: fit-content; + opacity: 0; + font-size: 0.6em; + text-shadow: red 0 0.2em 1em; + transition: 0.3s ease-in-out 1ms; + padding:0.1em; + position: absolute; + right: 0.2em; + bottom: 0.2em; + height: fit-content; +} +.invalid-field { + box-shadow: red 0 0 1em; + transition: 0.3s ease-in-out 1ms; +} +.valid-field { + box-shadow: #40ff00 0 0 1em; + border: #40ff00 solid 0.1em; + transition: 0.3s ease-in-out 1ms; +} + +#invalidLogin { + color: red; + text-shadow: black 0 0.1em 0.2em; + width: auto; + height: auto; + font-size: 0.6em; + opacity: 0; + transition: 0.5s ease-in-out 1ms; } \ No newline at end of file diff --git a/src/main/resources/static/scripts/login.js b/src/main/resources/static/scripts/login.js new file mode 100644 index 00000000..929b8b61 --- /dev/null +++ b/src/main/resources/static/scripts/login.js @@ -0,0 +1,49 @@ +let username = document.forms["loginForm"]["username"]; +let password = document.forms["loginForm"]["password"]; +let pattern = new RegExp("^[a-z0-9_-]{3,15}$"); + +username.addEventListener("input", validateUsername) +password.addEventListener("input", validatePassword) + +function validateUsername() { + if (!(username.value === "") && pattern.test(username.value)){ + username.classList.remove("invalid-field"); + username.classList.add("valid-field"); + document.getElementById(username.name+"Invalid").style.opacity = 0; + username.style.borderColor = "green"; + return true; + } else if( ! (username.classList.contains("invalid-field") ) ){ + username.classList.add("invalid-field"); + username.classList.remove("valid-field"); + document.getElementById(username.name+"Invalid").style.opacity = 1; + username.style.borderColor = "red"; + } + return false; +} +function validatePassword(){ + if (password.value === "") { + password.classList.add("invalid-field"); + password.classList.remove("valid-field"); + document.getElementById(password.name+"Invalid").style.opacity = 1; + password.style.borderColor = "red"; + return false; + } else if( ! (password.classList.contains("valid-field") ) ) { + password.classList.remove("invalid-field"); + password.classList.add("valid-field"); + document.getElementById(password.name+"Invalid").style.opacity = 0; + password.style.borderColor = "green"; + } + return true; +} + +function validateForm(){ + if (validateUsername() & validatePassword()) { //Using just & so it checks both, even if the first is false (it applies the style) + console.log("VALID"); + return false; + } else { + console.log("Invalid"); + document.getElementById("invalidLogin").style.opacity = 1; + return false; + } + //TODO SERVER SIDE VALIDATION AND CHECK AGAINST USERS DB TABLE +} \ No newline at end of file diff --git a/src/main/resources/templates/rewards/login.html b/src/main/resources/templates/rewards/login.html index ed1791fd..9c7aea8b 100644 --- a/src/main/resources/templates/rewards/login.html +++ b/src/main/resources/templates/rewards/login.html @@ -4,6 +4,7 @@ <meta charset="UTF-8"> <title>User Log In</title> <link rel="stylesheet" th:href="@{/css/userProfile.css}"> + </head> <body> @@ -18,12 +19,20 @@ </header> <main class="solidBg"> <div class="loginWrapper"> - <form action="/login" method="post"> + <form action="" onsubmit="return validateForm()" method="post" name="loginForm"> <h2>Log In</h2> - <label for="username"><b>Username</b><br></label> - <input type="text" name="username" id="username" placeholder="Enter Username"> - <label for="password"><b>Password</b><a>Forgot Password</a><br></label> - <input type="password" id="password" name="password"> + <div class="label"> + <label for="username"><b>Username</b><br></label> + <div id="usernameInvalid" class="invalid-tooltip">Please fill out this field.</div> + </div> + <input type="text" name="username" id="username" placeholder="Enter Username" title="Username Input"> + + <div class="label"> + <label for="password"><b>Password</b><br></label> + <div id="passwordInvalid" class="invalid-tooltip">Please fill out this field.</div> + </div> + <input type="password" id="password" name="password"> + <div id="invalidLogin">Username and/or Password incorrect. Please try again.</div> <button type="submit"><b>Log In</b></button> </form> @@ -32,5 +41,8 @@ </main> + +<script type="text/javascript" th:src="@{scripts/login.js}"></script> + </body> </html> \ No newline at end of file diff --git a/src/main/resources/templates/rewards/userProfile.html b/src/main/resources/templates/rewards/userProfile.html index cecdb406..dbf4b0e0 100644 --- a/src/main/resources/templates/rewards/userProfile.html +++ b/src/main/resources/templates/rewards/userProfile.html @@ -14,7 +14,7 @@ <li class="footerButton"><b>About</b></li> <li class="footerButton"><b>Map</b></li> <li class="footerButton"><b>Facilities</b></li> - <li class="footerButton"><b>Search</b></li> + <li class="footerButton"><b>Log In</b></li> </ul> </header> @@ -37,7 +37,7 @@ <!-- </div>--> <!-- </article>--> <article class="dragonProgression"> - <h1>The Dragon Trail</h1> + <h1>The Dragon's Tale</h1> <div class="dragonContainer"> <div class="dragonFill" th:style="'width:'+ ${user.getDragonProgress()} + '%;'"> <img th:src="@{/images/rewards/dragonFilled.png}" @@ -70,8 +70,4 @@ <script> </script> </body> -</html> - -<!--TODO finished doing the tooltips, need to add some more changes to them for sure - TODO afterwards probably need to implement thymeleaf so it shows badges based on the list - TODO implement some placeholder pictures as well for the badges and for the stickers --> \ No newline at end of file +</html> \ No newline at end of file -- GitLab