strava-frontend/src/layouts/AppLayout.vue

119 lines
3.0 KiB
Vue

<template>
<VaLayout
:top="{ fixed: true, order: 2 }"
:left="{
fixed: true,
absolute: breakpoints.mdDown,
order: 1,
overlay: breakpoints.mdDown && !isSidebarMinimized,
}"
@leftOverlayClick="isSidebarMinimized = true"
>
<template #top>
<AppNavbar :is-mobile="isMobile" />
</template>
<template #left>
<AppSidebar
:minimized="isSidebarMinimized"
:animated="!isMobile"
:mobile="isMobile"
/>
</template>
<template #content>
<div
:class="{ minimized: isSidebarMinimized }"
class="app-layout__sidebar-wrapper"
>
<div v-if="isFullScreenSidebar" class="flex justify-end">
<VaButton
class="px-4 py-4"
icon="md_close"
preset="plain"
@click="onCloseSidebarButtonClick"
/>
</div>
</div>
<AppLayoutNavigation v-if="!isMobile" class="p-4" />
<main class="p-4 pt-0">
<article>
<RouterView />
</article>
</main>
</template>
</VaLayout>
</template>
<script setup>
import { onBeforeUnmount, onMounted, ref, computed } from "vue";
import { useRouter, useRoute } from "vue-router";
import { storeToRefs } from "pinia";
import { onBeforeRouteUpdate } from "vue-router";
import { useBreakpoint } from "vuestic-ui";
import { useGlobalStore } from "../stores/global-store";
import AppLayoutNavigation from "../components/app-layout-navigation/AppLayoutNavigation.vue";
import AppNavbar from "../components/navbar/AppNavbar.vue";
import AppSidebar from "../components/sidebar/AppSidebar.vue";
const GlobalStore = useGlobalStore();
const breakpoints = useBreakpoint();
const sidebarWidth = ref("16rem");
const sidebarMinimizedWidth = ref(undefined);
const isMobile = ref(false);
const isTablet = ref(false);
const { isSidebarMinimized } = storeToRefs(GlobalStore);
const onResize = () => {
isSidebarMinimized.value = breakpoints.mdDown;
isMobile.value = breakpoints.smDown;
isTablet.value = breakpoints.mdDown;
sidebarMinimizedWidth.value = isMobile.value ? "0" : "4.5rem";
sidebarWidth.value = isTablet.value ? "100%" : "16rem";
};
onMounted(() => {
const token = localStorage.getItem("token");
if (!token && useRoute().path != "/explore" && useRoute().path != "/") {
useRouter().push({ name: "login" });
}
window.addEventListener("resize", onResize);
onResize();
});
onBeforeUnmount(() => {
window.removeEventListener("resize", onResize);
});
onBeforeRouteUpdate(() => {
if (breakpoints.mdDown) {
// Collapse sidebar after route change for Mobile
isSidebarMinimized.value = true;
}
});
const isFullScreenSidebar = computed(
() => isTablet.value && !isSidebarMinimized.value,
);
const onCloseSidebarButtonClick = () => {
isSidebarMinimized.value = true;
};
</script>
<style lang="scss" scoped>
// Prevent icon jump on animation
.va-sidebar {
width: unset !important;
min-width: unset !important;
}
body {
min-width: 350px;
}
</style>