feat: Add menu bar component and initial English and German i18n translations.

This commit is contained in:
Elmar Kresse
2025-11-23 01:30:53 +01:00
parent df17fa28de
commit 05e5bf77b9
3 changed files with 56 additions and 16 deletions

View File

@@ -25,6 +25,16 @@ import DarkModeSwitcher from "./DarkModeSwitcher.vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { pb, login, logout } from "../service/pocketbase"; import { pb, login, logout } from "../service/pocketbase";
interface MenuItem {
label: string;
icon: string;
route?: string;
url?: string;
info?: string;
items?: MenuItem[];
command?: (event?: unknown) => void;
}
const { t } = useI18n({ useScope: "global" }); const { t } = useI18n({ useScope: "global" });
const toast = useToast(); const toast = useToast();
@@ -44,7 +54,7 @@ onUnmounted(() => {
}); });
const items = computed(() => { const items = computed(() => {
const menuItems = [ const menuItems: MenuItem[] = [
{ {
label: t("createCalendar"), label: t("createCalendar"),
icon: "pi pi-fw pi-plus", icon: "pi pi-fw pi-plus",
@@ -91,10 +101,21 @@ const items = computed(() => {
if (currentUser.value) { if (currentUser.value) {
menuItems.push({ menuItems.push({
label: "Professor Dashboard", label: t("professorDashboard"),
icon: "pi pi-fw pi-user", icon: "pi pi-fw pi-user",
route: "/professor/dashboard", route: "/professor/dashboard",
}); });
menuItems.push({
label: t("logout"),
icon: "pi pi-fw pi-sign-out",
command: () => logout(),
});
} else {
menuItems.push({
label: t("login"),
icon: "pi pi-fw pi-sign-in",
command: () => handleLogin(),
});
} }
return menuItems; return menuItems;
@@ -180,6 +201,18 @@ function handleDarkModeToggled(isDarkVar: boolean) {
<span :class="item.icon" /> <span :class="item.icon" />
<span class="ml-2 p-menuitem-label">{{ item.label }}</span> <span class="ml-2 p-menuitem-label">{{ item.label }}</span>
</a> </a>
<!-- @ts-ignore TypeScript incorrectly infers MenuItemCommandEvent instead of MouseEvent -->
<a
v-else-if="item.command"
class="flex align-items-center p-menuitem-link"
role="menuitem"
tabindex="0"
@click.prevent.stop="(e) => item.command?.(e as any)"
@keydown.enter.prevent.stop="(e) => item.command?.(e as any)"
>
<span :class="item.icon" />
<span class="ml-2 p-menuitem-label">{{ item.label }}</span>
</a>
<span <span
v-else v-else
:class=" :class="
@@ -199,20 +232,6 @@ function handleDarkModeToggled(isDarkVar: boolean) {
@dark-mode-toggled="handleDarkModeToggled" @dark-mode-toggled="handleDarkModeToggled"
></DarkModeSwitcher> ></DarkModeSwitcher>
<LocaleSwitcher></LocaleSwitcher> <LocaleSwitcher></LocaleSwitcher>
<Button
v-if="!currentUser"
label="Login"
icon="pi pi-sign-in"
class="p-button-text"
@click="handleLogin"
/>
<Button
v-else
label="Logout"
icon="pi pi-sign-out"
class="p-button-text"
@click="logout"
/>
</div> </div>
</template> </template>
</Menubar> </Menubar>
@@ -249,4 +268,19 @@ function handleDarkModeToggled(isDarkVar: boolean) {
:deep(.p-menuitem-link.active .p-menuitem-label::after) { :deep(.p-menuitem-link.active .p-menuitem-label::after) {
width: 100%; width: 100%;
} }
/* Ensure command menu items look like other menu items */
:deep(a.p-menuitem-link[role="menuitem"]) {
cursor: pointer;
text-decoration: none;
color: inherit;
}
:deep(a.p-menuitem-link[role="menuitem"]:visited) {
color: inherit;
}
:deep(a.p-menuitem-link[role="menuitem"]:hover) {
background-color: var(--surface-hover);
}
</style> </style>

View File

@@ -9,6 +9,9 @@
"description": "Dein individueller Stundenplan mit Sportevents und Prüfungen. Finde kommende Veranstaltungen oder freie Räume zum Lernen und Arbeiten.", "description": "Dein individueller Stundenplan mit Sportevents und Prüfungen. Finde kommende Veranstaltungen oder freie Räume zum Lernen und Arbeiten.",
"english": "Englisch", "english": "Englisch",
"german": "Deutsch", "german": "Deutsch",
"login": "Anmelden",
"logout": "Abmelden",
"professorDashboard": "Mitarbeitende Kalender",
"toast": { "toast": {
"loginError": "Login fehlgeschlagen", "loginError": "Login fehlgeschlagen",
"loginRestricted": "Login nur für Mitarbeitende der HTWK Leipzig.", "loginRestricted": "Login nur für Mitarbeitende der HTWK Leipzig.",

View File

@@ -9,6 +9,9 @@
"description": "Your individual timetable with sports events and exams. Find upcoming events or free rooms for studying and working.", "description": "Your individual timetable with sports events and exams. Find upcoming events or free rooms for studying and working.",
"english": "English", "english": "English",
"german": "German", "german": "German",
"login": "login",
"logout": "logout",
"professorDashboard": "employee calendar",
"toast": { "toast": {
"loginError": "login failed", "loginError": "login failed",
"loginRestricted": "login restricted to htwk employees", "loginRestricted": "login restricted to htwk employees",