FitTrackee/fittrackee_client/src/App.vue

136 lines
3.4 KiB
Vue
Raw Normal View History

<template>
<div id="top" />
<NavBar @menuInteraction="updateHideScrollBar" />
2023-07-13 16:18:03 +02:00
<main>
<div v-if="appLoading" class="app-container">
<div class="app-loading">
<Loader />
</div>
</div>
2023-07-13 16:18:03 +02:00
<div v-else class="app-container" :class="{ 'hide-scroll': hideScrollBar }">
<router-view v-if="appConfig" />
<NoConfig v-else />
</div>
2023-07-13 16:18:03 +02:00
<div class="container scroll">
<div
class="scroll-button"
:class="{ 'display-button': displayScrollButton }"
@click="scrollToTop"
>
<i class="fa fa-chevron-up" aria-hidden="true"></i>
</div>
</div>
</main>
<Footer
v-if="appConfig"
:version="appConfig ? appConfig.version : ''"
:adminContact="appConfig.admin_contact"
/>
</template>
<script setup lang="ts">
import { computed, ref, onBeforeMount, onMounted } from 'vue'
import type { ComputedRef } from 'vue'
2021-08-11 22:21:26 +02:00
import Footer from '@/components/Footer.vue'
2021-07-25 13:23:25 +02:00
import NavBar from '@/components/NavBar.vue'
import NoConfig from '@/components/NoConfig.vue'
import { ROOT_STORE } from '@/store/constants'
import type { TAppConfig } from '@/types/application'
2023-11-11 20:16:18 +01:00
import type { TLanguage } from '@/types/locales'
import { useStore } from '@/use/useStore'
2023-11-11 20:16:18 +01:00
import { isLanguageSupported } from '@/utils/locales'
2021-07-25 13:03:34 +02:00
const store = useStore()
const appConfig: ComputedRef<TAppConfig> = computed(
() => store.getters[ROOT_STORE.GETTERS.APP_CONFIG]
)
const appLoading: ComputedRef<boolean> = computed(
() => store.getters[ROOT_STORE.GETTERS.APP_LOADING]
)
const hideScrollBar = ref(false)
const displayScrollButton = ref(false)
onBeforeMount(() => {
initLanguage()
store.dispatch(ROOT_STORE.ACTIONS.GET_APPLICATION_CONFIG)
})
onMounted(() => scroll())
function updateHideScrollBar(isMenuOpen: boolean) {
hideScrollBar.value = isMenuOpen
}
function isScrolledToBottom(element: Element): boolean {
return (
element.getBoundingClientRect().top < window.innerHeight &&
element.getBoundingClientRect().bottom >= 0
)
}
function scroll() {
window.onscroll = () => {
2022-06-22 17:53:59 +02:00
const bottom = document.querySelector('#bottom')
displayScrollButton.value = bottom !== null && isScrolledToBottom(bottom)
}
}
function scrollToTop() {
window.scrollTo({
top: 0,
behavior: 'smooth',
})
setTimeout(() => {
displayScrollButton.value = false
}, 300)
}
function initLanguage() {
2023-11-11 20:16:18 +01:00
let language: TLanguage = 'en'
try {
const navigatorLanguage = navigator.language.split('-')[0]
2023-11-11 20:16:18 +01:00
if (isLanguageSupported(navigatorLanguage)) {
language = navigatorLanguage
}
} catch (e) {
language = 'en'
}
store.dispatch(ROOT_STORE.ACTIONS.UPDATE_APPLICATION_LANGUAGE, language)
}
2021-07-25 13:03:34 +02:00
</script>
2021-11-29 11:23:21 +01:00
<style lang="scss">
@import '~@/scss/base.scss';
2021-08-15 09:24:10 +02:00
.app-container {
height: $app-height;
&.hide-scroll {
overflow: hidden;
}
.app-loading {
display: flex;
align-items: center;
height: 100%;
}
2021-08-15 09:24:10 +02:00
}
.scroll {
display: flex;
justify-content: flex-end;
position: fixed;
bottom: 42px;
right: -15px;
padding: 0 $default-padding * 2.5;
.scroll-button {
background-color: var(--scroll-button-bg-color);
border-radius: $border-radius;
box-shadow: 1px 1px 3px lightgrey;
display: none;
padding: 0 $default-padding;
&.display-button {
display: block;
}
}
}
</style>