refactor: DRY template in pages, fix signup flow

This commit is contained in:
roschaefer 2019-10-07 22:36:44 +02:00 committed by mattwr18
parent 1dc4bc1411
commit 4c7cc0a9cf
6 changed files with 151 additions and 137 deletions

View File

@ -1,98 +1,78 @@
<template>
<ds-container width="small">
<ds-card v-if="success" class="success">
<ds-space>
<sweetalert-icon icon="success" />
<ds-text align="center" bold color="success">
{{ $t('registration.create-user-account.success') }}
</ds-text>
</ds-space>
</ds-card>
<ds-card v-else class="create-account-card">
<client-only>
<locale-switch />
</client-only>
<ds-space centered>
<img
class="create-account-image"
alt="Create an account for Human Connection"
src="/img/sign-up/nicetomeetyou.svg"
<ds-space v-if="success">
<sweetalert-icon icon="success" />
<ds-text align="center" bold color="success">
{{ $t('registration.create-user-account.success') }}
</ds-text>
</ds-space>
<div v-else class="create-account-card">
<ds-space margin-top="large">
<ds-heading size="h3">
{{ $t('components.registration.create-user-account.title') }}
</ds-heading>
</ds-space>
<ds-form class="create-user-account" v-model="formData" :schema="formSchema" @submit="submit">
<template v-slot="{ errors }">
<ds-input
id="name"
model="name"
icon="user"
:label="$t('settings.data.labelName')"
:placeholder="$t('settings.data.namePlaceholder')"
/>
</ds-space>
<ds-space>
<ds-heading size="h3">
{{ $t('registration.create-user-account.title') }}
</ds-heading>
</ds-space>
<ds-input
id="about"
model="about"
type="textarea"
rows="3"
:label="$t('settings.data.labelBio')"
:placeholder="$t('settings.data.labelBio')"
/>
<ds-input
id="password"
model="password"
type="password"
autocomplete="off"
:label="$t('settings.security.change-password.label-new-password')"
/>
<ds-input
id="passwordConfirmation"
model="passwordConfirmation"
type="password"
autocomplete="off"
:label="$t('settings.security.change-password.label-new-password-confirm')"
/>
<password-strength :password="formData.password" />
<ds-form class="create-user-account" v-model="formData" :schema="formSchema" @submit="submit">
<template v-slot="{ errors }">
<ds-flex gutter="base">
<ds-flex-item width="100%">
<ds-input
id="name"
model="name"
icon="user"
:label="$t('settings.data.labelName')"
:placeholder="$t('settings.data.namePlaceholder')"
/>
<ds-input
id="about"
model="about"
type="textarea"
rows="3"
:label="$t('settings.data.labelBio')"
:placeholder="$t('settings.data.labelBio')"
/>
<ds-input
id="password"
model="password"
type="password"
autocomplete="off"
:label="$t('settings.security.change-password.label-new-password')"
/>
<ds-input
id="passwordConfirmation"
model="passwordConfirmation"
type="password"
autocomplete="off"
:label="$t('settings.security.change-password.label-new-password-confirm')"
/>
<password-strength :password="formData.password" />
<ds-text>
<input
id="checkbox"
type="checkbox"
v-model="termsAndConditionsConfirmed"
:checked="termsAndConditionsConfirmed"
/>
<label
for="checkbox"
v-html="$t('termsAndConditions.termsAndConditionsConfirmed')"
></label>
</ds-text>
</ds-flex-item>
<ds-flex-item width="100%">
<ds-space class="backendErrors" v-if="backendErrors">
<ds-text align="center" bold color="danger">{{ backendErrors.message }}</ds-text>
</ds-space>
<ds-button
style="float: right;"
icon="check"
type="submit"
:loading="$apollo.loading"
:disabled="errors || !termsAndConditionsConfirmed"
primary
>
{{ $t('actions.save') }}
</ds-button>
</ds-flex-item>
</ds-flex>
</template>
</ds-form>
</ds-card>
</ds-container>
<ds-text>
<input
id="checkbox"
type="checkbox"
v-model="termsAndConditionsConfirmed"
:checked="termsAndConditionsConfirmed"
/>
<label
for="checkbox"
v-html="$t('termsAndConditions.termsAndConditionsConfirmed')"
></label>
</ds-text>
<ds-space class="backendErrors" v-if="backendErrors">
<ds-text align="center" bold color="danger">{{ backendErrors.message }}</ds-text>
</ds-space>
<ds-button
style="float: right;"
icon="check"
type="submit"
:loading="$apollo.loading"
:disabled="errors || !termsAndConditionsConfirmed"
primary
>
{{ $t('actions.save') }}
</ds-button>
</template>
</ds-form>
</div>
</template>
<script>
@ -101,13 +81,11 @@ import { SweetalertIcon } from 'vue-sweetalert-icons'
import PasswordForm from '~/components/utils/PasswordFormHelper'
import { VERSION } from '~/constants/terms-and-conditions-version.js'
import { SignupVerificationMutation } from '~/graphql/Registration.js'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
export default {
components: {
PasswordStrength,
SweetalertIcon,
LocaleSwitch,
},
data() {
const passwordForm = PasswordForm({ translate: this.$t })

View File

@ -69,15 +69,18 @@ describe('Signup', () => {
})
it('displays a message that a mail for email verification was sent', () => {
const expected = ['registration.signup.form.success', { email: 'mail@example.org' }]
const expected = [
'components.registration.signup.form.success',
{ email: 'mail@example.org' },
]
expect(mocks.$t).toHaveBeenCalledWith(...expected)
})
describe('after animation', () => {
beforeEach(jest.runAllTimers)
it('emits `handleSubmitted`', () => {
expect(wrapper.emitted('handleSubmitted')).toEqual([[{ email: 'mail@example.org' }]])
it('emits `submit`', () => {
expect(wrapper.emitted('submit')).toEqual([[{ email: 'mail@example.org' }]])
})
})
})
@ -121,7 +124,9 @@ describe('Signup', () => {
it('explains the error', async () => {
await action()
expect(mocks.$t).toHaveBeenCalledWith('registration.signup.form.errors.email-exists')
expect(mocks.$t).toHaveBeenCalledWith(
'components.registration.signup.form.errors.email-exists',
)
})
})
@ -137,7 +142,7 @@ describe('Signup', () => {
it('explains the error', async () => {
await action()
expect(mocks.$t).toHaveBeenCalledWith(
'registration.signup.form.errors.invalid-invitation-token',
'components.registration.signup.form.errors.invalid-invitation-token',
)
})
})

View File

@ -1,7 +1,6 @@
<template>
<ds-space margin="large">
<ds-space v-if="!success && !error" margin="large">
<ds-form
v-if="!success && !error"
@input="handleInput"
@input-valid="handleInputValid"
v-model="formData"
@ -42,18 +41,19 @@
>
{{ $t('components.registration.signup.form.submit') }}
</ds-button>
<slot></slot>
</ds-form>
<div v-else>
<template v-if="!error">
<sweetalert-icon icon="info" />
<ds-text align="center" v-html="submitMessage" />
</template>
<template v-else>
<sweetalert-icon icon="error" />
<ds-text align="center">{{ error.message }}</ds-text>
</template>
</div>
</ds-space>
<div v-else margin="large">
<template v-if="!error">
<sweetalert-icon icon="info" />
<ds-text align="center" v-html="submitMessage" />
</template>
<template v-else>
<sweetalert-icon icon="error" />
<ds-text align="center">{{ error.message }}</ds-text>
</template>
</div>
</template>
<script>
@ -103,7 +103,7 @@ export default {
computed: {
submitMessage() {
const { email } = this.formData
return this.$t('registration.signup.form.success', { email })
return this.$t('components.registration.signup.form.success', { email })
},
},
methods: {
@ -123,7 +123,7 @@ export default {
this.success = true
setTimeout(() => {
this.$emit('handleSubmitted', { email })
this.$emit('submit', { email })
}, 3000)
} catch (err) {
const { message } = err
@ -133,7 +133,10 @@ export default {
}
for (const [pattern, key] of Object.entries(mapping)) {
if (message.includes(pattern))
this.error = { key, message: this.$t(`registration.signup.form.errors.${key}`) }
this.error = {
key,
message: this.$t(`components.registration.signup.form.errors.${key}`),
}
}
if (!this.error) {
this.$toast.error(message)

View File

@ -1,9 +1,29 @@
<template>
<nuxt-child />
<ds-container width="medium">
<ds-card>
<ds-flex gutter="small">
<ds-flex-item :width="{ base: '100%', sm: '50%' }">
<client-only>
<locale-switch offset="5" />
</client-only>
<ds-space margin-top="small" margin-bottom="xxx-small">
<img class="signup-image" alt="Human Connection" src="/img/sign-up/nicetomeetyou.svg" />
</ds-space>
</ds-flex-item>
<ds-flex-item :width="{ base: '100%', sm: '50%' }" centered>
<nuxt-child />
</ds-flex-item>
</ds-flex>
</ds-card>
</ds-container>
</template>
<script>
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
export default {
components: {
LocaleSwitch,
},
layout: 'no-header',
asyncData({ store, redirect }) {
if (store.getters['auth/isLoggedIn']) {

View File

@ -1,7 +1,25 @@
<template>
<h1>Enter nonce</h1>
<enter-nonce :email="email" @nonceEntered="nonceEntered">
<ds-space margin-bottom="xxx-small" margin-top="large" centered>
<nuxt-link to="/login">{{ $t('site.back-to-login') }}</nuxt-link>
</ds-space>
</enter-nonce>
</template>
<script>
export default {}
import EnterNonce from '~/components/EnterNonce/EnterNonce.vue'
export default {
components: {
EnterNonce,
},
data() {
const { email = '' } = this.$route.query
return { email }
},
methods: {
nonceEntered({ email, nonce }) {
this.$router.push({ path: 'create-user-account', query: { email, nonce } })
},
},
}
</script>

View File

@ -1,33 +1,23 @@
<template>
<ds-container width="medium">
<ds-card>
<ds-flex gutter="small">
<ds-flex-item :width="{ base: '100%', sm: '50%' }" centered>
<client-only>
<locale-switch offset="5" />
</client-only>
<ds-space margin-top="small" margin-bottom="xxx-small" centered>
<img class="signup-image" alt="Human Connection" src="/img/sign-up/nicetomeetyou.svg" />
</ds-space>
</ds-flex-item>
<ds-flex-item :width="{ base: '100%', sm: '50%' }" centered>
<signup :invitation="false" />
<nuxt-link to="/login">{{ $t('site.back-to-login') }}</nuxt-link>
</ds-flex-item>
</ds-flex>
</ds-card>
</ds-container>
<signup :invitation="false" @submit="handleSubmitted">
<ds-space centered margin-top="large">
<nuxt-link to="/login">{{ $t('site.back-to-login') }}</nuxt-link>
</ds-space>
</signup>
</template>
<script>
import Signup from '~/components/Registration/Signup'
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
export default {
layout: 'no-header',
components: {
Signup,
LocaleSwitch,
},
methods: {
handleSubmitted({ email }) {
this.$router.push({ path: 'enter-nonce', query: { email } })
},
},
}
</script>