add Login and Register views
This commit is contained in:
parent
fac00735ad
commit
7f546ed13e
3 changed files with 295 additions and 3 deletions
|
@ -15,7 +15,6 @@
|
|||
"base-64": "^0.1.0",
|
||||
"bootstrap": "^4.3.1",
|
||||
"core-js": "^3.3.2",
|
||||
"dotenv-webpack": "^1.7.0",
|
||||
"jquery": "^3.4.1",
|
||||
"lodash": "^4.17.15",
|
||||
"luxon": "^1.21.3",
|
||||
|
@ -26,14 +25,18 @@
|
|||
"utf8": "^3.0.0",
|
||||
"vue": "^2.6.10",
|
||||
"vue-debounce": "^2.2.0",
|
||||
"vue-qrcode-component": "^2.1.1",
|
||||
"vue-router": "^3.1.3",
|
||||
"vuex": "^3.1.2",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
"vuex-router-sync": "^5.0.0",
|
||||
"yarn": "^1.22.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^5.0.8",
|
||||
"@vue/cli-service": "^5.0.8",
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
"express-basic-auth": "^1.2.1",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"webpack": "^5"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
|
|
120
web/src/views/Login.vue
Normal file
120
web/src/views/Login.vue
Normal file
|
@ -0,0 +1,120 @@
|
|||
<template>
|
||||
<main class="d-flex w-100">
|
||||
<div class="container d-flex flex-column">
|
||||
<div class="row vh-100">
|
||||
<div class="col-sm-10 col-md-8 col-lg-6 mx-auto d-table h-100">
|
||||
<div class="d-table-cell align-middle">
|
||||
<div class="text-center mt-4">
|
||||
<h1 class="h2">
|
||||
C3LF System3
|
||||
</h1>
|
||||
<p class="lead" v-if="msg">
|
||||
{{ msg }}
|
||||
</p>
|
||||
<p class="lead" v-else>
|
||||
Sign in to your account to continue
|
||||
</p>
|
||||
</div>
|
||||
<div class="card bg-dark">
|
||||
<div class="card-body">
|
||||
<div class="m-sm-4">
|
||||
<form role="form" @submit.prevent="do_login">
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Username</label>
|
||||
<input class="form-control" type="text"
|
||||
name="username" placeholder="Enter your username"
|
||||
v-model="username"/>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Password</label>
|
||||
<input class="form-control" type="password"
|
||||
name="password" placeholder="Enter your password"
|
||||
v-model="password"/>
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="remember-me"
|
||||
name="remember-me" checked v-model="remember"
|
||||
@change="setRemember(remember)">
|
||||
<span class="form-check-label">
|
||||
Remember me next time
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="text-center mt-3">
|
||||
<button type="submit" name="login" class="btn btn-primary">Login
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<br/>
|
||||
<div class="text-center">
|
||||
<p class="mb-0 text-muted">
|
||||
Don’t have an account?
|
||||
<router-link to="/register">Sign up</router-link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapActions, mapMutations} from 'vuex';
|
||||
import router from "@/router";
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
data() {
|
||||
return {
|
||||
msg: 'Welcome to ' + window.location.hostname,
|
||||
username: '',
|
||||
password: '',
|
||||
remember: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['login']),
|
||||
...mapMutations(['setRemember']),
|
||||
async do_login(e) {
|
||||
e.preventDefault();
|
||||
if (await this.login({username: this.username, password: this.password, remember: this.remember})) {
|
||||
if (this.$route.query.redirect) {
|
||||
await router.push({path: this.$route.query.redirect});
|
||||
} else {
|
||||
await router.push({path: '/'});
|
||||
}
|
||||
} else {
|
||||
this.msg = 'Invalid username or password';
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
input{
|
||||
background-color: var(--dark);
|
||||
border: var(--gray) 1px solid;;
|
||||
|
||||
&:focus {
|
||||
background-color: var(--dark);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--dark);
|
||||
}
|
||||
|
||||
&[type="checkbox"] {
|
||||
background-color: var(--dark);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
169
web/src/views/Register.vue
Normal file
169
web/src/views/Register.vue
Normal file
|
@ -0,0 +1,169 @@
|
|||
<template>
|
||||
<main class="d-flex w-100">
|
||||
<div class="container d-flex flex-column">
|
||||
<div class="row vh-100">
|
||||
<div class="col-sm-10 col-md-8 col-lg-6 mx-auto d-table h-100">
|
||||
<div class="d-table-cell align-middle">
|
||||
<div class="text-center mt-4">
|
||||
<h1 class="h2">
|
||||
C3LF System3
|
||||
</h1>
|
||||
<p class="lead" v-if="msg">
|
||||
{{ msg }}
|
||||
</p>
|
||||
<p class="lead" v-else>
|
||||
Create an account to get started
|
||||
</p>
|
||||
</div>
|
||||
<div class="card bg-dark">
|
||||
<div class="card-body">
|
||||
<div class="m-sm-4">
|
||||
<form role="form" method="post" @submit.prevent="do_register">
|
||||
<div :class="errors.username?['mb-3','is-invalid']:['mb-3']">
|
||||
<label class="form-label">Username</label>
|
||||
<div class="input-group">
|
||||
<input class="form-control"
|
||||
type="text" v-model="form.username" id="validationCustomUsername"
|
||||
placeholder="Enter your username" required/>
|
||||
</div>
|
||||
<div class="invalid-feedback">
|
||||
{{ errors.username }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div :class="errors.email?['mb-3','is-invalid']:['mb-3']">
|
||||
<label class="form-label">E-Mail</label>
|
||||
<div class="input-group">
|
||||
<input class="form-control"
|
||||
type="email" v-model="form.email" id="validationCustomEmail"
|
||||
placeholder="Enter your email" required/>
|
||||
</div>
|
||||
<div class="invalid-feedback">
|
||||
{{ errors.email }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div :class="errors.password?['mb-3','is-invalid']:['mb-3']">
|
||||
<label class="form-label">Password</label>
|
||||
<input class="form-control" type="password"
|
||||
v-model="form.password" placeholder="Enter your password"/>
|
||||
<div class="invalid-feedback">{{ errors.password }}</div>
|
||||
</div>
|
||||
|
||||
<div :class="errors.password2?['mb-3','is-invalid']:['mb-3']">
|
||||
<label class="form-label">Password Check</label>
|
||||
<input class="form-control" type="password"
|
||||
v-model="password2" placeholder="Enter your password again"/>
|
||||
<div class="invalid-feedback">{{ errors.password2 }}</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-3">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<br/>
|
||||
<div class="text-center">
|
||||
<p class="mb-0 text-muted">
|
||||
Already have an account?
|
||||
<router-link to="/login">Login</router-link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'Register',
|
||||
data() {
|
||||
return {
|
||||
msg: 'Register',
|
||||
password2: '',
|
||||
form: {
|
||||
username: '',
|
||||
password: '',
|
||||
email: '',
|
||||
},
|
||||
errors: {
|
||||
username: null,
|
||||
password: null,
|
||||
password2: null,
|
||||
email: null,
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
do_register() {
|
||||
console.log('do_register');
|
||||
console.log(this.form);
|
||||
if (this.form.password !== this.password2) {
|
||||
this.errors.password2 = 'Passwords do not match';
|
||||
return;
|
||||
} else {
|
||||
this.errors.password2 = null;
|
||||
}
|
||||
fetch('/api/2/register/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(this.form)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.errors) {
|
||||
console.error('Error:', data.errors);
|
||||
this.errors = data.errors;
|
||||
return;
|
||||
}
|
||||
console.log('Success:', data);
|
||||
this.msg = 'Success';
|
||||
this.$router.push('/login');
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error:', error);
|
||||
this.msg = 'Error';
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.is-invalid input, .is-invalid select {
|
||||
border: 1px solid var(--danger);
|
||||
}
|
||||
|
||||
.is-invalid .invalid-feedback {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input {
|
||||
background-color: var(--dark);
|
||||
border: var(--gray) 1px solid;;
|
||||
|
||||
&:focus {
|
||||
background-color: var(--dark);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--dark);
|
||||
}
|
||||
|
||||
&[type="checkbox"] {
|
||||
background-color: var(--dark);
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in a new issue