fix meilisearch

This commit is contained in:
2026-03-26 22:00:42 +01:00
parent 29260080c2
commit ec05101037
21 changed files with 545 additions and 294 deletions

View File

@@ -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>

View File

@@ -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)

View File

@@ -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

View File

@@ -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
}

View File

@@ -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>
}

View 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>