feat: подготовил дизайн (изменения из другого репозитория)
🚀 Create and publish a Docker image / Detect changes in backend and frontend (push) Successful in 5s
🚀 Create and publish a Docker image / Build & publish backend image (push) Successful in 8s
🚀 Create and publish a Docker image / Update stack on Portainer (push) Successful in 3s

This commit is contained in:
2026-05-08 01:06:22 +03:00
parent 655ab1b5c5
commit 047611fd24
54 changed files with 4497 additions and 28 deletions
+92 -7
View File
@@ -1,11 +1,96 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useRoute } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import AppTopbar from '@/components/layout/AppTopbar.vue'
import AppSidebar from '@/components/layout/AppSidebar.vue'
import AppBottomNav from '@/components/layout/AppBottomNav.vue'
import ToastNotification from '@/components/ui/ToastNotification.vue'
const auth = useAuthStore()
const route = useRoute()
const isAuthPage = computed(() => route.path === '/login')
interface Toast { id: number; message: string; type: 'success' | 'error' | 'info' }
const toasts = ref<Toast[]>([])
let toastId = 0
function addToast(msg: string, type: Toast['type'] = 'success') {
toasts.value.push({ id: ++toastId, message: msg, type })
}
function removeToast(id: number) {
toasts.value = toasts.value.filter(t => t.id !== id)
}
// expose globally via provide
import { provide } from 'vue'
provide('addToast', addToast)
</script>
<template>
<h1>You did it!</h1>
<p>
Visit <a href="https://vuejs.org/" target="_blank" rel="noopener">vuejs.org</a> to read the
documentation
</p>
<div class="app-root">
<!-- Auth page: no layout -->
<template v-if="isAuthPage">
<RouterView />
</template>
<!-- Main layout -->
<template v-else-if="auth.isAuthenticated">
<AppTopbar />
<AppSidebar />
<main class="main-content">
<RouterView />
</main>
<AppBottomNav />
</template>
<!-- Redirect to login if not authenticated -->
<template v-else>
<RouterView />
</template>
<!-- Toast container -->
<div class="toast-container">
<ToastNotification
v-for="t in toasts"
:key="t.id"
:message="t.message"
:type="t.type"
@close="removeToast(t.id)"
/>
</div>
</div>
</template>
<style scoped></style>
<style scoped>
.app-root {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.main-content {
margin-top: var(--topbar-height);
margin-left: var(--sidebar-width);
min-height: calc(100vh - var(--topbar-height));
padding: 28px 28px 80px;
}
.toast-container {
position: fixed;
bottom: 80px;
right: 20px;
display: flex;
flex-direction: column;
gap: 10px;
z-index: 300;
pointer-events: none;
}
@media (max-width: 768px) {
.main-content {
margin-left: 0;
padding: 16px 16px 80px;
}
}
</style>