feat: Agregar visualizador de preview para templates

- Nuevo composable usePreview.ts para procesar operaciones en líneas de preview
- Nuevo componente PaperSimulator.vue que simula el papel térmico
- Nuevo modal PreviewModal.vue para vista previa con edición inline de variables
- Botón "Vista previa" agregado a TemplateCard.vue
- Integración del modal en TemplateList.vue
This commit is contained in:
2025-11-26 17:29:10 -06:00
parent 3105e83038
commit 413ec6d27e
5 changed files with 750 additions and 8 deletions

View File

@@ -7,6 +7,7 @@ const props = defineProps<{
const emit = defineEmits<{
load: [id: string]
preview: [id: string]
duplicate: [id: string]
delete: [id: string]
}>()
@@ -70,14 +71,24 @@ function formatDate(date: string | number) {
</div>
<template #footer>
<UButton
icon="i-heroicons-play"
color="primary"
block
@click="$emit('load', template.id)"
>
Cargar en cola
</UButton>
<div class="flex gap-2">
<UButton
icon="i-heroicons-eye"
variant="outline"
class="flex-1"
@click="$emit('preview', template.id)"
>
Vista previa
</UButton>
<UButton
icon="i-heroicons-play"
color="primary"
class="flex-1"
@click="$emit('load', template.id)"
>
Cargar
</UButton>
</div>
</template>
</UCard>
</template>

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import type { PrintTemplate } from '~/composables/useTemplates'
import type { Operation } from '~/composables/usePrintQueue'
import { resolveVariables } from '~/composables/useTemplates'
const templates = useTemplates()
@@ -10,6 +11,10 @@ const toast = useToast()
const variablesDrawerOpen = ref(false)
const selectedTemplate = ref<PrintTemplate | null>(null)
// Estado para el modal de preview
const previewModalOpen = ref(false)
const previewTemplate = ref<PrintTemplate | null>(null)
// Cargar templates al montar
onMounted(() => {
templates.fetchTemplates()
@@ -62,6 +67,40 @@ async function deleteTemplate(id: string) {
toast.add({ title: 'Error al eliminar template', color: 'error' })
}
}
// Abrir preview de un template
function openPreview(id: string) {
const template = templates.templates.value.find(t => t.id === id)
if (template) {
previewTemplate.value = template
previewModalOpen.value = true
}
}
// Imprimir desde el preview
async function handlePrintFromPreview(operations: Operation[], variables: Record<string, string>) {
// Resolver variables en las operaciones
const resolvedOps = resolveVariables(operations, variables)
// Enviar a imprimir directamente
try {
const result = await $fetch('/api/print', {
method: 'POST',
body: { operations: resolvedOps }
})
if (result.ok) {
toast.add({ title: 'Enviado a imprimir', color: 'success' })
} else {
toast.add({ title: result.error || 'Error al imprimir', color: 'error' })
}
} catch (error: any) {
toast.add({ title: error.message || 'Error al imprimir', color: 'error' })
}
previewModalOpen.value = false
previewTemplate.value = null
}
</script>
<template>
@@ -95,6 +134,7 @@ async function deleteTemplate(id: string) {
:key="template.id"
:template="template"
@load="loadTemplate"
@preview="openPreview"
@duplicate="duplicateTemplate"
@delete="deleteTemplate"
/>
@@ -107,5 +147,12 @@ async function deleteTemplate(id: string) {
@update:open="variablesDrawerOpen = $event"
@load="handleLoadWithVariables"
/>
<!-- Modal de vista previa -->
<PreviewModal
v-model="previewModalOpen"
:template="previewTemplate"
@print="handlePrintFromPreview"
/>
</div>
</template>