Added a global `notify` method via Nuxt plugin to replace `useNotification`. Improved messaging structure by embedding progress bars and handled dynamic durations. Updated usage across composables and components for consistency. - Replaced `useNotification` with `$notify` in all applicable files. - Updated `app.config.ts` to support customizable notification positions. - Refactored affected composables for simplified notification calls. - Enhanced progress indicator display within notifications. Breaking Changes: `useNotification` is removed, requiring migration to the new `$notify` API.
204 lines
No EOL
4.6 KiB
Vue
204 lines
No EOL
4.6 KiB
Vue
<template>
|
|
<div
|
|
class="main"
|
|
:style="{ 'padding-top': uiConfig.isHeaderFixed ? '83px': '0' }"
|
|
>
|
|
<nuxt-loading-indicator :color="accentColor" />
|
|
<base-header />
|
|
<ui-breadcrumbs v-if="uiConfig.showBreadcrumbs && showBreadcrumbs" />
|
|
<transition
|
|
name="opacity"
|
|
mode="out-in"
|
|
v-if="uiConfig.isAuthModals"
|
|
>
|
|
<base-auth v-if="activeState">
|
|
<forms-login v-if="appStore.isLogin" />
|
|
<forms-register v-if="appStore.isRegister" />
|
|
<forms-reset-password v-if="appStore.isForgot" />
|
|
<forms-new-password v-if="appStore.isReset" />
|
|
</base-auth>
|
|
</transition>
|
|
<nuxt-page />
|
|
<ui-button
|
|
:type="'button'"
|
|
class="demo__button"
|
|
v-if="isDemoMode"
|
|
@click="appStore.setDemoSettings(!appStore.isDemoSettings)"
|
|
>
|
|
<icon
|
|
name="material-symbols:settings"
|
|
size="30"
|
|
/>
|
|
</ui-button>
|
|
<transition name="opacity" mode="out-in">
|
|
<demo-settings />
|
|
</transition>
|
|
<base-footer />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import {useRefresh} from '@composables/auth';
|
|
import {useLanguages, useLocaleRedirect} from '@composables/languages';
|
|
import {useCompanyInfo} from '@composables/company';
|
|
import {useCategories} from '@composables/categories';
|
|
import {useProjectConfig} from '@composables/config';
|
|
|
|
const { locale } = useI18n();
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
const appStore = useAppStore();
|
|
const { $appHelpers } = useNuxtApp();
|
|
|
|
const { isDemoMode, uiConfig } = useProjectConfig();
|
|
const switchLocalePath = useSwitchLocalePath();
|
|
|
|
const showBreadcrumbs = computed(() => {
|
|
const name = typeof route.name === 'string' ? route.name : '';
|
|
return ![
|
|
'index',
|
|
'search',
|
|
'profile',
|
|
'activate-user',
|
|
'reset-password',
|
|
'auth-sign-in',
|
|
'auth-sign-up',
|
|
'auth-reset-password',
|
|
'contact',
|
|
'blog',
|
|
'docs'
|
|
].some(prefix => name.startsWith(prefix));
|
|
});
|
|
|
|
const activeState = computed(() => appStore.activeAuthState);
|
|
|
|
const cookieLocale = useCookie(
|
|
$appHelpers.COOKIES_LOCALE_KEY,
|
|
{
|
|
default: () => $appHelpers.DEFAULT_LOCALE,
|
|
path: '/'
|
|
}
|
|
);
|
|
|
|
const { refresh } = useRefresh();
|
|
const { getCategories } = await useCategories();
|
|
const { isSupportedLocale } = useLocaleRedirect();
|
|
|
|
let refreshInterval: NodeJS.Timeout;
|
|
|
|
if (import.meta.server) {
|
|
await Promise.all([
|
|
refresh(),
|
|
useLanguages(),
|
|
useCompanyInfo(),
|
|
getCategories()
|
|
]);
|
|
}
|
|
|
|
watch(
|
|
() => [appStore.activeAuthState, appStore.isDemoSettings],
|
|
([authState, isDemo]) => {
|
|
appStore.setOverflowHidden(authState !== '' || isDemo);
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
watch(locale, () => {
|
|
useHead({
|
|
htmlAttrs: {
|
|
lang: locale.value
|
|
}
|
|
});
|
|
});
|
|
|
|
let stopWatcher: VoidFunction = () => {};
|
|
|
|
if (!cookieLocale.value) {
|
|
cookieLocale.value = $appHelpers.DEFAULT_LOCALE;
|
|
await router.push({path: switchLocalePath(cookieLocale.value)});
|
|
}
|
|
|
|
if (locale.value !== cookieLocale.value) {
|
|
if (isSupportedLocale(cookieLocale.value)) {
|
|
await router.push({
|
|
path: switchLocalePath(cookieLocale.value),
|
|
query: route.query
|
|
});
|
|
} else {
|
|
cookieLocale.value = $appHelpers.DEFAULT_LOCALE;
|
|
|
|
await router.push({
|
|
path: switchLocalePath($appHelpers.DEFAULT_LOCALE),
|
|
query: route.query
|
|
});
|
|
}
|
|
}
|
|
|
|
const accentColor = ref('');
|
|
|
|
const getCssVariable = (name: string): string => {
|
|
if (import.meta.client) {
|
|
return getComputedStyle(document.documentElement)
|
|
.getPropertyValue(name)
|
|
.trim();
|
|
}
|
|
return '';
|
|
};
|
|
|
|
onMounted( async () => {
|
|
refreshInterval = setInterval(async () => {
|
|
await refresh();
|
|
}, 600000);
|
|
|
|
stopWatcher = watch(
|
|
() => appStore.isOverflowHidden,
|
|
(hidden) => {
|
|
const root = document.documentElement;
|
|
const body = document.body;
|
|
if (hidden) {
|
|
root.classList.add('lock-scroll');
|
|
body.classList.add('lock-scroll');
|
|
} else {
|
|
root.classList.remove('lock-scroll');
|
|
body.classList.remove('lock-scroll');
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
accentColor.value = getCssVariable('--accent');
|
|
|
|
useHead({
|
|
htmlAttrs: {
|
|
lang: locale.value
|
|
}
|
|
});
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
stopWatcher()
|
|
document.documentElement.classList.remove('lock-scroll');
|
|
document.body.classList.remove('lock-scroll');
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.main {
|
|
background-color: $light;
|
|
position: relative;
|
|
}
|
|
|
|
.lock-scroll {
|
|
overflow: hidden !important;
|
|
}
|
|
|
|
.demo {
|
|
&__button {
|
|
position: fixed !important;
|
|
width: fit-content !important;
|
|
bottom: 20px;
|
|
right: 20px;
|
|
padding: 10px !important;
|
|
}
|
|
}
|
|
</style> |