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/oaweb/layouts/default.vue

173 lines
4.2 KiB
Vue

<!--
* default.vue
* Copyright (C) 2024 veypi <i@veypi.com>
* 2024-05-31 17:09
* Distributed under terms of the MIT license.
-->
<template>
<div class="page">
<div class="header flex justify-center items-center">
<div class="ico" @click="router.push('/')"></div>
<div>OneAuth</div>
<div class="grow"></div>
<OneIcon class="mx-2 cursor-pointer" @click="oaer.goto('/docs')" name="help" />
<OneIcon class="mx-2 cursor-pointer" @click="toggle_lang"
:name="$i18n.locale !== 'zh-CN' ? 'in-Zh_Cn' : 'in-en'" />
<OneIcon class="mx-2 cursor-pointer" @click="toggle_fullscreen"
:name="app.layout.fullscreen ? 'compress' : 'expend'" />
<OneIcon class="mx-2 cursor-pointer" @click="toggle_theme" :name="app.layout.theme === '' ? 'light' : 'dark'">
</OneIcon>
<div class="mr-4 ml-2" id='oaer'></div>
</div>
<div class="page-body">
<div v-if="menusCount" class="menu">
<Menu :show_name="menu_mode === 2"></Menu>
</div>
<div v-if="menusCount" class="menu-hr"></div>
<div class="main px-8 py-6">
<slot />
</div>
</div>
<div class="footer flex justify-around items-center">
<div @click="util.goto('https://veypi.com')">© 2024 veypi</div>
<div>使用说明</div>
<div>联系我们</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { OneIcon } from '@veypi/one-icon'
import oaer from '@veypi/oaer'
import { useI18n } from 'vue-i18n';
let i18n = useI18n()
let app = useAppConfig()
let router = useRouter()
const colorMode = useColorMode()
let menu_handler = useMenuStore()
let menusCount = computed(() => menu_handler.menus.length)
let menu_mode = ref(1)
let toggle_menu = (m: 0 | 1 | 2) => {
menu_mode.value = m
if (m == 0) {
app.layout.menu_width = 0
} else if (m == 1) {
app.layout.menu_width = 40
} else {
app.layout.menu_width = 108
}
}
toggle_menu(2)
const toggle_lang = () => {
if (i18n.locale.value === 'zh-CN') {
i18n.locale.value = 'en-US'
} else {
i18n.locale.value = 'zh-CN'
}
localStorage.setItem('lang', i18n.locale.value)
}
const toggle_fullscreen = () => {
app.layout.fullscreen = !app.layout.fullscreen
if (app.layout.fullscreen) {
let docElm = document.documentElement;
docElm.requestFullscreen();
} else {
document.exitFullscreen();
}
}
const toggle_theme = () => {
app.layout.theme =
app.layout.theme === '' ? 'dark' : ''
document.documentElement.setAttribute('theme', app.layout.theme)
colorMode.preference = app.layout.theme === '' ? 'light' : 'dark'
}
onMounted(() => {
oaer.render_ui('oaer')
useMenuStore().default()
})
</script>
<style scoped lang="scss">
.page {
height: 100vh;
width: 100vw;
.header {
height: v-bind('app.layout.header_height + "px"');
user-select: none;
background: var(--header-bg);
color: var(--header-txt);
font-size: 24px;
.ico {
width: v-bind('app.layout.header_height * 0.8 + "px"');
height: v-bind('app.layout.header_height * 0.8 + "px"');
background: url('/favicon.ico') no-repeat;
background-size: cover;
}
#oaer {
width: v-bind('app.layout.header_height * 0.6 + "px"');
height: v-bind('app.layout.header_height * 0.6 + "px"');
}
}
.page-body {
display: flex;
height: calc(100vh - v-bind('app.layout.header_height + app.layout.footer_height + "px"'));
.menu {
overflow: hidden;
vertical-align: top;
display: inline-block;
width: v-bind("app.layout.menu_width + 'px'");
height: 100%;
transition: width 0.3s linear;
}
.menu-hr {
vertical-align: top;
display: inline-block;
width: 1px;
height: 100%;
background: #999;
}
.main {
flex-grow: 1;
vertical-align: top;
display: inline-block;
overflow: auto;
height: 100%;
transition: width 0.3s linear;
}
}
.footer {
height: v-bind("app.layout.footer_height + 'px'");
user-select: none;
background: var(--footer-bg);
color: var(--footer-txt);
font-size: 12px;
line-height: v-bind("app.layout.footer_height + 'px'");
div {
cursor: pointer;
opacity: 0.6;
}
div:hover {
opacity: 1;
}
}
}
</style>