@plevands/epson-thermal-printer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ import { PdfProcessingConfig, ProcessedPage } from '../types';
2
+ interface PdfPreviewProps {
3
+ file: File | null;
4
+ onPagesLoaded?: (pages: ProcessedPage[]) => void;
5
+ paperWidth?: 576 | 384;
6
+ pdfProcessing?: PdfProcessingConfig;
7
+ }
8
+ export declare function PdfPreview({ file, onPagesLoaded, paperWidth, pdfProcessing, }: PdfPreviewProps): import("react/jsx-runtime").JSX.Element | null;
9
+ export {};
@@ -0,0 +1,6 @@
1
+ interface PdfUploaderProps {
2
+ onFileSelect: (file: File) => void;
3
+ disabled?: boolean;
4
+ }
5
+ export declare function PdfUploader({ onFileSelect, disabled }: PdfUploaderProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,16 @@
1
+ interface PrintControlsProps {
2
+ printerConfig: {
3
+ printerIP: string;
4
+ printerPort: number;
5
+ deviceId: string;
6
+ } | null;
7
+ pages: {
8
+ base64: string;
9
+ width: number;
10
+ height: number;
11
+ rasterBase64: string;
12
+ canvas: HTMLCanvasElement;
13
+ }[];
14
+ }
15
+ export declare function PrintControls({ printerConfig, pages }: PrintControlsProps): import("react/jsx-runtime").JSX.Element;
16
+ export {};
@@ -0,0 +1,10 @@
1
+ interface PrinterConfigProps {
2
+ onConfigChange: (config: {
3
+ printerIP: string;
4
+ printerPort: number;
5
+ deviceId: string;
6
+ paperWidth: number;
7
+ }) => void;
8
+ }
9
+ export declare function PrinterConfig({ onConfigChange }: PrinterConfigProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,2 @@
1
+ const e=require(`./pdf-processor-DwUY-8_K.cjs`);let t=require(`pdfjs-dist`);t=e.g(t);let n=require(`react`),r=require(`react/jsx-runtime`);function i({onFileSelect:e,disabled:t}){let[i,a]=(0,n.useState)(!1),[o,s]=(0,n.useState)(null),c=(0,n.useRef)(null),l=(0,n.useCallback)(e=>{e.preventDefault(),a(!0)},[]),u=(0,n.useCallback)(e=>{e.preventDefault(),a(!1)},[]),d=(0,n.useCallback)(t=>{t.preventDefault(),a(!1);let n=t.dataTransfer.files;if(n.length>0){let t=n[0];t.type===`application/pdf`?(s(t),e(t)):alert(`Por favor selecciona un archivo PDF`)}},[e]),f=(0,n.useCallback)(t=>{let n=t.target.files;if(n&&n.length>0){let t=n[0];s(t),e(t)}},[e]);return(0,r.jsxs)(`div`,{className:`pdf-uploader`,children:[(0,r.jsx)(`h3`,{children:`šŸ“„ Subir Archivo PDF`}),(0,r.jsxs)(`div`,{className:`drop-zone ${i?`dragging`:``} ${t?`disabled`:``}`,onDragOver:l,onDragLeave:u,onDrop:d,onClick:t?void 0:()=>{c.current?.click()},children:[(0,r.jsx)(`input`,{ref:c,type:`file`,accept:`.pdf,application/pdf`,onChange:f,style:{display:`none`},disabled:t}),o?(0,r.jsxs)(`div`,{className:`file-info`,children:[(0,r.jsx)(`span`,{className:`file-icon`,children:`šŸ“„`}),(0,r.jsxs)(`div`,{className:`file-details`,children:[(0,r.jsx)(`span`,{className:`file-name`,children:o.name}),(0,r.jsx)(`span`,{className:`file-size`,children:(e=>e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`)(o.size)})]}),(0,r.jsx)(`button`,{className:`btn-clear`,onClick:e=>{e.stopPropagation(),s(null),c.current&&(c.current.value=``)},children:`āœ•`})]}):(0,r.jsxs)(`div`,{className:`drop-message`,children:[(0,r.jsx)(`span`,{className:`drop-icon`,children:`šŸ“„`}),(0,r.jsx)(`p`,{children:`Arrastra un archivo PDF aquĆ­`}),(0,r.jsx)(`p`,{className:`drop-hint`,children:`o haz clic para seleccionar`})]})]})]})}var a=`4.10.38`;typeof window<`u`&&(t.GlobalWorkerOptions.workerSrc=`https://unpkg.com/pdfjs-dist@${a}/build/pdf.worker.min.mjs`);function o({file:i,onPagesLoaded:a,paperWidth:o=576,pdfProcessing:s=e.t}){let[c,l]=(0,n.useState)([]),[u,d]=(0,n.useState)(!1),[f,p]=(0,n.useState)(null),[m,h]=(0,n.useState)(0);return(0,n.useEffect)(()=>{if(!i){l([]),h(0);return}(async()=>{d(!0),p(null);try{let n=await i.arrayBuffer(),r=await t.getDocument({data:n}).promise,c=[],u={...s,targetWidth:o};for(let t=1;t<=r.numPages;t++){let n=await e.r(await r.getPage(t),u);c.push(n)}l(c),h(0),a&&a(c),d(!1)}catch(t){e.m(`Error loading PDF:`,t),p(t instanceof Error?t.message:`Error al cargar el PDF`),d(!1)}})()},[i,a,o,s]),i?(0,r.jsxs)(`div`,{className:`pdf-preview`,children:[(0,r.jsx)(`h3`,{children:`šŸ‘ļø Vista Previa`}),u&&(0,r.jsxs)(`div`,{className:`preview-loading`,children:[(0,r.jsx)(`div`,{className:`spinner`}),(0,r.jsx)(`p`,{children:`Cargando PDF...`})]}),f&&(0,r.jsx)(`div`,{className:`preview-error`,children:(0,r.jsxs)(`p`,{children:[`āŒ `,f]})}),!u&&!f&&c.length>0&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(`div`,{className:`preview-navigation`,children:[(0,r.jsx)(`button`,{onClick:()=>h(Math.max(0,m-1)),disabled:m===0,children:`ā—€ Anterior`}),(0,r.jsxs)(`span`,{children:[`PĆ”gina `,m+1,` de `,c.length]}),(0,r.jsx)(`button`,{onClick:()=>h(Math.min(c.length-1,m+1)),disabled:m===c.length-1,children:`Siguiente ā–¶`})]}),(0,r.jsxs)(`div`,{className:`preview-container`,children:[(0,r.jsx)(`img`,{src:c[m].base64,alt:`PĆ”gina ${m+1}`,className:`preview-image`}),(0,r.jsxs)(`div`,{className:`preview-info`,children:[c[m].width,` x `,c[m].height,` px`]})]})]})]}):null}var s=`epson-printer-config`;function c(){try{let e=localStorage.getItem(s);if(e){let t=JSON.parse(e);return{printerIP:t.printerIP||`192.168.1.100`,printerPort:t.printerPort||80,deviceId:t.deviceId||`local_printer`,paperWidth:t.paperWidth||576}}}catch{}return{printerIP:`192.168.1.100`,printerPort:80,deviceId:`local_printer`,paperWidth:576}}function l({onConfigChange:e}){let t=c(),[i,a]=(0,n.useState)(t.printerIP),[o,l]=(0,n.useState)(t.printerPort),[u,d]=(0,n.useState)(t.deviceId),[f,p]=(0,n.useState)(t.paperWidth),m=(0,n.useCallback)(t=>{e(t)},[e]);return(0,n.useEffect)(()=>{m(t)},[]),(0,r.jsxs)(`div`,{className:`printer-config`,children:[(0,r.jsx)(`h3`,{children:`āš™ļø Configuración de Impresora`}),(0,r.jsxs)(`div`,{className:`config-form`,children:[(0,r.jsxs)(`div`,{className:`form-group`,children:[(0,r.jsx)(`label`,{htmlFor:`printerIP`,children:`IP de la Impresora:`}),(0,r.jsx)(`input`,{type:`text`,id:`printerIP`,value:i,onChange:e=>a(e.target.value),placeholder:`192.168.1.100`})]}),(0,r.jsxs)(`div`,{className:`form-group`,children:[(0,r.jsx)(`label`,{htmlFor:`printerPort`,children:`Puerto:`}),(0,r.jsx)(`input`,{type:`number`,id:`printerPort`,value:o,onChange:e=>l(parseInt(e.target.value)||80),placeholder:`80`})]}),(0,r.jsxs)(`div`,{className:`form-group`,children:[(0,r.jsx)(`label`,{htmlFor:`deviceId`,children:`Device ID:`}),(0,r.jsx)(`input`,{type:`text`,id:`deviceId`,value:u,onChange:e=>d(e.target.value),placeholder:`local_printer`})]}),(0,r.jsxs)(`div`,{className:`form-group`,children:[(0,r.jsx)(`label`,{htmlFor:`paperWidth`,children:`Ancho de Papel:`}),(0,r.jsxs)(`select`,{id:`paperWidth`,value:f,onChange:e=>p(parseInt(e.target.value)),children:[(0,r.jsx)(`option`,{value:576,children:`80mm (576px)`}),(0,r.jsx)(`option`,{value:384,children:`58mm (384px)`})]})]}),(0,r.jsx)(`button`,{onClick:()=>{let t={printerIP:i,printerPort:o,deviceId:u,paperWidth:f};localStorage.setItem(s,JSON.stringify(t)),e(t)},className:`btn-save`,children:`šŸ’¾ Guardar Configuración`})]}),(0,r.jsx)(`div`,{className:`config-help`,children:(0,r.jsxs)(`p`,{children:[(0,r.jsx)(`strong`,{children:`Nota:`}),` La IP debe ser la dirección de tu impresora Epson con ePOS habilitado. El puerto por defecto es 80. El Device ID suele ser "local_printer" o el nombre configurado en la impresora.`]})})]})}function u({printerConfig:t,pages:i}){let[a,o]=(0,n.useState)(!1),[s,c]=(0,n.useState)(!1),[l,u]=(0,n.useState)(null),[d,f]=(0,n.useState)(!0),[p,m]=(0,n.useState)([]),[h,g]=(0,n.useState)(!1),[_,v]=(0,n.useState)(``),[y,b]=(0,n.useState)(!1),[x,S]=(0,n.useState)(``),[C,w]=(0,n.useState)({loaded:!1,classes:[]}),[T,E]=(0,n.useState)(1),[D,O]=(0,n.useState)(1),[k,A]=(0,n.useState)(`mono`);(0,n.useEffect)(()=>{let t=()=>{let t=e.a();w(t),e.p(`SDK Status:`,t)};t();let n=setTimeout(t,1e3);return()=>clearTimeout(n)},[]);let j=()=>({halftone:T,brightness:D,mode:k,cut:!0,align:`center`}),M=async()=>{if(!t){u({success:!1,message:`Configura la impresora primero`});return}c(!0),u(null);try{u(await new e.i({printerIP:t.printerIP,printerPort:t.printerPort,deviceId:t.deviceId},j()).testConnection())}catch(e){u({success:!1,message:e instanceof Error?e.message:`Error desconocido`})}finally{c(!1)}},N=async()=>{if(!t){u({success:!1,message:`Configura la impresora primero`});return}if(i.length===0){u({success:!1,message:`No hay pĆ”ginas para imprimir`});return}o(!0),u(null);try{let n=new e.i({printerIP:t.printerIP,printerPort:t.printerPort,deviceId:t.deviceId},j()),r=d?i:p.map(e=>i[e]).filter(Boolean);if(r.length===0){u({success:!1,message:`No hay pĆ”ginas seleccionadas`}),o(!1);return}let a=r.map(e=>e.canvas);u(await n.printPages(a,{header:h&&_?_:void 0,footer:y&&x?x:void 0,pageSeparator:!0}))}catch(e){u({success:!1,message:e instanceof Error?e.message:`Error desconocido`})}finally{o(!1)}},P=async()=>{if(!t){u({success:!1,message:`Configura la impresora primero`});return}o(!0),u(null);try{u(await new e.i({printerIP:t.printerIP,printerPort:t.printerPort,deviceId:t.deviceId},j()).printTestPage())}catch(e){u({success:!1,message:e instanceof Error?e.message:`Error desconocido`})}finally{o(!1)}},F=e=>{m(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e].sort((e,t)=>e-t))};return(0,r.jsxs)(`div`,{className:`print-controls`,children:[(0,r.jsx)(`h3`,{children:`šŸ–Øļø Controles de Impresión`}),(0,r.jsx)(`div`,{className:`sdk-status ${C.loaded?`sdk-loaded`:`sdk-error`}`,children:C.loaded?(0,r.jsxs)(r.Fragment,{children:[`āœ… Epson SDK cargado (`,C.classes.join(`, `),`)`]}):(0,r.jsx)(r.Fragment,{children:`āŒ Epson SDK no cargado - Recarga la pĆ”gina`})}),(0,r.jsxs)(`div`,{className:`control-section`,children:[(0,r.jsx)(`h4`,{children:`Conexión`}),(0,r.jsx)(`button`,{onClick:M,disabled:s||!t||!C.loaded,className:`btn-test`,children:s?`ā³ Probando...`:`šŸ”Œ Probar Conexión`}),(0,r.jsx)(`button`,{onClick:P,disabled:a||!t||!C.loaded,className:`btn-test-print`,children:a?`ā³ Imprimiendo...`:`šŸ“ Imprimir PĆ”gina de Prueba`})]}),i.length>0&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(`div`,{className:`control-section`,children:[(0,r.jsx)(`h4`,{children:`Calidad de Impresión (SDK Oficial)`}),(0,r.jsxs)(`label`,{className:`select-label`,children:[`Algoritmo de Halftone:`,(0,r.jsxs)(`select`,{value:T,onChange:e=>E(Number(e.target.value)),className:`select-input`,children:[(0,r.jsx)(`option`,{value:0,children:`Dither (rĆ”pido)`}),(0,r.jsx)(`option`,{value:1,children:`Error Diffusion (mejor calidad)`}),(0,r.jsx)(`option`,{value:2,children:`Threshold (alto contraste)`})]})]}),(0,r.jsxs)(`label`,{className:`select-label`,children:[`Brillo (`,D.toFixed(1),`):`,(0,r.jsx)(`input`,{type:`range`,min:`0.1`,max:`3.0`,step:`0.1`,value:D,onChange:e=>O(parseFloat(e.target.value)),className:`range-input`})]}),(0,r.jsxs)(`label`,{className:`select-label`,children:[`Modo:`,(0,r.jsxs)(`select`,{value:k,onChange:e=>A(e.target.value),className:`select-input`,children:[(0,r.jsx)(`option`,{value:`mono`,children:`MonocromĆ”tico (1-bit)`}),(0,r.jsx)(`option`,{value:`gray16`,children:`Escala de grises (16 niveles)`})]})]})]}),(0,r.jsxs)(`div`,{className:`control-section`,children:[(0,r.jsx)(`h4`,{children:`Opciones de Impresión`}),(0,r.jsxs)(`label`,{className:`checkbox-label`,children:[(0,r.jsx)(`input`,{type:`checkbox`,checked:d,onChange:e=>f(e.target.checked)}),`Imprimir todas las pĆ”ginas (`,i.length,`)`]}),!d&&(0,r.jsxs)(`div`,{className:`page-selection`,children:[(0,r.jsx)(`p`,{children:`Selecciona pĆ”ginas:`}),(0,r.jsx)(`div`,{className:`page-buttons`,children:i.map((e,t)=>(0,r.jsx)(`button`,{className:`page-btn ${p.includes(t)?`selected`:``}`,onClick:()=>F(t),children:t+1},t))})]})]}),(0,r.jsxs)(`div`,{className:`control-section`,children:[(0,r.jsx)(`h4`,{children:`Encabezado y Pie`}),(0,r.jsxs)(`label`,{className:`checkbox-label`,children:[(0,r.jsx)(`input`,{type:`checkbox`,checked:h,onChange:e=>g(e.target.checked)}),`Agregar encabezado`]}),h&&(0,r.jsx)(`input`,{type:`text`,value:_,onChange:e=>v(e.target.value),placeholder:`Texto del encabezado`,className:`text-input`}),(0,r.jsxs)(`label`,{className:`checkbox-label`,children:[(0,r.jsx)(`input`,{type:`checkbox`,checked:y,onChange:e=>b(e.target.checked)}),`Agregar pie de pĆ”gina`]}),y&&(0,r.jsx)(`input`,{type:`text`,value:x,onChange:e=>S(e.target.value),placeholder:`Texto del pie de pĆ”gina`,className:`text-input`})]}),(0,r.jsx)(`div`,{className:`control-section`,children:(0,r.jsx)(`button`,{onClick:N,disabled:a||!t,className:`btn-print`,children:a?`ā³ Imprimiendo...`:`šŸ–Øļø Imprimir PDF`})})]}),l&&(0,r.jsxs)(`div`,{className:`print-result ${l.success?`success`:`error`}`,children:[(0,r.jsxs)(`p`,{children:[l.success?`āœ…`:`āŒ`,` `,l.message]}),l.code&&(0,r.jsxs)(`p`,{className:`result-code`,children:[`Código: `,l.code]})]})]})}exports.PdfPreview=o,exports.PdfUploader=i,exports.PrintControls=u,exports.PrinterConfig=l;
2
+ //# sourceMappingURL=components.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.cjs","names":["loadedPages: ProcessedPage[]","processingConfig: PdfProcessingConfig"],"sources":["../src/components/PdfUploader.tsx","../src/components/PdfPreview.tsx","../src/components/PrinterConfig.tsx","../src/components/PrintControls.tsx"],"sourcesContent":["import { useState, useCallback, useRef } from 'react';\n\ninterface PdfUploaderProps {\n onFileSelect: (file: File) => void;\n disabled?: boolean;\n}\n\nexport function PdfUploader({ onFileSelect, disabled }: PdfUploaderProps) {\n const [isDragging, setIsDragging] = useState(false);\n const [selectedFile, setSelectedFile] = useState<File | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(true);\n }, []);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n }, []);\n\n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n\n const files = e.dataTransfer.files;\n if (files.length > 0) {\n const file = files[0];\n if (file.type === 'application/pdf') {\n setSelectedFile(file);\n onFileSelect(file);\n } else {\n alert('Por favor selecciona un archivo PDF');\n }\n }\n }, [onFileSelect]);\n\n const handleFileChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const files = e.target.files;\n if (files && files.length > 0) {\n const file = files[0];\n setSelectedFile(file);\n onFileSelect(file);\n }\n }, [onFileSelect]);\n\n const handleClick = () => {\n fileInputRef.current?.click();\n };\n\n const formatFileSize = (bytes: number): string => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n };\n\n return (\n <div className=\"pdf-uploader\">\n <h3>šŸ“„ Subir Archivo PDF</h3>\n \n <div\n className={`drop-zone ${isDragging ? 'dragging' : ''} ${disabled ? 'disabled' : ''}`}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={disabled ? undefined : handleClick}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".pdf,application/pdf\"\n onChange={handleFileChange}\n style={{ display: 'none' }}\n disabled={disabled}\n />\n \n {selectedFile ? (\n <div className=\"file-info\">\n <span className=\"file-icon\">šŸ“„</span>\n <div className=\"file-details\">\n <span className=\"file-name\">{selectedFile.name}</span>\n <span className=\"file-size\">{formatFileSize(selectedFile.size)}</span>\n </div>\n <button \n className=\"btn-clear\"\n onClick={(e) => {\n e.stopPropagation();\n setSelectedFile(null);\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n }}\n >\n āœ•\n </button>\n </div>\n ) : (\n <div className=\"drop-message\">\n <span className=\"drop-icon\">šŸ“„</span>\n <p>Arrastra un archivo PDF aquĆ­</p>\n <p className=\"drop-hint\">o haz clic para seleccionar</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useState, useEffect } from 'react';\nimport * as pdfjsLib from 'pdfjs-dist';\nimport { processPdfPage, DEFAULT_PDF_CONFIG } from '../lib/pdf-processor';\nimport { error as logError } from '../lib/logger';\nimport type { PdfProcessingConfig, ProcessedPage } from '../types';\n\n// Configure PDF.js worker from CDN to avoid bundling\nconst PDFJS_VERSION = '4.10.38';\nif (typeof window !== 'undefined') {\n pdfjsLib.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${PDFJS_VERSION}/build/pdf.worker.min.mjs`;\n}\n\ninterface PdfPreviewProps {\n file: File | null;\n onPagesLoaded?: (pages: ProcessedPage[]) => void;\n paperWidth?: 576 | 384; // 576 for 80mm, 384 for 58mm\n pdfProcessing?: PdfProcessingConfig; // Configurable PDF processing\n}\n\nexport function PdfPreview({\n file, \n onPagesLoaded, \n paperWidth = 576,\n pdfProcessing = DEFAULT_PDF_CONFIG,\n}: PdfPreviewProps) {\n const [pages, setPages] = useState<ProcessedPage[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [currentPage, setCurrentPage] = useState(0);\n\n useEffect(() => {\n if (!file) {\n setPages([]);\n setCurrentPage(0);\n return;\n }\n\n const loadPdf = async () => {\n setLoading(true);\n setError(null);\n\n try {\n const arrayBuffer = await file.arrayBuffer();\n const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;\n\n const loadedPages: ProcessedPage[] = [];\n\n // Merge config with paperWidth\n const processingConfig: PdfProcessingConfig = {\n ...pdfProcessing,\n targetWidth: paperWidth,\n };\n\n for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {\n const page = await pdf.getPage(pageNum);\n \n // Use the centralized processor\n const processedPage = await processPdfPage(page, processingConfig);\n loadedPages.push(processedPage);\n }\n\n setPages(loadedPages);\n setCurrentPage(0);\n\n if (onPagesLoaded) {\n onPagesLoaded(loadedPages);\n }\n\n setLoading(false);\n } catch (err) {\n logError('Error loading PDF:', err);\n setError(err instanceof Error ? err.message : 'Error al cargar el PDF');\n setLoading(false);\n }\n };\n\n loadPdf();\n }, [file, onPagesLoaded, paperWidth, pdfProcessing]);\n\n if (!file) {\n return null;\n }\n\n return (\n <div className=\"pdf-preview\">\n <h3>šŸ‘ļø Vista Previa</h3>\n\n {loading && (\n <div className=\"preview-loading\">\n <div className=\"spinner\"></div>\n <p>Cargando PDF...</p>\n </div>\n )}\n\n {error && (\n <div className=\"preview-error\">\n <p>āŒ {error}</p>\n </div>\n )}\n\n {!loading && !error && pages.length > 0 && (\n <>\n <div className=\"preview-navigation\">\n <button\n onClick={() => setCurrentPage(Math.max(0, currentPage - 1))}\n disabled={currentPage === 0}\n >\n ā—€ Anterior\n </button>\n <span>\n PĆ”gina {currentPage + 1} de {pages.length}\n </span>\n <button\n onClick={() => setCurrentPage(Math.min(pages.length - 1, currentPage + 1))}\n disabled={currentPage === pages.length - 1}\n >\n Siguiente ā–¶\n </button>\n </div>\n\n <div className=\"preview-container\">\n <img\n src={pages[currentPage].base64}\n alt={`PĆ”gina ${currentPage + 1}`}\n className=\"preview-image\"\n />\n <div className=\"preview-info\">\n {pages[currentPage].width} x {pages[currentPage].height} px\n </div>\n </div>\n </>\n )}\n </div>\n );\n}\n","import { useState, useEffect, useCallback } from 'react';\n\ninterface PrinterConfigProps {\n onConfigChange: (config: { printerIP: string; printerPort: number; deviceId: string; paperWidth: number }) => void;\n}\n\nconst STORAGE_KEY = 'epson-printer-config';\n\n// Get initial config from localStorage\nfunction getInitialConfig() {\n try {\n const saved = localStorage.getItem(STORAGE_KEY);\n if (saved) {\n const config = JSON.parse(saved);\n return {\n printerIP: config.printerIP || '192.168.1.100',\n printerPort: config.printerPort || 80,\n deviceId: config.deviceId || 'local_printer',\n paperWidth: config.paperWidth || 576,\n };\n }\n } catch {\n // Ignore parse errors\n }\n return {\n printerIP: '192.168.1.100',\n printerPort: 80,\n deviceId: 'local_printer',\n paperWidth: 576,\n };\n}\n\nexport function PrinterConfig({ onConfigChange }: PrinterConfigProps) {\n const initialConfig = getInitialConfig();\n const [printerIP, setPrinterIP] = useState(initialConfig.printerIP);\n const [printerPort, setPrinterPort] = useState(initialConfig.printerPort);\n const [deviceId, setDeviceId] = useState(initialConfig.deviceId);\n const [paperWidth, setPaperWidth] = useState(initialConfig.paperWidth);\n\n const notifyChange = useCallback((config: { printerIP: string; printerPort: number; deviceId: string; paperWidth: number }) => {\n onConfigChange(config);\n }, [onConfigChange]);\n\n // Notify parent of initial config on mount\n useEffect(() => {\n notifyChange(initialConfig);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleSave = () => {\n const config = { printerIP, printerPort, deviceId, paperWidth };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(config));\n onConfigChange(config);\n };\n\n return (\n <div className=\"printer-config\">\n <h3>āš™ļø Configuración de Impresora</h3>\n \n <div className=\"config-form\">\n <div className=\"form-group\">\n <label htmlFor=\"printerIP\">IP de la Impresora:</label>\n <input\n type=\"text\"\n id=\"printerIP\"\n value={printerIP}\n onChange={(e) => setPrinterIP(e.target.value)}\n placeholder=\"192.168.1.100\"\n />\n </div>\n\n <div className=\"form-group\">\n <label htmlFor=\"printerPort\">Puerto:</label>\n <input\n type=\"number\"\n id=\"printerPort\"\n value={printerPort}\n onChange={(e) => setPrinterPort(parseInt(e.target.value) || 80)}\n placeholder=\"80\"\n />\n </div>\n\n <div className=\"form-group\">\n <label htmlFor=\"deviceId\">Device ID:</label>\n <input\n type=\"text\"\n id=\"deviceId\"\n value={deviceId}\n onChange={(e) => setDeviceId(e.target.value)}\n placeholder=\"local_printer\"\n />\n </div>\n\n <div className=\"form-group\">\n <label htmlFor=\"paperWidth\">Ancho de Papel:</label>\n <select\n id=\"paperWidth\"\n value={paperWidth}\n onChange={(e) => setPaperWidth(parseInt(e.target.value))}\n >\n <option value={576}>80mm (576px)</option>\n <option value={384}>58mm (384px)</option>\n </select>\n </div>\n\n <button onClick={handleSave} className=\"btn-save\">\n šŸ’¾ Guardar Configuración\n </button>\n </div>\n\n <div className=\"config-help\">\n <p>\n <strong>Nota:</strong> La IP debe ser la dirección de tu impresora Epson con ePOS habilitado.\n El puerto por defecto es 80. El Device ID suele ser \"local_printer\" o el nombre configurado en la impresora.\n </p>\n </div>\n </div>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { EposPrintService, checkEpsonSDKStatus } from '../lib/epos-print';\nimport { debug } from '../lib/logger';\nimport type { PrintResult, PrintOptions } from '../lib/epos-print';\n\ninterface PrintControlsProps {\n printerConfig: { printerIP: string; printerPort: number; deviceId: string } | null;\n pages: { base64: string; width: number; height: number; rasterBase64: string; canvas: HTMLCanvasElement }[];\n}\n\nexport function PrintControls({ printerConfig, pages }: PrintControlsProps) {\n const [printing, setPrinting] = useState(false);\n const [testingConnection, setTestingConnection] = useState(false);\n const [result, setResult] = useState<PrintResult | null>(null);\n const [printAllPages, setPrintAllPages] = useState(true);\n const [selectedPages, setSelectedPages] = useState<number[]>([]);\n const [addHeader, setAddHeader] = useState(false);\n const [headerText, setHeaderText] = useState('');\n const [addFooter, setAddFooter] = useState(false);\n const [footerText, setFooterText] = useState('');\n const [sdkStatus, setSdkStatus] = useState<{ loaded: boolean; classes: string[] }>({ loaded: false, classes: [] });\n \n // SDK print options\n const [halftone, setHalftone] = useState<0 | 1 | 2>(1); // 1 = ERROR_DIFFUSION (best quality)\n const [brightness, setBrightness] = useState(1.0);\n const [printMode, setPrintMode] = useState<'mono' | 'gray16'>('mono');\n\n // Check SDK status on mount\n useEffect(() => {\n const checkStatus = () => {\n const status = checkEpsonSDKStatus();\n setSdkStatus(status);\n debug('SDK Status:', status);\n };\n \n // Check immediately\n checkStatus();\n \n // Check again after a short delay (in case SDK loads async)\n const timer = setTimeout(checkStatus, 1000);\n return () => clearTimeout(timer);\n }, []);\n\n const getPrintOptions = (): PrintOptions => ({\n halftone,\n brightness,\n mode: printMode,\n cut: true,\n align: 'center',\n });\n\n const handleTestConnection = async () => {\n if (!printerConfig) {\n setResult({ success: false, message: 'Configura la impresora primero' });\n return;\n }\n\n setTestingConnection(true);\n setResult(null);\n\n try {\n const service = new EposPrintService({\n printerIP: printerConfig.printerIP,\n printerPort: printerConfig.printerPort,\n deviceId: printerConfig.deviceId,\n }, getPrintOptions());\n\n const testResult = await service.testConnection();\n setResult(testResult);\n } catch (error) {\n setResult({\n success: false,\n message: error instanceof Error ? error.message : 'Error desconocido',\n });\n } finally {\n setTestingConnection(false);\n }\n };\n\n const handlePrint = async () => {\n if (!printerConfig) {\n setResult({ success: false, message: 'Configura la impresora primero' });\n return;\n }\n\n if (pages.length === 0) {\n setResult({ success: false, message: 'No hay pĆ”ginas para imprimir' });\n return;\n }\n\n setPrinting(true);\n setResult(null);\n\n try {\n const service = new EposPrintService({\n printerIP: printerConfig.printerIP,\n printerPort: printerConfig.printerPort,\n deviceId: printerConfig.deviceId,\n }, getPrintOptions());\n\n const pagesToPrint = printAllPages\n ? pages\n : selectedPages.map((i) => pages[i]).filter(Boolean);\n\n if (pagesToPrint.length === 0) {\n setResult({ success: false, message: 'No hay pĆ”ginas seleccionadas' });\n setPrinting(false);\n return;\n }\n\n // Use the official SDK's printPages method with canvas elements\n const canvases = pagesToPrint.map(p => p.canvas);\n const printResult = await service.printPages(canvases, {\n header: addHeader && headerText ? headerText : undefined,\n footer: addFooter && footerText ? footerText : undefined,\n pageSeparator: true,\n });\n\n setResult(printResult);\n } catch (error) {\n setResult({\n success: false,\n message: error instanceof Error ? error.message : 'Error desconocido',\n });\n } finally {\n setPrinting(false);\n }\n };\n\n const handlePrintTestPage = async () => {\n if (!printerConfig) {\n setResult({ success: false, message: 'Configura la impresora primero' });\n return;\n }\n\n setPrinting(true);\n setResult(null);\n\n try {\n const service = new EposPrintService({\n printerIP: printerConfig.printerIP,\n printerPort: printerConfig.printerPort,\n deviceId: printerConfig.deviceId,\n }, getPrintOptions());\n\n const printResult = await service.printTestPage();\n setResult(printResult);\n } catch (error) {\n setResult({\n success: false,\n message: error instanceof Error ? error.message : 'Error desconocido',\n });\n } finally {\n setPrinting(false);\n }\n };\n\n const togglePageSelection = (pageIndex: number) => {\n setSelectedPages((prev) =>\n prev.includes(pageIndex)\n ? prev.filter((i) => i !== pageIndex)\n : [...prev, pageIndex].sort((a, b) => a - b)\n );\n };\n\n return (\n <div className=\"print-controls\">\n <h3>šŸ–Øļø Controles de Impresión</h3>\n\n {/* SDK Status */}\n <div className={`sdk-status ${sdkStatus.loaded ? 'sdk-loaded' : 'sdk-error'}`}>\n {sdkStatus.loaded ? (\n <>āœ… Epson SDK cargado ({sdkStatus.classes.join(', ')})</>\n ) : (\n <>āŒ Epson SDK no cargado - Recarga la pĆ”gina</>\n )}\n </div>\n\n <div className=\"control-section\">\n <h4>Conexión</h4>\n <button\n onClick={handleTestConnection}\n disabled={testingConnection || !printerConfig || !sdkStatus.loaded}\n className=\"btn-test\"\n >\n {testingConnection ? 'ā³ Probando...' : 'šŸ”Œ Probar Conexión'}\n </button>\n <button\n onClick={handlePrintTestPage}\n disabled={printing || !printerConfig || !sdkStatus.loaded}\n className=\"btn-test-print\"\n >\n {printing ? 'ā³ Imprimiendo...' : 'šŸ“ Imprimir PĆ”gina de Prueba'}\n </button>\n </div>\n\n {pages.length > 0 && (\n <>\n <div className=\"control-section\">\n <h4>Calidad de Impresión (SDK Oficial)</h4>\n \n <label className=\"select-label\">\n Algoritmo de Halftone:\n <select \n value={halftone} \n onChange={(e) => setHalftone(Number(e.target.value) as 0 | 1 | 2)}\n className=\"select-input\"\n >\n <option value={0}>Dither (rĆ”pido)</option>\n <option value={1}>Error Diffusion (mejor calidad)</option>\n <option value={2}>Threshold (alto contraste)</option>\n </select>\n </label>\n\n <label className=\"select-label\">\n Brillo ({brightness.toFixed(1)}):\n <input\n type=\"range\"\n min=\"0.1\"\n max=\"3.0\"\n step=\"0.1\"\n value={brightness}\n onChange={(e) => setBrightness(parseFloat(e.target.value))}\n className=\"range-input\"\n />\n </label>\n\n <label className=\"select-label\">\n Modo:\n <select \n value={printMode} \n onChange={(e) => setPrintMode(e.target.value as 'mono' | 'gray16')}\n className=\"select-input\"\n >\n <option value=\"mono\">MonocromĆ”tico (1-bit)</option>\n <option value=\"gray16\">Escala de grises (16 niveles)</option>\n </select>\n </label>\n </div>\n\n <div className=\"control-section\">\n <h4>Opciones de Impresión</h4>\n\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={printAllPages}\n onChange={(e) => setPrintAllPages(e.target.checked)}\n />\n Imprimir todas las pĆ”ginas ({pages.length})\n </label>\n\n {!printAllPages && (\n <div className=\"page-selection\">\n <p>Selecciona pĆ”ginas:</p>\n <div className=\"page-buttons\">\n {pages.map((_, index) => (\n <button\n key={index}\n className={`page-btn ${selectedPages.includes(index) ? 'selected' : ''}`}\n onClick={() => togglePageSelection(index)}\n >\n {index + 1}\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n\n <div className=\"control-section\">\n <h4>Encabezado y Pie</h4>\n\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={addHeader}\n onChange={(e) => setAddHeader(e.target.checked)}\n />\n Agregar encabezado\n </label>\n {addHeader && (\n <input\n type=\"text\"\n value={headerText}\n onChange={(e) => setHeaderText(e.target.value)}\n placeholder=\"Texto del encabezado\"\n className=\"text-input\"\n />\n )}\n\n <label className=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={addFooter}\n onChange={(e) => setAddFooter(e.target.checked)}\n />\n Agregar pie de pĆ”gina\n </label>\n {addFooter && (\n <input\n type=\"text\"\n value={footerText}\n onChange={(e) => setFooterText(e.target.value)}\n placeholder=\"Texto del pie de pĆ”gina\"\n className=\"text-input\"\n />\n )}\n </div>\n\n <div className=\"control-section\">\n <button\n onClick={handlePrint}\n disabled={printing || !printerConfig}\n className=\"btn-print\"\n >\n {printing ? 'ā³ Imprimiendo...' : 'šŸ–Øļø Imprimir PDF'}\n </button>\n </div>\n </>\n )}\n\n {result && (\n <div className={`print-result ${result.success ? 'success' : 'error'}`}>\n <p>\n {result.success ? 'āœ…' : 'āŒ'} {result.message}\n </p>\n {result.code && <p className=\"result-code\">Código: {result.code}</p>}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @plevands/epson-thermal-printer - UI Components
3
+ * Optional exports for ready-to-use React components
4
+ */
5
+ export { PdfUploader } from './components/PdfUploader';
6
+ export { PdfPreview } from './components/PdfPreview';
7
+ export { PrinterConfig } from './components/PrinterConfig';
8
+ export { PrintControls } from './components/PrintControls';