pronounss/frontend/src/routes/nav/Navigation.svelte

159 lines
4.1 KiB
Svelte
Raw Normal View History

2023-03-09 17:08:43 +01:00
<script lang="ts">
import { onMount } from "svelte";
import { browser } from "$app/environment";
import { decodeJwt } from "jose";
2023-03-09 17:08:43 +01:00
2023-03-11 16:52:48 +01:00
import {
Badge,
2023-03-11 16:52:48 +01:00
Collapse,
Icon,
Nav,
Navbar,
NavbarBrand,
NavbarToggler,
NavItem,
NavLink,
} from "sveltestrap";
2023-03-09 17:08:43 +01:00
import Logo from "./Logo.svelte";
2023-03-11 16:52:48 +01:00
import { userStore, themeStore } from "$lib/store";
import {
ErrorCode,
type APIError,
type MeUser,
type Report,
type Warning,
} from "$lib/api/entities";
import { apiFetch, apiFetchClient } from "$lib/api/fetch";
import { addToast } from "$lib/toast";
2023-03-09 17:08:43 +01:00
2023-03-11 16:52:48 +01:00
let theme: string;
let currentUser: MeUser | null;
2023-03-09 17:08:43 +01:00
let showMenu: boolean = false;
let isAdmin = false;
let numReports = 0;
let numWarnings = 0;
2023-03-11 16:52:48 +01:00
$: currentUser = $userStore;
$: theme = $themeStore;
2023-03-09 17:08:43 +01:00
onMount(() => {
2023-03-11 16:52:48 +01:00
const localUser = localStorage.getItem("pronouns-user");
userStore.set(localUser ? JSON.parse(localUser) : null);
const token = localStorage.getItem("pronouns-token");
if (token) {
apiFetch<MeUser>("/users/@me", { token })
.then((user) => {
userStore.set(user);
localStorage.setItem("pronouns-user", JSON.stringify(user));
})
.catch((e) => {
console.log("getting /users/@me:", e);
if (
(e as APIError).code == ErrorCode.InvalidToken ||
(e as APIError).code == ErrorCode.Forbidden
) {
localStorage.removeItem("pronouns-token");
localStorage.removeItem("pronouns-user");
}
});
isAdmin = !!decodeJwt(token)["adm"];
if (isAdmin) {
apiFetchClient<Report[]>("/admin/reports")
.then((reports) => {
numReports = reports.length;
})
.catch((e) => {
console.log("getting reports:", e);
});
}
apiFetchClient<Warning[]>("/auth/warnings")
.then((warnings) => {
if (warnings.length !== 0) {
numWarnings = warnings.length;
addToast({
header: "Warnings",
body: "You have unread warnings. Go to your settings to view them.",
duration: -1,
});
}
})
.catch((e) => {
console.log("getting warnings:", e);
});
2023-03-11 16:52:48 +01:00
}
2023-03-09 17:08:43 +01:00
});
2023-03-11 16:52:48 +01:00
$: updateTheme(theme);
2023-03-09 17:08:43 +01:00
2023-03-11 16:52:48 +01:00
const updateTheme = (newTheme: string) => {
2023-03-09 17:08:43 +01:00
if (!browser) return;
2023-03-11 16:52:48 +01:00
document.documentElement.setAttribute("data-bs-theme", newTheme);
localStorage.setItem("pronouns-theme", newTheme);
2023-03-09 17:08:43 +01:00
};
const toggleTheme = () => {
themeStore.set(theme === "dark" ? "light" : "dark");
2023-03-09 17:08:43 +01:00
};
2023-03-11 01:36:30 +01:00
const toggleMenu = () => {
showMenu = !showMenu;
};
2023-03-09 17:08:43 +01:00
</script>
2023-03-11 01:36:30 +01:00
<Navbar
2023-03-11 16:52:48 +01:00
color={theme === "dark" ? "dark" : "light"}
light={theme !== "dark"}
dark={theme === "dark"}
2023-03-11 01:36:30 +01:00
expand="lg"
class="mb-4"
2023-03-09 17:08:43 +01:00
>
2023-03-11 01:36:30 +01:00
<NavbarBrand href="/"><Logo /></NavbarBrand>
<NavbarToggler on:click={toggleMenu} />
<Collapse isOpen={showMenu} navbar expand="lg">
<Nav class="ms-auto" navbar>
{#if currentUser}
<NavItem>
2023-03-11 16:52:48 +01:00
<NavLink href="/@{currentUser.name}">@{currentUser.name}</NavLink>
</NavItem>
<NavItem>
<NavLink href="/settings">
Settings
{#if numWarnings}
<Badge color="danger">{numWarnings}</Badge>
{/if}
</NavLink>
</NavItem>
{#if isAdmin}
<NavItem>
<NavLink href="/reports">
Reports
{#if numReports !== 0}
<Badge color="danger">{numReports}</Badge>
{/if}
</NavLink>
</NavItem>
{/if}
{:else}
<NavItem>
<NavLink href="/auth/login">Log in</NavLink>
</NavItem>
{/if}
2023-03-11 01:36:30 +01:00
<NavItem>
<NavLink
on:click={() => toggleTheme()}
2023-03-11 16:52:48 +01:00
title={theme === "dark" ? "Switch to light mode" : "Switch to dark mode"}
2023-03-11 01:36:30 +01:00
>
2023-03-11 16:52:48 +01:00
<Icon name={theme === "dark" ? "sun" : "moon-stars"} height="24" />
{theme === "dark" ? "Light mode" : "Dark mode"}
2023-03-11 01:36:30 +01:00
</NavLink>
</NavItem>
</Nav>
</Collapse>
</Navbar>