feat: Templates persistentes en servidor + Constructor con tabs por tipo de comando

- Templates ahora se guardan en servidor (data/templates.json) disponibles para todos
- API CRUD para templates: GET/POST /api/templates, GET/PUT/DELETE /api/templates/[id]
- Constructor de comandos rediseñado con tabs: Texto, Feed, Cortar, Pulse, QR, Barcode
- Cada tipo de comando tiene su formulario específico con campos relevantes
- Eliminado QuickActions (integrado en tabs del constructor)
- Mejorada UI de lista de impresoras con renderizado condicional
- Agregado data/ a .gitignore (datos de runtime)
This commit is contained in:
2025-11-25 01:18:36 -06:00
parent 09f5b81067
commit 155995c773
15 changed files with 825 additions and 293 deletions

View File

@@ -0,0 +1,23 @@
import { deleteTemplate } from '../../utils/templates'
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id')
if (!id) {
throw createError({
statusCode: 400,
message: 'ID requerido'
})
}
const success = await deleteTemplate(id)
if (!success) {
throw createError({
statusCode: 404,
message: 'Template no encontrado'
})
}
return { success: true }
})

View File

@@ -0,0 +1,23 @@
import { getTemplateById } from '../../utils/templates'
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id')
if (!id) {
throw createError({
statusCode: 400,
message: 'ID requerido'
})
}
const template = await getTemplateById(id)
if (!template) {
throw createError({
statusCode: 404,
message: 'Template no encontrado'
})
}
return template
})

View File

@@ -0,0 +1,28 @@
import { updateTemplate } from '../../utils/templates'
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id')
const body = await readBody(event)
if (!id) {
throw createError({
statusCode: 400,
message: 'ID requerido'
})
}
const template = await updateTemplate(id, {
name: body.name,
description: body.description,
operations: body.operations
})
if (!template) {
throw createError({
statusCode: 404,
message: 'Template no encontrado'
})
}
return template
})

View File

@@ -0,0 +1,23 @@
import { duplicateTemplate } from '../../../utils/templates'
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id')
if (!id) {
throw createError({
statusCode: 400,
message: 'ID requerido'
})
}
const template = await duplicateTemplate(id)
if (!template) {
throw createError({
statusCode: 404,
message: 'Template no encontrado'
})
}
return template
})

View File

@@ -0,0 +1,6 @@
import { getAllTemplates } from '../../utils/templates'
export default defineEventHandler(async () => {
const templates = await getAllTemplates()
return templates
})

View File

@@ -0,0 +1,27 @@
import { createTemplate } from '../../utils/templates'
export default defineEventHandler(async (event) => {
const body = await readBody(event)
if (!body.name) {
throw createError({
statusCode: 400,
message: 'El nombre es requerido'
})
}
if (!body.operations || !Array.isArray(body.operations)) {
throw createError({
statusCode: 400,
message: 'Las operaciones son requeridas'
})
}
const template = await createTemplate({
name: body.name,
description: body.description,
operations: body.operations
})
return template
})