mirror of
https://github.com/BeamMP/BeamMP-Website.git
synced 2026-04-07 16:26:22 +00:00
Fix language selection to persist between pages and allow for sharing of specfic pages in chosen lang
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { RouterLink } from 'vue-router'
|
||||
import { RouterLink, useRoute } from 'vue-router'
|
||||
import {
|
||||
NavigationMenu,
|
||||
NavigationMenuItem,
|
||||
@@ -12,8 +12,10 @@ import { cn } from '@/lib/utils'
|
||||
import ThemeToggle from '@/components/ThemeToggle.vue'
|
||||
import LanguageSelector from '@/components/LanguageSelector.vue'
|
||||
import { Menu, X } from 'lucide-vue-next'
|
||||
import { getLocalizedPath } from '@/utils/locale'
|
||||
|
||||
const mobileMenuOpen = ref(false)
|
||||
const route = useRoute()
|
||||
|
||||
function toggleMobileMenu() {
|
||||
mobileMenuOpen.value = !mobileMenuOpen.value
|
||||
@@ -22,12 +24,21 @@ function toggleMobileMenu() {
|
||||
function closeMobileMenu() {
|
||||
mobileMenuOpen.value = false
|
||||
}
|
||||
|
||||
// Generate localized route
|
||||
function localRoute(path) {
|
||||
return getLocalizedPath(path, route.params.locale)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header class="border-b border-neutral-200 dark:border-neutral-800 bg-white/80 dark:bg-neutral-900/70 backdrop-blur sticky top-0 z-20">
|
||||
<nav class="max-w-6xl mx-auto px-4 h-16 flex items-center justify-between">
|
||||
<RouterLink to="/" class="flex items-center gap-2 shrink-0" @click="closeMobileMenu">
|
||||
<RouterLink
|
||||
:to="localRoute('')"
|
||||
class="flex items-center gap-2 shrink-0"
|
||||
@click="closeMobileMenu"
|
||||
>
|
||||
<!-- Light mode logo (black) -->
|
||||
<img
|
||||
src="/src/assets/BeamMP_blk.png"
|
||||
@@ -74,7 +85,7 @@ function closeMobileMenu() {
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuLink as-child>
|
||||
<RouterLink
|
||||
to="/communities"
|
||||
:to="localRoute('communities')"
|
||||
:class="cn(navigationMenuTriggerStyle(), 'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white')"
|
||||
>
|
||||
{{ $t('message.nav.communities') }}
|
||||
@@ -84,7 +95,7 @@ function closeMobileMenu() {
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuLink as-child>
|
||||
<RouterLink
|
||||
to="/servers"
|
||||
:to="localRoute('servers')"
|
||||
:class="cn(navigationMenuTriggerStyle(), 'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white')"
|
||||
>
|
||||
{{ $t('message.nav.servers') }}
|
||||
@@ -94,7 +105,7 @@ function closeMobileMenu() {
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuLink as-child>
|
||||
<RouterLink
|
||||
to="/stats"
|
||||
:to="localRoute('stats')"
|
||||
:class="cn(navigationMenuTriggerStyle(), 'bg-transparent text-neutral-900 hover:bg-neutral-100 hover:text-neutral-900 dark:bg-transparent dark:text-white dark:hover:bg-neutral-800 dark:hover:text-white')"
|
||||
>
|
||||
{{ $t('message.nav.statistics') }}
|
||||
@@ -138,9 +149,9 @@ function closeMobileMenu() {
|
||||
<LanguageSelector />
|
||||
<ThemeToggle />
|
||||
<button
|
||||
@click="toggleMobileMenu"
|
||||
class="p-2 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
|
||||
aria-label="Toggle menu"
|
||||
@click="toggleMobileMenu"
|
||||
>
|
||||
<Menu v-if="!mobileMenuOpen" class="w-6 h-6" />
|
||||
<X v-else class="w-6 h-6" />
|
||||
@@ -181,21 +192,21 @@ function closeMobileMenu() {
|
||||
{{ $t('message.nav.docs') }}
|
||||
</a>
|
||||
<RouterLink
|
||||
to="/communities"
|
||||
:to="localRoute('communities')"
|
||||
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
|
||||
@click="closeMobileMenu"
|
||||
>
|
||||
{{ $t('message.nav.communities') }}
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/servers"
|
||||
:to="localRoute('servers')"
|
||||
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
|
||||
@click="closeMobileMenu"
|
||||
>
|
||||
{{ $t('message.nav.servers') }}
|
||||
</RouterLink>
|
||||
<RouterLink
|
||||
to="/stats"
|
||||
:to="localRoute('stats')"
|
||||
class="block px-4 py-3 text-neutral-900 dark:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-md transition-colors"
|
||||
@click="closeMobileMenu"
|
||||
>
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { LANGUAGES, loadLocaleMessages } from '@/i18n'
|
||||
import { switchLocale, getCurrentLocale } from '@/utils/locale'
|
||||
import { ChevronDown } from 'lucide-vue-next'
|
||||
|
||||
const { locale } = useI18n()
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const isOpen = ref(false)
|
||||
|
||||
const currentLanguage = () => {
|
||||
@@ -22,6 +26,11 @@ const selectLanguage = async (langCode) => {
|
||||
locale.value = langCode
|
||||
localStorage.setItem('lang', langCode)
|
||||
isOpen.value = false
|
||||
|
||||
// Navigate to the new locale route
|
||||
const currentPath = route.fullPath
|
||||
const newPath = switchLocale(langCode, currentPath)
|
||||
router.push(newPath)
|
||||
}
|
||||
|
||||
const toggleDropdown = () => {
|
||||
@@ -29,7 +38,7 @@ const toggleDropdown = () => {
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
const saved = localStorage.getItem('lang')
|
||||
const saved = localStorage.getItem('lang') || getCurrentLocale()
|
||||
if (saved && saved !== locale.value) {
|
||||
try {
|
||||
await loadLocaleMessages(window.i18n, saved)
|
||||
@@ -45,7 +54,7 @@ onMounted(async () => {
|
||||
<div class="relative">
|
||||
<button
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-lg bg-neutral-200 dark:bg-neutral-800/50 hover:bg-neutral-300 dark:hover:bg-neutral-800 transition-colors text-neutral-900 dark:text-white text-sm font-medium"
|
||||
style="height: 40px;"
|
||||
style="height: 40px"
|
||||
:aria-expanded="isOpen"
|
||||
:aria-label="$t('message.nav.language')"
|
||||
@click="toggleDropdown"
|
||||
|
||||
Reference in New Issue
Block a user