Files
Website/src/components/Navbar.svelte
2025-05-07 14:33:48 +02:00

147 lines
6.1 KiB
Svelte

<!--
- This file is a part of the SteamWar software.
-
- Copyright (C) 2024 SteamWar.de-Serverteam
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<script lang="ts">
import "../styles/button.css";
import { CaretDownOutline, SearchOutline } from "flowbite-svelte-icons";
import { t } from "astro-i18n";
import { l } from "../util/util";
import { onMount } from "svelte";
import { loggedIn } from "@repo/authv2.ts";
interface Props {
logo?: import("svelte").Snippet;
}
let { logo }: Props = $props();
let navbar = $state<HTMLElement>();
let searchOpen = $state(false);
let accountBtn = $state<HTMLAnchorElement>();
$effect(() => {
if ($loggedIn) {
accountBtn!.href = l("/dashboard");
} else {
accountBtn!.href = l("/login");
}
});
onMount(() => {
handleScroll();
});
function handleScroll() {
if (window.scrollY > 0) {
navbar!.classList.add("before:scale-y-100");
} else {
navbar!.classList.remove("before:scale-y-100");
}
}
</script>
<svelte:window onscroll={handleScroll} />
<nav
data-pagefind-ignore
class="z-20 fixed top-0 left-0 right-0 sm:px-4 py-1 transition-colors flex justify-center before:backdrop-blur before:shadow-2xl before:absolute before:top-0 before:left-0 before:bottom-0 before:right-0 before:-z-10 before:scale-y-0 before:transition-transform before:origin-top"
bind:this={navbar}
>
<div class="flex flex-row items-center justify-evenly md:justify-between match">
<a class="flex items-center" href={l("/")}>
{@render logo?.()}
<span class="text-2xl uppercase font-bold text-white hidden md:inline-block">
{t("navbar.title")}
<span class="before:scale-y-100" style="display: none" aria-hidden="true"></span>
</span>
</a>
<div class="flex justify-center flex-wrap">
<div class="btn-dropdown">
<button class="btn btn-gray">
<a href={l("/")}>
<span class="btn__text">{t("navbar.links.home.title")}</span>
</a>
<CaretDownOutline class="ml-2 mt-auto" />
</button>
<div>
<a class="btn btn-gray" href={l("/announcements")}>{t("navbar.links.home.announcements")}</a>
<a class="btn btn-gray" href={l("/downloads")}>{t("navbar.links.home.downloads")}</a>
<a class="btn btn-gray" href={l("/faq")}>{t("navbar.links.home.faq")}</a>
<a class="btn btn-gray" href={l("/code-of-conduct")}>{t("navbar.links.rules.coc")}</a>
</div>
</div>
<div class="btn-dropdown">
<button class="btn btn-gray">
<a rel="prefetch" href={l("/rules")}>
<span class="btn__text">{t("navbar.links.rules.title")}</span>
</a>
<CaretDownOutline class="ml-2 mt-auto" />
</button>
<div>
<a href={l("/rules/wargear")} class="btn btn-gray">{t("navbar.links.rules.wg")}</a>
<a href={l("/rules/miniwargear")} class="btn btn-gray">{t("navbar.links.rules.mwg")}</a>
<a href={l("/rules/warship")} class="btn btn-gray">{t("navbar.links.rules.ws")}</a>
<a href={l("/rules/airship")} class="btn btn-gray">{t("navbar.links.rules.as")}</a>
<a href={l("/rules/quickgear")} class="btn btn-gray">{t("navbar.links.rules.qg")}</a>
<h2 class="px-2 text-gray-300">{t("navbar.links.rules.rotating")}</h2>
<a href={l("/rules/megawargear")} class="btn btn-gray">{t("navbar.links.rules.megawg")}</a>
<a href={l("/rules/microwargear")} class="btn btn-gray">{t("navbar.links.rules.micro")}</a>
<a href={l("/rules/streetfight")} class="btn btn-gray">{t("navbar.links.rules.sf")}</a>
<h2 class="px-2 text-gray-300">{t("navbar.links.rules.ranked")}</h2>
<a href={l("/rangliste/missilewars")} class="btn btn-gray">{t("navbar.links.ranked.mw")}</a>
</div>
</div>
<!-- TODO: Add help center
<div class="btn-dropdown my-1">
<div class="btn btn-gray" tabindex="1">
<a rel="prefetch">
<span class="btn__text">{t("navbar.links.help.title")}</span>
</a>
<CaretDownOutline class="ml-2 mt-auto" />
</div>
<div>
<a class="btn btn-gray" href={l("/help")}>{t("navbar.links.help.center")}</a>
<a class="btn btn-gray">{t("navbar.links.help.docs")}</a>
</div>
</div>
-->
<a class="btn" href={l("/login")} bind:this={accountBtn}>
<span class="btn__text">{t("navbar.links.account")}</span>
</a>
<!--
<button class="btn my-1" onclick={() => searchOpen = true}>
<SearchOutline ariaLabel="Site Search" class="inline-block h-6"/>
</button>
-->
</div>
</div>
</nav>
{#if searchOpen}
{#await import("./SearchComponent.svelte") then c}
<c.default bind:open={searchOpen} />
{/await}
{/if}
<style lang="scss">
.match {
width: min(100vw, 70em);
}
</style>