mirror of
https://github.com/JonasunderscoreJones/Website-v1.git
synced 2025-10-25 11:39:18 +02:00
Add files via upload
This commit is contained in:
parent
75684c5f91
commit
4a1ac1b789
9 changed files with 338 additions and 1 deletions
9
login/README.md
Normal file
9
login/README.md
Normal 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
87
login/css/style.css
Normal 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
1
login/css/style.min.css
vendored
Normal 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
18
login/dashboard.html
Normal 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>
|
||||||
|
|
@ -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
5
login/init.js
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
const auth = new Auth();
|
||||||
|
|
||||||
|
document.querySelector(".logout").addEventListener("click", (e) => {
|
||||||
|
auth.logOut();
|
||||||
|
});
|
||||||
20
login/js/auth.js
Normal file
20
login/js/auth.js
Normal 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
77
login/js/login.js
Normal 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
89
login/sass/style.scss
Normal 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%);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue