fix: Corregir configuración de estilos y componentes

- Agregar imports de Tailwind CSS v4 y Nuxt UI en main.css
- Renombrar QueueActions.vue -> Actions.vue y QueueItem.vue -> Item.vue para evitar conflictos de nombres de componentes
- Crear composable useMediaQuery para manejo de responsive
- Corregir referencias a componentes en index.vue y PrintQueue.vue
- Actualizar imports de servidor a rutas relativas
- Instalar @iconify-json/heroicons y @iconify-json/lucide
- Actualizar Jimp a sintaxis v1.x
This commit is contained in:
2025-11-24 18:27:29 -06:00
parent 470ecef4f1
commit 955584275b
13 changed files with 87 additions and 29 deletions

View File

@@ -1,3 +1,6 @@
@import "tailwindcss";
@import "@nuxt/ui";
/* Safe area para PWA en iOS */
.safe-area-bottom {
padding-bottom: env(safe-area-inset-bottom);
@@ -19,11 +22,20 @@
}
::-webkit-scrollbar-thumb {
@apply bg-gray-300 dark:bg-gray-700 rounded-full;
background: rgb(209 213 219); /* gray-300 */
border-radius: 9999px;
}
::-webkit-scrollbar-thumb:hover {
@apply bg-gray-400 dark:bg-gray-600;
background: rgb(156 163 175); /* gray-400 */
}
.dark ::-webkit-scrollbar-thumb {
background: rgb(55 65 81); /* gray-700 */
}
.dark ::-webkit-scrollbar-thumb:hover {
background: rgb(75 85 99); /* gray-600 */
}
/* Reset básico */

View File

@@ -15,7 +15,7 @@ const queue = usePrintQueue()
</div>
<TransitionGroup name="list" tag="div" class="space-y-2">
<QueueQueueItem
<QueueItem
v-for="(op, index) in queue.operations.value"
:key="index"
:operation="op"

View File

@@ -0,0 +1,20 @@
export function useMediaQuery(query: string) {
const matches = ref(false)
if (import.meta.client) {
const mediaQuery = window.matchMedia(query)
matches.value = mediaQuery.matches
const handler = (e: MediaQueryListEvent) => {
matches.value = e.matches
}
mediaQuery.addEventListener('change', handler)
onUnmounted(() => {
mediaQuery.removeEventListener('change', handler)
})
}
return matches
}

View File

@@ -28,7 +28,7 @@ const queue = usePrintQueue()
</div>
<div class="p-4 border-t border-gray-200 dark:border-gray-800">
<QueueQueueActions />
<QueueActions />
</div>
</aside>
@@ -44,7 +44,7 @@ const queue = usePrintQueue()
<template v-else-if="activeTab === 'queue'">
<QueuePrintQueue />
<QueueQueueActions class="mt-4" />
<QueueActions class="mt-4" />
</template>
<template v-else-if="activeTab === 'templates'">

24
package-lock.json generated
View File

@@ -14,6 +14,10 @@
"nuxt": "^4.2.1",
"vue": "^3.5.24",
"vue-router": "^4.6.3"
},
"devDependencies": {
"@iconify-json/heroicons": "^1.2.3",
"@iconify-json/lucide": "^1.2.75"
}
},
"node_modules/@ai-sdk/gateway": {
@@ -2236,6 +2240,26 @@
}
}
},
"node_modules/@iconify-json/heroicons": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@iconify-json/heroicons/-/heroicons-1.2.3.tgz",
"integrity": "sha512-n+vmCEgTesRsOpp5AB5ILB6srsgsYK+bieoQBNlafvoEhjVXLq8nIGN4B0v/s4DUfa0dOrjwE/cKJgIKdJXOEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@iconify/types": "*"
}
},
"node_modules/@iconify-json/lucide": {
"version": "1.2.75",
"resolved": "https://registry.npmjs.org/@iconify-json/lucide/-/lucide-1.2.75.tgz",
"integrity": "sha512-sWBN0t/rTo1FxWG/46xKgkIcDerHpsjyNgMH48nvtC4/kUG88sFQXI+7mxX3SD8eSUaQQ2kS9C7ZKWm2DKgBlw==",
"dev": true,
"license": "ISC",
"dependencies": {
"@iconify/types": "*"
}
},
"node_modules/@iconify/collections": {
"version": "1.0.616",
"resolved": "https://registry.npmjs.org/@iconify/collections/-/collections-1.0.616.tgz",

View File

@@ -17,5 +17,9 @@
"nuxt": "^4.2.1",
"vue": "^3.5.24",
"vue-router": "^4.6.3"
},
"devDependencies": {
"@iconify-json/heroicons": "^1.2.3",
"@iconify-json/lucide": "^1.2.75"
}
}

