import { defineStore } from 'pinia' import { getMyMenus } from '@/services/menuService' let pendingMenuRequest = null function extractErrorMessage(error) { const fallback = 'Gagal memuat menu.' const data = error?.response?.data if (!data) return error?.message || fallback if (typeof data?.message === 'string') return data.message return fallback } function mapMenuItem(item, isChild = false) { const hasChildren = Array.isArray(item?.children) && item.children.filter(Boolean).length > 0 const name = item?.name || 'Untitled' const to = item?.url || '#' if (hasChildren) { return { component: 'CNavGroup', name, to, ...(isChild ? {} : { icon: item?.icon || 'cil-menu' }), items: item.children.filter(Boolean).map((child) => mapMenuItem(child, true)), } } return { component: 'CNavItem', name, to, ...(isChild ? {} : { icon: item?.icon || 'cil-menu' }), } } export const useMenuStore = defineStore('menu', { state: () => ({ isMaster: false, dynamicMenus: [], loading: false, error: null, initialized: false, }), getters: { mappedMenus(state) { return state.dynamicMenus.map((item) => mapMenuItem(item)) }, }, actions: { async fetchMenus({ force = false } = {}) { if (this.initialized && !force) { return this.dynamicMenus } if (pendingMenuRequest) { return pendingMenuRequest } this.loading = true this.error = null pendingMenuRequest = (async () => { try { const response = await getMyMenus() const payload = response?.data || {} this.isMaster = !!payload?.is_master this.dynamicMenus = Array.isArray(payload?.menus) ? payload.menus : [] this.initialized = true return this.dynamicMenus } catch (error) { this.error = extractErrorMessage(error) this.initialized = false this.dynamicMenus = [] throw error } finally { this.loading = false pendingMenuRequest = null } })() return pendingMenuRequest }, reset() { this.isMaster = false this.dynamicMenus = [] this.loading = false this.error = null this.initialized = false pendingMenuRequest = null }, }, })