OpenAuth_views/src/pages/User/App.svelte

255 lines
5.3 KiB
Svelte

<script>
import HomePage from "./Pages/Home.svelte";
import AccountPage from "./Pages/Account.svelte";
import SecurityPage from "./Pages/Security.svelte";
import AppsPage from "./Pages/Apps.svelte";
import { slide, fade } from "svelte/transition";
import HomeIcon from "../../Icons/Home.svelte";
import AccountIcon from "../../Icons/Account.svelte";
import SecurityIcon from "../../Icons/Security.svelte";
import AppsIcon from "../../Icons/Apps.svelte";
import AdminIcon from "../../Icons/Admin.svelte";
import MenuIcon from "../../Icons/Menu.svelte";
import DarkthemeIcon from "../../Icons/Darktheme.svelte";
import { isAdmin } from "./api";
let dark = localStorage.getItem("theme") === "dark";
$: {
localStorage.setItem("theme", dark ? "dark" : "light");
}
let pages = [
{
id: "home",
title: "Home",
icon: HomeIcon,
component: HomePage,
},
{
id: "account",
title: "Account",
icon: AccountIcon,
component: AccountPage,
},
{
id: "security",
title: "Security",
icon: SecurityIcon,
component: SecurityPage,
},
{
id: "apps",
title: "Applications",
icon: AppsIcon,
component: AppsPage,
},
];
isAdmin().then((admin) => {
if (admin) {
pages = [
...pages,
{
id: "admin",
title: "Admin",
icon: AdminIcon,
component: HomePage,
divide: true,
subComponents: [
{
id: "admin_user",
title: "User",
component: HomePage,
},
],
},
];
}
});
function getPage() {
let pageid = window.location.hash.slice(1);
return pages.find((e) => e.id === pageid) || pages[0];
}
let page = getPage();
window.addEventListener("hashchange", () => {
page = getPage();
});
// $: title = pages.find(e => e.id === page).title;
const mq = window.matchMedia("(min-width: 45rem)");
let sidebar_button = !mq.matches;
mq.addEventListener("change", (ev) => {
sidebar_button = !ev.matches;
});
let sidebar_active = false;
function setPage(pageid) {
let pg = pages.find((e) => e.id === pageid);
if (!pg) {
throw new Error("Invalid Page " + pageid);
} else {
let url = new URL(window.location.href);
url.hash = pg.id;
window.history.pushState({}, pg.title, url);
page = getPage();
}
sidebar_active = false;
}
let loading = true;
import NavigationBar from "./NavigationBar.svelte";
import Theme from "../../components/theme/Theme.svelte";
</script>
<style>
.loading {
background-color: rgba(0, 0, 0, 0.04);
filter: blur(10px);
}
:root {
--sidebar-width: 250px;
}
.root {
height: 100%;
}
.app-container {
display: grid;
height: 100vh;
width: 100vw;
overflow-x: hidden;
grid-template-columns: auto 100%;
grid-template-rows: 60px auto 60px;
grid-template-areas:
"sidebar header"
"sidebar mc"
"sidebar footer";
}
.header {
grid-area: header;
background-color: var(--primary);
padding: 12px;
display: flex;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
.header > h1 {
margin: 0;
padding: 0;
font-size: 24px;
line-height: 36px;
color: white;
margin-left: 2rem;
}
.header > button {
height: 36px;
background-color: transparent;
border: none;
font-size: 20px;
}
.header > button:hover {
background-color: rgba(255, 255, 255, 0.151);
}
.header > .dark-theme-btn {
}
.sidebar {
width: 0;
overflow: hidden;
grid-area: sidebar;
transition: width 0.2s;
/* background-color: lightgrey; */
height: 100%;
}
.sidebar-visible {
width: var(--sidebar-width);
transition: width 0.2s;
box-shadow: 10px 0px 10px 2px rgba(0, 0, 0, 0.52);
}
.content {
grid-area: mc;
padding: 1rem;
}
.footer {
grid-area: footer;
}
@media (min-width: 45rem) {
.app-container {
grid-template-columns: auto 1fr;
}
.sidebar {
width: var(--sidebar-width);
transition: all 0.2s;
box-shadow: 10px 0px 10px 2px rgba(0, 0, 0, 0.52);
}
.content {
padding: 2rem;
}
}
.loader_container {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 2;
}
</style>
<Theme {dark}>
<div class:loading class="root">
<div class="app-container">
<div class="header">
{#if sidebar_button}
<button on:click={() => (sidebar_active = !sidebar_active)}>
<MenuIcon />
</button>
{/if}
<h1>{page.title}</h1>
<button on:click={() => (dark = !dark)} class="theme-btn">
<DarkthemeIcon />
</button>
</div>
<div class="sidebar elv-16" class:sidebar-visible={sidebar_active}>
<NavigationBar open={setPage} {pages} active={page} />
</div>
<div class="content">
<svelte:component this={page.component} bind:loading />
</div>
<div class="footer" />
</div>
</div>
{#if loading}
<div class="loader_container">
<div class="loader_box">
<div class="loader" />
</div>
</div>
{/if}
</Theme>