fix meilisearch
This commit is contained in:
@@ -3,37 +3,35 @@ import { useFetchJson } from '@/composable/useFetchJson'
|
||||
import LangSwitch from './inner/langSwitch.vue'
|
||||
import ThemeSwitch from './inner/themeSwitch.vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import type { ApiResponse } from '@/types'
|
||||
import { computed, ref } from 'vue'
|
||||
import { currentLang } from '@/router/langs'
|
||||
import type { LabelTrans, TopMenuItem } from '@/types'
|
||||
import type { NavigationMenuItem } from '@nuxt/ui'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
let menu = ref()
|
||||
async function getTopMenu() {
|
||||
try {
|
||||
const { items } = await useFetchJson<ApiResponse>('/api/v1/restricted/menu/get-top-menu')
|
||||
const { items } = await useFetchJson<TopMenuItem>('/api/v1/restricted/menu/get-top-menu')
|
||||
menu.value = items
|
||||
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
console.log(err)
|
||||
}
|
||||
}
|
||||
|
||||
const menuItems = computed(() =>
|
||||
transformMenu(menu.value[0].children, currentLang.value?.iso_code)
|
||||
)
|
||||
function transformMenu(items, locale: string | undefined) {
|
||||
const menuItems = computed(() => transformMenu(menu.value[0].children, currentLang.value?.iso_code))
|
||||
function transformMenu(items: TopMenuItem[], locale: string | undefined): NavigationMenuItem[] {
|
||||
return items.map((item) => {
|
||||
const parsedLabel = JSON.parse(item.label)
|
||||
|
||||
return {
|
||||
let route = {
|
||||
icon: 'i-lucide-house',
|
||||
label: parsedLabel.trans[locale] || parsedLabel.name,
|
||||
to: { name: parsedLabel.name },
|
||||
children: item.children
|
||||
? transformMenu(item.children, locale)
|
||||
: undefined,
|
||||
label: item.label.trans[locale as keyof LabelTrans].label,
|
||||
children: item.children ? transformMenu(item.children, locale) : undefined,
|
||||
}
|
||||
if (item.params?.route) {
|
||||
route = { ...route, ...{ to: { name: item.params.route.name, params: { locale: locale } } } }
|
||||
}
|
||||
|
||||
return route
|
||||
})
|
||||
}
|
||||
|
||||
@@ -43,8 +41,7 @@ await getTopMenu()
|
||||
<template>
|
||||
{{ menuItems }}
|
||||
<!-- fixed top-0 left-0 right-0 z-50 -->
|
||||
<header
|
||||
class=" bg-white/80 dark:bg-(--black) backdrop-blur-md border-b border-(--border-light) dark:border-(--border-dark)">
|
||||
<header class="bg-white/80 dark:bg-(--black) backdrop-blur-md border-b border-(--border-light) dark:border-(--border-dark)">
|
||||
<div class="container mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex items-center justify-between h-14">
|
||||
<!-- Logo -->
|
||||
@@ -55,7 +52,7 @@ await getTopMenu()
|
||||
<span class="font-semibold text-gray-900 dark:text-white">TimeTracker</span>
|
||||
</RouterLink>
|
||||
|
||||
<UNavigationMenu :items="menuItems" />
|
||||
<UNavigationMenu :items="menuItems" class="w-full" />
|
||||
|
||||
<!-- {{ router }} -->
|
||||
<!-- <RouterLink :to="{ name: 'admin-products' }">
|
||||
@@ -93,8 +90,11 @@ await getTopMenu()
|
||||
<!-- 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)">
|
||||
<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)"
|
||||
>
|
||||
{{ $t('general.logout') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -10,6 +10,18 @@ function isAuthenticated(): boolean {
|
||||
}
|
||||
await getSettings()
|
||||
|
||||
const routes = await getRoutes()
|
||||
let newRoutes = []
|
||||
for (let r of routes) {
|
||||
const component = () => import(/* @vite-ignore */ `..${r.component}`)
|
||||
newRoutes.push({
|
||||
path: r.path,
|
||||
component,
|
||||
name: r.name,
|
||||
meta: r.meta ? JSON.parse(r.meta) : {},
|
||||
})
|
||||
}
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.VITE_BASE_URL),
|
||||
routes: [
|
||||
@@ -21,8 +33,9 @@ const router = createRouter({
|
||||
path: '/:locale',
|
||||
name: 'locale',
|
||||
children: [
|
||||
...newRoutes,
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
path: ':pathMatch(.*)*',
|
||||
component: () => import('@/views/NotFoundView.vue'),
|
||||
name: 'not-found-child',
|
||||
},
|
||||
@@ -36,25 +49,6 @@ const router = createRouter({
|
||||
],
|
||||
})
|
||||
|
||||
await getRoutes().then(routes => {
|
||||
const modules = import.meta.glob('/src/**/**/*.vue')
|
||||
routes.forEach(item => {
|
||||
const component = modules[`/src${item.Component}`]
|
||||
|
||||
if (!component) {
|
||||
console.error('Component not found:', item.Component)
|
||||
return
|
||||
}
|
||||
|
||||
router.addRoute('locale', {
|
||||
path: item.Path,
|
||||
component,
|
||||
name: item.Name,
|
||||
meta: item.Meta ? JSON.parse(item.Meta) : {}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
router.beforeEach((to, from) => {
|
||||
const locale = to.params.locale as string
|
||||
const localeLang = langs.find((x) => x.iso_code === locale)
|
||||
|
||||
@@ -10,7 +10,7 @@ export const getMenu = async () => {
|
||||
|
||||
|
||||
export const getRoutes = async () => {
|
||||
const resp = await useFetchJson<Route[]>('/api/v1/restricted/menu/get-routes');
|
||||
const resp = await useFetchJson<Route[]>('/api/v1/public/menu/get-routes');
|
||||
|
||||
return resp.items
|
||||
|
||||
|
||||
5
bo/src/types/index.d.ts
vendored
5
bo/src/types/index.d.ts
vendored
@@ -1,8 +1,9 @@
|
||||
export * from '@types/lang'
|
||||
export * from '@types/response'
|
||||
export * from '@types/menu'
|
||||
|
||||
export interface ApiResponse {
|
||||
export interface ApiResponse<T> {
|
||||
message: string
|
||||
items: Product[]
|
||||
items: T
|
||||
count: number
|
||||
}
|
||||
|
||||
51
bo/src/types/menu.d.ts
vendored
51
bo/src/types/menu.d.ts
vendored
@@ -12,15 +12,42 @@ export interface Params {
|
||||
}
|
||||
|
||||
export interface Route {
|
||||
ID: number
|
||||
Name: string
|
||||
Path: string
|
||||
Component: string
|
||||
Layout: string
|
||||
Meta: string
|
||||
IsActive: boolean
|
||||
SortOrder: number
|
||||
ParentID: any
|
||||
Parent: any
|
||||
Children: any
|
||||
}
|
||||
id: number
|
||||
name: string
|
||||
path: string
|
||||
component: string
|
||||
meta: string
|
||||
active: boolean
|
||||
}
|
||||
|
||||
export interface TopMenuItem {
|
||||
menu_id: number
|
||||
label: Label
|
||||
params: TopMenuParams
|
||||
active: number
|
||||
position: number
|
||||
children: TopMenuItem[]
|
||||
}
|
||||
|
||||
export interface Label {
|
||||
label: string
|
||||
trans:LabelTrans
|
||||
}
|
||||
|
||||
export interface LabelTrans{
|
||||
pl:LabelItem
|
||||
en:LabelItem
|
||||
de: LabelItem
|
||||
}
|
||||
export interface LabelItem {
|
||||
label: string
|
||||
}
|
||||
|
||||
export interface TopMenuParams {
|
||||
route: TopMenuRoute
|
||||
}
|
||||
|
||||
export interface TopMenuRoute {
|
||||
name: string
|
||||
params: Record<string, string>
|
||||
}
|
||||
|
||||
9
bo/src/views/HomeView.vue
Normal file
9
bo/src/views/HomeView.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<component :is="Default || 'div'">
|
||||
home View
|
||||
</component>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import Default from '@/layouts/default.vue';
|
||||
|
||||
</script>
|
||||
Reference in New Issue
Block a user