Client - error message style (wip)
Need some updates api side.
This commit is contained in:
parent
4bbfb800cb
commit
6c770ed76b
41
fittrackee_client/src/components/Common/ErrorMessage.vue
Normal file
41
fittrackee_client/src/components/Common/ErrorMessage.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="error-message">
|
||||
<ul v-if="Array.isArray(message)">
|
||||
<li v-for="(submessage, index) in message" :key="index">
|
||||
{{ t(submessage) }}
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else>{{ t(message) }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ErrorMessage',
|
||||
props: {
|
||||
message: [String, Array],
|
||||
},
|
||||
setup() {
|
||||
const { t } = useI18n()
|
||||
return {
|
||||
t,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '~@/scss/base';
|
||||
.error-message {
|
||||
background: var(--error-background-color);
|
||||
color: var(--error-color);
|
||||
|
||||
border-radius: 4px;
|
||||
|
||||
margin: $default-margin;
|
||||
padding: $default-padding;
|
||||
}
|
||||
</style>
|
@ -36,9 +36,7 @@
|
||||
</div>
|
||||
<button type="submit">{{ t(buttonText) }}</button>
|
||||
</form>
|
||||
<p v-if="errorMessage">
|
||||
{{ errorMessage }}
|
||||
</p>
|
||||
<ErrorMessage :message="errorMessages" v-if="errorMessages" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -51,9 +49,13 @@
|
||||
import { IFormData } from '@/interfaces'
|
||||
import { ROOT_STORE, USER_STORE } from '@/store/constants'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import ErrorMessage from '@/components/Common/ErrorMessage.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LoginForm',
|
||||
components: {
|
||||
ErrorMessage,
|
||||
},
|
||||
props: {
|
||||
action: {
|
||||
type: String,
|
||||
@ -73,8 +75,8 @@
|
||||
const buttonText: ComputedRef<string> = computed(() =>
|
||||
props.action === 'register' ? 'buttons.REGISTER' : 'buttons.LOGIN'
|
||||
)
|
||||
const errorMessage: ComputedRef<string | null> = computed(
|
||||
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGE]
|
||||
const errorMessages: ComputedRef<string | string[] | null> = computed(
|
||||
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGES]
|
||||
)
|
||||
|
||||
function onSubmit(actionType: string) {
|
||||
@ -87,7 +89,7 @@
|
||||
return {
|
||||
t,
|
||||
buttonText,
|
||||
errorMessage,
|
||||
errorMessages,
|
||||
formData,
|
||||
onSubmit,
|
||||
}
|
||||
@ -119,6 +121,7 @@
|
||||
|
||||
@media screen and (max-width: $medium-limit) {
|
||||
height: auto;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
10
fittrackee_client/src/locales/en/api.json
Normal file
10
fittrackee_client/src/locales/en/api.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ERROR": {
|
||||
"UNKNOWN": "Error. Please try again or contact the administrator.",
|
||||
"Invalid credentials": "Invalid credentials.",
|
||||
"Password and password confirmation don't match": "Password and password confirmation don't match.",
|
||||
"Password: 8 characters required": "Password: 8 characters required.",
|
||||
"Username: 3 to 12 characters required": "Username: 3 to 12 characters required.",
|
||||
"Valid email must be provided": "Valid email must be provided."
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import AdministrationTranslations from './administration.json'
|
||||
import ApiTranslations from './api.json'
|
||||
import ButtonsTranslations from './buttons.json'
|
||||
import CommonTranslations from './common.json'
|
||||
import DashboardTranslations from './dashboard.json'
|
||||
@ -9,6 +10,7 @@ import WorkoutsTranslations from './workouts.json'
|
||||
|
||||
export default {
|
||||
administration: AdministrationTranslations,
|
||||
api: ApiTranslations,
|
||||
buttons: ButtonsTranslations,
|
||||
common: CommonTranslations,
|
||||
dashboard: DashboardTranslations,
|
||||
|
10
fittrackee_client/src/locales/fr/api.json
Normal file
10
fittrackee_client/src/locales/fr/api.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"ERROR": {
|
||||
"UNKNOWN": "Erreur. Veuillez réessayer ou contacter l'administrateur.",
|
||||
"Invalid credentials": "Identifiants invalides.",
|
||||
"Password and password confirmation don't match": "Les mots de passe saisis sont différents.",
|
||||
"Password: 8 characters required": "8 caractères minimum pour le mot de passe.",
|
||||
"Username: 3 to 12 characters required": "3 à 12 caractères requis pour le nom.",
|
||||
"Valid email must be provided": "L'email fourni n'est pas valide."
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import AdministrationTranslations from './administration.json'
|
||||
import ApiTranslations from './api.json'
|
||||
import ButtonsTranslations from './buttons.json'
|
||||
import CommonTranslations from './common.json'
|
||||
import DashboardTranslations from './dashboard.json'
|
||||
@ -9,6 +10,7 @@ import WorkoutsTranslations from './workouts.json'
|
||||
|
||||
export default {
|
||||
administration: AdministrationTranslations,
|
||||
api: ApiTranslations,
|
||||
buttons: ButtonsTranslations,
|
||||
common: CommonTranslations,
|
||||
dashboard: DashboardTranslations,
|
||||
|
@ -14,4 +14,7 @@
|
||||
--footer-border-color: #ebeef3;
|
||||
--footer-color: #8b8c8c;
|
||||
|
||||
--error-background-color: #ffd2d2;
|
||||
--error-color: #db1924;
|
||||
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
export enum RootGetters {
|
||||
ERROR_MESSAGE = 'ERROR_MESSAGE',
|
||||
ERROR_MESSAGES = 'ERROR_MESSAGES',
|
||||
LANGUAGE = 'LANGUAGE',
|
||||
}
|
||||
|
||||
export enum RootMutations {
|
||||
EMPTY_ERROR_MESSAGE = 'EMPTY_ERROR_MESSAGE',
|
||||
SET_ERROR_MESSAGE = 'SET_ERROR_MESSAGE',
|
||||
EMPTY_ERROR_MESSAGES = 'EMPTY_ERROR_MESSAGES',
|
||||
SET_ERROR_MESSAGES = 'SET_ERROR_MESSAGES',
|
||||
UPDATE_LANG = 'UPDATE_LANG',
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import { ROOT_STORE } from '@/store/constants'
|
||||
import { IRootState, IRootGetters } from '@/store/modules/root/interfaces'
|
||||
|
||||
export const getters: GetterTree<IRootState, IRootState> & IRootGetters = {
|
||||
[ROOT_STORE.GETTERS.ERROR_MESSAGE]: (state: IRootState) => {
|
||||
return state.errorMessage
|
||||
[ROOT_STORE.GETTERS.ERROR_MESSAGES]: (state: IRootState) => {
|
||||
return state.errorMessages
|
||||
},
|
||||
[ROOT_STORE.GETTERS.LANGUAGE]: (state: IRootState) => {
|
||||
return state.language
|
||||
|
@ -3,10 +3,12 @@ import { ROOT_STORE } from '@/store/constants'
|
||||
export interface IRootState {
|
||||
root: boolean
|
||||
language: string
|
||||
errorMessage: string | null
|
||||
errorMessages: string | string[] | null
|
||||
}
|
||||
|
||||
export interface IRootGetters {
|
||||
[ROOT_STORE.GETTERS.ERROR_MESSAGE](state: IRootState): string | null
|
||||
[ROOT_STORE.GETTERS.ERROR_MESSAGES](
|
||||
state: IRootState
|
||||
): string | string[] | null
|
||||
[ROOT_STORE.GETTERS.LANGUAGE](state: IRootState): string
|
||||
}
|
||||
|
@ -5,14 +5,14 @@ import { IRootState } from '@/store/modules/root/interfaces'
|
||||
import { TRootMutations } from '@/store/modules/root/types'
|
||||
|
||||
export const mutations: MutationTree<IRootState> & TRootMutations = {
|
||||
[ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGE](state: IRootState) {
|
||||
state.errorMessage = null
|
||||
[ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES](state: IRootState) {
|
||||
state.errorMessages = null
|
||||
},
|
||||
[ROOT_STORE.MUTATIONS.SET_ERROR_MESSAGE](
|
||||
[ROOT_STORE.MUTATIONS.SET_ERROR_MESSAGES](
|
||||
state: IRootState,
|
||||
errorMessage: string
|
||||
errorMessages: string
|
||||
) {
|
||||
state.errorMessage = errorMessage
|
||||
state.errorMessages = errorMessages
|
||||
},
|
||||
[ROOT_STORE.MUTATIONS.UPDATE_LANG](state: IRootState, language: string) {
|
||||
state.language = language
|
||||
|
@ -3,5 +3,5 @@ import { IRootState } from '@/store/modules/root/interfaces'
|
||||
export const state: IRootState = {
|
||||
root: true,
|
||||
language: 'en',
|
||||
errorMessage: null,
|
||||
errorMessages: null,
|
||||
}
|
||||
|
@ -4,8 +4,11 @@ import { ROOT_STORE } from '@/store/constants'
|
||||
import { IRootGetters, IRootState } from '@/store/modules/root/interfaces'
|
||||
|
||||
export type TRootMutations<S = IRootState> = {
|
||||
[ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGE](state: S): void
|
||||
[ROOT_STORE.MUTATIONS.SET_ERROR_MESSAGE](state: S, errorMessage: string): void
|
||||
[ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES](state: S): void
|
||||
[ROOT_STORE.MUTATIONS.SET_ERROR_MESSAGES](
|
||||
state: S,
|
||||
errorMessages: string
|
||||
): void
|
||||
[ROOT_STORE.MUTATIONS.UPDATE_LANG](state: S, language: string): void
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ export const actions: ActionTree<IUserState, IRootState> & IUserActions = {
|
||||
[USER_STORE.ACTIONS.GET_USER_PROFILE](
|
||||
context: ActionContext<IUserState, IRootState>
|
||||
): void {
|
||||
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGE)
|
||||
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
||||
authApi
|
||||
.get('auth/profile')
|
||||
.then((res) => {
|
||||
@ -49,7 +49,7 @@ export const actions: ActionTree<IUserState, IRootState> & IUserActions = {
|
||||
context: ActionContext<IUserState, IRootState>,
|
||||
data: ILoginOrRegisterData
|
||||
): void {
|
||||
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGE)
|
||||
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
||||
api
|
||||
.post(`/auth/${data.actionType}`, data.formData)
|
||||
.then((res) => {
|
||||
@ -71,7 +71,7 @@ export const actions: ActionTree<IUserState, IRootState> & IUserActions = {
|
||||
): void {
|
||||
localStorage.removeItem('authToken')
|
||||
context.commit(USER_STORE.MUTATIONS.CLEAR_AUTH_USER_TOKEN)
|
||||
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGE)
|
||||
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
||||
router.push('/login')
|
||||
},
|
||||
}
|
||||
|
@ -10,12 +10,15 @@ export const getApiUrl = (): string => {
|
||||
: 'http://localhost:5000/api'
|
||||
}
|
||||
|
||||
// TODO: update api error messages to remove these workarounds
|
||||
const removeLastEndOfLine = (text: string): string => text.replace(/\n$/gm, '')
|
||||
const removeLastDot = (text: string): string => text.replace(/\.$/gm, '')
|
||||
export const handleError = (
|
||||
context: ActionContext<IUserState, IRootState>,
|
||||
error: AxiosError | null,
|
||||
msg = 'error.UNKNOWN'
|
||||
msg = 'UNKNOWN'
|
||||
): void => {
|
||||
const errorMessage = !error
|
||||
let errorMessages = !error
|
||||
? msg
|
||||
: error.response
|
||||
? error.response.data.message
|
||||
@ -24,5 +27,13 @@ export const handleError = (
|
||||
: error.message
|
||||
? error.message
|
||||
: msg
|
||||
context.commit(ROOT_STORE.MUTATIONS.SET_ERROR_MESSAGE, errorMessage)
|
||||
errorMessages = removeLastEndOfLine(errorMessages)
|
||||
context.commit(
|
||||
ROOT_STORE.MUTATIONS.SET_ERROR_MESSAGES,
|
||||
errorMessages.includes('\n')
|
||||
? errorMessages
|
||||
.split('\n')
|
||||
.map((m: string) => `api.ERROR.${removeLastDot(m)}`)
|
||||
: `api.ERROR.${removeLastDot(errorMessages)}`
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user