refactor: 🍰 Refactor THX Page – 2. Step
This commit is contained in:
Wolfgang Huß 2022-05-31 11:20:08 +02:00 committed by GitHub
commit 1640484c93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 157 additions and 307 deletions

View File

@ -45,7 +45,6 @@ module.exports = {
extensions: ['.js', '.vue'],
// TODO: remove ignores
ignores: [
'/site.thx./',
'/form./',
'/time./',
'/decay.types./',
@ -55,7 +54,6 @@ module.exports = {
'settings.password.set',
'settings.password.set-password.text',
'settings.password.subtitle',
'site.login.signin',
],
enableFix: false,
},

View File

@ -4,8 +4,8 @@ import Message from './Message'
const localVue = global.localVue
const propsData = {
headline: 'site.thx.title',
subtitle: 'site.thx.email',
headline: 'Headline text',
subtitle: 'Subtitle text',
buttonText: 'login',
linkTo: '/login',
}
@ -32,8 +32,8 @@ describe('Message', () => {
describe('with button', () => {
it('renders title, subtitle, and button text', () => {
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email')
expect(wrapper.find('.test-message-headline').text()).toBe('Headline text')
expect(wrapper.find('.test-message-subtitle').text()).toBe('Subtitle text')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
@ -51,8 +51,8 @@ describe('Message', () => {
})
it('renders title, subtitle, and button text', () => {
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email')
expect(wrapper.find('.test-message-headline').text()).toBe('Headline text')
expect(wrapper.find('.test-message-subtitle').text()).toBe('Subtitle text')
})
it('button is not shown', () => {

View File

@ -189,7 +189,7 @@ describe('UserCard_FormUserPasswort', () => {
})
it('toasts a success message', () => {
expect(toastSuccessSpy).toBeCalledWith('site.thx.reset')
expect(toastSuccessSpy).toBeCalledWith('message.reset')
})
it('cancels the edit process', () => {

View File

@ -89,7 +89,7 @@ export default {
},
})
.then(() => {
this.toastSuccess(this.$t('site.thx.reset'))
this.toastSuccess(this.$t('message.reset'))
this.cancelEdit()
})
.catch((error) => {

View File

@ -172,6 +172,16 @@
"minus": "",
"pipe": "|"
},
"message": {
"activateEmail": "Dein Konto wurde noch nicht aktiviert. Bitte überprüfe deine E-Mail und klicke den Aktivierungslink oder fordere einen neuen Aktivierungslink über die Password Reset Seite an.",
"checkEmail": "Deine E-Mail wurde erfolgreich verifiziert. Du kannst dich jetzt anmelden.",
"email": "Wir haben dir eine E-Mail gesendet.",
"errorTitle": "Achtung!",
"register": "Du bist jetzt registriert, bitte überprüfe deine Emails und klicke auf den Aktivierungslink.",
"reset": "Dein Passwort wurde geändert.",
"title": "Danke!",
"unsetPassword": "Dein Passwort wurde noch nicht gesetzt. Bitte setze es neu."
},
"navigation": {
"admin_area": "Adminbereich",
"logout": "Abmelden",
@ -240,18 +250,6 @@
"one_number": "Zahl erforderlich.",
"special-char": "Sonderzeichen erforderlich (z.B. _ oder ä)",
"uppercase": "Großbuchstabe erforderlich."
},
"thx": {
"activateEmail": "Dein Konto wurde noch nicht aktiviert. Bitte überprüfe deine E-Mail und klicke den Aktivierungslink oder fordere einen neuen Aktivierungslink über die Password Reset Seite.",
"checkEmail": "Deine E-Mail wurde erfolgreich verifiziert. Du kannst dich jetzt anmelden.",
"email": "Wir haben dir eine E-Mail gesendet.",
"emailActivated": "Danke dass Du deine E-Mail bestätigt hast.",
"errorTitle": "Achtung!",
"register": "Du bist jetzt registriert, bitte überprüfe deine Emails und klicke auf den Aktivierungslink.",
"reset": "Dein Passwort wurde geändert.",
"resetPassword": "Den Code den Du genutzt hast ist zu alt bitte fordere ein neuen über die Passwort Reset Seite an.",
"title": "Danke!",
"unsetPassword": "Dein Passwort wurde noch nicht gesetzt. Bitte setze es neu."
}
},
"success": "Erfolg",

View File

@ -172,6 +172,16 @@
"minus": "",
"pipe": "|"
},
"message": {
"activateEmail": "Your account has not been activated yet. Please check your emails and click the activation link or order a new activation link over the password reset page.",
"checkEmail": "Your email has been successfully verified. You can sign in now.",
"email": "We have sent you an email.",
"errorTitle": "Attention!",
"register": "You are registered now, please check your emails and click the activation link.",
"reset": "Your password has been changed.",
"title": "Thank you!",
"unsetPassword": "Your password has not been set yet. Please set it again."
},
"navigation": {
"admin_area": "Admin Area",
"logout": "Logout",
@ -240,18 +250,6 @@
"one_number": "One number required.",
"special-char": "One special character required (e.g. _ or ä)",
"uppercase": "One uppercase letter required."
},
"thx": {
"activateEmail": "Your account has not been activated yet. Please check your emails and click the activation link or order a new activation link over the password reset page.",
"checkEmail": "Your email has been successfully verified. You can sign in now.",
"email": "We have sent you an email.",
"emailActivated": "Thank you your email has been activated.",
"errorTitle": "Attention!",
"register": "You are registered now, please check your emails and click the activation link.",
"reset": "Your password has been changed.",
"resetPassword": "The code you used was to old please order a new on over the password reset page.",
"title": "Thank you!",
"unsetPassword": "Your password has not been set yet. Please set it again."
}
},
"success": "Success",

View File

@ -111,7 +111,7 @@ describe('ForgotPassword', () => {
it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle')
expect(wrapper.find('.test-message-headline').text()).toBe('message.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('error.email-already-sent')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
@ -121,6 +121,8 @@ describe('ForgotPassword', () => {
})
it.skip('click redirects to "/login"', async () => {
// wrapper.find('.test-message-button').trigger('click')
// await wrapper.vm.$nextTick()
expect(mockRouterPush).toBeCalledWith('/login')
})
@ -144,14 +146,18 @@ describe('ForgotPassword', () => {
it('shows success title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email')
expect(wrapper.find('.test-message-headline').text()).toBe('message.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.email')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
it('button link redirects to "/login"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login')
})
it.skip('click redirects to "/login"', () => {
// expect(mockRouterPush).toBeCalledWith('/login')
})
})
})
})

View File

@ -26,8 +26,8 @@
</b-container>
<b-container v-else>
<message
:headline="success ? $t('site.thx.title') : $t('site.thx.errorTitle')"
:subtitle="success ? $t('site.thx.email') : $t('error.email-already-sent')"
:headline="success ? $t('message.title') : $t('message.errorTitle')"
:subtitle="success ? $t('message.email') : $t('error.email-already-sent')"
:buttonText="$t('login')"
linkTo="/login"
/>

View File

@ -198,8 +198,8 @@ describe('Login', () => {
it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.activateEmail')
expect(wrapper.find('.test-message-headline').text()).toBe('message.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.activateEmail')
expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset')
})
@ -226,8 +226,8 @@ describe('Login', () => {
it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.unsetPassword')
expect(wrapper.find('.test-message-headline').text()).toBe('message.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.unsetPassword')
expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset')
})

View File

@ -41,7 +41,7 @@
</b-container>
<b-container v-else>
<message
:headline="$t('site.thx.errorTitle')"
:headline="$t('message.errorTitle')"
:subtitle="errorSubtitle"
:buttonText="$t('settings.password.reset')"
:linkTo="errorLinkTo"
@ -107,12 +107,12 @@ export default {
.catch((error) => {
if (error.message.includes('User email not validated')) {
this.showPageMessage = true
this.errorSubtitle = this.$t('site.thx.activateEmail')
this.errorSubtitle = this.$t('message.activateEmail')
this.errorLinkTo = '/forgot-password'
this.toastError(this.$t('error.no-account'))
} else if (error.message.includes('User has no password set yet')) {
this.showPageMessage = true
this.errorSubtitle = this.$t('site.thx.unsetPassword')
this.errorSubtitle = this.$t('message.unsetPassword')
this.errorLinkTo = '/reset-password/login'
this.toastError(this.$t('error.no-account'))
} else if (error.message.includes('No user with this credentials')) {

View File

@ -202,8 +202,8 @@ describe('Register', () => {
it('shows success title, subtitle', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.register')
expect(wrapper.find('.test-message-headline').text()).toBe('message.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.register')
})
it('button is not present', () => {

View File

@ -90,7 +90,7 @@
</validation-observer>
</b-container>
<b-container v-else>
<message :headline="$t('site.thx.title')" :subtitle="$t('site.thx.register')" />
<message :headline="$t('message.title')" :subtitle="$t('message.register')" />
</b-container>
</div>
</template>

View File

@ -118,14 +118,32 @@ describe('ResetPassword', () => {
await flushPromises()
})
it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('message.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe(
'...email was sent more than 23 hours and 10 minutes ago',
)
expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset')
})
it('button link directs to "/forgot-password/resetPassword"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe(
'/forgot-password/resetPassword',
)
})
it('toasts an error message', () => {
expect(toastErrorSpy).toHaveBeenCalledWith(
'...email was sent more than 23 hours and 10 minutes ago',
)
})
it('router pushes to /forgot-password/resetPassword', () => {
expect(routerPushMock).toHaveBeenCalledWith('/forgot-password/resetPassword')
it.skip('click redirects to "/forgot-password/resetPassword"', () => {
// wrapper.find('.test-message-button').trigger('click')
// await flushPromises()
// await wrapper.vm.$nextTick()
// expect(routerPushMock).toHaveBeenCalledWith('/forgot-password/resetPassword')
})
})
@ -137,9 +155,26 @@ describe('ResetPassword', () => {
await flushPromises()
})
it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('message.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('Error')
expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset')
})
it('button link directs to "/forgot-password/resetPassword"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe(
'/forgot-password/resetPassword',
)
})
it('toasts an error message', () => {
expect(toastErrorSpy).toHaveBeenCalledWith('Error')
})
it.skip('click redirects to "/forgot-password/resetPassword"', () => {
// expect(routerPushMock).toHaveBeenCalledWith('/forgot-password/resetPassword')
})
})
describe('server response with success on /checkEmail', () => {
@ -168,30 +203,19 @@ describe('ResetPassword', () => {
)
})
it('redirects to "/thx/checkEmail"', () => {
expect(routerPushMock).toHaveBeenCalledWith('/thx/checkEmail')
it('shows message title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('message.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.checkEmail')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
describe('with param code', () => {
beforeEach(async () => {
mocks.$route.params.code = 'the-most-secret-code-ever'
apolloMutationMock.mockResolvedValue({
data: {
resetPassword: 'success',
},
})
wrapper = Wrapper()
await wrapper.findAll('input').at(0).setValue('Aa123456_')
await wrapper.findAll('input').at(1).setValue('Aa123456_')
await wrapper.find('form').trigger('submit')
await flushPromises()
})
it('button link directs to "/login"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login')
})
it('redirects to "/thx/checkEmail/the-most-secret-code-ever"', () => {
expect(routerPushMock).toHaveBeenCalledWith(
'/thx/checkEmail/the-most-secret-code-ever',
)
})
it.skip('click redirects to "/login"', () => {
// expect(routerPushMock).toHaveBeenCalledWith('/login')
})
})
@ -210,8 +234,19 @@ describe('ResetPassword', () => {
await flushPromises()
})
it('redirects to "/thx/resetPassword"', () => {
expect(routerPushMock).toHaveBeenCalledWith('/thx/resetPassword')
it('shows message title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('message.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.reset')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
it('button link directs to "/login"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login')
})
it.skip('click redirects to "/login"', () => {
// expect(routerPushMock).toHaveBeenCalledWith('/login')
})
})
})

View File

@ -1,5 +1,5 @@
<template>
<div class="resetpwd-form">
<div v-if="enterData" class="resetpwd-form">
<div class="pb-5">{{ $t('site.resetPassword.heading') }}</div>
<validation-observer ref="observer" v-slot="{ handleSubmit }">
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
@ -13,12 +13,21 @@
</b-form>
</validation-observer>
</div>
<div v-else>
<message
:headline="messageHeadline"
:subtitle="messageSubtitle"
:buttonText="messageButtonText"
:linkTo="messageButtonLinktTo"
/>
</div>
</template>
<script>
import InputPasswordConfirmation from '@/components/Inputs/InputPasswordConfirmation'
import { setPassword } from '@/graphql/mutations'
import { queryOptIn } from '@/graphql/queries'
import InputPasswordConfirmation from '@/components/Inputs/InputPasswordConfirmation'
import Message from '@/components/Message/Message'
const textFields = {
reset: {
@ -39,6 +48,7 @@ export default {
name: 'ResetPassword',
components: {
InputPasswordConfirmation,
Message,
},
data() {
return {
@ -47,8 +57,17 @@ export default {
passwordRepeat: '',
},
displaySetup: {},
showPageMessage: false,
messageHeadline: null,
messageSubtitle: null,
messageButtonText: null,
messageButtonLinktTo: null,
}
},
created() {
this.$emit('set-mobile-start', false)
this.setDisplaySetup()
},
methods: {
async onSubmit() {
this.$apollo
@ -61,24 +80,33 @@ export default {
})
.then(() => {
this.form.password = ''
if (this.$route.path.includes('checkEmail')) {
if (this.$route.params.code) {
this.$router.push('/thx/checkEmail/' + this.$route.params.code)
} else {
this.$router.push('/thx/checkEmail')
}
} else {
this.$router.push('/thx/resetPassword')
}
this.form.passwordRepeat = ''
this.showPageMessage = true
this.messageHeadline = this.$t('message.title')
this.messageSubtitle = this.$route.path.includes('checkEmail')
? this.$t('message.checkEmail')
: this.$t('message.reset')
this.messageButtonText = this.$t('login')
this.messageButtonLinktTo = '/login'
})
.catch((error) => {
this.toastError(error.message)
let errorMessage
if (
error.message.match(
/email was sent more than ([0-9]+ hours)?( and )?([0-9]+ minutes)? ago/,
)
)
this.$router.push('/forgot-password/resetPassword')
) {
errorMessage = error.message
} else {
errorMessage = error.message
}
this.showPageMessage = true
this.messageHeadline = this.$t('message.errorTitle')
this.messageSubtitle = errorMessage
this.messageButtonText = this.$t('settings.password.reset')
this.messageButtonLinktTo = '/forgot-password/resetPassword'
this.toastError(errorMessage)
})
},
checkOptInCode() {
@ -105,9 +133,10 @@ export default {
}
},
},
created() {
this.$emit('set-mobile-start', false)
this.setDisplaySetup()
computed: {
enterData() {
return !this.showPageMessage
},
},
}
</script>

View File

@ -1,101 +0,0 @@
import { mount } from '@vue/test-utils'
import Thx from './thx'
const localVue = global.localVue
const createMockObject = (comingFrom) => {
return {
$t: jest.fn((t) => t),
$route: {
params: {
comingFrom,
},
},
}
}
describe('Thx', () => {
let wrapper
const Wrapper = (mocks) => {
return mount(Thx, { localVue, mocks })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper(createMockObject('forgotPassword'))
})
it('renders the thx page', () => {
expect(wrapper.find('div.header').exists()).toBeTruthy()
})
it('renders the title', () => {
expect(wrapper.find('p.h1').text()).toBe('site.thx.title')
})
})
describe('coming from /forgot-password', () => {
beforeEach(() => {
wrapper = Wrapper(createMockObject('forgotPassword'))
})
it('renders the thanks text', () => {
expect(wrapper.find('p.h4').text()).toBe('site.thx.email')
})
it('renders the thanks redirect button', () => {
expect(wrapper.find('a.btn').text()).toBe('login')
})
it('links the redirect button to /login', () => {
expect(wrapper.find('a.btn').attributes('href')).toBe('/login')
})
})
describe('coming from /reset-password', () => {
beforeEach(() => {
wrapper = Wrapper(createMockObject('resetPassword'))
})
it('renders the thanks text', () => {
expect(wrapper.find('p.h4').text()).toBe('site.thx.reset')
})
it('renders the thanks redirect button', () => {
expect(wrapper.find('a.btn').text()).toBe('login')
})
it('links the redirect button to /login', () => {
expect(wrapper.find('a.btn').attributes('href')).toBe('/login')
})
})
describe('coming from /register', () => {
beforeEach(() => {
wrapper = Wrapper(createMockObject('register'))
})
it('renders the thanks text', () => {
expect(wrapper.find('p.h4').text()).toBe('site.thx.register')
})
})
describe('coming from /login', () => {
beforeEach(() => {
wrapper = Wrapper(createMockObject('login'))
})
it('renders the thanks text', () => {
expect(wrapper.find('p.h4').text()).toBe('site.thx.activateEmail')
})
it('renders the thanks redirect button', () => {
expect(wrapper.find('a.btn').text()).toBe('settings.password.reset')
})
it('links the redirect button to /forgot-password', () => {
expect(wrapper.find('a.btn').attributes('href')).toBe('/forgot-password')
})
})
})

