timetracker update
This commit is contained in:
36
bo/src/components/TopBar.vue
Normal file
36
bo/src/components/TopBar.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import LangSwitch from './inner/langSwitch.vue'
|
||||
import ThemeSwitch from './inner/themeSwitch.vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header
|
||||
class="fixed top-0 left-0 right-0 z-50 bg-white/80 dark:bg-(--black) backdrop-blur-md border-b border-(--border-light) dark:border-(--border-dark)">
|
||||
<div class="container px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex items-center justify-between h-14">
|
||||
<!-- Logo -->
|
||||
<RouterLink :to="{ name: 'home' }" class="flex items-center gap-2">
|
||||
<div class="w-8 h-8 rounded-lg bg-primary text-white flex items-center justify-center">
|
||||
<UIcon name="i-heroicons-clock" class="w-5 h-5" />
|
||||
</div>
|
||||
<span class="font-semibold text-gray-900 dark:text-white">TimeTracker</span>
|
||||
</RouterLink>
|
||||
<!-- Right Side Actions -->
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- Language Switcher -->
|
||||
<LangSwitch />
|
||||
<!-- Theme Switcher -->
|
||||
<ThemeSwitch />
|
||||
<!-- Logout Button (only when authenticated) -->
|
||||
<button v-if="authStore.isAuthenticated" @click="authStore.logout()"
|
||||
class="px-3 py-1.5 text-sm font-medium text-black dark:text-white hover:text-black dark:hover:text-white hover:bg-gray-100 dark:hover:bg-gray-600 rounded-lg transition-colors border border-(--border-light) dark:border-(--border-dark)">
|
||||
Logout
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
@@ -1,5 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
import HomeView from '@/views/HomeView.vue';
|
||||
import LangSwitch from './inner/langSwitch.vue'
|
||||
import ThemeSwitch from './inner/themeSwitch.vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
@@ -20,17 +19,11 @@ const authStore = useAuthStore()
|
||||
<span class="font-semibold text-gray-900 dark:text-white">TimeTracker</span>
|
||||
</RouterLink>
|
||||
<!-- Right Side Actions -->
|
||||
<HomeView />
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- Language Switcher -->
|
||||
<LangSwitch />
|
||||
<!-- Theme Switcher -->
|
||||
<ThemeSwitch />
|
||||
<!-- Logout Button (only when authenticated) -->
|
||||
<button v-if="authStore.isAuthenticated" @click="authStore.logout()"
|
||||
class="px-3 py-1.5 text-sm font-medium text-gray-700 dark:text-gray-200 hover:text-primary dark:hover:text-primary hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors">
|
||||
Logout
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<template>
|
||||
<button :type="type" :disabled="disabled"
|
||||
:class="['px-[25px] h-[43px] leading-none rounded-md text-[15px] sm:text-[16px] dark:text-white text-black',
|
||||
fillType === 'border' ? 'border border-(--border-light) dark:border-(--border-dark)' : false,]">
|
||||
<slot />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
withDefaults(defineProps<{ type?: 'button' | 'submit', fillType?: 'border', disabled?: boolean }>(), {
|
||||
type: 'button',
|
||||
fillType: 'border',
|
||||
disabled: false,
|
||||
})
|
||||
</script>
|
||||
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<USelectMenu v-model="locale" :items="langs"
|
||||
class="w-40 bg-white dark:bg-(--black) rounded-md shadow-sm hover:none!"
|
||||
<USelectMenu v-model="locale" :items="langs" class="w-40 bg-white dark:bg-(--black) rounded-md shadow-sm hover:none!"
|
||||
valueKey="iso_code" :searchInput="false">
|
||||
<template #default="{ modelValue }">
|
||||
<div class="flex items-center gap-1">
|
||||
@@ -22,7 +21,7 @@ import { langs, currentLang } from '@/router/langs'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { useCookie } from '@/composable/useCookie'
|
||||
import { computed, watch } from 'vue'
|
||||
import { i18n } from '@/plugins/i18n'
|
||||
import { i18n } from '@/plugins/02_i18n'
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
@@ -36,28 +35,23 @@ const locale = computed({
|
||||
i18n.locale.value = value
|
||||
currentLang.value = langs.find((x) => x.iso_code == value)
|
||||
|
||||
// Update URL to reflect language change
|
||||
const currentPath = route.path
|
||||
const pathParts = currentPath.split('/').filter(Boolean)
|
||||
|
||||
cookie.setCookie('lang_id', `${langs.find((x) => x.iso_code == value)?.id}`, { days: 60, secure: true, sameSite: 'Lax' })
|
||||
|
||||
if (pathParts.length > 0) {
|
||||
// Check if first part is a locale
|
||||
const isLocale = langs.some((l) => l.lang_code === pathParts[0])
|
||||
if (isLocale) {
|
||||
// Replace existing locale
|
||||
pathParts[0] = value
|
||||
router.replace({ path: '/' + pathParts.join('/'), query: route.query })
|
||||
} else {
|
||||
// Add locale to path
|
||||
router.replace({ path: '/' + value + currentPath, query: route.query })
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
// Sync i18n locale with router locale on initial load
|
||||
watch(
|
||||
() => route.params.locale,
|
||||
(newLocale) => {
|
||||
|
||||
Reference in New Issue
Block a user