Files
fnx_web/svelte/src/wrap/MainMenu.svelte
2026-01-30 17:21:46 +01:00

208 lines
5.0 KiB
Svelte

<script lang="ts">
import { highlight_current_page } from "lib/HighlightCurrentPage";
import { user } from "lib/UserStore";
import Euro from "util/Euro.svelte";
import { formatDataVolume } from "util/Formatting";
import Router from "wrap/Router.svelte";
import Bookmarks from "./Bookmarks.svelte";
import { onMount } from "svelte";
import { fs_get_node } from "lib/FilesystemAPI.svelte";
import { css_from_path } from "filesystem/edit_window/Branding";
import { loading_run, loading_store } from "lib/Loading";
import Spinner from "util/Spinner.svelte";
import { get_user } from "lib/PixeldrainAPI";
import Tree from "./Tree.svelte";
let menu_collapsed = false
const toggle_menu = (e: MouseEvent) => {
menu_collapsed = !menu_collapsed
}
onMount(async () => {
menu_collapsed = document.documentElement.clientWidth < 1000
await loading_run(async () => {
const user = await get_user()
if (user.username === undefined || user.username === "") {
return
}
const root = await fs_get_node("/me")
document.documentElement.style = css_from_path(root.path)
})
})
</script>
<div class="nav_container">
<div class="scroll_container">
<nav class="nav" class:collapse={menu_collapsed}>
<button class="button" onclick={toggle_menu}>
<i class="icon small">menu</i>
<span class:hide={menu_collapsed}>Collapse menu</span>
</button>
<a class="button" href="/" use:highlight_current_page>
<i class="icon small">home</i>
<span class:hide={menu_collapsed}>Home</span>
</a>
{#if $user.username !== undefined && $user.username !== ""}
<div class="separator" class:hide={menu_collapsed}></div>
<div class="username" class:hide={menu_collapsed}>
{$user.username}
</div>
<div class="separator"></div>
<div class="stats_table" class:hide={menu_collapsed}>
<div>Subscription</div>
<div>{$user.subscription.name}</div>
{#if $user.subscription.type === "prepaid"}
<div>Credit</div>
<div><Euro amount={$user.balance_micro_eur}/></div>
{/if}
<div>Storage used</div>
<div>{formatDataVolume($user.filesystem_storage_used, 3)}</div>
<div>Transfer used</div>
<div>{formatDataVolume($user.monthly_transfer_used, 3)}</div>
</div>
<div class="separator" class:hide={menu_collapsed}></div>
<a class="button" href="/d/me" use:highlight_current_page>
<i class="icon small">folder</i>
<span class:hide={menu_collapsed}>Filesystem</span>
</a>
<a class="button" href="/user" use:highlight_current_page>
<i class="icon small">dashboard</i>
<span class:hide={menu_collapsed}>Dashboard</span>
</a>
{#if $user.is_admin}
<a class="button" href="/admin" use:highlight_current_page>
<i class="icon small">admin_panel_settings</i>
<span class:hide={menu_collapsed}>Admin Panel</span>
</a>
{/if}
{:else}
<a class="button" href="/login" use:highlight_current_page>
<i class="icon small">login</i>
<span class:hide={menu_collapsed}>Login</span>
</a>
<a class="button" href="/register" use:highlight_current_page>
<i class="icon small">how_to_reg</i>
<span class:hide={menu_collapsed}>Register</span>
</a>
{/if}
<div class="separator"></div>
<a class="button" href="/speedtest" use:highlight_current_page>
<i class="icon small">speed</i>
<span class:hide={menu_collapsed}>Speedtest</span>
</a>
<a class="button" href="/appearance" use:highlight_current_page>
<i class="icon small">palette</i>
<span class:hide={menu_collapsed}>Themes</span>
</a>
<div class="separator"></div>
<Bookmarks menu_collapsed={menu_collapsed}/>
{#if !menu_collapsed}
<Tree/>
{/if}
</nav>
</div>
</div>
<div class="page">
<Router/>
</div>
{#if $loading_store !== 0}
<div class="spinner">
<Spinner/>
</div>
{/if}
<style>
:global(body) {
display: flex;
flex-direction: row;
color: var(--body_text_color);
background-image: var(--background_image);
background-color: var(--background_pattern_color);
background-size: var(--background_image_size, initial);
background-position: var(--background_image_position, initial);
background-repeat: var(--background_image_repeat, repeat);
background-attachment: fixed;
}
.nav_container {
flex: 0 0 auto;
border-right: 1px solid var(--separator);
background: var(--shaded_background);
backdrop-filter: blur(4px);
}
.scroll_container {
position: sticky;
top: 0;
max-height: 100vh;
overflow-x: hidden;
overflow-y: auto;
}
.nav {
display: flex;
flex-direction: column;
width: 15em;
min-width: 10em;
max-width: 15em;
}
.nav.collapse {
width: unset;
min-width: unset;
}
.nav > .button {
background: none;
box-shadow: none;
}
.page {
flex: 1 1 auto;
overflow-x: hidden;
max-width: 100%;
}
.separator {
height: 1px;
margin: 2px 0;
width: 100%;
background-color: var(--separator);
}
.username {
text-align: center;
}
.stats_table {
display: grid;
grid-template-columns: auto auto;
gap: 0.2em 1em;
margin: 5px;
}
.hide {
display: none;
}
.spinner {
position: fixed;
top: 10px;
right: 10px;
height: 120px;
width: 120px;
}
</style>