mirror of
https://github.com/CorentinTh/it-tools.git
synced 2026-08-31 08:28:58 +00:00
feat: add logout menu to navbar
This commit is contained in:
parent
59a70ebfa0
commit
651410e2b6
5 changed files with 161 additions and 42 deletions
|
|
@ -27,6 +27,9 @@ home:
|
|||
darkMode: 'Dark mode'
|
||||
lightMode: 'Light mode'
|
||||
mode: 'Toggle dark/light mode'
|
||||
more: 'More'
|
||||
themeTitle: 'Theme switch'
|
||||
logout: 'Logout'
|
||||
about:
|
||||
content: >
|
||||
# About IT-Tools
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ home:
|
|||
darkMode: '深色模式'
|
||||
lightMode: '浅色模式'
|
||||
mode: '颜色模式'
|
||||
more: '更多'
|
||||
themeTitle: '主题切换'
|
||||
logout: '退出'
|
||||
about:
|
||||
content: >
|
||||
# 关于 IT-Tools
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { IconBrandGithub, IconBrandX, IconInfoCircle, IconMoon, IconSun } from '@tabler/icons-vue';
|
||||
import { useStyleStore } from '@/stores/style.store';
|
||||
|
||||
const styleStore = useStyleStore();
|
||||
const { isDarkTheme } = toRefs(styleStore);
|
||||
import { IconBrandGithub, IconBrandX, IconInfoCircle } from '@tabler/icons-vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -38,12 +34,6 @@ const { isDarkTheme } = toRefs(styleStore);
|
|||
<n-icon size="25" :component="IconInfoCircle" />
|
||||
</c-button>
|
||||
</c-tooltip>
|
||||
<c-tooltip :tooltip="isDarkTheme ? $t('home.nav.lightMode') : $t('home.nav.darkMode')" position="bottom">
|
||||
<c-button circle variant="text" :aria-label="$t('home.nav.mode')" @click="() => styleStore.toggleDark()">
|
||||
<n-icon v-if="isDarkTheme" size="25" :component="IconSun" />
|
||||
<n-icon v-else size="25" :component="IconMoon" />
|
||||
</c-button>
|
||||
</c-tooltip>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
|||
151
src/components/NavbarMoreMenu.vue
Normal file
151
src/components/NavbarMoreMenu.vue
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
<script setup lang="ts">
|
||||
import { useThemeVars } from 'naive-ui';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { IconDotsVertical, IconLogout, IconMoon, IconSun } from '@tabler/icons-vue';
|
||||
import { useStyleStore } from '@/stores/style.store';
|
||||
|
||||
const styleStore = useStyleStore();
|
||||
const { isDarkTheme } = storeToRefs(styleStore);
|
||||
const theme = useThemeVars();
|
||||
|
||||
const isOpen = ref(false);
|
||||
const menuRef = ref<HTMLElement | null>(null);
|
||||
|
||||
function closeMenu() {
|
||||
isOpen.value = false;
|
||||
}
|
||||
|
||||
function toggleMenu() {
|
||||
isOpen.value = !isOpen.value;
|
||||
}
|
||||
|
||||
function setLightTheme() {
|
||||
if (isDarkTheme.value) {
|
||||
styleStore.toggleDark();
|
||||
}
|
||||
|
||||
closeMenu();
|
||||
}
|
||||
|
||||
function setDarkTheme() {
|
||||
if (!isDarkTheme.value) {
|
||||
styleStore.toggleDark();
|
||||
}
|
||||
|
||||
closeMenu();
|
||||
}
|
||||
|
||||
function logout() {
|
||||
window.location.assign(new URL('/cdn-cgi/access/logout', window.location.origin).toString());
|
||||
}
|
||||
|
||||
onClickOutside(menuRef, closeMenu);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="menuRef" class="navbar-more-menu" relative>
|
||||
<c-tooltip :tooltip="$t('home.nav.more')" position="bottom">
|
||||
<c-button
|
||||
circle
|
||||
variant="text"
|
||||
:aria-label="$t('home.nav.more')"
|
||||
@click="toggleMenu"
|
||||
>
|
||||
<n-icon size="25" :component="IconDotsVertical" />
|
||||
</c-button>
|
||||
</c-tooltip>
|
||||
|
||||
<transition name="fade">
|
||||
<div v-if="isOpen" class="menu-panel">
|
||||
<div class="menu-title">
|
||||
{{ $t('home.nav.themeTitle') }}
|
||||
</div>
|
||||
|
||||
<button class="menu-option" :class="{ active: !isDarkTheme }" type="button" @click="setLightTheme">
|
||||
<n-icon size="20" :component="IconSun" />
|
||||
<span>{{ $t('home.nav.lightMode') }}</span>
|
||||
</button>
|
||||
|
||||
<button class="menu-option" :class="{ active: isDarkTheme }" type="button" @click="setDarkTheme">
|
||||
<n-icon size="20" :component="IconMoon" />
|
||||
<span>{{ $t('home.nav.darkMode') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider" />
|
||||
|
||||
<button class="menu-option logout" type="button" @click="logout">
|
||||
<n-icon size="20" :component="IconLogout" />
|
||||
<span>{{ $t('home.nav.logout') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.navbar-more-menu {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.menu-panel {
|
||||
position: absolute;
|
||||
top: calc(100% + 12px);
|
||||
right: 0;
|
||||
z-index: 30;
|
||||
min-width: 220px;
|
||||
padding: 18px 12px 14px;
|
||||
border-radius: 28px;
|
||||
background: v-bind('theme.bodyColor');
|
||||
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.18);
|
||||
border: 1px solid rgba(127, 127, 127, 0.14);
|
||||
}
|
||||
|
||||
.menu-title {
|
||||
color: rgba(127, 127, 127, 0.95);
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
padding: 0 12px 10px;
|
||||
}
|
||||
|
||||
.menu-option {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
border: 0;
|
||||
border-radius: 18px;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
padding: 14px 12px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
background: rgba(255, 217, 102, 0.18);
|
||||
}
|
||||
}
|
||||
|
||||
.logout {
|
||||
color: #d9480f;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
margin: 10px 8px 8px;
|
||||
background: rgba(127, 127, 127, 0.18);
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.15s ease, transform 0.15s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-6px);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -2,17 +2,17 @@
|
|||
import { NIcon, useThemeVars } from 'naive-ui';
|
||||
|
||||
import { RouterLink } from 'vue-router';
|
||||
import { Heart, Home2, Menu2 } from '@vicons/tabler';
|
||||
import { Home2, Menu2 } from '@vicons/tabler';
|
||||
|
||||
import { storeToRefs } from 'pinia';
|
||||
import HeroGradient from '../assets/hero-gradient.svg?component';
|
||||
import MenuLayout from '../components/MenuLayout.vue';
|
||||
import NavbarButtons from '../components/NavbarButtons.vue';
|
||||
import NavbarMoreMenu from '../components/NavbarMoreMenu.vue';
|
||||
import { useStyleStore } from '@/stores/style.store';
|
||||
import { config } from '@/config';
|
||||
import type { ToolCategory } from '@/tools/tools.types';
|
||||
import { useToolStore } from '@/tools/tools.store';
|
||||
import { useTracker } from '@/modules/tracker/tracker.services';
|
||||
import CollapsibleToolMenu from '@/components/CollapsibleToolMenu.vue';
|
||||
|
||||
const themeVars = useThemeVars();
|
||||
|
|
@ -20,7 +20,6 @@ const styleStore = useStyleStore();
|
|||
const version = config.app.version;
|
||||
const commitSha = config.app.lastCommitSha.slice(0, 7);
|
||||
|
||||
const { tracker } = useTracker();
|
||||
const { t } = useI18n();
|
||||
|
||||
const toolStore = useToolStore();
|
||||
|
|
@ -119,21 +118,7 @@ const tools = computed<ToolCategory[]>(() => [
|
|||
<div>
|
||||
<NavbarButtons v-if="!styleStore.isSmallScreen" />
|
||||
</div>
|
||||
|
||||
<c-tooltip position="bottom" :tooltip="$t('home.support')">
|
||||
<c-button
|
||||
round
|
||||
href="https://www.buymeacoffee.com/cthmsst"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
class="support-button"
|
||||
:bordered="false"
|
||||
@click="() => tracker.trackEvent({ eventName: 'Support button clicked' })"
|
||||
>
|
||||
{{ $t('home.buyMeACoffee') }}
|
||||
<NIcon v-if="!styleStore.isSmallScreen" :component="Heart" ml-2 />
|
||||
</c-button>
|
||||
</c-tooltip>
|
||||
<NavbarMoreMenu />
|
||||
</div>
|
||||
<slot />
|
||||
</template>
|
||||
|
|
@ -152,19 +137,6 @@ const tools = computed<ToolCategory[]>(() => [
|
|||
// background-size: @size @size;
|
||||
// }
|
||||
|
||||
.support-button {
|
||||
background: rgb(37, 99, 108);
|
||||
background: linear-gradient(48deg, rgba(37, 99, 108, 1) 0%, rgba(59, 149, 111, 1) 60%, rgba(20, 160, 88, 1) 100%);
|
||||
color: #fff !important;
|
||||
transition: padding ease 0.2s !important;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
color: #838587;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue