From 002f8d1b18e6f8bb8cab17fe58198b31521bbcaa Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Wed, 5 Feb 2025 07:50:03 +0300 Subject: [PATCH] feat: add alerts --- src/components/ui/AppAlert.vue | 35 ++++++++++++++++++++++ src/hooks/useLoginForm.ts | 6 ++-- src/layout/AuthLayout.vue | 6 +++- src/store/index.ts | 4 ++- src/store/modules/alert.module.ts | 49 +++++++++++++++++++++++++++++++ src/store/modules/auth.module.ts | 10 +++++-- src/utils/constants.ts | 1 + src/views/AuthPage.vue | 14 +++++++++ 8 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 src/components/ui/AppAlert.vue create mode 100644 src/store/modules/alert.module.ts diff --git a/src/components/ui/AppAlert.vue b/src/components/ui/AppAlert.vue new file mode 100644 index 0000000..54d90f1 --- /dev/null +++ b/src/components/ui/AppAlert.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/hooks/useLoginForm.ts b/src/hooks/useLoginForm.ts index 3e9f4ef..8016870 100644 --- a/src/hooks/useLoginForm.ts +++ b/src/hooks/useLoginForm.ts @@ -27,8 +27,10 @@ const useLoginForm = () => { }); const onSubmit = handleSubmit(async (values) => { - await store.dispatch('auth/login', values); - await router.push({name: PAGE.HOME}); + try { + await store.dispatch('auth/login', values); + await router.push({name: PAGE.HOME}); + } catch (e) {} }) const {value: email, errorMessage: eError, handleBlur: eBlur} = useField('email'); diff --git a/src/layout/AuthLayout.vue b/src/layout/AuthLayout.vue index 16fc17e..83e9371 100644 --- a/src/layout/AuthLayout.vue +++ b/src/layout/AuthLayout.vue @@ -1,5 +1,6 @@ diff --git a/src/store/index.ts b/src/store/index.ts index 62cf1c5..b4a2dcf 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,5 +1,6 @@ import { createLogger, createStore } from 'vuex' import authModule from './modules/auth.module.ts'; +import alertModule from './modules/alert.module.ts'; const isDev = process.env.NODE_ENV === 'development'; @@ -8,7 +9,8 @@ const store = createStore({ isDev && createLogger() ].filter(Boolean), modules: { - auth: authModule + auth: authModule, + alert: alertModule, }, }) diff --git a/src/store/modules/alert.module.ts b/src/store/modules/alert.module.ts new file mode 100644 index 0000000..e52dd20 --- /dev/null +++ b/src/store/modules/alert.module.ts @@ -0,0 +1,49 @@ +import type { Module } from 'vuex'; + +type State = { + title: string | null; + message: string | null; + type: 'danger' | 'warning' | 'primary' | null; +} + +type SetAlertPayload = { + time?: number; + title: Required; + message: Required; + type: Required; +} + +const alertModule: Module = { + namespaced: true, + state: { + title: null, + message: null, + type: null, + }, + mutations: { + setAlert(state, payload: SetAlertPayload) { + state.message = payload.message; + state.type = payload.type + state.title = payload.title + }, + clearAlert(state) { + state.message = null; + state.type = null; + state.title = null; + }, + }, + actions: { + setAlert: async (context, payload: SetAlertPayload) => { + const { commit } = context; + const { time = 3000, ...restPayload } = payload; + + commit('setAlert', restPayload); + + setTimeout(() => { + commit('clearAlert'); + }, time) + } + } +} + +export default alertModule; diff --git a/src/store/modules/auth.module.ts b/src/store/modules/auth.module.ts index c01d0ac..61149c8 100644 --- a/src/store/modules/auth.module.ts +++ b/src/store/modules/auth.module.ts @@ -23,7 +23,7 @@ const authModule: Module = { }, actions: { async login(context, payload: {email: string, password: string}) { - const { commit } = context; + const { commit, dispatch } = context; try { const { data } = await authApi.login({ email: payload.email, @@ -34,8 +34,12 @@ const authModule: Module = { commit('setToken', data.idToken); } catch (e) { // @ts-ignore - const message = e.response?.data.error.message as keyof typeof ERROR_MESSAGES; - alert(ERROR_MESSAGES?.[message] || 'Ошибка при попытке авторизации'); + const errorKey = e.response?.data.error.message as keyof typeof ERROR_MESSAGES; + const errorMessage = ERROR_MESSAGES[errorKey] || 'Ошибка при попытке авторизации' + + await dispatch('alert/setAlert', { message: errorMessage, type: 'danger', title: 'Ошибка авторизации', time: 5000 }, {root: true}) + + throw new Error(errorMessage) } }, logout(context) { diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 6fb88ed..9460c8f 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -1,3 +1,4 @@ export const ERROR_MESSAGES = { 'INVALID_LOGIN_CREDENTIALS': 'Неправильный логин или пароль', + 'auth-required': 'Требуется авторизация', } diff --git a/src/views/AuthPage.vue b/src/views/AuthPage.vue index c091a45..a065b25 100644 --- a/src/views/AuthPage.vue +++ b/src/views/AuthPage.vue @@ -54,7 +54,21 @@