feat: Sistema de gestión de impresoras persistente

- Crear modelo Printer con campos: id, name, host, deviceId, timeout, isDefault
- Almacenamiento persistente en data/printers.json
- APIs CRUD: GET/POST /api/printers, GET/PUT/DELETE /api/printers/:id
- API para seleccionar impresora activa: POST /api/printers/select
- Endpoint de impresión ahora usa la impresora seleccionada o la especificada por printerId
- Composable usePrinters() para el cliente
- UI: Selector de impresora en sidebar, tab Impresoras en mobile
- Componentes: PrintersList, PrintersCard, PrintersForm, PrintersSelector
This commit is contained in:
2025-11-25 00:44:50 -06:00
parent 955584275b
commit e97b2b4d8e
15 changed files with 1006 additions and 6 deletions

View File

@@ -0,0 +1,34 @@
// DELETE /api/printers/:id - Eliminar una impresora
import { deletePrinter } from '../../utils/printers'
export default defineEventHandler(async (event) => {
try {
const id = getRouterParam(event, 'id')
if (!id) {
return {
ok: false,
error: 'ID requerido'
}
}
const deleted = await deletePrinter(id)
if (!deleted) {
return {
ok: false,
error: 'Impresora no encontrada'
}
}
return {
ok: true,
message: 'Impresora eliminada'
}
} catch (err: any) {
return {
ok: false,
error: err.message
}
}
})

View File

@@ -0,0 +1,34 @@
// GET /api/printers/:id - Obtener una impresora por ID
import { getPrinterById } from '../../utils/printers'
export default defineEventHandler(async (event) => {
try {
const id = getRouterParam(event, 'id')
if (!id) {
return {
ok: false,
error: 'ID requerido'
}
}
const printer = await getPrinterById(id)
if (!printer) {
return {
ok: false,
error: 'Impresora no encontrada'
}
}
return {
ok: true,
printer
}
} catch (err: any) {
return {
ok: false,
error: err.message
}
}
})

View File

@@ -0,0 +1,50 @@
// PUT /api/printers/:id - Actualizar una impresora
import { updatePrinter } from '../../utils/printers'
export default defineEventHandler(async (event) => {
try {
const id = getRouterParam(event, 'id')
if (!id) {
return {
ok: false,
error: 'ID requerido'
}
}
const body = await readBody(event)
const { name, host, deviceId, timeout, isDefault } = body as {
name?: string
host?: string
deviceId?: string
timeout?: number
isDefault?: boolean
}
const printer = await updatePrinter(id, {
name,
host,
deviceId,
timeout,
isDefault
})
if (!printer) {
return {
ok: false,
error: 'Impresora no encontrada'
}
}
return {
ok: true,
printer
}
} catch (err: any) {
return {
ok: false,
error: err.message
}
}
})

View File

@@ -0,0 +1,20 @@
// GET /api/printers - Listar todas las impresoras
import { getAllPrinters, getSelectedPrinter } from '../../utils/printers'
export default defineEventHandler(async () => {
try {
const printers = await getAllPrinters()
const selected = await getSelectedPrinter()
return {
ok: true,
printers,
selectedPrinterId: selected?.id || null
}
} catch (err: any) {
return {
ok: false,
error: err.message
}
}
})

View File

@@ -0,0 +1,41 @@
// POST /api/printers - Crear nueva impresora
import { createPrinter } from '../../utils/printers'
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event)
const { name, host, deviceId, timeout, isDefault } = body as {
name: string
host: string
deviceId: string
timeout?: number
isDefault?: boolean
}
if (!name || !host || !deviceId) {
return {
ok: false,
error: 'name, host y deviceId son requeridos'
}
}
const printer = await createPrinter({
name,
host,
deviceId,
timeout,
isDefault
})
return {
ok: true,
printer
}
} catch (err: any) {
return {
ok: false,
error: err.message
}
}
})

View File

@@ -0,0 +1,31 @@
// POST /api/printers/select - Seleccionar la impresora activa
import { setSelectedPrinter, getPrinterById } from '../../utils/printers'
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event)
const { printerId } = body as { printerId: string | null }
if (printerId) {
const printer = await getPrinterById(printerId)
if (!printer) {
return {
ok: false,
error: 'Impresora no encontrada'
}
}
}
await setSelectedPrinter(printerId)
return {
ok: true,
selectedPrinterId: printerId
}
} catch (err: any) {
return {
ok: false,
error: err.message
}
}
})