vi-ilo/apps/vdn-static/src/App.vue
2026-02-23 01:29:47 -06:00

106 lines
2.6 KiB
Vue

<script setup lang="ts">
import "./assets/style.scss";
import { computed, ref, type Ref } from "vue";
import LocalePicker from "./components/organisms/LocalePicker.vue";
import { vOnClickOutside } from "@vueuse/components";
import { useRouter } from "vue-router";
import SmartLink from "./components/atoms/SmartLink.vue";
import type { SmartDest } from "./utils/smart-dest";
import { useLocale, type Locale } from "./new-i18n";
const locale = useLocale();
const burgerOpen: Ref<boolean> = ref<boolean>(false);
const toggleBurger = (): void => {
burgerOpen.value = !burgerOpen.value;
};
const closeBurger = (): void => {
burgerOpen.value = false;
};
const router = useRouter();
router.beforeEach(() => {
closeBurger();
});
interface NavbarItem {
to: SmartDest;
label: string;
}
const NAVBAR_ITEM_ORDER = [
"whatIsViossa",
"resources",
"kotoba",
] as const satisfies (keyof Locale["navbar"])[];
const navbarItems = computed(() =>
NAVBAR_ITEM_ORDER.map((id): NavbarItem => {
const label = locale.value.navbar[id]();
const to = ((): SmartDest => {
switch (id) {
case "whatIsViossa": {
return { type: "internal", internal: { route: "/" } };
}
case "resources": {
return {
type: "internal",
internal: { route: "/resources" },
};
}
case "kotoba": {
return { type: "internal", internal: { route: "/kotoba" } };
}
}
})();
return { to, label };
}),
);
</script>
<template>
<div class="min-h-screen flex flex-col" v-on-click-outside="closeBurger">
<!-- Main application wrapper -->
<nav
class="navbar is-fixed-top"
role="navigation"
aria-label="main navigation">
<div class="navbar-brand">
<SmartLink
class="navbar-item has-text-weight-bold"
:to="{ type: 'internal', internal: { route: '/' } }">
<img src="@/assets/ViossaFlagRect.svg" alt="" />
</SmartLink>
<div class="navbar-item is-hidden-desktop">
<button
type="button"
@click="toggleBurger()"
:class="`button is-link is-hoverable is-hidden-desktop ${burgerOpen ? 'is-active' : ''}`"
aria-label="menu"
:aria-expanded="`${burgerOpen ? 'true' : 'false'}`">
<span class="bx bx-burger"></span>
</button>
</div>
</div>
<div :class="`navbar-menu ${burgerOpen ? 'is-active' : ''}`">
<div class="navbar-start">
<SmartLink
v-for="(item, index) in navbarItems"
:key="index"
class="navbar-item"
:to="item.to"
>{{ item.label }}
</SmartLink>
<LocalePicker class="navbar-item" />
</div>
</div>
</nav>
<RouterView />
</div>
</template>