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/default.html

198 lines
4.8 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Default Layout">
<title>VBase</title>
<style>
.layout-container {
display: flex;
height: 100vh;
width: 100vw;
overflow: hidden;
background-color: var(--bg-color);
}
.sidebar-container {
height: 100%;
background-color: #fff;
border-right: 1px solid var(--border-color);
display: flex;
flex-direction: column;
transition: width 0.3s;
}
.main-content {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
background-color: var(--bg-color);
}
.header {
height: 60px;
background-color: #fff;
border-bottom: 1px solid var(--border-color);
display: flex;
align-items: center;
padding: 0 20px;
justify-content: space-between;
}
.header-left {
display: flex;
align-items: center;
gap: 20px;
}
.header-right {
display: flex;
align-items: center;
gap: 15px;
}
.content-body {
flex: 1;
overflow-y: auto;
padding: 20px;
}
.logo {
height: 60px;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 18px;
color: var(--color-primary);
border-bottom: 1px solid var(--border-color);
}
.org-switcher {
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
padding: 5px 10px;
border-radius: 4px;
transition: background 0.2s;
}
.org-switcher:hover {
background-color: var(--bg-color-tertiary);
}
.user-profile {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
}
.breadcrumb {
color: var(--text-color-secondary);
font-size: 14px;
}
</style>
</head>
<body>
<div class="layout-container">
<!-- Sidebar -->
<div class="sidebar-container" :style="{width: collapsed ? '64px' : '240px'}">
<v-sidebar :items="menuItems" :collapsed="collapsed" width="240px" collapsedWidth="64px">
<div vslot="header" class="logo">
<span v-if="!collapsed">VBase</span>
<span v-else>VB</span>
</div>
</v-sidebar>
</div>
<!-- Main Content -->
<div class="main-content">
<!-- Header -->
<header class="header">
<div class="header-left">
<div @click="toggleCollapse" style="cursor: pointer;">
<i class="fas" :class="collapsed ? 'fa-indent' : 'fa-outdent'"></i>
</div>
<div class="breadcrumb">
{{ currentRouteName }}
</div>
</div>
<div class="header-right">
<!-- Org Switcher -->
<div class="org-switcher" @click="openOrgSwitch" v-if="currentOrg">
<i class="fas fa-building"></i>
<span>{{ currentOrg.name }}</span>
<i class="fas fa-chevron-down" style="font-size: 12px;"></i>
</div>
<v-lang></v-lang>
<!-- User Profile -->
<div class="user-profile" @click="goToProfile">
<i class="fas fa-user-circle" style="font-size: 24px;"></i>
<span>{{ user ? user.nickname || user.username : 'User' }}</span>
</div>
<div @click="logout" style="cursor: pointer; color: var(--color-danger);" title="Logout">
<i class="fas fa-sign-out-alt"></i>
</div>
</div>
</header>
<!-- Page Content -->
<vslot class="content-body">
</vslot>
</div>
</div>
</body>
<script setup>
collapsed = false;
user = $env.$vbase.user;
currentOrg = $env.$vbase.currentOrg;
// Define Menu Items
menuItems = [
{label: () => $t('nav.dashboard'), icon: "<i class='fas fa-tachometer-alt'></i>", path: "/"},
{label: () => $t('nav.org'), icon: "<i class='fas fa-sitemap'></i>", path: "/org"},
{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.oauth'), icon: "<i class='fas fa-key'></i>", path: "/oauth/apps"},
];
currentRouteName = "";
toggleCollapse = () => {
collapsed = !collapsed;
};
logout = () => {
$env.$vbase.logout();
};
goToProfile = () => {
$router.push('/profile');
};
openOrgSwitch = () => {
// Simple alert for now, should be a modal or dropdown
// In vhtml we can use $message or navigate to org list
$router.push('/org');
};
</script>
<script>
$router.onChange(() => {
const path = $router.current.path;
console.log(path)
const item = $data.menuItems.find(i => i.path === path);
$data.currentRouteName = item ? item.label : path;
});
</script>
</html>