feat: register validation + create + admin improvements
This commit is contained in:
303
client/components/register.vue
Normal file
303
client/components/register.vue
Normal file
@@ -0,0 +1,303 @@
|
||||
<template lang="pug">
|
||||
v-app
|
||||
.register
|
||||
v-container(grid-list-lg)
|
||||
v-layout(row, wrap)
|
||||
v-flex(
|
||||
xs12
|
||||
offset-sm1, sm10
|
||||
offset-md2, md8
|
||||
offset-lg3, lg6
|
||||
offset-xl4, xl4
|
||||
)
|
||||
transition(name='zoom')
|
||||
v-card.elevation-5.md2(v-show='isShown')
|
||||
v-toolbar(color='indigo', flat, dense, dark)
|
||||
v-spacer
|
||||
.subheading {{ $t('auth:registerTitle') }}
|
||||
v-spacer
|
||||
v-card-text.text-xs-center
|
||||
h1.display-1.indigo--text.py-2 {{ siteTitle }}
|
||||
.body-2 {{ $t('auth:registerSubTitle') }}
|
||||
v-text-field.md2.mt-3(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='email'
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
ref='iptEmail'
|
||||
v-model='email'
|
||||
:placeholder='$t("auth:fields.email")'
|
||||
color='indigo'
|
||||
)
|
||||
v-text-field.md2.mt-2(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='vpn_key'
|
||||
background-color='grey lighten-4'
|
||||
ref='iptPassword'
|
||||
v-model='password'
|
||||
:append-icon='hidePassword ? "visibility" : "visibility_off"'
|
||||
@click:append='() => (hidePassword = !hidePassword)'
|
||||
:type='hidePassword ? "password" : "text"'
|
||||
:placeholder='$t("auth:fields.password")'
|
||||
color='indigo'
|
||||
loading
|
||||
)
|
||||
password-strength(slot='progress', v-model='password')
|
||||
v-text-field.md2.mt-2(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='vpn_key'
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
ref='iptVerifyPassword'
|
||||
v-model='verifyPassword'
|
||||
@click:append='() => (hidePassword = !hidePassword)'
|
||||
type='password'
|
||||
:placeholder='$t("auth:fields.verifyPassword")'
|
||||
color='indigo'
|
||||
)
|
||||
v-text-field.md2.mt-2(
|
||||
solo
|
||||
flat
|
||||
prepend-icon='person'
|
||||
background-color='grey lighten-4'
|
||||
hide-details
|
||||
ref='iptName'
|
||||
v-model='name'
|
||||
:placeholder='$t("auth:fields.name")'
|
||||
@keyup.enter='register'
|
||||
color='indigo'
|
||||
)
|
||||
v-card-actions.pb-4
|
||||
v-spacer
|
||||
v-btn.md2(
|
||||
block
|
||||
large
|
||||
dark
|
||||
color='indigo'
|
||||
@click='register'
|
||||
round
|
||||
:loading='isLoading'
|
||||
) {{ $t('auth:actions.register') }}
|
||||
v-spacer
|
||||
v-divider
|
||||
v-card-actions.py-3.grey.lighten-4
|
||||
v-spacer
|
||||
i18next.caption(path='auth:switchToLogin.text', tag='div')
|
||||
a.caption(href='/login', place='link') {{ $t('auth:switchToLogin.link') }}
|
||||
v-spacer
|
||||
|
||||
loader(v-model='isLoading', :color='loaderColor', :title='loaderTitle', :subtitle='$t(`auth:pleaseWait`)')
|
||||
nav-footer(color='grey darken-4', dark-color='grey darken-4')
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* global siteConfig */
|
||||
|
||||
import _ from 'lodash'
|
||||
import Cookies from 'js-cookie'
|
||||
import validate from 'validate.js'
|
||||
import PasswordStrength from './common/password-strength.vue'
|
||||
|
||||
import registerMutation from 'gql/register/register-mutation-create.gql'
|
||||
|
||||
export default {
|
||||
i18nOptions: { namespaces: 'auth' },
|
||||
components: {
|
||||
PasswordStrength
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
email: '',
|
||||
password: '',
|
||||
verifyPassword: '',
|
||||
name: '',
|
||||
hidePassword: true,
|
||||
isLoading: false,
|
||||
isShown: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
siteTitle () {
|
||||
return siteConfig.title
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.isShown = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.iptEmail.focus()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* REGISTER
|
||||
*/
|
||||
async register () {
|
||||
const validation = validate({
|
||||
email: this.email,
|
||||
password: this.password,
|
||||
verifyPassword: this.verifyPassword,
|
||||
name: this.name
|
||||
}, {
|
||||
email: {
|
||||
presence: {
|
||||
message: this.$t('auth:missingEmail'),
|
||||
allowEmpty: false
|
||||
},
|
||||
email: {
|
||||
message: this.$t('auth:invalidEmail')
|
||||
}
|
||||
},
|
||||
password: {
|
||||
presence: {
|
||||
message: this.$t('auth:missingPassword'),
|
||||
allowEmpty: false
|
||||
},
|
||||
length: {
|
||||
minimum: 6,
|
||||
tooShort: this.$t('auth:passwordTooShort')
|
||||
}
|
||||
},
|
||||
verifyPassword: {
|
||||
equality: {
|
||||
attribute: 'password',
|
||||
message: this.$t('auth:passwordNotMatch')
|
||||
}
|
||||
},
|
||||
name: {
|
||||
presence: {
|
||||
message: this.$t('auth:missingName'),
|
||||
allowEmpty: false
|
||||
},
|
||||
length: {
|
||||
minimum: 2,
|
||||
maximum: 255,
|
||||
tooShort: this.$t('auth:nameTooShort'),
|
||||
tooLong: this.$t('auth:nameTooLong')
|
||||
}
|
||||
},
|
||||
}, { fullMessages: false })
|
||||
|
||||
if (validation) {
|
||||
if(validation.email) {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: validation.email[0],
|
||||
icon: 'warning'
|
||||
})
|
||||
this.$refs.iptEmail.focus()
|
||||
} else if (validation.password) {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: validation.password[0],
|
||||
icon: 'warning'
|
||||
})
|
||||
this.$refs.iptPassword.focus()
|
||||
} else if (validation.verifyPassword) {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: validation.verifyPassword[0],
|
||||
icon: 'warning'
|
||||
})
|
||||
this.$refs.iptVerifyPassword.focus()
|
||||
} else {
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: validation.name[0],
|
||||
icon: 'warning'
|
||||
})
|
||||
this.$refs.iptName.focus()
|
||||
}
|
||||
} else {
|
||||
this.isLoading = true
|
||||
try {
|
||||
let resp = await this.$apollo.mutate({
|
||||
mutation: registerMutation,
|
||||
variables: {
|
||||
email: this.email,
|
||||
password: this.password,
|
||||
name: this.name
|
||||
}
|
||||
})
|
||||
if (_.has(resp, 'data.authentication.register')) {
|
||||
let respObj = _.get(resp, 'data.authentication.register', {})
|
||||
if (respObj.responseResult.succeeded === true) {
|
||||
this.$store.commit('showNotification', {
|
||||
message: 'Account created successfully! Redirecting...',
|
||||
style: 'success',
|
||||
icon: 'check'
|
||||
})
|
||||
Cookies.set('jwt', respObj.jwt, { expires: 365 })
|
||||
_.delay(() => {
|
||||
window.location.replace('/')
|
||||
}, 1000)
|
||||
} else {
|
||||
throw new Error(respObj.responseResult.message)
|
||||
}
|
||||
} else {
|
||||
throw new Error('Registration is unavailable at this time.')
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
this.$store.commit('showNotification', {
|
||||
style: 'red',
|
||||
message: err.message,
|
||||
icon: 'warning'
|
||||
})
|
||||
this.isLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.register {
|
||||
background-color: mc('indigo', '900');
|
||||
background-image: url('../static/svg/motif-blocks.svg');
|
||||
background-repeat: repeat;
|
||||
background-size: 200px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: loginBgReveal 20s linear infinite;
|
||||
|
||||
@include keyframes(loginBgReveal) {
|
||||
0% {
|
||||
background-position-x: 0;
|
||||
}
|
||||
100% {
|
||||
background-position-x: 800px;
|
||||
}
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background-image: url('../static/svg/motif-overlay.svg');
|
||||
background-attachment: fixed;
|
||||
background-size: cover;
|
||||
opacity: .5;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
> .container {
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Varela Round' !important;
|
||||
}
|
||||
|
||||
.v-text-field.centered input {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user