web improve (#1047)

This commit is contained in:
Sijie.Sun
2025-06-24 09:09:52 +08:00
committed by GitHub
parent 760a1e6306
commit ae4a158e36
18 changed files with 1628 additions and 176 deletions
@@ -1,12 +1,14 @@
<script setup lang="ts">
import { Api, I18nUtils } from 'easytier-frontend-lib'
import { computed, onMounted, ref } from 'vue';
import { computed, onMounted, ref, onUnmounted, nextTick } from 'vue';
import { Button, TieredMenu } from 'primevue';
import { useRoute, useRouter } from 'vue-router';
import { useDialog } from 'primevue/usedialog';
import ChangePassword from './ChangePassword.vue';
import Icon from '../assets/easytier.png'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const route = useRoute();
const router = useRouter();
const api = computed<Api.ApiClient | undefined>(() => {
@@ -21,14 +23,10 @@ const api = computed<Api.ApiClient | undefined>(() => {
const dialog = useDialog();
onMounted(async () => {
await I18nUtils.loadLanguageAsync('cn')
});
const userMenu = ref();
const userMenuItems = ref([
{
label: 'Change Password',
label: t('web.main.change_password'),
icon: 'pi pi-key',
command: () => {
console.log('File');
@@ -45,7 +43,7 @@ const userMenuItems = ref([
},
},
{
label: 'Logout',
label: t('web.main.logout'),
icon: 'pi pi-sign-out',
command: async () => {
try {
@@ -59,18 +57,58 @@ const userMenuItems = ref([
])
const forceShowSideBar = ref(false)
const sidebarRef = ref<HTMLElement>()
const toggleButtonRef = ref<HTMLElement>()
// 处理点击外部区域关闭侧边栏
const handleClickOutside = (event: Event) => {
const target = event.target as HTMLElement;
// 如果侧边栏是隐藏的,不需要处理
if (!forceShowSideBar.value) return;
// 检查点击是否在侧边栏内部或切换按钮上
const isClickInsideSidebar = sidebarRef.value?.contains(target);
const isClickOnToggleButton = toggleButtonRef.value?.contains(target);
// 如果点击在侧边栏外部且不在切换按钮上,则关闭侧边栏
if (!isClickInsideSidebar && !isClickOnToggleButton) {
forceShowSideBar.value = false;
}
};
// 切换侧边栏显示状态
const toggleSidebar = () => {
forceShowSideBar.value = !forceShowSideBar.value;
};
// 点击背景遮罩关闭侧边栏
const closeSidebar = () => {
forceShowSideBar.value = false;
};
onMounted(async () => {
// 等待 DOM 渲染完成后添加事件监听器
await nextTick();
document.addEventListener('click', handleClickOutside);
});
onUnmounted(() => {
document.removeEventListener('click', handleClickOutside);
});
</script>
<!-- https://flowbite.com/docs/components/sidebar/#sidebar-with-navbar -->
<template>
<nav class="fixed top-0 z-50 w-full bg-white border-b border-gray-200 dark:bg-gray-800 dark:border-gray-700">
<nav
class="fixed top-0 z-50 w-full bg-white border-b border-gray-200 dark:bg-gray-800 dark:border-gray-700 top-navbar">
<div class="px-3 py-3 lg:px-5 lg:pl-3">
<div class="flex items-center justify-between">
<div class="flex items-center justify-start rtl:justify-end">
<div class="sm:hidden">
<Button type="button" aria-haspopup="true" icon="pi pi-list" variant="text" size="large"
severity="contrast" @click="forceShowSideBar = !forceShowSideBar" />
<Button ref="toggleButtonRef" type="button" aria-haspopup="true" icon="pi pi-list"
variant="text" size="large" severity="contrast" @click="toggleSidebar" />
</div>
<a href="https://easytier.top" class="flex ms-2 md:me-24">
<img :src="Icon" class="h-9 me-3" alt="FlowBite Logo" />
@@ -79,52 +117,27 @@ const forceShowSideBar = ref(false)
</a>
</div>
<div class="flex items-center">
<div class="language-switch">
<Button icon="pi pi-language" @click="I18nUtils.toggleLanguage" rounded severity="contrast" />
</div>
<div class="flex items-center ms-3">
<div>
<Button type="button" @click="userMenu.toggle($event)" aria-haspopup="true"
aria-controls="user-menu" icon="pi pi-user" raised rounded />
<TieredMenu ref="userMenu" id="user-menu" :model="userMenuItems" popup />
</div>
<div class="z-50 hidden my-4 text-base list-none bg-white divide-y divide-gray-100 rounded shadow dark:bg-gray-700 dark:divide-gray-600"
id="dropdown-user">
<div class="px-4 py-3" role="none">
<p class="text-sm text-gray-900 dark:text-white" role="none">
Neil Sims
</p>
<p class="text-sm font-medium text-gray-900 truncate dark:text-gray-300" role="none">
neil.sims@flowbite.com
</p>
</div>
<ul class="py-1" role="none">
<li>
<a href="#"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white"
role="menuitem">Dashboard</a>
</li>
<li>
<a href="#"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white"
role="menuitem">Settings</a>
</li>
<li>
<a href="#"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white"
role="menuitem">Earnings</a>
</li>
<li>
<a href="#"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white"
role="menuitem">Sign out</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</nav>
<aside id="logo-sidebar"
<!-- 背景遮罩 - 只在侧边栏显示时显示 -->
<div v-if="forceShowSideBar" class="fixed inset-0 z-30 bg-black bg-opacity-50 sm:hidden" @click="closeSidebar">
</div>
<aside ref="sidebarRef" id="logo-sidebar"
class="fixed top-1 left-0 z-40 w-64 h-screen pt-20 transition-transform bg-white border-r border-gray-201 sm:translate-x-0 dark:bg-gray-800 dark:border-gray-700"
:class="{ '-translate-x-full': !forceShowSideBar }" aria-label="Sidebar">
<div class="h-full px-3 pb-4 overflow-y-auto bg-white dark:bg-gray-800">
@@ -133,21 +146,21 @@ const forceShowSideBar = ref(false)
<Button variant="text" class="w-full justify-start gap-x-3 pl-1.5 sidebar-button"
severity="contrast" @click="router.push({ name: 'dashboard' })">
<i class="pi pi-chart-pie text-xl"></i>
<span class="mb-0.5">DashBoard</span>
<span class="mb-0.5">{{ t('web.main.dashboard') }}</span>
</Button>
</li>
<li>
<Button variant="text" class="w-full justify-start gap-x-3 pl-1.5 sidebar-button"
severity="contrast" @click="router.push({ name: 'deviceList' })">
<i class="pi pi-server text-xl"></i>
<span class="mb-0.5">Devices</span>
<span class="mb-0.5">{{ t('web.main.device_list') }}</span>
</Button>
</li>
<li>
<Button variant="text" class="w-full justify-start gap-x-3 pl-1.5 sidebar-button"
severity="contrast" @click="router.push({ name: 'login' })">
<i class="pi pi-sign-in text-xl"></i>
<span class="mb-0.5">Login Page</span>
<span class="mb-0.5">{{ t('web.main.login_page') }}</span>
</Button>
</li>
</ul>
@@ -155,7 +168,7 @@ const forceShowSideBar = ref(false)
</aside>
<div class="p-4 sm:ml-64">
<div class="p-4 border-2 border-gray-200 border-dashed rounded-lg dark:border-gray-700 mt-14">
<div class="p-4 border-2 border-gray-200 border-dashed rounded-lg dark:border-gray-700">
<div class="grid grid-cols-1 gap-4">
<RouterView v-slot="{ Component }">
<component :is="Component" :api="api" />