first commit antrean operasi
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const { menuId, reference } = await readBody<{
|
||||
menuId: string
|
||||
reference: string
|
||||
}>(event)
|
||||
|
||||
if (!menuId || !reference) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'MenuId and reference are required'
|
||||
})
|
||||
}
|
||||
|
||||
const filePath = path.join(process.cwd(), 'matdash', 'data', 'menus.json')
|
||||
const fileContent = await fs.readFile(filePath, 'utf-8')
|
||||
const data = JSON.parse(fileContent)
|
||||
|
||||
// Remove menu item and its children recursively
|
||||
const removeMenuItem = (items: any[], id: string): any[] => {
|
||||
return items.filter(item => {
|
||||
if (item.id === id) return false
|
||||
if (item.children) {
|
||||
item.children = removeMenuItem(item.children, id)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
data.menus = removeMenuItem(data.menus, menuId)
|
||||
|
||||
// Save updated data
|
||||
await fs.writeFile(filePath, JSON.stringify(data, null, 2))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Menu deleted successfully'
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting menu:', error)
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Failed to delete menu'
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,34 @@
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const filePath = path.join(process.cwd(), 'matdash', 'data', 'menus.json')
|
||||
|
||||
// Check if file exists, create if not
|
||||
try {
|
||||
await fs.access(filePath)
|
||||
} catch {
|
||||
const defaultData = {
|
||||
menus: [],
|
||||
references: ["Referensi", "Main", "Admin"],
|
||||
menuOptions: ["Select a menu", "Main Menu", "Side Menu", "Footer Menu"]
|
||||
}
|
||||
await fs.writeFile(filePath, JSON.stringify(defaultData, null, 2))
|
||||
}
|
||||
|
||||
const fileContent = await fs.readFile(filePath, 'utf-8')
|
||||
const data = JSON.parse(fileContent)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error reading menus:', error)
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Failed to load menus'
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,57 @@
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import type { MenuItem } from '../../../types/menu'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const { menuItem, reference } = await readBody<{
|
||||
menuItem: MenuItem
|
||||
reference: string
|
||||
}>(event)
|
||||
|
||||
if (!menuItem || !reference) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'MenuItem and reference are required'
|
||||
})
|
||||
}
|
||||
|
||||
const filePath = path.join(process.cwd(), 'matdash', 'data', 'menus.json')
|
||||
|
||||
// Read current data
|
||||
let data
|
||||
try {
|
||||
const fileContent = await fs.readFile(filePath, 'utf-8')
|
||||
data = JSON.parse(fileContent)
|
||||
} catch {
|
||||
data = { menus: [], references: [], menuOptions: [] }
|
||||
}
|
||||
|
||||
// Update or add menu item
|
||||
const existingIndex = data.menus.findIndex((item: MenuItem) => item.id === menuItem.id)
|
||||
|
||||
if (existingIndex >= 0) {
|
||||
data.menus[existingIndex] = { ...menuItem, updatedAt: new Date().toISOString() }
|
||||
} else {
|
||||
data.menus.push({
|
||||
...menuItem,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString()
|
||||
})
|
||||
}
|
||||
|
||||
// Save to file
|
||||
await fs.writeFile(filePath, JSON.stringify(data, null, 2))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: menuItem
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error saving menu:', error)
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Failed to save menu'
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,111 @@
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const pageData = await readBody(event)
|
||||
|
||||
if (!pageData.name || !pageData.path) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Page name and path are required'
|
||||
})
|
||||
}
|
||||
|
||||
// Generate Vue file content
|
||||
const vueTemplate = `<template>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-card elevation="2">
|
||||
<v-card-title class="d-flex align-center">
|
||||
<v-icon left v-if="pageData.content?.icon">{{ pageData.content.icon }}</v-icon>
|
||||
<span>{{ pageData.metadata?.title || 'Page Title' }}</span>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text>
|
||||
<p>{{ pageData.metadata?.description || 'Page description goes here.' }}</p>
|
||||
|
||||
<!-- Add your custom content here -->
|
||||
<v-alert type="info" variant="tonal">
|
||||
This page was automatically generated from the menu system.
|
||||
</v-alert>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
title: '${pageData.metadata?.title || 'Generated Page'}',
|
||||
description: '${pageData.metadata?.description || ''}',
|
||||
layout: 'default'
|
||||
})
|
||||
|
||||
// Page data
|
||||
const pageData = ${JSON.stringify(pageData, null, 2)}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Add your custom styles here */
|
||||
</style>
|
||||
`
|
||||
|
||||
// Determine file path
|
||||
const fileName = `${pageData.name.toLowerCase().replace(/\s+/g, '-')}.vue`
|
||||
const pagesDir = path.join(process.cwd(), 'matdash', 'pages')
|
||||
const filePath = path.join(pagesDir, fileName)
|
||||
|
||||
// Ensure pages directory exists
|
||||
await fs.mkdir(pagesDir, { recursive: true })
|
||||
|
||||
// Write Vue file
|
||||
await fs.writeFile(filePath, vueTemplate)
|
||||
|
||||
// Save page data to JSON
|
||||
const dataPath = path.join(process.cwd(), 'matdash', 'data', 'pages.json')
|
||||
let pagesData
|
||||
|
||||
try {
|
||||
const fileContent = await fs.readFile(dataPath, 'utf-8')
|
||||
pagesData = JSON.parse(fileContent)
|
||||
} catch {
|
||||
pagesData = { pages: [] }
|
||||
}
|
||||
|
||||
// Add or update page data
|
||||
const existingIndex = pagesData.pages.findIndex((page: any) => page.path === pageData.path)
|
||||
const pageRecord = {
|
||||
...pageData,
|
||||
id: pageData.id || `page-${Date.now()}`,
|
||||
fileName,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString()
|
||||
}
|
||||
|
||||
if (existingIndex >= 0) {
|
||||
pagesData.pages[existingIndex] = pageRecord
|
||||
} else {
|
||||
pagesData.pages.push(pageRecord)
|
||||
}
|
||||
|
||||
await fs.writeFile(dataPath, JSON.stringify(pagesData, null, 2))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
fileName,
|
||||
filePath: filePath.replace(process.cwd(), ''),
|
||||
pageData: pageRecord
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error generating page:', error)
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Failed to generate page'
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user