View File

@ -1,76 +0,0 @@
<template>
<div>
<!-- Header -->
<div class="header py-7 py-lg-8 pt-lg-9">
<b-container>
<div class="header-body text-center mb-7">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<p class="h1">{{ $t(displaySetup.headline) }}</p>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<p class="h4">{{ $t(displaySetup.subtitle) }}</p>
<hr />
<b-button v-if="$route.params.code" :to="`/login/${$route.params.code}`">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
{{ $t(displaySetup.button) }}
</b-button>
<b-button v-else-if="displaySetup.linkTo" :to="displaySetup.linkTo">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
{{ $t(displaySetup.button) }}
</b-button>
</div>
</b-container>
</div>
<!-- Page content -->
</div>
</template>
<script>
const textFields = {
forgotPassword: {
headline: 'site.thx.title',
subtitle: 'site.thx.email',
button: 'login',
linkTo: '/login',
},
resetPassword: {
headline: 'site.thx.title',
subtitle: 'site.thx.reset',
button: 'login',
linkTo: '/login',
},
register: {
headline: 'site.thx.title',
subtitle: 'site.thx.register',
button: 'signin',
// linkTo: '/login',
},
checkEmail: {
headline: 'site.thx.title',
subtitle: 'site.thx.checkEmail',
button: 'login',
linkTo: '/login',
},
login: {
headline: 'site.thx.errorTitle',
subtitle: 'site.thx.activateEmail',
button: 'settings.password.reset',
linkTo: '/forgot-password',
},
}
export default {
name: 'Thx',
data() {
return {
displaySetup: {},
}
},
methods: {
setDisplaySetup(from) {
this.displaySetup = textFields[this.$route.params.comingFrom]
},
},
created() {
this.setDisplaySetup()
},
}
</script>

