mirror of
https://github.com/mCaptcha/mCaptcha.git
synced 2026-02-11 10:05:41 +00:00
frontend integration
This commit is contained in:
101
templates/auth/forms.scss
Normal file
101
templates/auth/forms.scss
Normal file
@@ -0,0 +1,101 @@
|
||||
@import '../reset';
|
||||
|
||||
.form__logo {
|
||||
width: 110px;
|
||||
padding-top: 50px;
|
||||
display: block;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
top: 20%;
|
||||
transform: translate(0%, -40.9%);
|
||||
}
|
||||
|
||||
.form__brand {
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: 20%;
|
||||
transform: translate(0%, -90.9%);
|
||||
}
|
||||
|
||||
.form-container {
|
||||
max-width: 40%;
|
||||
min-width: 20%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -49.9%);
|
||||
box-sizing: border-box;
|
||||
margin: auto;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.form__box {
|
||||
border: 1px solid #eaecef;
|
||||
background-color: #f6f8fa;
|
||||
border-radius: 5px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.form__in-group {
|
||||
display: block;
|
||||
position: relative;
|
||||
margin: auto;
|
||||
max-width: 80%;
|
||||
padding: 10px 0px;
|
||||
|
||||
box-sizing: content-box;
|
||||
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.form__in-field {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
margin: 10px 0;
|
||||
padding: 10px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form__in-field--warn {
|
||||
border: solid 1px red;
|
||||
}
|
||||
|
||||
.form__in-field--success {
|
||||
border: solid 1px #2ea44f;
|
||||
}
|
||||
|
||||
.form__pw-recovery {
|
||||
text-decoration: none;
|
||||
color: rgb(3, 102, 214);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.form__submit-button {
|
||||
display: block;
|
||||
border: 1px solid skyblue;
|
||||
background: #2ea44f;
|
||||
color: white;
|
||||
height: 40px;
|
||||
border-radius: 5px;
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.form__secondary-action {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.form__secondary-action__banner {
|
||||
display: block;
|
||||
margin: auto;
|
||||
max-width: 80%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form__secondary-action__link {
|
||||
text-decoration: none;
|
||||
color: rgb(3, 102, 214);
|
||||
}
|
||||
46
templates/auth/login/index.html
Normal file
46
templates/auth/login/index.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<. include!("../../components/headers.html"); .>
|
||||
<div class="form-container">
|
||||
<img src="<.= crate::FILES.get("./static/img/icon-trans.png").unwrap().>" class="form__logo" alt="" />
|
||||
<h2 class="form__brand">Sign in to mCaptcha</h2>
|
||||
|
||||
<form class="form__box" id="form">
|
||||
<label class="form__in-group" for="username"
|
||||
>Username
|
||||
<input
|
||||
class="form__in-field"
|
||||
id="username"
|
||||
type="text"
|
||||
name="username"
|
||||
required=""
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label for="password" class="form__in-group"
|
||||
>Password
|
||||
<input
|
||||
class="form__in-field"
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
required=""
|
||||
/>
|
||||
<!--
|
||||
<a class="form__pw-recovery" -href="/recovert/password"
|
||||
>Forgot password?</a
|
||||
>
|
||||
-->
|
||||
</label>
|
||||
<button class="form__submit-button" type="submit">
|
||||
Submit
|
||||
</button>
|
||||
</form>
|
||||
<div class="form__secondary-action">
|
||||
<p class="form__secondary-action__banner">
|
||||
New to mCaptcha?
|
||||
<a href="/join" class="form__secondary-action__link"
|
||||
>Create account</a
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<. include!("../../components/footers.html"); .>
|
||||
31
templates/auth/login/index.js
Normal file
31
templates/auth/login/index.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import ROUTES from '../../api/v1/routes';
|
||||
|
||||
import isBlankString from '../../utils/genJsonPayload';
|
||||
import genJsonPayload from '../../utils/genJsonPayload';
|
||||
|
||||
import '../forms.scss';
|
||||
|
||||
const login = e => {
|
||||
e.preventDefault();
|
||||
let username = document.getElementById('username').value;
|
||||
isBlankString(e, username, 'username');
|
||||
|
||||
let password = document.getElementById('password').value;
|
||||
let payload = {
|
||||
username,
|
||||
password,
|
||||
};
|
||||
|
||||
fetch(ROUTES.loginUser, genJsonPayload(payload)).then(res => {
|
||||
if (res.ok) {
|
||||
alert('success');
|
||||
} else {
|
||||
res.json().then(err => alert(`error: ${err.error}`));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const index = () => {
|
||||
let form = document.getElementById('form');
|
||||
form.addEventListener('submit', login, true);
|
||||
};
|
||||
43
templates/auth/register/emailExists.js
Normal file
43
templates/auth/register/emailExists.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import ROUTES from '../../api/v1/routes';
|
||||
|
||||
import genJsonPayload from '../../utils/genJsonPayload';
|
||||
|
||||
const checkEmailExists = async () => {
|
||||
let email = document.getElementById('email');
|
||||
let val = email.value;
|
||||
let payload = {
|
||||
val,
|
||||
};
|
||||
|
||||
// return fetch(ROUTES.emailExists, genJsonPayload(payload)).then(res => {
|
||||
// if (res.ok) {
|
||||
// res.json().then(data => {
|
||||
// if (data.exists) {
|
||||
// console.log(email.className);
|
||||
// email.className += ' form__in-field--warn';
|
||||
// alert('Email taken');
|
||||
// }
|
||||
//
|
||||
// return data.exists;
|
||||
// });
|
||||
// } else {
|
||||
// res.json().then(err => alert(`error: ${err.error}`));
|
||||
// }
|
||||
// });
|
||||
//
|
||||
|
||||
let res = await fetch(ROUTES.emailExists, genJsonPayload(payload));
|
||||
if (res.ok) {
|
||||
let data = await res.json();
|
||||
if (data.exists) {
|
||||
email.className += ' form__in-field--warn';
|
||||
alert('Email taken');
|
||||
}
|
||||
return data.exists;
|
||||
} else {
|
||||
let err = await res.json();
|
||||
alert(`error: ${err.error}`);
|
||||
}
|
||||
};
|
||||
|
||||
export {checkEmailExists};
|
||||
65
templates/auth/register/index.html
Normal file
65
templates/auth/register/index.html
Normal file
@@ -0,0 +1,65 @@
|
||||
<. include!("../../components/headers.html"); .>
|
||||
<div class="form-container">
|
||||
<img src="<.= crate::FILES.get("./static/img/icon-trans.png").unwrap().>" class="form__logo" alt="" />
|
||||
<h2 class="form__brand">Join mCaptcha</h2>
|
||||
|
||||
<form class="form__box" id="form">
|
||||
<label class="form__in-group" for="username"
|
||||
>Username
|
||||
<input
|
||||
class="form__in-field"
|
||||
id="username"
|
||||
type="text"
|
||||
name="username"
|
||||
id="username"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label class="form__in-group" for="username"
|
||||
>Email
|
||||
<input
|
||||
class="form__in-field"
|
||||
id="email"
|
||||
type="email"
|
||||
name="email"
|
||||
id="email"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label for="password" class="form__in-group"
|
||||
>Password
|
||||
<input
|
||||
class="form__in-field"
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
id="password"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
|
||||
<label for="password" class="form__in-group"
|
||||
>Re-enter Password
|
||||
<input
|
||||
class="form__in-field"
|
||||
type="password"
|
||||
id="password-check"
|
||||
name="password-check"
|
||||
id="password-check"
|
||||
required
|
||||
/>
|
||||
</label>
|
||||
<button class="form__submit-button" type="submit">
|
||||
Submit
|
||||
</button>
|
||||
</form>
|
||||
<div class="form__secondary-action">
|
||||
<p class="form__secondary-action__banner">
|
||||
New to mCaptcha?
|
||||
<a href="/" class="form__secondary-action__link">Create account</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<. include!("../../components/footers.html"); .>
|
||||
57
templates/auth/register/index.js
Normal file
57
templates/auth/register/index.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import ROUTES from '../../api/v1/routes';
|
||||
|
||||
import isBlankString from '../../utils/genJsonPayload';
|
||||
import genJsonPayload from '../../utils/genJsonPayload';
|
||||
|
||||
import userExists from './userExists';
|
||||
import {checkEmailExists} from './emailExists';
|
||||
|
||||
import '../forms.scss';
|
||||
|
||||
const registerUser = async e => {
|
||||
e.preventDefault();
|
||||
|
||||
let username = document.getElementById('username').value;
|
||||
isBlankString(e, username, 'username');
|
||||
|
||||
let password = document.getElementById('password').value;
|
||||
let passwordCheck = document.getElementById('password-check').value;
|
||||
if (password != passwordCheck) {
|
||||
return alert("passwords don't match, check again!");
|
||||
}
|
||||
|
||||
let email = document.getElementById('email').value;
|
||||
isBlankString(e, email, 'email');
|
||||
|
||||
let exists = await checkUsernameExists();
|
||||
if (exists) {
|
||||
return;
|
||||
}
|
||||
|
||||
exists = await checkEmailExists();
|
||||
if (exists) {
|
||||
return;
|
||||
}
|
||||
|
||||
let payload = {
|
||||
username,
|
||||
password,
|
||||
email,
|
||||
};
|
||||
|
||||
let res = await fetch(ROUTES.registerUser, genJsonPayload(payload));
|
||||
if (res.ok) {
|
||||
alert('success');
|
||||
} else {
|
||||
let err = await res.json();
|
||||
alert(`error: ${err.error}`);
|
||||
}
|
||||
};
|
||||
|
||||
export const index = () => {
|
||||
let form = document.getElementById('form');
|
||||
form.addEventListener('submit', registerUser, true);
|
||||
|
||||
let username = document.getElementById('username');
|
||||
username.addEventListener('input', userExists, false);
|
||||
}
|
||||
44
templates/auth/register/userExists.js
Normal file
44
templates/auth/register/userExists.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import ROUTES from '../../api/v1/routes';
|
||||
|
||||
import genJsonPayload from '../../utils/genJsonPayload';
|
||||
|
||||
|
||||
//export const checkUsernameExists = async () => {
|
||||
async function userExists() {
|
||||
let username = document.getElementById('username');
|
||||
let val = username.value;
|
||||
let payload = {
|
||||
val,
|
||||
};
|
||||
|
||||
// return fetch(ROUTES.usernameExists, genJsonPayload(payload)).then(res => {
|
||||
// if (res.ok) {
|
||||
// res.json().then(data => {
|
||||
// if (data.exists) {
|
||||
// username.className += ' form__in-field--warn';
|
||||
// alert('Username taken');
|
||||
// }
|
||||
// return data.exists;
|
||||
// });
|
||||
// } else {
|
||||
// res.json().then(err => alert(`error: ${err.error}`));
|
||||
// }
|
||||
// });
|
||||
//
|
||||
|
||||
let res = await fetch(ROUTES.usernameExists, genJsonPayload(payload));
|
||||
if (res.ok) {
|
||||
let data = await res.json();
|
||||
if (data.exists) {
|
||||
username.className += ' form__in-field--warn';
|
||||
alert('Username taken');
|
||||
}
|
||||
return data.exists;
|
||||
} else {
|
||||
let err = await res.json();
|
||||
alert(`error: ${err.error}`);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export default userExists;
|
||||
Reference in New Issue
Block a user