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:
@@ -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 */
|
||||
|
||||
@@ -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"
|
||||
|
||||
20
app/composables/useMediaQuery.ts
Normal file
20
app/composables/useMediaQuery.ts
Normal 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
|
||||
}
|
||||
@@ -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
24
package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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--
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user