c80fd0313c
Adds internationalization support in filters and origins pages by importing the useI18n function. Expands ESLint configuration to include new rules and plugins, ensuring improved code quality. Introduces Grafana monitoring plugin to enhance performance tracking capabilities in the application.
112 lines
3.6 KiB
Vue
112 lines
3.6 KiB
Vue
<template>
|
|
<v-app :key='locale + isAuthenticated'>
|
|
<v-navigation-drawer v-model='nav' temporary app>
|
|
<v-list dense>
|
|
<v-list-item v-if='isAuthenticated && user' :title='user.name' :prepend-avatar='user.picture' />
|
|
<v-list-item>
|
|
<v-switch v-model='darkMode' color='primary' :label="t('app.darkMode')" hide-details class='ms-1' />
|
|
</v-list-item>
|
|
<!-- eslint-disable-next-line vue/no-bare-strings-in-template -->
|
|
<v-list-item title='In English' :to="switchLocalePath('en')">
|
|
<template #prepend>
|
|
<!-- eslint-disable-next-line vue/no-bare-strings-in-template -->
|
|
<div class='d-flex d-inline-flex text-h5 me-8'>
|
|
🇬🇧
|
|
</div>
|
|
</template>
|
|
</v-list-item>
|
|
<!-- eslint-disable-next-line vue/no-bare-strings-in-template -->
|
|
<v-list-item title='På Svenska' :to="switchLocalePath('sv')">
|
|
<template #prepend>
|
|
<!-- eslint-disable-next-line vue/no-bare-strings-in-template -->
|
|
<div class='d-flex d-inline-flex text-h5 me-8'>
|
|
🇸🇪
|
|
</div>
|
|
</template>
|
|
</v-list-item>
|
|
<v-list-item to='/' :title="t('app.links.events')" prepend-icon='mdi-calendar-outline' />
|
|
<v-list-item v-if='isAuthenticated' to='/origins/' :title="t('app.links.origins')" prepend-icon='mdi-home' />
|
|
<v-list-item
|
|
v-if='isAuthenticated' to='/filters/' :title="t('app.links.filters')"
|
|
prepend-icon='mdi-magnify' />
|
|
<v-list-item v-if='!user' link :title="t('app.login')" prepend-icon='mdi-login' @click='doLogin' />
|
|
<v-list-item
|
|
v-if='isAuthenticated' link :title="t('app.logout')" prepend-icon='mdi-logout'
|
|
@click='doLogout' />
|
|
</v-list>
|
|
</v-navigation-drawer>
|
|
<v-app-bar app scroll-off-screen>
|
|
<v-app-bar-nav-icon @click='nav = !nav' />
|
|
<v-toolbar-title :title='title' />
|
|
<v-spacer />
|
|
<v-toolbar-items>
|
|
<v-list-item v-if='isAuthenticated && user' :prepend-avatar='user.picture' :title='user.name' />
|
|
</v-toolbar-items>
|
|
</v-app-bar>
|
|
<v-main>
|
|
<v-container v-if='!isLoading' fluid>
|
|
<slot />
|
|
</v-container>
|
|
</v-main>
|
|
</v-app>
|
|
</template>
|
|
|
|
<script setup lang='ts'>
|
|
import { useAuth0 } from '@auth0/auth0-vue'
|
|
import { computed, onMounted, ref } from 'vue'
|
|
import { useTheme } from 'vuetify'
|
|
|
|
import { useSwitchLocalePath } from '#i18n'
|
|
import { useState } from '~/store'
|
|
|
|
const { t, locale } = useI18n()
|
|
const { $faro } = useNuxtApp()
|
|
const switchLocalePath = useSwitchLocalePath()
|
|
const state = useState()
|
|
const { isLoading, isAuthenticated, user, loginWithRedirect, logout } =
|
|
useAuth0()
|
|
const doLogin = () => {
|
|
loginWithRedirect({
|
|
appState: { targetUrl: window.location.pathname },
|
|
})
|
|
}
|
|
const doLogout = () => {
|
|
logout({
|
|
logoutParams: {
|
|
returnTo: window.location.origin,
|
|
},
|
|
})
|
|
}
|
|
const theme = useTheme()
|
|
onMounted(() => {
|
|
if (state.darkMode) {
|
|
theme.global.name.value = 'dark'
|
|
} else {
|
|
theme.global.name.value = 'light'
|
|
}
|
|
})
|
|
const darkMode = computed<boolean>({
|
|
get: () => theme.global.current.value.dark,
|
|
set: (value: boolean) => {
|
|
state.setDarkMode(value)
|
|
if (value) {
|
|
theme.global.name.value = 'dark'
|
|
} else {
|
|
theme.global.name.value = 'light'
|
|
}
|
|
},
|
|
})
|
|
|
|
const nav = ref(false)
|
|
const title = computed(() => state.title)
|
|
watchEffect(() => {
|
|
if ($faro && !isLoading.value && user.value) {
|
|
$faro.api.setUser({
|
|
id: user.value.sub,
|
|
email: user.value.email,
|
|
username: user.value.preferred_username,
|
|
})
|
|
}
|
|
})
|
|
</script>
|