View File

@@ -1,6 +1,6 @@
// Endpoint para cortar papel
import { buildFromOperations } from '~/server/utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '~/server/utils/printer'
import { buildFromOperations } from '../../utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '../../utils/printer'
export default defineEventHandler(async (event) => {
try {

View File

@@ -1,7 +1,7 @@
// Endpoint para imprimir imágenes usando Jimp
import Jimp from 'jimp'
import { EposMessageBuilder } from '~/server/utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '~/server/utils/printer'
import { Jimp } from 'jimp'
import { EposMessageBuilder } from '../../utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '../../utils/printer'
export default defineEventHandler(async (event) => {
try {
@@ -29,14 +29,15 @@ export default defineEventHandler(async (event) => {
// Leer y procesar imagen
const img = await Jimp.read(path)
let targetWidth = width || img.bitmap.width
if (targetWidth <= 0) targetWidth = img.bitmap.width
let targetWidth = width || img.width
if (targetWidth <= 0) targetWidth = img.width
const scale = targetWidth / img.bitmap.width
const targetHeight = Math.max(1, Math.round(img.bitmap.height * scale))
const scale = targetWidth / img.width
const targetHeight = Math.max(1, Math.round(img.height * scale))
img.resize(targetWidth, targetHeight, Jimp.RESIZE_BILINEAR)
img.grayscale()
// Resize y convertir a escala de grises
img.resize({ w: targetWidth, h: targetHeight })
img.greyscale()
// Empaquetar bits MSB first por byte
const bytesPerRow = Math.ceil(targetWidth / 8)
@@ -49,13 +50,10 @@ export default defineEventHandler(async (event) => {
let rowBytes = 0
for (let x = 0; x < targetWidth; x++) {
const idx = (y * targetWidth + x) * 4
const rgba = img.bitmap.data
const r = rgba[idx]
const g = rgba[idx + 1]
const b = rgba[idx + 2]
const lum = 0.299 * r + 0.587 * g + 0.114 * b
const isBlack = lum < threshold
const color = img.getPixelColor(x, y)
// Extraer componente rojo (ya es greyscale, todos los canales son iguales)
const r = (color >> 24) & 0xFF
const isBlack = r < threshold
if (isBlack) byte |= (1 << bit)
bit--

View File

@@ -1,6 +1,6 @@
// Endpoint genérico de impresión que acepta una lista de operaciones
import { buildFromOperations, type Operation } from '~/server/utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '~/server/utils/printer'
import { buildFromOperations, type Operation } from '../../utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '../../utils/printer'
export default defineEventHandler(async (event) => {
try {

View File

@@ -1,6 +1,6 @@
// Endpoint para abrir cajón de dinero
import { buildFromOperations } from '~/server/utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '~/server/utils/printer'
import { buildFromOperations } from '../../utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '../../utils/printer'
export default defineEventHandler(async (event) => {
try {

View File

@@ -1,6 +1,6 @@
// Endpoint de conveniencia para imprimir texto con opciones
import { buildFromOperations, type Operation } from '~/server/utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '~/server/utils/printer'
import { buildFromOperations, type Operation } from '../../utils/eposBuilder'
import { buildSoapEnvelope, sendToPrinter, parsePrinterResponse } from '../../utils/printer'
export default defineEventHandler(async (event) => {
try {