124 lines
3.2 KiB
TypeScript
124 lines
3.2 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
|
|
export interface MenuItem {
|
|
title?: string
|
|
icon?: string
|
|
to?: string
|
|
children?: MenuItem[] | null
|
|
}
|
|
|
|
export interface MenuGroup {
|
|
id: string
|
|
header: string
|
|
children: MenuItem[]
|
|
}
|
|
|
|
export interface UserMenuState {
|
|
menuItems: MenuGroup[]
|
|
isLoading: boolean
|
|
error: string | null
|
|
menuFetched: boolean // Track if menu has been fetched (even if empty)
|
|
noAccess: boolean // Track if user has no access (data: null from API)
|
|
}
|
|
|
|
export const useUserMenuStore = defineStore('userMenu', {
|
|
state: (): UserMenuState => ({
|
|
menuItems: [],
|
|
isLoading: false,
|
|
error: null,
|
|
menuFetched: false,
|
|
noAccess: false
|
|
}),
|
|
|
|
getters: {
|
|
hasMenu: (state) => state.menuItems.length > 0,
|
|
|
|
// Transform to format compatible with existing sidebar
|
|
sidebarMenuItems: (state) => {
|
|
const result = state.menuItems.map((group, index) => ({
|
|
header: group.header,
|
|
id: group.id || (index + 1).toString(),
|
|
children: group.children
|
|
}))
|
|
return result
|
|
}
|
|
},
|
|
|
|
actions: {
|
|
setMenuItems(items: MenuGroup[]) {
|
|
this.menuItems = items
|
|
this.error = null
|
|
this.menuFetched = true
|
|
this.noAccess = false
|
|
},
|
|
|
|
setNoAccess() {
|
|
this.menuItems = []
|
|
this.error = 'No access - User role is inactive or has no permissions'
|
|
this.menuFetched = true
|
|
this.noAccess = true
|
|
},
|
|
|
|
setLoading(loading: boolean) {
|
|
this.isLoading = loading
|
|
},
|
|
|
|
setError(error: string) {
|
|
this.error = error
|
|
this.menuFetched = true
|
|
},
|
|
|
|
clearMenu() {
|
|
this.menuItems = []
|
|
this.error = null
|
|
this.menuFetched = false
|
|
this.noAccess = false
|
|
},
|
|
|
|
async fetchUserMenu(userId: string, token: string) {
|
|
this.setLoading(true)
|
|
|
|
try {
|
|
const { getUserAccess } = await import('~/services/access')
|
|
const response = await getUserAccess(userId, token)
|
|
|
|
if (response && response.success) {
|
|
// Check if data is null (user has no access/role inactive)
|
|
if (response.data === null) {
|
|
console.warn('⚠️ User has no access - role inactive or no permissions')
|
|
this.setNoAccess()
|
|
return
|
|
}
|
|
|
|
// Data exists, process it
|
|
if (response.data && response.data.length > 0) {
|
|
//change all id to 1
|
|
response.data.forEach((group: any) => {
|
|
group.id = '1'
|
|
})
|
|
this.setMenuItems(response.data)
|
|
} else {
|
|
// Empty data array (different from null)
|
|
console.warn('⚠️ No menu items returned from API')
|
|
this.setMenuItems([])
|
|
}
|
|
} else {
|
|
const errorMsg = response?.message || 'Failed to fetch user menu'
|
|
console.error('❌ API returned unsuccessful response:', errorMsg)
|
|
throw new Error(errorMsg)
|
|
}
|
|
} catch (error: any) {
|
|
console.error('❌ Error in fetchUserMenu:', {
|
|
message: error?.message,
|
|
stack: error?.stack?.split('\n')[0]
|
|
})
|
|
this.setError(error.message || 'Failed to fetch menu')
|
|
// Set empty menu on error
|
|
this.menuItems = []
|
|
} finally {
|
|
this.setLoading(false)
|
|
}
|
|
}
|
|
}
|
|
})
|