Ocelot-Social/webapp/components/Registration/RegistrationSlideEmail.vue
sebastian2357 b1c19d0c94
fix(webapp): optimize registration layout (#8630)
* - fixed nowrap for button
- restyled bullets for slider
- relocated back links
- removed icons

* - removed icon from RegistrationSlideEmail too

* - added media query for padding

* - fixed missing constants

* - fixed padding in no-header layout

* - fixed sticky footer in registration flow

* - removed icons from inputs

* - set fixed height for back link

* - fixed invite code placeholder

* - added auto submit to invite and email code forms
- fixed layout password inputs
- added layout to checkboxes (create)
- removed unnecessary texts
- moved backLink for password-reset
- tidied up create layout

* fixed margin

* - fixed nonceLength

* lint fixes

* corrected path

---------

Co-authored-by: Sebastian Stein <sebastian@codepassion.de>
Co-authored-by: Ulf Gebhardt <ulf.gebhardt@webcraft-media.de>
2025-06-11 16:45:03 +00:00

190 lines
5.7 KiB
Vue

<template>
<ds-form
class="enter-email"
v-model="formData"
:schema="formSchema"
@input="handleInput"
@input-valid="handleInputValid"
>
<ds-text>
{{ $t('components.registration.signup.form.description') }}
</ds-text>
<ds-input :placeholder="$t('login.email')" type="email" id="email" model="email" name="email" />
<slot></slot>
<ds-text v-if="sliderData.collectedInputData.emailSend">
<input id="checkbox" type="checkbox" v-model="sendEmailAgain" :checked="sendEmailAgain" />
<label for="checkbox0">
{{ $t('components.registration.email.form.sendEmailAgain') }}
</label>
</ds-text>
<ds-space margin="xxx-small" />
</ds-form>
</template>
<script>
import gql from 'graphql-tag'
import metadata from '~/constants/metadata'
import { isEmail } from 'validator'
import translateErrorMessage from '~/components/utils/TranslateErrorMessage'
export const SignupMutation = gql`
mutation ($email: String!, $locale: String!, $inviteCode: String) {
Signup(email: $email, locale: $locale, inviteCode: $inviteCode) {
email
}
}
`
export default {
name: 'RegistrationSlideEmail',
props: {
sliderData: { type: Object, required: true },
},
data() {
return {
metadata,
formData: {
email: '',
},
formSchema: {
email: {
type: 'email',
required: true,
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,
}
},
mounted: function () {
this.formData.email = this.sliderData.collectedInputData.email
? this.sliderData.collectedInputData.email
: ''
this.sendValidation()
this.sliderData.setSliderValuesCallback(this.validInput, {
sliderSettings: {
...this.buttonValues().sliderSettings,
buttonSliderCallback: this.onNextClick,
},
})
},
watch: {
sendEmailAgain() {
this.setButtonValues()
},
},
computed: {
sliderIndex() {
return this.sliderData.sliderIndex // to have a shorter notation
},
validInput() {
return isEmail(this.formData.email)
},
},
methods: {
async sendValidation() {
const { email } = this.formData
this.sliderData.setSliderValuesCallback(this.validInput, { collectedInputData: { email } })
},
async handleInput() {
this.sendValidation()
},
async handleInputValid() {
this.sendValidation()
},
buttonValues() {
return {
sliderSettings: {
buttonTitleIdent: this.sliderData.collectedInputData.emailSend
? this.sendEmailAgain
? 'components.registration.email.buttonTitle.resend'
: 'components.registration.email.buttonTitle.skipResend'
: 'components.registration.email.buttonTitle.send',
buttonIcon: null,
},
}
},
setButtonValues() {
this.sliderData.setSliderValuesCallback(this.validInput, this.buttonValues())
},
isVariablesRequested(variables) {
return (
this.sliderData.sliders[this.sliderIndex].data.request &&
this.sliderData.sliders[this.sliderIndex].data.request.variables &&
this.sliderData.sliders[this.sliderIndex].data.request.variables.email === variables.email
)
},
async onNextClick() {
const { email } = this.formData
const { inviteCode = null } = this.sliderData.collectedInputData
const variables = { email, inviteCode, locale: this.$i18n.locale() }
if (this.sliderData.collectedInputData.emailSend && !this.sendEmailAgain) {
return true
}
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 loginMiddleware of backend
this.sliderData.setSliderValuesCallback(null, {
sliderData: { request: { variables }, response: response.data },
})
if (this.sliderData.sliders[this.sliderIndex].data.response) {
this.sliderData.setSliderValuesCallback(this.validInput, {
collectedInputData: { emailSend: true },
})
this.setButtonValues()
const { email: responseEmail } =
this.sliderData.sliders[this.sliderIndex].data.response.Signup
this.$toast.success(
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()
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
}
}
},
},
}
</script>
<style>
.space-top {
margin-top: 6ex;
}
</style>