Skip to content
Original file line number Diff line number Diff line change
@@ -1,62 +1,84 @@
<template>

<MessageLayout
<StudioMessageLayout
:header="$tr('activationExpiredTitle')"
:text="$tr('activationExpiredText')"
>
<VForm
ref="form"
lazy-validation
<form
class="request-activation-form"
novalidate
@submit.prevent="requestActivationLink"
>
<Banner
:text="$tr('activationRequestFailed')"
:value="error"
<StudioBanner
v-if="error"
error
class="mb-4"
/>
<EmailField
class="banner"
>
{{ $tr('activationRequestFailed') }}
</StudioBanner>
<StudioEmailField
v-model="email"
autofocus
:label="$tr('emailLabel')"
:errorMessages="errors.email ? [emailErrorText] : []"

@rtibblesbot rtibblesbot Jul 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — addressed in the current code.

suggestion: With generateFormMixin, the email setter runs the validator on every v-model update, so errorMessages can now appear after the very first keystroke rather than on blur/submit as before. Matches Create.vue's existing behavior, but flagging since it's a UX change not called out in the issue.

@rtibblesbot rtibblesbot Jul 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved — addressed in the current code.

suggestion: With generateFormMixin, the email setter runs the validator on every v-model update, so error text can now appear after the first keystroke rather than on blur/submit as before. Matches Create.vue's existing behavior, but it's a UX shift not called out in the issue.

/>
<KButton
primary
class="w-100"
:text="$tr('submitButton')"
type="submit"
/>
</VForm>
</MessageLayout>
</form>
</StudioMessageLayout>

</template>


<script>

import { mapActions } from 'vuex';
import MessageLayout from '../../components/MessageLayout';
import EmailField from 'shared/views/form/EmailField';
import Banner from 'shared/views/Banner';
import StudioMessageLayout from '../../components/StudioMessageLayout';
import StudioEmailField from '../../components/form/StudioEmailField';
import StudioBanner from 'shared/views/StudioBanner';
import commonStrings from 'shared/translator';
import { generateFormMixin } from 'shared/mixins';

const formMixin = generateFormMixin({
email: {
required: true,
validator: v => Boolean(v && v.trim()) && /.+@.+\..+/.test(v),
},
});

export default {
name: 'RequestNewActivationLink',
components: {
MessageLayout,
EmailField,
Banner,
StudioMessageLayout,
StudioEmailField,
StudioBanner,
},
mixins: [formMixin],
data() {
return {
email: '',
error: false,
};
},
computed: {
emailErrorText() {
if (!this.email || !this.email.trim()) {
/* eslint-disable-next-line kolibri/vue-no-undefined-string-uses */
return commonStrings.$tr('fieldRequired');
}
return this.$tr('emailValidationMessage');
},
},
methods: {
...mapActions('account', ['sendActivationLink']),
requestActivationLink() {
this.error = false;
if (this.$refs.form.validate()) {
this.sendActivationLink(this.email)
const formData = this.clean();
if (this.validate(formData)) {
this.sendActivationLink(formData.email)
.then(() => {
this.$router.replace({ name: 'ActivationLinkReSent' }).catch(() => {});
})
Expand All @@ -71,6 +93,8 @@
activationExpiredText: 'This activation link has been used already or has expired.',
submitButton: 'Submit',
activationRequestFailed: 'Failed to send a new activation link. Please try again.',
emailLabel: 'Email',
emailValidationMessage: 'Please enter a valid email address',
},
};

Expand All @@ -79,6 +103,17 @@

<style lang="scss" scoped>

.request-activation-form {
width: 400px;
max-width: 100%;
text-align: left;
}

.banner {
width: 100%;
margin-bottom: 16px;
}

.w-100 {
width: 100%;
}
Expand Down
Loading