x-control-panel/web-ui/vue-app/src/App.vue

131 lines
3.3 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<v-app>
<LoginForm />
<Notifications />
<template v-if="!authStore.showLoginForm && !appStore.isLoading">
<div class="app-layout">
<!-- Часть А: Меню (слева для ПК, шторка для мобильных) -->
<NavigationMenu
ref="navigationMenu"
@update-collapsed="isCollapsed = $event"
@toggle-menu="toggleMobileMenu"
/>
<!-- Часть Б: Футер + Контент -->
<div
class="content-section"
:class="{ 'with-menu': !isMobile, 'menu-collapsed': !isMobile && isCollapsed }"
:style="{ marginLeft: !isMobile ? (isCollapsed ? '80px' : '250px') : '0' }"
>
<!-- Футер (HeaderBar) - скрыт для ПК, показан для мобильных -->
<HeaderBar v-if="isMobile || showFooter" @toggle-menu="toggleMobileMenu" />
<!-- Основной контент -->
<v-main
:class="{
'mobile-main': isMobile,
'with-menu': !isMobile
}"
>
<RouterView />
</v-main>
</div>
</div>
</template>
</v-app>
</template>
<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { RouterView } from 'vue-router'
import NavigationMenu from './components/NavigationMenu.vue'
import HeaderBar from './components/HeaderBar.vue'
import LoginForm from './components/LoginForm.vue'
import Notifications from './components/Notifications.vue'
import { useAppStore } from '@/stores/app'
import { useAuthStore } from '@/stores/auth'
import { useNotificationStore } from '@/stores/notification'
const appStore = useAppStore()
const authStore = useAuthStore()
const navigationMenu = ref()
const windowWidth = ref(window.innerWidth)
const isCollapsed = ref(false)
const showFooter = ref(false)
const isMobile = computed(() => windowWidth.value < 768)
const toggleMobileMenu = () => {
if (navigationMenu.value) {
navigationMenu.value.toggle()
}
}
const updateWidth = () => {
windowWidth.value = window.innerWidth
}
onMounted(async () => {
window.addEventListener('resize', updateWidth)
appStore.initializeApi('http://localhost:8080/api')
await authStore.initializeAuth()
})
onUnmounted(() => {
window.removeEventListener('resize', updateWidth)
})
</script>
<style>
#app {
min-height: 100vh;
}
.v-application {
min-height: 100vh;
width: 100%;
}
/* Основной layout контейнер */
.app-layout {
display: flex;
min-height: 100vh;
width: 100%;
}
/* Часть Б: Контентная секция */
.content-section {
flex: 1;
display: flex;
flex-direction: column;
width: 100%;
min-height: 100vh;
background: rgb(var(--v-theme-background));
transition: margin-left 0.3s ease;
}
/* Для ПК - основной контент без отступов */
.v-main.with-menu {
padding: 16px;
flex: 1;
background: transparent !important;
}
/* Для мобильных - контент с отступом под футером */
.mobile-main {
padding-top: 45px !important;
flex: 1 !important;
}
.mobile-main :deep(.v-main__content) {
padding: 0 !important;
}
.mobile-main :deep(.v-container) {
padding: 0 !important;
}
</style>