View File

@ -49,8 +49,8 @@ describe('router', () => {
expect(routes.find((r) => r.path === '/').redirect()).toEqual({ path: '/login' })
})
it('has seventeen routes defined', () => {
expect(routes).toHaveLength(17)
it('has sixteen routes defined', () => {
expect(routes).toHaveLength(16)
})
describe('overview', () => {
@ -111,31 +111,6 @@ describe('router', () => {
})
})
describe('thx', () => {
const thx = routes.find((r) => r.path === '/thx/:comingFrom/:code?')
it('loads the "Thx" page', async () => {
const component = await thx.component()
expect(component.default.name).toBe('Thx')
})
describe('beforeEnter', () => {
const beforeEnter = thx.beforeEnter
const next = jest.fn()
it('redirects to login when not coming from a valid page', () => {
beforeEnter({}, { path: '' }, next)
expect(next).toBeCalledWith({ path: '/login' })
})
it('enters the page when coming from a valid page', () => {
jest.resetAllMocks()
beforeEnter({}, { path: '/forgot-password' }, next)
expect(next).toBeCalledWith()
})
})
})
describe('forgot password', () => {
it('loads the "ForgotPassword" page', async () => {
const component = await routes.find((r) => r.path === '/forgot-password').component()

View File

@ -46,18 +46,6 @@ const routes = [
path: '/register/:code?',
component: () => import('@/pages/Register.vue'),
},
{
path: '/thx/:comingFrom/:code?',
component: () => import('@/pages/thx.vue'),
beforeEnter: (to, from, next) => {
const validFrom = ['forgot-password', 'reset-password', 'register', 'login', 'checkEmail']
if (!validFrom.includes(from.path.split('/')[1])) {
next({ path: '/login' })
} else {
next()
}
},
},
{
path: '/forgot-password',
component: () => import('@/pages/ForgotPassword.vue'),