Add files via upload

This commit is contained in:
Jonas_Jones 2021-11-23 23:32:05 +01:00 committed by GitHub
parent 75684c5f91
commit 4a1ac1b789
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 338 additions and 1 deletions

9
login/README.md Normal file
View file

@ -0,0 +1,9 @@
# Vanilla JS Login
## Authentication and Validation
In this video, we will create a form validator for a simple login page using HTML, SASS, and Vanilla JavaScript. Basically, we use JS to create classes that will validate the login variables based on our needs then we will store information in the browser for authentication.
I do not use Bootstrap, jQuery, or any other frameworks. This method can be used on local browsers, web apps, and even on your server since it is all front-end code.
View tutorial: https://youtu.be/Rrbwrk79WTw

87
login/css/style.css Normal file
View file

@ -0,0 +1,87 @@
@import url("https://fonts.googleapis.com/css2?family=Open+Sans&display=swap");
* {
box-sizing: border-box;
}
body {
font-family: "Open Sans", sans-serif;
background-color: #0084ff;
font-size: 16px;
}
h1,
h2,
h3,
h4,
h5,
h6 {
padding: 0;
margin: 0;
}
.container {
max-width: 98vw;
margin: 0 auto;
padding: 1rem;
background-color: #fff;
}
.text-center {
text-align: center;
}
.login .container {
max-width: 460px;
margin: 3rem auto;
padding: 2rem;
border: 1px solid #ddd;
border-radius: 0.25rem;
background-color: #fff;
}
.input {
appearance: none;
display: block;
width: 100%;
color: #333;
border: 1px solid rbg(180, 180, 180);
background-color: white;
padding: 1rem;
border-radius: 0.25rem;
}
.input.input-error {
border: 1px solid red;
}
.input.input-error:focus {
border: 1px solid red;
}
.input:focus {
outline: none;
border: 1px solid #0084ff;
background-clip: padding-box;
}
.error-message {
font-size: 0.85rem;
color: red;
}
.button {
background-color: #0084ff;
padding: 1rem;
border: none;
color: #fff;
font-weight: bold;
display: block;
width: 100%;
text-align: center;
cursor: pointer;
font-size: 1rem;
}
.button:hover {
filter: brightness(110%);
}

1
login/css/style.min.css vendored Normal file
View file

