Refine and translate registration sliders with database handling and auto login

This commit is contained in:
Wolfgang Huß 2021-03-17 18:30:46 +01:00
parent f9de1f05da
commit fc5b0f1b37
9 changed files with 135 additions and 69 deletions

View File

@ -40,7 +40,11 @@
:icon="sliderData.sliders[sliderIndex].button.icon"
type="submit"
filled
:loading="false"
:loading="
sliderData.sliders[sliderIndex].button.loading !== undefined
? sliderData.sliders[sliderIndex].button.loading
: false
"
:disabled="!sliderData.sliders[sliderIndex].validated"
@click="onNextClick"
>

View File

@ -284,6 +284,9 @@ export default {
const termsAndConditionsAgreedVersion = VERSION
const locale = this.$i18n.locale()
try {
this.sliderData.setSliderValuesCallback(null, {
sliderSettings: { buttonLoading: true },
})
await this.$apollo.mutate({
mutation: SignupVerificationMutation,
variables: {
@ -298,7 +301,18 @@ export default {
},
})
this.response = 'success'
setTimeout(async () => {
await this.$store.dispatch('auth/login', { email, password })
this.$toast.success('You are logged in!') // Wolle
this.$router.push('/')
this.sliderData.setSliderValuesCallback(null, {
sliderSettings: { buttonLoading: false },
})
}, 3000)
} catch (err) {
this.sliderData.setSliderValuesCallback(null, {
sliderSettings: { buttonLoading: false },
})
this.response = 'error'
}
},

View File

@ -1,5 +1,4 @@
<template>
<!-- Wolle <ds-space v-if="!data && !error" margin="large"> -->
<ds-form
v-model="formData"
:schema="formSchema"
@ -41,24 +40,6 @@
</label>
</ds-text>
</ds-form>
<!-- Wolle </ds-space>
<div v-else margin="large">
<template v-if="!error">
<transition name="ds-transition-fade">
<sweetalert-icon icon="info" />
</transition>
<ds-text align="center" v-html="submitMessage" />
</template>
<template v-else>
<transition name="ds-transition-fade">
<sweetalert-icon icon="error" />
</transition>
<ds-text align="center">{{ error.message }}</ds-text>
<ds-space centered class="space-top">
<nuxt-link to="/login">{{ $t('site.back-to-login') }}</nuxt-link>
</ds-space>
</template>
</div> -->
</template>
<script>
@ -66,6 +47,7 @@ import gql from 'graphql-tag'
import metadata from '~/constants/metadata'
import { isEmail } from 'validator'
import normalizeEmail from '~/components/utils/NormalizeEmail'
import translateErrorMessage from '~/components/utils/TranslateErrorMessage'
// Wolle import { SweetalertIcon } from 'vue-sweetalert-icons'
export const SignupMutation = gql`
@ -102,7 +84,6 @@ export default {
// Integrate termsAndConditionsConfirmed into `this.formData` once we
// have checkmarks available.
sendEmailAgain: false,
error: null, // Wolle
}
},
mounted: function () {
@ -131,10 +112,6 @@ export default {
sliderIndex() {
return this.sliderData.sliderIndex // to have a shorter notation
},
// Wolle submitMessage() {
// const { email } = this.data.Signup
// return this.$t('components.registration.signup.form.success', { email })
// },
validInput() {
return isEmail(this.formData.email)
},
@ -159,9 +136,9 @@ export default {
sliderSettings: {
buttonTitleIdent: this.sliderData.collectedInputData.emailSend
? this.sendEmailAgain
? 'components.email.buttonTitleResend'
: 'components.email.buttonTitleSkipResend'
: 'components.email.buttonTitleSend',
? 'components.email.buttonTitle.resend'
: 'components.email.buttonTitle.skipResend'
: 'components.email.buttonTitle.send',
buttonIcon: this.sliderData.collectedInputData.emailSend
? this.sendEmailAgain
? 'envelope'
@ -185,12 +162,19 @@ export default {
const { inviteCode = null } = this.sliderData.collectedInputData
const variables = { email, inviteCode }
if (!this.sendEmailAgain && this.sliderData.collectedInputData.emailSend) {
if (this.sliderData.collectedInputData.emailSend && !this.sendEmailAgain) {
return true
}
if (this.sendEmailAgain || !this.isVariablesRequested(variables)) {
if (
!this.sliderData.collectedInputData.emailSend ||
this.sendEmailAgain ||
!this.isVariablesRequested(variables)
) {
try {
this.sliderData.setSliderValuesCallback(null, {
sliderSettings: { buttonLoading: true },
})
const response = await this.$apollo.mutate({ mutation: SignupMutation, variables }) // e-mail is send in emailMiddleware of backend
this.sliderData.setSliderValuesCallback(null, {
sliderData: { request: { variables }, response: response.data },
@ -209,29 +193,28 @@ export default {
this.$t('components.registration.email.form.success', { email: responseEmail }),
)
}
this.sliderData.setSliderValuesCallback(null, {
sliderSettings: { buttonLoading: false },
})
return true
} catch (err) {
this.sliderData.setSliderValuesCallback(this.validInput, {
sliderData: { request: null, response: null },
collectedInputData: { emailSend: false },
sliderSettings: { buttonLoading: false },
})
this.setButtonValues()
const { message } = err
const mapping = {
'A user account with this email already exists': 'email-exists',
// Wolle 'Invitation code already used or does not exist': 'invalid-invitation-token',
}
for (const [pattern, key] of Object.entries(mapping)) {
if (message.includes(pattern))
this.error = {
key,
message: this.$t(`components.registration.signup.form.errors.${key}`),
}
}
if (!this.error) {
this.$toast.error(message)
}
this.$toast.error(
translateErrorMessage(
err.message,
{
'A user account with this email already exists':
'components.registration.signup.form.errors.email-exists',
},
this.$t,
),
)
return false
}
}

View File

@ -133,9 +133,7 @@ export default {
try {
this.dbRequestInProgress = true
console.log('handleSubmitVerify !!! variables: ', variables)
const response = await this.$apollo.query({ query: verifyNonceQuery, variables })
console.log('handleSubmitVerify !!! response: ', response)
this.sliderData.setSliderValuesCallback(null, {
sliderData: { request: { variables }, response: response.data },
})

View File

@ -1,8 +1,10 @@
import { storiesOf } from '@storybook/vue'
import { withA11y } from '@storybook/addon-a11y'
import RegistrationSlider from './RegistrationSlider.vue'
import { action } from '@storybook/addon-actions'
import Vuex from 'vuex'
import helpers from '~/storybook/helpers'
import Vue from 'vue'
import RegistrationSlider from './RegistrationSlider.vue'
const plugins = [
(app = {}) => {
@ -35,12 +37,51 @@ const plugins = [
]
helpers.init({ plugins })
const createStore = ({ loginSuccess }) => {
return new Vuex.Store({
modules: {
auth: {
namespaced: true,
state: () => ({
pending: false,
}),
mutations: {
SET_PENDING(state, pending) {
state.pending = pending
},
},
getters: {
pending(state) {
return !!state.pending
},
},
actions: {
async login({ commit, dispatch }, args) {
action('Vuex action `auth/login`')(args)
return new Promise((resolve, reject) => {
commit('SET_PENDING', true)
setTimeout(() => {
commit('SET_PENDING', false)
if (loginSuccess) {
resolve(loginSuccess)
} else {
reject(new Error('Login unsuccessful'))
}
}, 1000)
})
},
},
},
},
})
}
storiesOf('RegistrationSlider', module)
.addDecorator(withA11y)
.addDecorator(helpers.layout)
.add('invite-code empty', () => ({
components: { RegistrationSlider },
store: helpers.store,
store: createStore({ loginSuccess: true }),
data: () => ({}),
template: `
<registration-slider registrationType="invite-code" />
@ -48,7 +89,7 @@ storiesOf('RegistrationSlider', module)
}))
.add('invite-code with data', () => ({
components: { RegistrationSlider },
store: helpers.store,
store: createStore({ loginSuccess: true }),
data: () => ({
overwriteSliderData: {
collectedInputData: {
@ -74,7 +115,7 @@ storiesOf('RegistrationSlider', module)
}))
.add('public-registration empty', () => ({
components: { RegistrationSlider },
store: helpers.store,
store: createStore({ loginSuccess: true }),
data: () => ({}),
template: `
<registration-slider registrationType="public-registration" />
@ -82,7 +123,7 @@ storiesOf('RegistrationSlider', module)
}))
.add('public-registration with data', () => ({
components: { RegistrationSlider },
store: helpers.store,
store: createStore({ loginSuccess: true }),
data: () => ({
overwriteSliderData: {
collectedInputData: {
@ -108,7 +149,7 @@ storiesOf('RegistrationSlider', module)
}))
.add('invite-mail empty', () => ({
components: { RegistrationSlider },
store: helpers.store,
store: createStore({ loginSuccess: true }),
data: () => ({
overwriteSliderData: {
collectedInputData: {
@ -134,7 +175,7 @@ storiesOf('RegistrationSlider', module)
}))
.add('invite-mail with data', () => ({
components: { RegistrationSlider },
store: helpers.store,
store: createStore({ loginSuccess: true }),
data: () => ({
overwriteSliderData: {
collectedInputData: {
@ -160,7 +201,7 @@ storiesOf('RegistrationSlider', module)
}))
.add('no-public-registration', () => ({
components: { RegistrationSlider },
store: helpers.store,
store: createStore({ loginSuccess: true }),
data: () => ({}),
template: `
<registration-slider registrationType="no-public-registration" />

View File

@ -106,8 +106,8 @@ export default {
validated: false,
data: { request: null, response: null },
button: {
titleIdent: '', // set by slider component
icon: '', // set by slider component
titleIdent: 'components.email.buttonTitle.send', // changed by slider component
icon: 'envelope', // changed by slider component
callback: this.buttonCallback,
sliderCallback: null, // optional set by slot
},
@ -126,12 +126,13 @@ export default {
},
createUserAccount: {
name: 'create-user-account',
titleIdent: this.$t('components.registration.create-user-account.title'),
titleIdent: 'components.registration.create-user-account.title',
validated: false,
data: { request: null, response: null },
button: {
titleIdent: 'Create', // Wolle
titleIdent: 'components.registration.create-user-account.buttonTitle',
icon: 'check',
loading: false,
callback: this.buttonCallback,
sliderCallback: null, // optional set by slot
},
@ -223,14 +224,17 @@ export default {
}
}
if (sliderSettings) {
const { buttonTitleIdent, buttonIcon, buttonSliderCallback } = sliderSettings
if (buttonTitleIdent) {
const { buttonTitleIdent, buttonIcon, buttonLoading, buttonSliderCallback } = sliderSettings
if (buttonTitleIdent !== undefined) {
this.sliderData.sliders[this.sliderIndex].button.titleIdent = buttonTitleIdent
}
if (buttonIcon) {
if (buttonIcon !== undefined) {
this.sliderData.sliders[this.sliderIndex].button.icon = buttonIcon
}
if (buttonSliderCallback) {
if (buttonLoading !== undefined) {
this.sliderData.sliders[this.sliderIndex].button.loading = buttonLoading
}
if (buttonSliderCallback !== undefined) {
this.sliderData.sliders[this.sliderIndex].button.sliderCallback = buttonSliderCallback
}
}
@ -240,6 +244,10 @@ export default {
if (selectedIndex <= this.sliderIndex + 1 && selectedIndex < this.sliderData.sliders.length) {
this.sliderData.sliderIndex = selectedIndex
if (this.sliderData.sliders[this.sliderIndex].button.loading !== undefined) {
this.sliderData.sliders[this.sliderIndex].button.loading = false
}
}
},
buttonCallback(success) {

View File

@ -0,0 +1,12 @@
export default (message, mapping, translate) => {
let translatedMessage = null
for (const [pattern, ident] of Object.entries(mapping)) {
if (message.includes(pattern)) {
translatedMessage = translate(ident)
}
}
if (!translatedMessage) {
translatedMessage = message
}
return translatedMessage
}

View File

@ -121,9 +121,11 @@
},
"components": {
"email": {
"buttonTitleResend": "Erneut senden",
"buttonTitleSend": "Sende E-Mail",
"buttonTitleSkipResend": "Nicht senden",
"buttonTitle": {
"resend": "Erneut senden",
"send": "Sende E-Mail",
"skipResend": "Nicht senden"
},
"form": {
"sendEmailAgain": "E-Mail erneut senden"
}
@ -168,6 +170,7 @@
},
"registration": {
"create-user-account": {
"buttonTitle": "Erstellen",
"error": "Es konnte kein Benutzerkonto erstellt werden!",
"help": "Vielleicht war der Bestätigungscode falsch oder abgelaufen? Wenn das Problem weiterhin besteht, schicke uns gerne eine E-Mail an:",
"success": "Dein Benutzerkonto wurde erstellt!",

View File

@ -121,9 +121,11 @@
},
"components": {
"email": {
"buttonTitleResend": "Resend e-mail",
"buttonTitleSend": "Send e-mail",
"buttonTitleSkipResend": "Skip resend",
"buttonTitle": {
"resend": "Resend e-mail",
"send": "Send e-mail",
"skipResend": "Skip resend"
},
"form": {
"sendEmailAgain": "Send e-mail again"
}
@ -168,6 +170,7 @@
},
"registration": {
"create-user-account": {
"buttonTitle": "Create",
"error": "No user account could be created!",
"help": " Maybe the confirmation was invalid? In case of problems, feel free to ask for help by sending us a mail to:",
"success": "Your account has been created!",