mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-04-17 10:22:36 +00:00
created vue login and register pages with validation only
This commit is contained in:
parent
2c7ee656e0
commit
5b95994cac
12 changed files with 267 additions and 19 deletions
.editorconfig
web-frontend
|
@ -11,7 +11,7 @@ insert_final_newline = true
|
||||||
[Makefile]
|
[Makefile]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
||||||
[*.{js,yml,scss,json,eslintrc,stylelintrc,vue}]
|
[*.{js,yml,scss,json,eslintrc,stylelintrc,vue,html}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
|
|
|
@ -19,5 +19,6 @@ module.exports = {
|
||||||
],
|
],
|
||||||
// add your custom rules here
|
// add your custom rules here
|
||||||
rules: {
|
rules: {
|
||||||
|
'no-console': 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
web-frontend/layouts/login.vue
Normal file
10
web-frontend/layouts/login.vue
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="box-page-header"></div>
|
||||||
|
<div class="box-page">
|
||||||
|
<div class="box login-page login-page-login">
|
||||||
|
<nuxt />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1,7 +1,5 @@
|
||||||
import StyleLintPlugin from 'stylelint-webpack-plugin'
|
import StyleLintPlugin from 'stylelint-webpack-plugin'
|
||||||
|
|
||||||
import pkg from './package'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mode: 'universal',
|
mode: 'universal',
|
||||||
|
|
||||||
|
@ -9,13 +7,11 @@ export default {
|
||||||
** Headers of the page
|
** Headers of the page
|
||||||
*/
|
*/
|
||||||
head: {
|
head: {
|
||||||
title: pkg.name,
|
title: 'Baserow',
|
||||||
meta: [
|
meta: [
|
||||||
{ charset: 'utf-8' },
|
{ charset: 'utf-8' },
|
||||||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
|
||||||
{ hid: 'description', name: 'description', content: pkg.description }
|
]
|
||||||
],
|
|
||||||
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -31,7 +27,7 @@ export default {
|
||||||
/*
|
/*
|
||||||
** Plugins to load before mounting the App
|
** Plugins to load before mounting the App
|
||||||
*/
|
*/
|
||||||
plugins: [],
|
plugins: [{ src: '@/plugins/Vuelidate.js' }],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Nuxt.js modules
|
** Nuxt.js modules
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
"@nuxtjs/axios": "^5.3.6",
|
"@nuxtjs/axios": "^5.3.6",
|
||||||
"cross-env": "^5.2.0",
|
"cross-env": "^5.2.0",
|
||||||
"normalize-scss": "^7.0.1",
|
"normalize-scss": "^7.0.1",
|
||||||
"nuxt": "^2.4.0"
|
"nuxt": "^2.4.0",
|
||||||
|
"vuelidate": "^0.7.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxtjs/eslint-config": "^0.0.1",
|
"@nuxtjs/eslint-config": "^0.0.1",
|
||||||
|
|
91
web-frontend/pages/login/index.vue
Normal file
91
web-frontend/pages/login/index.vue
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1 class="box-title">
|
||||||
|
<img src="@/static/img/logo.svg" alt="" />
|
||||||
|
</h1>
|
||||||
|
<form @submit.prevent="login">
|
||||||
|
<div class="control">
|
||||||
|
<label class="control-label">E-mail address</label>
|
||||||
|
<div class="control-elements">
|
||||||
|
<input
|
||||||
|
v-model="credentials.email"
|
||||||
|
:class="{ 'input-error': $v.credentials.email.$error }"
|
||||||
|
type="text"
|
||||||
|
class="input input-large"
|
||||||
|
@blur="$v.credentials.email.$touch()"
|
||||||
|
/>
|
||||||
|
<div v-if="$v.credentials.email.$error" class="error">
|
||||||
|
Please enter a valid e-mail address.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<label class="control-label">Password</label>
|
||||||
|
<div class="control-elements">
|
||||||
|
<input
|
||||||
|
v-model="credentials.password"
|
||||||
|
:class="{ 'input-error': $v.credentials.password.$error }"
|
||||||
|
type="password"
|
||||||
|
class="input input-large"
|
||||||
|
@blur="$v.credentials.password.$touch()"
|
||||||
|
/>
|
||||||
|
<div v-if="$v.credentials.password.$error" class="error">
|
||||||
|
A password is required.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="actions">
|
||||||
|
<ul class="action-links">
|
||||||
|
<li>
|
||||||
|
<nuxt-link :to="{ name: 'login-signup' }">
|
||||||
|
Sign up
|
||||||
|
</nuxt-link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<button
|
||||||
|
:class="{ 'button-loading': loading }"
|
||||||
|
class="button button-large"
|
||||||
|
>
|
||||||
|
Sign in
|
||||||
|
<i class="fas fa-lock-open"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { required, email } from 'vuelidate/lib/validators'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
layout: 'login',
|
||||||
|
head() {
|
||||||
|
return {
|
||||||
|
title: 'Login'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
credentials: {
|
||||||
|
email: '',
|
||||||
|
password: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validations: {
|
||||||
|
credentials: {
|
||||||
|
email: { required, email },
|
||||||
|
password: { required }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
login() {
|
||||||
|
this.$v.$touch()
|
||||||
|
if (!this.$v.$invalid) {
|
||||||
|
this.loading = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
129
web-frontend/pages/login/signup.vue
Normal file
129
web-frontend/pages/login/signup.vue
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1 class="box-title">Sign up</h1>
|
||||||
|
<form @submit.prevent="register">
|
||||||
|
<div class="control">
|
||||||
|
<label class="control-label">E-mail address</label>
|
||||||
|
<div class="control-elements">
|
||||||
|
<input
|
||||||
|
v-model="account.email"
|
||||||
|
:class="{ 'input-error': $v.account.email.$error }"
|
||||||
|
type="text"
|
||||||
|
class="input input-large"
|
||||||
|
@blur="$v.account.email.$touch()"
|
||||||
|
/>
|
||||||
|
<div v-if="$v.account.email.$error" class="error">
|
||||||
|
Please enter a valid e-mail address.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<label class="control-label">Your name</label>
|
||||||
|
<div class="control-elements">
|
||||||
|
<input
|
||||||
|
v-model="account.name"
|
||||||
|
:class="{ 'input-error': $v.account.name.$error }"
|
||||||
|
type="text"
|
||||||
|
class="input input-large"
|
||||||
|
@blur="$v.account.name.$touch()"
|
||||||
|
/>
|
||||||
|
<div v-if="$v.account.name.$error" class="error">
|
||||||
|
A minimum of two characters is required here.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<label class="control-label">Password</label>
|
||||||
|
<div class="control-elements">
|
||||||
|
<input
|
||||||
|
v-model="account.password"
|
||||||
|
:class="{ 'input-error': $v.account.password.$error }"
|
||||||
|
type="password"
|
||||||
|
class="input input-large"
|
||||||
|
@blur="$v.account.password.$touch()"
|
||||||
|
/>
|
||||||
|
<div v-if="$v.account.password.$error" class="error">
|
||||||
|
A password is required.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<label class="control-label">Repeat password</label>
|
||||||
|
<div class="control-elements">
|
||||||
|
<input
|
||||||
|
v-model="account.passwordConfirm"
|
||||||
|
:class="{ 'input-error': $v.account.passwordConfirm.$error }"
|
||||||
|
type="password"
|
||||||
|
class="input input-large"
|
||||||
|
@blur="$v.account.passwordConfirm.$touch()"
|
||||||
|
/>
|
||||||
|
<div v-if="$v.account.passwordConfirm.$error" class="error">
|
||||||
|
This field must match your password field.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="actions">
|
||||||
|
<ul class="action-links">
|
||||||
|
<li>
|
||||||
|
<nuxt-link :to="{ name: 'login' }">
|
||||||
|
<i class="fas fa-arrow-left"></i>
|
||||||
|
Back
|
||||||
|
</nuxt-link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<button
|
||||||
|
:class="{ 'button-loading': loading }"
|
||||||
|
class="button button-large"
|
||||||
|
>
|
||||||
|
Sign up
|
||||||
|
<i class="fas fa-user-plus"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { required, email, sameAs, minLength } from 'vuelidate/lib/validators'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
layout: 'login',
|
||||||
|
head() {
|
||||||
|
return {
|
||||||
|
title: 'Create new account'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validations: {
|
||||||
|
account: {
|
||||||
|
email: { required, email },
|
||||||
|
name: {
|
||||||
|
required,
|
||||||
|
minLength: minLength(2)
|
||||||
|
},
|
||||||
|
password: { required },
|
||||||
|
passwordConfirm: {
|
||||||
|
sameAsPassword: sameAs('password')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
account: {
|
||||||
|
email: '',
|
||||||
|
name: '',
|
||||||
|
password: '',
|
||||||
|
passwordConfirm: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
register() {
|
||||||
|
this.$v.$touch()
|
||||||
|
if (!this.$v.$invalid) {
|
||||||
|
this.loading = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
4
web-frontend/plugins/Vuelidate.js
Normal file
4
web-frontend/plugins/Vuelidate.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import Vuelidate from 'vuelidate'
|
||||||
|
|
||||||
|
Vue.use(Vuelidate)
|
|
@ -1,7 +1,7 @@
|
||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
import Index from '@/pages/index.vue'
|
import Index from '@/pages/index.vue'
|
||||||
|
|
||||||
describe('Logo', () => {
|
describe('Home', () => {
|
||||||
test('is a Vue instance', () => {
|
test('is a Vue instance', () => {
|
||||||
const wrapper = mount(Index)
|
const wrapper = mount(Index)
|
||||||
expect(wrapper.isVueInstance()).toBeTruthy()
|
expect(wrapper.isVueInstance()).toBeTruthy()
|
||||||
|
|
9
web-frontend/test/pages/login/index.spec.js
Normal file
9
web-frontend/test/pages/login/index.spec.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import Index from '@/pages/login/index.vue'
|
||||||
|
|
||||||
|
describe('Login', () => {
|
||||||
|
test('is a Vue instance', () => {
|
||||||
|
const wrapper = mount(Index)
|
||||||
|
expect(wrapper.isVueInstance()).toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
9
web-frontend/test/pages/login/signup.spec.js
Normal file
9
web-frontend/test/pages/login/signup.spec.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import Signup from '@/pages/login/signup.vue'
|
||||||
|
|
||||||
|
describe('Signup', () => {
|
||||||
|
test('is a Vue instance', () => {
|
||||||
|
const wrapper = mount(Signup)
|
||||||
|
expect(wrapper.isVueInstance()).toBeTruthy()
|
||||||
|
})
|
||||||
|
})
|
|
@ -4933,7 +4933,7 @@ html-webpack-plugin@^3.2.0:
|
||||||
toposort "^1.0.0"
|
toposort "^1.0.0"
|
||||||
util.promisify "1.0.0"
|
util.promisify "1.0.0"
|
||||||
|
|
||||||
htmlparser2@^3.10.0, htmlparser2@^3.3.0, htmlparser2@^3.9.1:
|
htmlparser2@^3.10.0, htmlparser2@^3.3.0:
|
||||||
version "3.10.1"
|
version "3.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
|
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
|
||||||
integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
|
integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
|
||||||
|
@ -9724,13 +9724,6 @@ stylelint-config-standard@^18.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
stylelint-config-recommended "^2.2.0"
|
stylelint-config-recommended "^2.2.0"
|
||||||
|
|
||||||
stylelint-processor-html@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/stylelint-processor-html/-/stylelint-processor-html-1.0.0.tgz#6892b6b2855a45f0291cd845191d6908130a2918"
|
|
||||||
integrity sha1-aJK2soVaRfApHNhFGR1pCBMKKRg=
|
|
||||||
dependencies:
|
|
||||||
htmlparser2 "^3.9.1"
|
|
||||||
|
|
||||||
stylelint-webpack-plugin@^0.10.5:
|
stylelint-webpack-plugin@^0.10.5:
|
||||||
version "0.10.5"
|
version "0.10.5"
|
||||||
resolved "https://registry.yarnpkg.com/stylelint-webpack-plugin/-/stylelint-webpack-plugin-0.10.5.tgz#0b6e0d373ff5e03baa8197ebe0f2625981bd266b"
|
resolved "https://registry.yarnpkg.com/stylelint-webpack-plugin/-/stylelint-webpack-plugin-0.10.5.tgz#0b6e0d373ff5e03baa8197ebe0f2625981bd266b"
|
||||||
|
@ -10640,6 +10633,11 @@ vue@^2.6.10:
|
||||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637"
|
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637"
|
||||||
integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==
|
integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==
|
||||||
|
|
||||||
|
vuelidate@^0.7.4:
|
||||||
|
version "0.7.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/vuelidate/-/vuelidate-0.7.4.tgz#5a0e54be09ac0192f1aa3387d74b92e0945bf8aa"
|
||||||
|
integrity sha512-QHZWYOL325Zo+2K7VBNEJTZ496Kd8Z31p85aQJFldKudUUGBmgw4zu4ghl4CyqPwjRCmqZ9lDdx4FSdMnu4fGg==
|
||||||
|
|
||||||
vuex@^3.1.1:
|
vuex@^3.1.1:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.1.1.tgz#0c264bfe30cdbccf96ab9db3177d211828a5910e"
|
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.1.1.tgz#0c264bfe30cdbccf96ab9db3177d211828a5910e"
|
||||||
|
|
Loading…
Add table
Reference in a new issue