Implement e-mail resend functionality

This commit is contained in:
Wolfgang Huß 2021-02-27 17:02:55 +01:00
parent 091ed52b54
commit e3bf47679e
6 changed files with 177 additions and 106 deletions

View File

@ -64,7 +64,7 @@ export default {
if (this.sliderData.sliders[this.sliderIndex].button.slotOnNextClick) { if (this.sliderData.sliders[this.sliderIndex].button.slotOnNextClick) {
success = await this.sliderData.sliders[this.sliderIndex].button.slotOnNextClick() success = await this.sliderData.sliders[this.sliderIndex].button.slotOnNextClick()
} }
// this.sliderData.sliders[this.sliderIndex].button.callback() success = success && this.sliderData.sliders[this.sliderIndex].button.callback(success)
if (success && this.sliderIndex < this.sliderData.sliders.length - 1) { if (success && this.sliderIndex < this.sliderData.sliders.length - 1) {
this.sliderData.sliderSelectorCallback(this.sliderIndex + 1) this.sliderData.sliderSelectorCallback(this.sliderIndex + 1)
} }

View File

@ -289,7 +289,7 @@ export default {
} }
// Wolle validate in backend // Wolle validate in backend
// toaster // toaster
this.sliderData.setSliderValuesCallback(this.valid, { collectedInputData: values }, {}) this.sliderData.setSliderValuesCallback(this.valid, { collectedInputData: values })
}, },
async handleInput() { async handleInput() {
this.sendValidation() this.sendValidation()

View File

@ -1,38 +1,38 @@
<template> <template>
<ds-space v-if="!data && !error" margin="large"> <!-- Wolle <ds-space v-if="!data && !error" margin="large"> -->
<ds-form <ds-form
v-model="formData" v-model="formData"
:schema="formSchema" :schema="formSchema"
@input="handleInput" @input="handleInput"
@input-valid="handleInputValid" @input-valid="handleInputValid"
> >
<!-- Wolle <h1> <!-- Wolle <h1>
{{ {{
invitation invitation
? $t('profile.invites.title', metadata) ? $t('profile.invites.title', metadata)
: $t('components.registration.signup.title', metadata) : $t('components.registration.signup.title', metadata)
}} }}
</h1> --> </h1> -->
<ds-text <ds-text
v-if="token" v-if="token"
v-html="$t('registration.signup.form.invitation-code', { code: token })" v-html="$t('registration.signup.form.invitation-code', { code: token })"
/> />
<ds-text> <ds-text>
{{ {{
invitation invitation
? $t('profile.invites.description') ? $t('profile.invites.description')
: $t('components.registration.signup.form.description') : $t('components.registration.signup.form.description')
}} }}
</ds-text> </ds-text>
<ds-input <ds-input
:placeholder="invitation ? $t('profile.invites.emailPlaceholder') : $t('login.email')" :placeholder="invitation ? $t('profile.invites.emailPlaceholder') : $t('login.email')"
type="email" type="email"
id="email" id="email"
model="email" model="email"
name="email" name="email"
icon="envelope" icon="envelope"
/> />
<!-- Wolle <base-button <!-- Wolle <base-button
:disabled="disabled" :disabled="disabled"
:loading="$apollo.loading" :loading="$apollo.loading"
filled filled
@ -42,24 +42,17 @@
> >
{{ $t('components.registration.signup.form.submit') }} {{ $t('components.registration.signup.form.submit') }}
</base-button> --> </base-button> -->
<slot></slot> <slot></slot>
<ds-text v-if="sliderData.collectedInputData.emailSend"> <ds-text v-if="sliderData.collectedInputData.emailSend">
<!-- Wolle <ds-text v-if="sliderData.collectedInputData.emailSend"> --> <!-- Wolle <ds-text v-if="sliderData.collectedInputData.emailSend"> -->
<input <input id="checkbox" type="checkbox" v-model="sendEmailAgain" :checked="sendEmailAgain" />
id="checkbox" <label for="checkbox0">
type="checkbox" <!-- Wolle {{ $t('termsAndConditions.termsAndConditionsConfirmed') }} -->
v-model="sendEmailAgain" {{ 'Send e-mail again' }}
:checked="sendEmailAgain" </label>
/> </ds-text>
<label for="checkbox0"> </ds-form>
<!-- Wolle {{ $t('termsAndConditions.termsAndConditionsConfirmed') }} --> <!-- Wolle </ds-space>
Send e-mail again
<!-- <br />
<nuxt-link to="/terms-and-conditions">{{ $t('site.termsAndConditions') }}</nuxt-link> -->
</label>
</ds-text>
</ds-form>
</ds-space>
<div v-else margin="large"> <div v-else margin="large">
<template v-if="!error"> <template v-if="!error">
<transition name="ds-transition-fade"> <transition name="ds-transition-fade">
@ -76,7 +69,7 @@
<nuxt-link to="/login">{{ $t('site.back-to-login') }}</nuxt-link> <nuxt-link to="/login">{{ $t('site.back-to-login') }}</nuxt-link>
</ds-space> </ds-space>
</template> </template>
</div> </div> -->
</template> </template>
<script> <script>
@ -84,7 +77,7 @@ import gql from 'graphql-tag'
import metadata from '~/constants/metadata' import metadata from '~/constants/metadata'
import { isEmail } from 'validator' import { isEmail } from 'validator'
import normalizeEmail from '~/components/utils/NormalizeEmail' import normalizeEmail from '~/components/utils/NormalizeEmail'
import { SweetalertIcon } from 'vue-sweetalert-icons' // Wolle import { SweetalertIcon } from 'vue-sweetalert-icons'
export const SignupMutation = gql` export const SignupMutation = gql`
mutation($email: String!) { mutation($email: String!) {
@ -103,7 +96,7 @@ export const SignupByInvitationMutation = gql`
export default { export default {
name: 'RegistrationItemEnterEmail', name: 'RegistrationItemEnterEmail',
components: { components: {
SweetalertIcon, // Wolle SweetalertIcon,
}, },
props: { props: {
sliderData: { type: Object, required: true }, sliderData: { type: Object, required: true },
@ -123,10 +116,13 @@ export default {
message: this.$t('common.validations.email'), message: this.$t('common.validations.email'),
}, },
}, },
// TODO: Our styleguide does not support checkmarks.
// Integrate termsAndConditionsConfirmed into `this.formData` once we
// have checkmarks available.
sendEmailAgain: false, sendEmailAgain: false,
// Wolle disabled: true, // Wolle disabled: true,
data: null, // Wolle data: null,
error: null, error: null, // Wolle
} }
}, },
mounted: function () { mounted: function () {
@ -137,17 +133,26 @@ export default {
: '' : ''
this.sendValidation() this.sendValidation()
this.sliderData.setSliderValuesCallback(this.validInput, {}, this.onNextClick) this.sliderData.setSliderValuesCallback(
this.validInput,
this.buttonValues(),
this.onNextClick,
)
}) })
}, },
watch: {
sendEmailAgain() {
this.setButtonValues()
},
},
computed: { computed: {
sliderIndex() { sliderIndex() {
return this.sliderData.sliderIndex return this.sliderData.sliderIndex
}, },
submitMessage() { // Wolle submitMessage() {
const { email } = this.data.Signup // const { email } = this.data.Signup
return this.$t('components.registration.signup.form.success', { email }) // return this.$t('components.registration.signup.form.success', { email })
}, // },
validInput() { validInput() {
return isEmail(this.formData.email) return isEmail(this.formData.email)
}, },
@ -160,7 +165,7 @@ export default {
const { email } = this.formData const { email } = this.formData
const values = { email } const values = { email }
this.sliderData.setSliderValuesCallback(this.validInput, { collectedInputData: values }, {}) this.sliderData.setSliderValuesCallback(this.validInput, { collectedInputData: values })
}, },
async handleInput() { async handleInput() {
this.sendValidation() this.sendValidation()
@ -168,36 +173,73 @@ export default {
async handleInputValid() { async handleInputValid() {
this.sendValidation() this.sendValidation()
}, },
// enterEmailButtonTitle(emailSend) {
// // return emailSend ? 'Resend e-mail' : 'Send e-mail'
// return emailSend ? (this.sendEmailAgain ? 'Resend e-mail' : 'Skip resend') : 'Send e-mail' // Wolle
// },
// enterEmailButtonIcon(emailSend) {
// // return emailSend ? 'Resend e-mail' : 'Send e-mail'
// return emailSend ? (this.sendEmailAgain ? 'envelope' : 'arrow-right') : 'envelope' // Wolle
// },
buttonValues() {
return {
sliderSettings: {
// buttonTitle: this.enterEmailButtonTitle(this.sliderData.collectedInputData.emailSend),
// buttonIcon: this.enterEmailButtonIcon(this.sliderData.collectedInputData.emailSend),
buttonTitle: this.sliderData.collectedInputData.emailSend
? this.sendEmailAgain
? 'Resend e-mail'
: 'Skip resend'
: 'Send e-mail', // Wolle
buttonIcon: this.sliderData.collectedInputData.emailSend
? this.sendEmailAgain
? 'envelope'
: 'arrow-right'
: 'envelope', // Wolle
},
}
},
setButtonValues() {
this.sliderData.setSliderValuesCallback(this.validInput, this.buttonValues())
},
async onNextClick() { async onNextClick() {
const mutation = this.token ? SignupByInvitationMutation : SignupMutation const mutation = this.token ? SignupByInvitationMutation : SignupMutation
const { token } = this const { token } = this
const { email } = this.formData const { email } = this.formData
const variables = { email, token } const variables = { email, token }
// Wolle test for resend if (!this.sendEmailAgain && this.sliderData.collectedInputData.emailSend) {
return true
}
if ( if (
this.sendEmailAgain ||
!this.sliderData.sliders[this.sliderIndex].data.request || !this.sliderData.sliders[this.sliderIndex].data.request ||
(this.sliderData.sliders[this.sliderIndex].data.request && !this.sliderData.sliders[this.sliderIndex].data.request.variables) || (this.sliderData.sliders[this.sliderIndex].data.request &&
!this.sliderData.sliders[this.sliderIndex].data.request.variables) ||
(this.sliderData.sliders[this.sliderIndex].data.request && (this.sliderData.sliders[this.sliderIndex].data.request &&
this.sliderData.sliders[this.sliderIndex].data.request.variables && this.sliderData.sliders[this.sliderIndex].data.request.variables &&
!this.sliderData.sliders[this.sliderIndex].data.request.variables === variables) !this.sliderData.sliders[this.sliderIndex].data.request.variables === variables)
) { ) {
// this.sliderData.sliders[this.sliderIndex].data = { this.sliderData.setSliderValuesCallback(
// ...this.sliderData.sliders[this.sliderIndex].data, this.sliderData.sliders[this.sliderIndex].validated,
// request: { variables }, { sliderData: { request: { variables }, response: null } },
// } )
this.sliderData.setSliderValuesCallback(this.sliderData.sliders[this.sliderIndex].validated, { sliderData: { request: { variables }, response: null } })
try { try {
const response = await this.$apollo.mutate({ mutation, variables }) // e-mail is send in emailMiddleware of backend const response = await this.$apollo.mutate({ mutation, variables }) // e-mail is send in emailMiddleware of backend
// this.sliderData.sliders[this.sliderIndex].data = { this.sliderData.setSliderValuesCallback(
// ...this.sliderData.sliders[this.sliderIndex].data, this.sliderData.sliders[this.sliderIndex].validated,
// response: response.data, { sliderData: { response: response.data } },
// } )
this.sliderData.setSliderValuesCallback(this.sliderData.sliders[this.sliderIndex].validated, { sliderData: { response: response.data } })
if (this.sliderData.sliders[this.sliderIndex].data.response) { if (this.sliderData.sliders[this.sliderIndex].data.response) {
this.sliderData.collectedInputData.emailSend = true // this.sliderData.collectedInputData.emailSend = true
this.sliderData.setSliderValuesCallback(this.validInput, {
collectedInputData: { emailSend: true },
})
this.setButtonValues()
const { email: respnseEmail } = const { email: respnseEmail } =
this.sliderData.sliders[this.sliderIndex].data.response.Signup || this.sliderData.sliders[this.sliderIndex].data.response.Signup ||
this.sliderData.sliders[this.sliderIndex].data.response.SignupByInvitation this.sliderData.sliders[this.sliderIndex].data.response.SignupByInvitation
@ -207,9 +249,15 @@ export default {
} }
return true return true
} catch (err) { } catch (err) {
// this.sliderData.sliders[this.sliderIndex].data = { request: null, response: null } this.sliderData.setSliderValuesCallback(
this.sliderData.setSliderValuesCallback(this.sliderData.sliders[this.sliderIndex].validated, { sliderData: { request: null, response: null } }) this.sliderData.sliders[this.sliderIndex].validated,
this.sliderData.collectedInputData.emailSend = false { sliderData: { request: null, response: null } },
)
// this.sliderData.collectedInputData.emailSend = false
this.sliderData.setSliderValuesCallback(this.validInput, {
collectedInputData: { emailSend: false },
})
this.setButtonValues()
const { message } = err const { message } = err
const mapping = { const mapping = {

View File

@ -92,19 +92,23 @@ export default {
if ( if (
!this.sliderData.sliders[this.sliderIndex].data.request || !this.sliderData.sliders[this.sliderIndex].data.request ||
(this.sliderData.sliders[this.sliderIndex].data.request && !this.sliderData.sliders[this.sliderIndex].data.request.variables) || (this.sliderData.sliders[this.sliderIndex].data.request &&
!this.sliderData.sliders[this.sliderIndex].data.request.variables) ||
(this.sliderData.sliders[this.sliderIndex].data.request && (this.sliderData.sliders[this.sliderIndex].data.request &&
this.sliderData.sliders[this.sliderIndex].data.request.variables && this.sliderData.sliders[this.sliderIndex].data.request.variables &&
!this.sliderData.sliders[this.sliderIndex].data.request.variables === variables) !this.sliderData.sliders[this.sliderIndex].data.request.variables === variables)
) { ) {
// this.sliderData.sliders[this.sliderIndex].data.request.variables = variables this.sliderData.setSliderValuesCallback(
// this.sliderData.sliders[this.sliderIndex].data.request = { variables } this.sliderData.sliders[this.sliderIndex].validated,
this.sliderData.setSliderValuesCallback(this.sliderData.sliders[this.sliderIndex].validated, { sliderData: { request: { variables }, response: null } }) { sliderData: { request: { variables }, response: null } },
)
try { try {
const response = await this.$apollo.query({ query: isValidInviteCodeQuery, variables }) const response = await this.$apollo.query({ query: isValidInviteCodeQuery, variables })
// this.sliderData.sliders[this.sliderIndex].data.response = response.data this.sliderData.setSliderValuesCallback(
this.sliderData.setSliderValuesCallback(this.sliderData.sliders[this.sliderIndex].validated, { sliderData: { response: response.data } }) this.sliderData.sliders[this.sliderIndex].validated,
{ sliderData: { response: response.data } },
)
if ( if (
this.sliderData.sliders[this.sliderIndex].data.response && this.sliderData.sliders[this.sliderIndex].data.response &&
@ -115,8 +119,10 @@ export default {
) )
} }
} catch (err) { } catch (err) {
// this.sliderData.sliders[this.sliderIndex].data.response = { isValidInviteCode: false } this.sliderData.setSliderValuesCallback(
this.sliderData.setSliderValuesCallback(this.sliderData.sliders[this.sliderIndex].validated, { sliderData: { response: { isValidInviteCode: false } } }) this.sliderData.sliders[this.sliderIndex].validated,
{ sliderData: { response: { isValidInviteCode: false } } },
)
const { message } = err const { message } = err
this.$toast.error(message) this.$toast.error(message)

View File

@ -51,7 +51,7 @@ storiesOf('RegistrationSlider', module)
collectedInputData: { collectedInputData: {
inviteCode: 'IN1T6Y', inviteCode: 'IN1T6Y',
email: 'wolle.huss@pjannto.com', email: 'wolle.huss@pjannto.com',
emailSend: true, emailSend: false,
nonce: 'NTRSCZ', nonce: 'NTRSCZ',
name: 'Wolle', name: 'Wolle',
password: 'Hello', password: 'Hello',
@ -115,7 +115,7 @@ storiesOf('RegistrationSlider', module)
collectedInputData: { collectedInputData: {
inviteCode: null, inviteCode: null,
email: 'wolle.huss@pjannto.com', email: 'wolle.huss@pjannto.com',
emailSend: true, emailSend: false,
nonce: null, nonce: null,
name: null, name: null,
password: null, password: null,

View File

@ -24,10 +24,7 @@
> >
<!-- Wolle !!! may create same source with 'webapp/pages/registration/signup.vue' --> <!-- Wolle !!! may create same source with 'webapp/pages/registration/signup.vue' -->
<!-- <signup v-if="publicRegistration" :invitation="false" @submit="handleSubmitted"> --> <!-- <signup v-if="publicRegistration" :invitation="false" @submit="handleSubmitted"> -->
<registration-item-enter-email <registration-item-enter-email :sliderData="sliderData" :invitation="false" />
:sliderData="sliderData"
:invitation="false"
/>
</template> </template>
<template <template
@ -104,9 +101,8 @@ export default {
validated: false, validated: false,
data: { request: null, response: null }, data: { request: null, response: null },
button: { button: {
// title: 'Send E-Mail', // Wolle title: '', // set by slider component
title: this.enterEmailButtonTitle(this.overwriteSliderData.emailSend), // Wolle icon: '', // set by slider component
icon: 'envelope',
callback: this.buttonCallback, callback: this.buttonCallback,
slotOnNextClick: null, // optional set by slot slotOnNextClick: null, // optional set by slot
}, },
@ -190,11 +186,19 @@ export default {
}, },
}, },
methods: { methods: {
enterEmailButtonTitle(emailSend) { // Wolle enterEmailButtonTitle(emailSend) {
// return emailSend ? 'Resend e-mail' : 'Send e-mail' // // return emailSend ? 'Resend e-mail' : 'Send e-mail'
return emailSend ? 'Skip send' : 'Send e-mail' // Wolle // return emailSend ? 'Skip resend' : 'Send e-mail' // Wolle
}, // },
setSliderValuesCallback(isValid, { collectedInputData, sliderData, sliderSettings }, slotOnNextClick = null) { // enterEmailButtonIcon(emailSend) {
// // return emailSend ? 'Resend e-mail' : 'Send e-mail'
// return emailSend ? 'arrow-right' : 'envelope' // Wolle
// },
setSliderValuesCallback(
isValid,
{ collectedInputData, sliderData, sliderSettings },
slotOnNextClick = null,
) {
this.sliderData.sliders[this.sliderIndex].validated = isValid this.sliderData.sliders[this.sliderIndex].validated = isValid
if (collectedInputData) { if (collectedInputData) {
@ -206,13 +210,23 @@ export default {
if (sliderData) { if (sliderData) {
if (this.sliderData.sliders[this.sliderIndex].data) { if (this.sliderData.sliders[this.sliderIndex].data) {
this.sliderData.sliders[this.sliderIndex].data = { this.sliderData.sliders[this.sliderIndex].data = {
request: sliderData.request ? sliderData.request : this.sliderData.sliders[this.sliderIndex].data.request, request: sliderData.request
response: sliderData.response ? sliderData.response : this.sliderData.sliders[this.sliderIndex].data.response, ? sliderData.request
: this.sliderData.sliders[this.sliderIndex].data.request,
response: sliderData.response
? sliderData.response
: this.sliderData.sliders[this.sliderIndex].data.response,
} }
} }
} }
if (sliderSettings) { if (sliderSettings) {
const { buttonTitle, buttonIcon } = sliderSettings
if (buttonTitle) {
this.sliderData.sliders[this.sliderIndex].button.title = buttonTitle
}
if (buttonIcon) {
this.sliderData.sliders[this.sliderIndex].button.icon = buttonIcon
}
} }
if (slotOnNextClick) { if (slotOnNextClick) {
@ -221,15 +235,18 @@ export default {
}, },
sliderSelectorCallback(selectedIndex) { sliderSelectorCallback(selectedIndex) {
if (selectedIndex <= this.sliderIndex + 1 && selectedIndex < this.sliderData.sliders.length) { if (selectedIndex <= this.sliderIndex + 1 && selectedIndex < this.sliderData.sliders.length) {
if (this.sliderData.sliders[this.sliderIndex].name === 'enter-email') { // Wolle if (this.sliderData.sliders[this.sliderIndex].name === 'enter-email') {
this.sliderData.sliders[this.sliderIndex].button.title = this.enterEmailButtonTitle( // this.sliderData.sliders[this.sliderIndex].button.title = this.enterEmailButtonTitle(
this.sliderData.collectedInputData.emailSend, // this.sliderData.collectedInputData.emailSend,
) // )
} // this.sliderData.sliders[this.sliderIndex].button.icon = this.enterEmailButtonIcon(
// this.sliderData.collectedInputData.emailSend,
// )
// }
this.sliderData.sliderIndex = selectedIndex this.sliderData.sliderIndex = selectedIndex
} }
}, },
buttonCallback() { buttonCallback(success) {
// Wolle // Wolle
// if (this.sliderData.sliders[this.sliderIndex].name === 'enter-email') { // if (this.sliderData.sliders[this.sliderIndex].name === 'enter-email') {
// // if (this.sliderData.sliders[this.sliderIndex].button.slotOnNextClick) { // // if (this.sliderData.sliders[this.sliderIndex].button.slotOnNextClick) {
@ -239,7 +256,6 @@ export default {
// this.sliderData.collectedInputData.emailSend, // this.sliderData.collectedInputData.emailSend,
// ) // )
// } // }
// if (this.sliderIndex === this.sliderData.sliders.length - 1) { // if (this.sliderIndex === this.sliderData.sliders.length - 1) {
// // console.log('submit data: ', this.sliderData.collectedInputData) // // console.log('submit data: ', this.sliderData.collectedInputData)
// } else { // } else {
@ -250,6 +266,7 @@ export default {
// } // }
// } // }
// } // }
return success
}, },
}, },
} }