Files
antrean-operasi/composables/useMenuManagement.ts
2026-01-22 09:11:15 +07:00

135 lines
3.6 KiB
TypeScript

import type { MenuItem } from '~/types/menu'
export const useMenuManagement = () => {
const menuItems = ref<MenuItem[]>([])
const menuOptions = ref<string[]>([])
const references = ref<string[]>([])
const selectedReference = ref('Referensi')
const isLoading = ref(false)
// Load menus from JSON file
const loadMenus = async () => {
isLoading.value = true
try {
const response = await $fetch<{ success: boolean; data: { menus: MenuItem[]; menuOptions: string[]; references: string[] } }>('/api/menus/list')
const data = response.data
menuItems.value = data.menus || []
menuOptions.value = data.menuOptions || []
references.value = data.references || []
} catch (error) {
console.error('Error loading menus:', error)
throw error
} finally {
isLoading.value = false
}
}
// Save single menu item
const saveMenu = async (menuItem: MenuItem) => {
try {
const response = await $fetch<{ success: boolean; data: MenuItem }>('/api/menus/save', {
method: 'POST',
body: { menuItem, reference: selectedReference.value }
})
const data = response.data
// Update local state
const index = menuItems.value.findIndex(item => item.id === menuItem.id)
if (index >= 0) {
menuItems.value[index] = data
} else {
menuItems.value.push(data)
}
return data
} catch (error) {
console.error('Error saving menu:', error)
throw error
}
}
// Delete menu item
const deleteMenu = async (menuId: string) => {
try {
await $fetch('/api/menus/delete', {
method: 'DELETE',
body: { menuId, reference: selectedReference.value }
})
// Remove from local state
const removeFromItems = (items: MenuItem[]): MenuItem[] => {
return items.filter(item => {
if (item.id === menuId) return false
if (item.children) {
item.children = removeFromItems(item.children)
}
return true
})
}
menuItems.value = removeFromItems(menuItems.value)
} catch (error) {
console.error('Error deleting menu:', error)
throw error
}
}
// Update menu order
const updateMenuOrder = async (newOrder: MenuItem[]) => {
try {
await $fetch('/api/menus/reorder', {
method: 'POST',
body: { menus: newOrder, reference: selectedReference.value }
})
menuItems.value = newOrder
} catch (error) {
console.error('Error updating menu order:', error)
throw error
}
}
// Generate Vue page from menu
const generatePage = async (menuItem: MenuItem) => {
try {
const pageData = {
name: menuItem.title.replace(/\s+/g, ''),
path: menuItem.url,
templateType: 'default',
metadata: {
title: menuItem.title,
description: `Page for ${menuItem.title}`,
keywords: [menuItem.title.toLowerCase()]
},
content: {
title: menuItem.title,
icon: menuItem.icon
}
}
await $fetch('/api/pages/generate', {
method: 'POST',
body: pageData
})
return pageData
} catch (error) {
console.error('Error generating page:', error)
throw error
}
}
return {
menuItems: readonly(menuItems),
menuOptions: readonly(menuOptions),
references: readonly(references),
selectedReference,
isLoading: readonly(isLoading),
loadMenus,
saveMenu,
deleteMenu,
updateMenuOrder,
generatePage
}
}