Client - display page error if can not fetch app config
This commit is contained in:
parent
0b95b93e06
commit
9fc70fcf23
@ -1,30 +1,51 @@
|
||||
<template>
|
||||
<NavBar />
|
||||
<div class="app-container">
|
||||
<router-view />
|
||||
<div v-if="appLoading" class="app-container">
|
||||
<div class="app-loading">
|
||||
<Loader />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="app-container">
|
||||
<router-view v-if="appConfig" />
|
||||
<NoConfig v-else />
|
||||
</div>
|
||||
<Footer />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onBeforeMount } from 'vue'
|
||||
import { computed, ComputedRef, defineComponent, onBeforeMount } from 'vue'
|
||||
|
||||
import { ROOT_STORE } from '@/store/constants'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { IAppConfig } from '@/store/modules/root/interfaces'
|
||||
import Footer from '@/components/Footer.vue'
|
||||
import Loader from '@/components/Common/Loader.vue'
|
||||
import NavBar from '@/components/NavBar.vue'
|
||||
import NoConfig from '@/components/NoConfig.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App',
|
||||
components: {
|
||||
Footer,
|
||||
Loader,
|
||||
NavBar,
|
||||
NoConfig,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore()
|
||||
const appConfig: ComputedRef<IAppConfig> = computed(
|
||||
() => store.getters[ROOT_STORE.GETTERS.APP_CONFIG]
|
||||
)
|
||||
const appLoading: ComputedRef<boolean> = computed(
|
||||
() => store.getters[ROOT_STORE.GETTERS.APP_LOADING]
|
||||
)
|
||||
onBeforeMount(() =>
|
||||
store.dispatch(ROOT_STORE.ACTIONS.GET_APPLICATION_CONFIG)
|
||||
)
|
||||
return {
|
||||
appConfig,
|
||||
appLoading,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@ -33,5 +54,11 @@
|
||||
@import '~@/scss/base';
|
||||
.app-container {
|
||||
height: $app-height;
|
||||
|
||||
.app-loading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
31
fittrackee_client/src/components/Common/Loader.vue
Normal file
31
fittrackee_client/src/components/Common/Loader.vue
Normal file
@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<div class="loader" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
export default defineComponent({
|
||||
name: 'Loader',
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '~@/scss/base';
|
||||
.loader {
|
||||
animation: spin 2s linear infinite;
|
||||
border: 14px solid var(--app-loading-color);
|
||||
border-top: 14px solid var(--app-loading-top-color);
|
||||
border-radius: 50%;
|
||||
height: 60px;
|
||||
margin-left: 41%;
|
||||
width: 60px;
|
||||
}
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
84
fittrackee_client/src/components/NoConfig.vue
Normal file
84
fittrackee_client/src/components/NoConfig.vue
Normal file
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<div id="no-config">
|
||||
<div class="error-page">
|
||||
<div class="error-img">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -51 512 512">
|
||||
<g id="error">
|
||||
<path
|
||||
class="error-page-img"
|
||||
d="M 0 0 C 0 11.300781 0 399.777344 0 410 L 512 410 C 512 402.324219 512 2.425781 512 0 Z M 370 71 L 370 30 L 411 30 L 411 71 Z M 30 30 L 340 30 L 340 71 L 30 71 Z M 482 380 L 30 380 L 30 101 L 482 101 Z M 441 71 L 441 30 L 482 30 L 482 71 Z M 441 71 "
|
||||
/>
|
||||
<path
|
||||
class="error-page-img"
|
||||
d="M 325.519531 297.070312 C 294.328125 265.878906 294.328125 215.125 325.519531 183.929688 L 304.304688 162.71875 C 261.417969 205.605469 261.417969 275.390625 304.304688 318.28125 Z M 325.519531 297.070312 "
|
||||
/>
|
||||
<path
|
||||
class="error-page-img"
|
||||
d="M 197.089844 180 L 237.089844 180 L 237.089844 220 L 197.089844 220 Z M 197.089844 180 "
|
||||
/>
|
||||
<path
|
||||
class="error-page-img"
|
||||
d="M 197.089844 261 L 237.089844 261 L 237.089844 301 L 197.089844 301 Z M 197.089844 261 "
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<p class="error-message" v-html="$t('error.APP_ERROR')" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NoConfig',
|
||||
setup() {
|
||||
const { t } = useI18n()
|
||||
return { t }
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '~@/scss/base';
|
||||
|
||||
#no-config {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
padding: $default-padding;
|
||||
height: 100%;
|
||||
|
||||
.error-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
max-width: 100%;
|
||||
|
||||
.error-img {
|
||||
width: 150px;
|
||||
|
||||
svg {
|
||||
.error-page-img {
|
||||
stroke: none;
|
||||
fill-rule: nonzero;
|
||||
fill: var(--app-color);
|
||||
filter: drop-shadow(10px 10px 10px var(--app-shadow-color));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.error-message {
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
|
||||
@media screen and (max-width: $medium-limit) {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -2,6 +2,7 @@
|
||||
"ERROR": {
|
||||
"UNKNOWN": "Error. Please try again or contact the administrator.",
|
||||
"Invalid credentials": "Invalid credentials.",
|
||||
"Network Error": "Network Error",
|
||||
"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.",
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"UNKNOWN": "Error. Please try again or contact the administrator.",
|
||||
"APP_ERROR": "The application seems encounter some issues.<br />Please try later or contact the administrator.",
|
||||
"NOT_FOUND": {
|
||||
"PAGE": "Page not found"
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
"ERROR": {
|
||||
"UNKNOWN": "Erreur. Veuillez réessayer ou contacter l'administrateur.",
|
||||
"Invalid credentials": "Identifiants invalides.",
|
||||
"Network Error": "Erreur Réseau",
|
||||
"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.",
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"UNKNOWN": "Erreur. Veuillez réessayer ou contacter l'administrateur.",
|
||||
"APP_ERROR": "L'application semble rencontrer quelques problèmes.<br />Veuillez réessayer plus tard ou contacter l'administrateur.",
|
||||
"NOT_FOUND": {
|
||||
"PAGE": "Page introuvable"
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
--app-color: #2c3e50;
|
||||
--app-a-color: #40578a;
|
||||
--app-shadow-color: lightgrey;
|
||||
--app-loading-color: #f3f3f3;
|
||||
--app-loading-top-color: var(--app-color);
|
||||
|
||||
--input-border-color: #9da3af;
|
||||
|
||||
|
@ -10,6 +10,7 @@ export const actions: ActionTree<IRootState, IRootState> & IRootActions = {
|
||||
context: ActionContext<IRootState, IRootState>
|
||||
): void {
|
||||
context.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
||||
context.commit(ROOT_STORE.MUTATIONS.UPDATE_APPLICATION_LOADING, true)
|
||||
authApi
|
||||
.get('config')
|
||||
.then((res) => {
|
||||
@ -23,5 +24,8 @@ export const actions: ActionTree<IRootState, IRootState> & IRootActions = {
|
||||
}
|
||||
})
|
||||
.catch((error) => handleError(context, error))
|
||||
.finally(() =>
|
||||
context.commit(ROOT_STORE.MUTATIONS.UPDATE_APPLICATION_LOADING, false)
|
||||
)
|
||||
},
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ export enum RootActions {
|
||||
}
|
||||
|
||||
export enum RootGetters {
|
||||
APP_CONFIG = 'APP_CONFIG',
|
||||
APP_LOADING = 'APP_LOADING',
|
||||
ERROR_MESSAGES = 'ERROR_MESSAGES',
|
||||
LANGUAGE = 'LANGUAGE',
|
||||
}
|
||||
@ -11,5 +13,6 @@ export enum RootMutations {
|
||||
EMPTY_ERROR_MESSAGES = 'EMPTY_ERROR_MESSAGES',
|
||||
SET_ERROR_MESSAGES = 'SET_ERROR_MESSAGES',
|
||||
UPDATE_APPLICATION_CONFIG = 'UPDATE_APPLICATION_CONFIG',
|
||||
UPDATE_APPLICATION_LOADING = 'UPDATE_APPLICATION_LOADING',
|
||||
UPDATE_LANG = 'UPDATE_LANG',
|
||||
}
|
||||
|
@ -4,6 +4,12 @@ import { ROOT_STORE } from '@/store/constants'
|
||||
import { IRootState, IRootGetters } from '@/store/modules/root/interfaces'
|
||||
|
||||
export const getters: GetterTree<IRootState, IRootState> & IRootGetters = {
|
||||
[ROOT_STORE.GETTERS.APP_CONFIG]: (state: IRootState) => {
|
||||
return state.application.config
|
||||
},
|
||||
[ROOT_STORE.GETTERS.APP_LOADING]: (state: IRootState) => {
|
||||
return state.appLoading
|
||||
},
|
||||
[ROOT_STORE.GETTERS.ERROR_MESSAGES]: (state: IRootState) => {
|
||||
return state.errorMessages
|
||||
},
|
||||
|
@ -28,6 +28,7 @@ export interface IRootState {
|
||||
language: string
|
||||
errorMessages: string | string[] | null
|
||||
application: IApplication
|
||||
appLoading: boolean
|
||||
}
|
||||
|
||||
export interface IRootActions {
|
||||
@ -37,6 +38,8 @@ export interface IRootActions {
|
||||
}
|
||||
|
||||
export interface IRootGetters {
|
||||
[ROOT_STORE.GETTERS.APP_CONFIG](state: IRootState): IAppConfig
|
||||
[ROOT_STORE.GETTERS.APP_LOADING](state: IRootState): boolean
|
||||
[ROOT_STORE.GETTERS.ERROR_MESSAGES](
|
||||
state: IRootState
|
||||
): string | string[] | null
|
||||
|
@ -20,6 +20,12 @@ export const mutations: MutationTree<IRootState> & TRootMutations = {
|
||||
) {
|
||||
state.application.config = config
|
||||
},
|
||||
[ROOT_STORE.MUTATIONS.UPDATE_APPLICATION_LOADING](
|
||||
state: IRootState,
|
||||
loading: boolean
|
||||
) {
|
||||
state.appLoading = loading
|
||||
},
|
||||
[ROOT_STORE.MUTATIONS.UPDATE_LANG](state: IRootState, language: string) {
|
||||
state.language = language
|
||||
},
|
||||
|
@ -6,4 +6,5 @@ export const state: IRootState = {
|
||||
language: 'en',
|
||||
errorMessages: null,
|
||||
application: <IApplication>{},
|
||||
appLoading: false,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user