221 lines
7.8 KiB
Vue
221 lines
7.8 KiB
Vue
<template>
|
|
<nav class="navbar is-fixed-top has-shadow px-3" role="navigation">
|
|
<div class="navbar-brand mr-5">
|
|
<span class="navbar-item is-gap-1">
|
|
<div style="width: 16px; height: 16px" class="has-background-primary rounded-full"></div>
|
|
<span class="fs-17 font-semibold has-text-primary">{{$dayjs().format('DD/MM')}}</span>
|
|
</span>
|
|
<a
|
|
class="navbar-item p-0 has-text-primary"
|
|
@click="changeTab(leftmenu[0])"
|
|
>
|
|
<svg
|
|
style="max-height: none; width: 44px"
|
|
width="80" height="80" viewBox="0 0 80 80" xmlns="http://www.w3.org/2000/svg">
|
|
<path fill="currentColor" d="M40 8C57.6731 8 72 22.3269 72 40C72 57.6731 57.6731 72 40 72C22.3269 72 8 57.6731 8 40C8 22.3269 22.3269 8 40 8ZM15.7285 31.5762V49.2266H21.9854C23.778 49.2266 25.3185 48.8727 26.6055 48.166C27.898 47.4593 28.8887 46.4453 29.5781 45.124C30.2733 43.8025 30.6211 42.2224 30.6211 40.3838C30.6211 38.5511 30.2733 36.9768 29.5781 35.6611C28.8887 34.3455 27.9033 33.3367 26.6221 32.6357C25.3409 31.9292 23.8123 31.5762 22.0371 31.5762H15.7285ZM33.3857 49.2266H45.3135V46.1494H37.1172V41.9355H44.667V38.8584H37.1172V34.6533H45.2793V31.5762H33.3857V49.2266ZM53.3818 49.2266H58.1914L64.2754 31.5762H60.1387L55.8643 44.9863H55.7002L51.4346 31.5762H47.2891L53.3818 49.2266ZM21.8389 34.7734C22.942 34.7734 23.8704 34.9687 24.623 35.3594C25.3756 35.75 25.9411 36.3593 26.3203 37.1865C26.7052 38.0138 26.8984 39.0797 26.8984 40.3838C26.8984 41.6995 26.7053 42.7743 26.3203 43.6074C25.9411 44.4346 25.3726 45.047 24.6143 45.4434C23.8617 45.8339 22.9339 46.0292 21.8311 46.0293H19.4609V34.7734H21.8389Z" />
|
|
</svg>
|
|
</a>
|
|
<a
|
|
role="button"
|
|
class="navbar-burger"
|
|
id="burger"
|
|
aria-label="menu"
|
|
aria-expanded="false"
|
|
data-target="navMenu"
|
|
@click="handleClick()"
|
|
>
|
|
<span aria-hidden="true"></span>
|
|
<span aria-hidden="true"></span>
|
|
<span aria-hidden="true"></span>
|
|
<span aria-hidden="true"></span>
|
|
</a>
|
|
</div>
|
|
<div class="navbar-menu" id="navMenu">
|
|
<div class="navbar-start is-gap-1 is-align-items-center" style="min-width: 650px;">
|
|
<template v-for="(v, i) in leftmenu" :key="i" :id="v.code">
|
|
<a class="navbar-item rounded-lg is-clipped p-0" v-if="!v.submenu" @click="changeTab(v)">
|
|
<span :class="[
|
|
'px-3 py-1.5 fs-14 font-medium',
|
|
currentTab.code === v.code ? 'has-text-primary-50 has-background-primary-95' : 'has-text-grey-30'
|
|
]">
|
|
{{ v[lang] }}
|
|
</span>
|
|
</a>
|
|
<div class="navbar-item has-dropdown is-hoverable" v-else>
|
|
<a class="navbar-item px-2" @click="changeTab(v)">
|
|
<span :class="[
|
|
'px-3 py-1 font-medium',
|
|
currentTab.code === v.code ? 'has-text-primary-bold has-background-primary-soft' : 'has-text-grey-30'
|
|
]">
|
|
<span>{{ v[lang] }}</span>
|
|
<SvgIcon
|
|
style="padding-top: 5px"
|
|
v-bind="{ name: 'down2.svg', type: currentTab.code === v.code ? 'white' : 'dark', size: 15 }"
|
|
>
|
|
</SvgIcon>
|
|
</span>
|
|
</a>
|
|
<div class="navbar-dropdown has-background-light">
|
|
<a
|
|
class="navbar-item has-background-light py-1 border-bottom"
|
|
v-for="x in v.submenu"
|
|
@click="changeTab(v, x)"
|
|
>
|
|
{{ x[lang] }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
<div class="navbar-end">
|
|
<a class="navbar-item" @click="changeTab(tabConfig)" v-if="tabConfig">
|
|
<SvgIcon v-bind="{ name: 'configuration.svg', type: 'findata', size: 24 }"></SvgIcon>
|
|
</a>
|
|
<a class="navbar-item" @click="openProfile()" v-if="avatar">
|
|
<Avatarbox v-bind="avatar"></Avatarbox>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
</template>
|
|
<script setup>
|
|
import { watch } from "vue";
|
|
const router = useRouter();
|
|
const route = useRoute();
|
|
const emit = defineEmits(["changetab", "langChanged"]);
|
|
const { $find, $filter, $findIndex, $store } = useNuxtApp();
|
|
const lang = ref($store.lang);
|
|
// var menu = $filter($store.common, { category: "topmenu" });
|
|
const menu = [
|
|
{
|
|
id: 1,
|
|
category: 'topmenu',
|
|
classify: 'left',
|
|
code: 'dashboard',
|
|
vi: 'Dashboard',
|
|
link: null,
|
|
detail: {
|
|
base: 'Dashboard',
|
|
component: 'DashboardMaster',
|
|
},
|
|
index: 0,
|
|
},
|
|
{
|
|
id: 2,
|
|
category: 'topmenu',
|
|
classify: 'left',
|
|
code: 'orders',
|
|
vi: 'Đơn hàng',
|
|
link: null,
|
|
detail: {
|
|
base: 'Orders',
|
|
component: 'OrdersMaster',
|
|
},
|
|
index: 0,
|
|
},
|
|
{
|
|
id: 1,
|
|
category: 'topmenu',
|
|
classify: 'left',
|
|
code: 'inventory',
|
|
vi: 'Tồn kho',
|
|
link: null,
|
|
detail: {
|
|
base: 'Inventory',
|
|
component: 'InventoryMaster',
|
|
},
|
|
index: 0,
|
|
},
|
|
]
|
|
if($store.rights.length>0) {
|
|
menu = menu.filter(v=>$findIndex($store.rights, {setting: v.id})>=0)
|
|
}
|
|
if(menu.length===0) {
|
|
$snackbar($store.lang==='vi'? 'Bạn không có quyền truy cập' : 'You do not have permission to access.')
|
|
}
|
|
// menu.map(v=>{
|
|
// let arr = $filter($store.common, {category: 'submenu', classify: v.code})
|
|
// if($store.rights.length>0) {
|
|
// arr = arr.filter(x=>$findIndex($store.rights, {setting: x.id})>=0)
|
|
// }
|
|
// v.submenu = arr.length>0? arr : null
|
|
// })
|
|
var leftmenu = $filter(menu, {category: 'topmenu', classify: 'left'})
|
|
var currentTab = ref(leftmenu.length>0? leftmenu[0] : undefined)
|
|
var subTab = ref();
|
|
var tabConfig = $find(menu, { code: "configuration" });
|
|
var avatar = ref();
|
|
var isAdmin = ref();
|
|
const handleClick = function () {
|
|
const target = document.getElementById("burger");
|
|
target.classList.toggle("is-active");
|
|
const target1 = document.getElementById("navMenu");
|
|
target1.classList.toggle("is-active");
|
|
};
|
|
const closeMenu = function () {
|
|
if (!document) return;
|
|
const target = document.getElementById("burger");
|
|
const target1 = document.getElementById("navMenu");
|
|
if (!target) return;
|
|
if (target.classList.contains("is-active")) {
|
|
target.classList.remove("is-active");
|
|
target1.classList.remove("is-active");
|
|
}
|
|
};
|
|
function changeTab(tab, subtab) {
|
|
if (tab.submenu && tab.submenu.length > 0 && !subtab && !tab.detail) {
|
|
subtab = tab.submenu[0];
|
|
}
|
|
currentTab.value = tab;
|
|
subTab.value = subtab;
|
|
emit("changetab", tab, subtab);
|
|
closeMenu();
|
|
let query = subtab ? { tab: tab.code, subtab: subtab.code } : { tab: tab.code };
|
|
router.push({ query: query });
|
|
}
|
|
function openProfile() {
|
|
let modal = { component: "user/Profile", width: "1100px", height: "360px", title: $store.lang==='vi'? 'Thông tin cá nhân' : '"User profile"' };
|
|
$store.commit("showmodal", modal);
|
|
}
|
|
let found = route.query.tab? $find(menu, {code: route.query.tab}) : undefined
|
|
if(found || currentTab.value) changeTab(found || currentTab.value)
|
|
onMounted(() => {
|
|
if (!$store.login) return;
|
|
avatar.value = {
|
|
image: null,
|
|
text: $store.login.fullname.substring(0, 1).toUpperCase(),
|
|
size: "two",
|
|
type: "findata",
|
|
};
|
|
isAdmin.value = $store.login.type__code === "admin";
|
|
});
|
|
watch(
|
|
() => $store.login,
|
|
(newVal, oldVal) => {
|
|
if (!newVal) return;
|
|
avatar.value = {
|
|
image: null,
|
|
text: $store.login.fullname.substring(0, 1).toUpperCase(),
|
|
size: "two",
|
|
type: "findata",
|
|
};
|
|
isAdmin.value = $store.login.type__code === "admin";
|
|
lang.value = $store.lang;
|
|
}
|
|
);
|
|
</script>
|
|
<style scoped>
|
|
.navbar-dropdown {
|
|
padding-block: 0.375rem;
|
|
overflow: hidden;
|
|
}
|
|
.navbar-dropdown > .navbar-item {
|
|
&:hover {
|
|
background-color: hsl(30, 48%, 82%) !important;
|
|
}
|
|
|
|
&:last-child {
|
|
border-bottom: none;
|
|
}
|
|
}
|
|
</style> |