feat: add alerts
This commit is contained in:
parent
2ed124c918
commit
002f8d1b18
35
src/components/ui/AppAlert.vue
Normal file
35
src/components/ui/AppAlert.vue
Normal file
@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="error.message"
|
||||
class="alert"
|
||||
:class="[error.type]"
|
||||
>
|
||||
<p class="alert-title">
|
||||
{{ error.title }}
|
||||
</p>
|
||||
<p>
|
||||
{{ error.message }}
|
||||
</p>
|
||||
|
||||
<span
|
||||
class="alert-close"
|
||||
@click="onClose"
|
||||
>
|
||||
×
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useStore } from 'vuex';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const store = useStore();
|
||||
const error = computed(() => store.state.alert);
|
||||
|
||||
const onClose = () => store.commit('alert/clearAlert');
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@ -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');
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<app-alert />
|
||||
<div class="card">
|
||||
<router-view />
|
||||
</div>
|
||||
@ -7,8 +8,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
import AppAlert from '../components/ui/AppAlert.vue';
|
||||
|
||||
export default {
|
||||
components: {AppAlert},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@ -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,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
49
src/store/modules/alert.module.ts
Normal file
49
src/store/modules/alert.module.ts
Normal file
@ -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<State['title']>;
|
||||
message: Required<State['message']>;
|
||||
type: Required<State['type']>;
|
||||
}
|
||||
|
||||
const alertModule: Module<State, any> = {
|
||||
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;
|
||||
@ -23,7 +23,7 @@ const authModule: Module<any, any> = {
|
||||
},
|
||||
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<any, any> = {
|
||||
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) {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
export const ERROR_MESSAGES = {
|
||||
'INVALID_LOGIN_CREDENTIALS': 'Неправильный логин или пароль',
|
||||
'auth-required': 'Требуется авторизация',
|
||||
}
|
||||
|
||||
@ -54,7 +54,21 @@
|
||||
|
||||
<script setup>
|
||||
import useLoginForm from '../hooks/useLoginForm.ts';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useStore } from 'vuex';
|
||||
import { ERROR_MESSAGES } from '../utils/constants.ts';
|
||||
|
||||
const store = useStore();
|
||||
const route = useRoute();
|
||||
const message = route.query.message;
|
||||
if (message === 'auth-required') {
|
||||
store.dispatch('alert/setAlert', {
|
||||
message: ERROR_MESSAGES[message],
|
||||
type: 'warning',
|
||||
title: 'Ошибка',
|
||||
time: 5000
|
||||
})
|
||||
}
|
||||
const {
|
||||
disabled,
|
||||
eBlur,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user