Files
bssapp/ui/src/layouts/MainLayout.vue
2026-03-18 09:29:43 +03:00

379 lines
7.3 KiB
Vue
Raw 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>
<q-layout view="hHh Lpr fFf">
<!-- HEADER -->
<q-header elevated class="bg-primary text-white">
<q-toolbar>
<q-btn dense flat round icon="menu" @click="toggleLeftDrawer" />
<q-toolbar-title>
<q-avatar class="bg-secondary q-mr-sm">
<img src="/images/Baggi-tekstilas-logolu.jpg" />
</q-avatar>
Baggi Software System
</q-toolbar-title>
<q-btn flat dense round icon="logout" @click="confirmLogout" />
</q-toolbar>
</q-header>
<!-- DRAWER -->
<q-drawer
v-if="perm.loaded"
v-model="leftDrawerOpen"
:show-if-above="!$q.screen.lt.md"
:overlay="$q.screen.lt.md"
:behavior="$q.screen.lt.md ? 'mobile' : 'desktop'"
:breakpoint="1023"
bordered
class="bg-secondary text-white"
>
<div class="drawer-scroll">
<q-list padding>
<!-- DYNAMIC MENU -->
<template
v-for="(item, i) in filteredMenu"
:key="i"
>
<!-- GROUP -->
<q-expansion-item
v-if="item.children"
:icon="item.icon"
:label="item.label"
expand-separator
>
<q-item
v-for="(c, j) in item.children"
:key="j"
clickable
:to="c.to"
>
<q-item-section avatar>
<q-icon name="chevron_right" />
</q-item-section>
<q-item-section>
{{ c.label }}
</q-item-section>
</q-item>
</q-expansion-item>
<!-- SINGLE -->
<q-item
v-else
clickable
:to="item.to"
>
<q-item-section avatar>
<q-icon :name="item.icon" />
</q-item-section>
<q-item-section>
{{ item.label }}
</q-item-section>
</q-item>
<q-separator spaced />
</template>
<!-- PASSWORD -->
<q-item clickable to="/app/change-password">
<q-item-section avatar>
<q-icon name="vpn_key" />
</q-item-section>
<q-item-section>
Şifre Değiştir
</q-item-section>
</q-item>
</q-list>
</div>
</q-drawer>
<!-- CONTENT -->
<q-page-container class="with-bg">
<router-view />
</q-page-container>
<!-- FOOTER -->
<q-footer class="bg-grey-8 text-white">
<q-toolbar class="bg-secondary">
<q-toolbar-title>
Baggi Software System
</q-toolbar-title>
</q-toolbar>
</q-footer>
</q-layout>
</template>
<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Dialog, useQuasar } from 'quasar'
import { useAuthStore } from 'stores/authStore'
import { usePermissionStore } from 'stores/permissionStore'
/* ================= STORES ================= */
const router = useRouter()
const route = useRoute()
const $q = useQuasar()
const auth = useAuthStore()
const perm = usePermissionStore()
/* ================= UI ================= */
const leftDrawerOpen = ref(!$q.screen.lt.md)
function toggleLeftDrawer () {
leftDrawerOpen.value = !leftDrawerOpen.value
}
function confirmLogout () {
Dialog.create({
title: ıkış Yap',
message: 'Oturumunuzu kapatmak istediğinize emin misiniz?',
cancel: true,
persistent: true
}).onOk(() => {
auth.clearSession()
perm.clear()
router.push('/login')
})
}
/* ================= LOAD PERMISSIONS ================= */
onMounted(async () => {
if (!perm.loaded) {
await perm.fetchPermissions()
}
leftDrawerOpen.value = !$q.screen.lt.md
})
watch(
() => route.fullPath,
() => {
if ($q.screen.lt.md) {
leftDrawerOpen.value = false
}
}
)
watch(
() => $q.screen.lt.md,
(isMobile) => {
if (isMobile) {
leftDrawerOpen.value = false
}
}
)
/* ================= MENU CONFIG ================= */
const menuItems = [
{
label: 'Ana Panel',
icon: 'dashboard',
to: '/app',
permission: 'system:view'
},
{
label: 'Finans',
icon: 'account_balance',
children: [
{
label: 'Cari Ekstre',
to: '/app/statementofaccount',
permission: 'finance:view'
},
{
label: 'Cari Bakiye Listesi',
to: '/app/customer-balance-list',
permission: 'finance:view'
},
{
label: 'Cari Yaşlandırmalı Ekstre',
to: '/app/account-aging-statement',
permission: 'finance:view'
},
{
label: 'Cari Yaşlandırmalı Cari Bakiye Listesi',
to: '/app/aged-customer-balance-list',
permission: 'finance:view'
}
]
},
{
label: 'Sipariş',
icon: 'shopping_cart',
children: [
{
label: 'Siparişler',
to: '/app/order-gateway',
permission: 'order:view'
},
{
label: 'Üretime Verilen Siparişleri Güncelle',
to: '/app/orderproductionupdate',
permission: 'order:update'
},
{
label: 'Tamamlanan Siparişleri Toplu Kapatma',
to: '/app/order-bulk-close',
permission: 'order:update'
}
]
},
{
label: 'Ürün',
icon: 'inventory_2',
children: [
{
label: 'Ürün Kodundan Stok Sorgula',
to: '/app/product-stock-query',
permission: 'order:view'
},
{
label: 'Ürün Özelliklerinden Stok Bul',
to: '/app/product-stock-by-attributes',
permission: 'order:view'
}
]
},
{
label: 'Sistem',
icon: 'settings',
children: [
{
label: 'Rol + Departman Yetkileri',
to: '/app/role-dept-permissions',
permission: 'system:update'
},
{
label: 'Kullanıcı Yetkileri',
to: '/app/user-permissions',
permission: 'system:update'
},
{
label: 'Loglar',
to: '/app/activity-logs',
permission: 'system:read'
},
{
label: 'Test Mail',
to: '/app/test-mail',
permission: 'system:update'
},
{
label: 'Piyasa Mail Eşleştirme',
to: '/app/market-mail-mapping',
permission: 'system:update'
}
]
},
{
label: 'Kullanıcı Yönetimi',
icon: 'people',
children: [
{
label: 'Kullanıcılar',
to: '/app/users',
permission: 'system:read'
}
]
}
]
/* ================= FILTERED MENU ================= */
const filteredMenu = computed(() => {
if (!perm.loaded) return []
return menuItems
.map(item => {
if (item.children) {
const children = item.children.filter(c =>
perm.hasApiPermission(c.permission)
)
if (!children.length) return null
return {
...item,
children
}
}
if (!perm.hasApiPermission(item.permission)) {
return null
}
return item
})
.filter(Boolean)
})
</script>
<style scoped>
.drawer-scroll {
height: 100%;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
touch-action: pan-y;
}
</style>