@ -0,0 +1 @@
@import url("https://fonts.googleapis.com/css2?family=Open+Sans&display=swap");*{box-sizing:border-box}body{font-family:"Open Sans", sans-serif;background-color:#0084ff;font-size:16px}h1,h2,h3,h4,h5,h6{padding:0;margin:0}.container{max-width:98vw;margin:0 auto;padding:1rem;background-color:#fff}.text-center{text-align:center}.login .container{max-width:460px;margin:3rem auto;padding:2rem;border:1px solid #ddd;border-radius:0.25rem;background-color:#fff}.input{appearance:none;display:block;width:100%;color:#333;border:1px solid rbg(180, 180, 180);background-color:white;padding:1rem;border-radius:0.25rem}.input.input-error{border:1px solid red}.input.input-error:focus{border:1px solid red}.input:focus{outline:none;border:1px solid #0084ff;background-clip:padding-box}.error-message{font-size:0.85rem;color:red}.button{background-color:#0084ff;padding:1rem;border:none;color:#fff;font-weight:bold;display:block;width:100%;text-align:center;cursor:pointer;font-size:1rem}.button:hover{filter:brightness(110%)}

18
login/dashboard.html Normal file
View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard</title>
<link rel="stylesheet" href="/css/style.min.css">
<script defer src="/js/auth.js"></script>
<script defer src="/init.js"></script>
</head>
<body>
<div class="container">
<h1 class="text-center">Welcome to the Dashboard</h1>
<p class="text-center"><a href="#" class="logout">Log Out</a></p>
</div>
</body>
</html>

View file

@ -1 +1,32 @@
COMING SOON...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<link rel="stylesheet" href="/css/style.min.css">
<script defer src="/js/login.js"></script>
</head>
<body class="login">
<div class="container">
<h2 class="text-center">Login</h2>
<br>
<form action="/dashboard.html" class="loginForm">
<div class="input-group">
<label for="username" class="label">Username</label>
<input type="text" id="username" class="input">
<span class="error-message"></span>
</div>
<br>
<div class="input-group">
<label for="password" class="label">Password</label>
<input type="password" id="password" class="input">
<span class="error-message"></span>
</div>
<br>
<button class="button" type="submit">Login</button>
</form>
</div>
</body>
</html>

5
login/init.js Normal file
View file

@ -0,0 +1,5 @@
const auth = new Auth();
document.querySelector(".logout").addEventListener("click", (e) => {
auth.logOut();
});

20
login/js/auth.js Normal file
View file

@ -0,0 +1,20 @@
class Auth {
constructor() {
document.querySelector("body").style.display = "none";
const auth = localStorage.getItem("auth");
this.validateAuth(auth);
}
validateAuth(auth) {
if (auth != 1) {
window.location.replace("/");
} else {
document.querySelector("body").style.display = "block";
}
}
logOut() {
localStorage.removeItem("auth");
window.location.replace("/");
}
}

77
login/js/login.js Normal file
View file

@ -0,0 +1,77 @@
class Login {
constructor(form, fields) {
this.form = form;
this.fields = fields;
this.validateonSubmit();
}
validateonSubmit() {
let self = this;
this.form.addEventListener("submit", (e) => {
e.preventDefault();
var error = 0;
self.fields.forEach((field) => {
const input = document.querySelector(`#${field}`);
if (self.validateFields(input) == false) {
error++;
}
});
if (error == 0) {
//do login api here
localStorage.setItem("auth", 1);
this.form.submit();
}
});
}
validateFields(field) {
if (field.value.trim() === "") {
this.setStatus(
field,
`${field.previousElementSibling.innerText} cannot be blank`,
"error"
);
return false;
} else {
if (field.type == "password") {
if (field.value.length < 8) {
this.setStatus(
field,
`${field.previousElementSibling.innerText} must be at least 8 characters`,
"error"
);
return false;
} else {
this.setStatus(field, null, "success");
return true;
}
} else {
this.setStatus(field, null, "success");
return true;
}
}
}
setStatus(field, message, status) {
const errorMessage = field.parentElement.querySelector(".error-message");
if (status == "success") {
if (errorMessage) {
errorMessage.innerText = "";
}
field.classList.remove("input-error");
}
if (status == "error") {
errorMessage.innerText = message;
field.classList.add("input-error");
}
}
}
const form = document.querySelector(".loginForm");
if (form) {
const fields = ["username", "password"];
const validator = new Login(form, fields);
}

89
login/sass/style.scss Normal file
View file

@ -0,0 +1,89 @@
$primary: rgb(0, 132, 255);
$error: red;
@import url("https://fonts.googleapis.com/css2?family=Open+Sans&display=swap");
* {
box-sizing: border-box;
}
body {
font-family: "Open Sans", sans-serif;
background-color: $primary;
font-size: 16px;
}
h1,
h2,
h3,
h4,
h5,
h6 {
padding: 0;
margin: 0;
}
.container {
max-width: 98vw;
margin: 0 auto;
padding: 1rem;
background-color: #fff;
}
.text-center {
text-align: center;
}
.login {
.container {
max-width: 460px;
margin: 3rem auto;
padding: 2rem;
border: 1px solid #ddd;
border-radius: 0.25rem;
background-color: #fff;
}
}
.input {
appearance: none;
display: block;
width: 100%;
color: #333;
border: 1px solid rbg(180, 180, 180);
background-color: white;
padding: 1rem;
border-radius: 0.25rem;
&.input-error {
border: 1px solid $error;
&:focus {
border: 1px solid $error;
}
}
&:focus {
outline: none;
border: 1px solid $primary;
background-clip: padding-box;
}
}
.error-message {
font-size: 0.85rem;
color: $error;
}
.button {
background-color: $primary;
padding: 1rem;
border: none;
color: #fff;
font-weight: bold;
display: block;
width: 100%;
text-align: center;
cursor: pointer;
font-size: 1rem;
&:hover {
filter: brightness(110%);
}
}