LoongPanel-Asp/web/components/shell/SideBar.vue

322 lines
6.0 KiB
Vue
Executable File

<script lang="ts" setup>
import Logo from "~/components/Logo.vue";
import {ArrowLeft, Search} from 'lucide-vue-next';
import {useMainLayoutStore} from "~/strores/UseMainLayoutStore";
const {$gsap} = useNuxtApp()
const mainLayoutStore = useMainLayoutStore()
const Menus = [
{
"label": "系统概览",
"icon": "LayoutGrid",
"route": "/Home"
}, {
"label": "主机监测",
"icon": "Cpu",
"route": "/host/cpu"
},{
"label": "用户监测",
"icon": "Cctv",
"route": "/serverUser/all"
},{
"label": "账号列表",
"icon": "UsersRound",
"route": "/User"
},{
"label": "巡检记录",
"icon": "PackageSearch",
"route": "/InspectionRecords"
},
]
onMounted(() => {
const t1 = $gsap.timeline();
if (mainLayoutStore.IsLeftSidebarMini) {
t1.to(".sidebar-layout", {
duration: 0,
width: "104px",
ease: "power2.out",
}, 0)
t1.to(".sidebar-layout p,.sidebar-layout h3,.sidebar-layout .aa>svg", {
display: "none",
duration: 0,
}, 0)
t1.to(".sidebar-layout .user", {
duration: 0,
gap: 0
}, 0)
t1.to(".switch-button", {
duration: 0,
//旋转3圈
rotate: 360 + 180,
ease: "power2.out",
}, 0)
}
t1.from(".sidebar-layout", {
duration: 0.5,
x: "-100%",
opacity: 0,
ease: "power2.out",
})
})
watch(() => mainLayoutStore.IsLeftSidebarMini, (newValue) => {
const t1 = $gsap.timeline();
t1.to(".sidebar-layout .header,.folder", {
duration: 0.5,
x: "-200%",
opacity: 0,
ease: "power2.out",
}, 0)
if (newValue) {
t1.to(".sidebar-layout", {
duration: 0.5,
width: "104px",
ease: "power2.out",
}, 0.5)
t1.to(".switch-button", {
duration: 1,
//旋转3圈
rotate: 180,
ease: "power2.out",
}, 0.5)
t1.to(".sidebar-layout p,.sidebar-layout h3,.sidebar-layout .aa>svg", {
display: "none",
duration: 0,
}, 0.5)
t1.to(".sidebar-layout .user", {
duration: 0,
gap: 0
}, 0.5)
} else {
t1.to(".sidebar-layout", {
duration: 0.5,
width: 210,
ease: "power2.out",
}, 0.5)
t1.to(".sidebar-layout", {
width: "auto",
}, 0.55)
t1.to(".switch-button", {
duration: 1,
y: 0,
rotate: 360,
ease: "power2.out",
}, 0.5)
t1.to(".sidebar-layout p,.sidebar-layout h3,.sidebar-layout .aa>svg", {
display: "block",
duration: 0,
ease: "power2.out",
}, 0.5)
t1.to(".sidebar-layout .user", {
duration: 0,
gap: "1rem"
}, 0.5)
}
t1.to(".sidebar-layout .header,.sidebar-layout .folder", {
duration: 0.5,
x: 0,
opacity: 1,
ease: "power2.out",
}, 1)
})
</script>
<template>
<section class="sidebar-layout">
<div class="switch-button" @click="mainLayoutStore.toggleLeftSidebarMini()">
<ArrowLeft/>
</div>
<div class="header">
<div class="user">
<!-- <Logo/>-->
<NuxtImg src="/Dragon_Head.gif" style="transform: scaleX(-1)" width="48"/>
<div class="name">
<h3>
龙盾云御
</h3>
</div>
</div>
<div class="search">
<Search/>
<p>搜索</p>
</div>
<div class="menus">
<div v-for="menu in Menus" v-tooltip="menu.label" class="menu-item" @click="navigateTo(menu.route)">
<Icon :name="menu.icon"/>
<p>{{ menu.label }}</p>
</div>
</div>
</div>
<div class="folder">
<div class="menu-item">
<Icon name="LogOut"/>
<p>登出</p>
</div>
<div class="menu-item aa">
<Icon name="Sun"/>
<p>颜色模式</p>
<color-switch/>
</div>
</div>
</section>
</template>
<style lang="scss" scoped>
@import "base";
.sidebar-layout {
display: flex;
grid-area: sidebar;
padding: 24px 24px 32px 24px;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
flex-shrink: 0;
background: $light-bg-color;
position: relative;
.dark-mode & {
background: $dark-bg-color;
}
}
.header {
display: flex;
gap: 44px;
width: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
}
.user {
display: flex;
gap: $gap*2;
align-items: center;
width: 100%;
justify-content: center;
> svg {
height: 44px;
width: 44px;
}
.name {
h3, p {
color: #09090A;
font-size: 24px;
font-style: normal;
font-weight: 700;
line-height: normal;
.dark-mode & {
color: #FFF;
}
}
}
}
.search {
width: 100%;
padding: $padding;
background: $light-bg-underline-color;
display: flex;
align-items: center;
gap: $gap*2;
border-radius: $radius*2;
.dark-mode & {
background: $dark-bg-underline-color;
svg, p {
color: #FFF;
stroke: #FFF;
}
}
> p {
color: #2A2A2E;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 140%; /* 22.4px */
}
}
.menus {
width: 100%;
display: flex;
flex-direction: column;
gap: $gap*3;
}
.menu-item {
display: flex;
padding: $padding;
gap: $gap*2;
align-items: center;
cursor: pointer;
border-radius: $radius;
.dark-mode & {
> svg, p {
color: #FFF;
stroke: #FFF;
}
&:hover {
background: $dark-bg-underline-color;
}
}
&:hover {
background: $light-bg-underline-color;
}
> svg {
stroke: #09090A;
}
> p {
color: #09090A;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 140%; /* 22.4px */
}
}
.folder {
display: flex;
flex-direction: column;
width: 100%;
gap: $gap;
}
.switch-button {
position: absolute;
top: 2%;
right: -15px;
display: flex;
justify-content: center;
align-items: center;
z-index: 10;
width: 30px;
height: 30px;
cursor: pointer;
background: $primary-color;
color: #FFF;
border-radius: $radius*100;
box-shadow: 0 2px 4px 0 rgba(138, 146, 166, 0.30);
> svg {
width: 18px;
height: 18px;
}
}
</style>