You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/ui/layout/ico.html

186 lines
4.5 KiB
HTML

<!DOCTYPE html>
<html>
<style>
body {
position: relative;
}
.header-user {
position: relative;
display: flex;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-xs) var(--spacing-sm);
border-radius: var(--radius-xl);
transition: all var(--transition-base);
cursor: pointer;
}
.header-user:hover {
background: color-mix(in srgb, var(--bg-color), var(--color-primary) 10%);
}
.user-avatar {
width: 36px;
height: 36px;
border-radius: 50%;
object-fit: cover;
border: 2px solid var(--border-color);
box-shadow: var(--shadow-sm);
}
.user-name {
font-size: var(--font-size-md);
font-weight: var(--font-weight-medium);
color: var(--text-color);
text-decoration: none;
}
.dropdown-arrow {
font-size: var(--font-size-xs);
color: var(--text-color-secondary);
transition: transform var(--transition-base);
}
.dropdown-arrow.open {
transform: rotate(180deg);
}
.dropdown-menu {
position: absolute;
top: 100%;
right: 0;
background: var(--bg-color);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-lg);
border: 1px solid var(--border-color);
min-width: 160px;
z-index: 1000;
margin-top: 4px;
opacity: 0;
visibility: hidden;
transform: translateY(-10px);
transition: all var(--transition-base);
}
.dropdown-menu.show {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.dropdown-item {
display: block;
width: 100%;
padding: 12px 16px;
text-decoration: none;
color: var(--text-color);
font-size: var(--font-size-md);
border: none;
background: none;
text-align: left;
cursor: pointer;
transition: background-color var(--transition-base);
}
.dropdown-item:hover {
background: var(--bg-color-tertiary);
}
.dropdown-item.danger {
color: var(--color-danger);
}
.dropdown-item.danger:hover {
background: rgba(239, 68, 68, 0.1);
}
.dropdown-divider {
height: 1px;
background: var(--border-color);
margin: 4px 0;
}
.auth-btn {
padding: 6px 16px;
border-radius: var(--radius-xl);
font-size: var(--font-size-md);
font-weight: var(--font-weight-medium);
cursor: pointer;
transition: all var(--transition-base);
}
.login-btn {
background: var(--color-primary);
color: var(--color-primary-text);
border: none;
}
.login-btn:hover {
background: var(--color-primary-hover);
}
</style>
<body>
<div class="header-user" v-if="user.id" @click="toggleDropdown">
<img :src="user.avatar" class="user-avatar" alt="用户头像">
<span class="user-name">{{ user.nickname || user.username }}</span>
<span class="dropdown-arrow" :class="{open: dropdownOpen}"></span>
<div class="dropdown-menu" :class="{show: dropdownOpen}">
<a v-for="menu in menus" :href="menu.path" class="dropdown-item">
{{ menu.label }}
</a>
<div class="dropdown-divider"></div>
<button @click="logout" class="dropdown-item danger">
<i class="fa-solid fa-sign-out-alt" style="margin-right: 8px;"></i>
退出登录
</button>
</div>
</div>
<div class="header-user" v-else>
<a @click='logout' class="auth-btn login-btn" reload>
登录
</a>
</div>
</body>
<script setup>
menus = [
{label: () => $t('nav.dashboard'), icon: "<i class='fas fa-tachometer-alt'></i>", path: "/"},
{label: () => $t('nav.profile'), icon: "<i class='fas fa-user'></i>", path: "/profile"},
// Admin only items would be filtered here ideally
{label: () => $t('nav.users'), icon: "<i class='fas fa-users-cog'></i>", path: "/users"},
{label: () => $t('nav.roles'), icon: "<i class='fas fa-user-tag'></i>", path: "/roles"},
{label: () => $t('nav.oauth'), icon: "<i class='fas fa-rocket'></i>", path: "/oauth/apps"},
{label: () => $t('nav.oauth_providers'), icon: "<i class='fas fa-id-card'></i>", path: "/oauth/providers"},
{label: () => $t('nav.settings'), icon: "<i class='fas fa-cog'></i>", path: "/settings"},
];
user = $vbase.user || {}
dropdownOpen = false
toggleDropdown = (event) => {
event.stopPropagation()
dropdownOpen = !dropdownOpen
}
logout = (event) => {
event.stopPropagation()
dropdownOpen = false
$vbase.logout(window.location.href)
}
</script>
<script>
// 点击外部区域关闭下拉菜单
document.addEventListener('click', (event) => {
if (!$node.contains(event.target)) {
$data.dropdownOpen = false
}
})
</script>
</html>