diff --git a/package-lock.json b/package-lock.json index 2069d37..4046481 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "vue": "^3.5.13", "vue-i18n": "^11.1.1", "vue-multiselect": "^3.2.0", + "vue-qrcode-reader": "^5.7.3", "vue-router": "^4.5.0", "ziggy-js": "^2.5.2" }, @@ -1234,6 +1235,18 @@ "vite": "^5.2.0 || ^6" } }, + "node_modules/@types/dom-webcodecs": { + "version": "0.1.18", + "resolved": "https://registry.npmjs.org/@types/dom-webcodecs/-/dom-webcodecs-0.1.18.tgz", + "integrity": "sha512-vAvE8C9DGWR+tkb19xyjk1TSUlJ7RUzzp4a9Anu7mwBT+fpyePWK1UxmH14tMO5zHmrnrRIMg5NutnnDztLxgg==", + "license": "MIT" + }, + "node_modules/@types/emscripten": { + "version": "1.41.5", + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.41.5.tgz", + "integrity": "sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q==", + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", @@ -1522,6 +1535,16 @@ "dev": true, "license": "MIT" }, + "node_modules/barcode-detector": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-2.2.2.tgz", + "integrity": "sha512-JcSekql+EV93evfzF9zBr+Y6aRfkR+QFvgyzbwQ0dbymZXoAI9+WgT7H1E429f+3RKNncHz2CW98VQtaaKpmfQ==", + "license": "MIT", + "dependencies": { + "@types/dom-webcodecs": "^0.1.11", + "zxing-wasm": "1.1.3" + } + }, "node_modules/base64-arraybuffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", @@ -3416,6 +3439,12 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/sdp": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.1.tgz", + "integrity": "sha512-lwsAIzOPlH8/7IIjjz3K0zYBk7aBVVcvjMwt3M4fLxpjMYyy7i3I97SLHebgn4YBjirkzfp3RvRDWSKsh/+WFw==", + "license": "MIT" + }, "node_modules/socket.io-client": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", @@ -3867,6 +3896,19 @@ "npm": ">= 6.14.15" } }, + "node_modules/vue-qrcode-reader": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/vue-qrcode-reader/-/vue-qrcode-reader-5.7.3.tgz", + "integrity": "sha512-iSGko42FsEvdHyizBMBs/X+HMO9Z5ONDxjW+mQdoraOR5emRNedmjC5SEJdYzGz8ZP5ME3lwB4iHy3S7MOt5Qw==", + "license": "MIT", + "dependencies": { + "barcode-detector": "2.2.2", + "webrtc-adapter": "8.2.3" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/vue-router": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", @@ -3888,6 +3930,19 @@ "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", "license": "MIT" }, + "node_modules/webrtc-adapter": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-8.2.3.tgz", + "integrity": "sha512-gnmRz++suzmvxtp3ehQts6s2JtAGPuDPjA1F3a9ckNpG1kYdYuHWYpazoAnL9FS5/B21tKlhkorbdCXat0+4xQ==", + "license": "BSD-3-Clause", + "dependencies": { + "sdp": "^3.2.0" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=3.10.0" + } + }, "node_modules/ws": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", @@ -3937,6 +3992,15 @@ "@types/qs": "^6.9.17", "qs": "~6.9.7" } + }, + "node_modules/zxing-wasm": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/zxing-wasm/-/zxing-wasm-1.1.3.tgz", + "integrity": "sha512-MYm9k/5YVs4ZOTIFwlRjfFKD0crhefgbnt1+6TEpmKUDFp3E2uwqGSKwQOd2hOIsta/7Usq4hnpNRYTLoljnfA==", + "license": "MIT", + "dependencies": { + "@types/emscripten": "^1.39.10" + } } } } diff --git a/package.json b/package.json index ff9ae63..d27f6a2 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "vue": "^3.5.13", "vue-i18n": "^11.1.1", "vue-multiselect": "^3.2.0", + "vue-qrcode-reader": "^5.7.3", "vue-router": "^4.5.0", "ziggy-js": "^2.5.2" }, diff --git a/src/components/POS/QRscan.vue b/src/components/POS/QRscan.vue new file mode 100644 index 0000000..3279ae8 --- /dev/null +++ b/src/components/POS/QRscan.vue @@ -0,0 +1,130 @@ + + + + + \ No newline at end of file diff --git a/src/lang/es.js b/src/lang/es.js index 360ad08..2011425 100644 --- a/src/lang/es.js +++ b/src/lang/es.js @@ -451,6 +451,7 @@ export default { }, pos: { title: 'Punto de Venta', + subtitle: 'Gestión de ventas y caja', category: 'Categorías', inventory: 'Inventario', prices: 'Precios', diff --git a/src/pages/POS/Point.vue b/src/pages/POS/Point.vue index 920456c..e4d6950 100644 --- a/src/pages/POS/Point.vue +++ b/src/pages/POS/Point.vue @@ -11,6 +11,7 @@ import GoogleIcon from '@Shared/GoogleIcon.vue'; import ProductCard from '@Components/POS/ProductCard.vue'; import CartItem from '@Components/POS/CartItem.vue'; import CheckoutModal from '@Components/POS/CheckoutModal.vue'; +import QRscan from '@Components/POS/QRscan.vue'; /** i18n */ const { t } = useI18n(); @@ -23,6 +24,7 @@ const products = ref([]); const showCheckoutModal = ref(false); const searchQuery = ref(''); const processingPayment = ref(false); +const scanMode = ref(false); /** Buscador de productos */ const searcher = useSearcher({ @@ -79,6 +81,15 @@ const closeCheckout = () => { showCheckoutModal.value = false; }; +const toggleScanMode = () => { + scanMode.value = !scanMode.value; + if(scanMode.value) { + window.Notify.info('Modo escaneo activado'); + } else { + window.Notify.info('Modo escaneo desactivado'); + } +}; + const handleConfirmSale = async (paymentData) => { processingPayment.value = true; @@ -187,6 +198,19 @@ onMounted(() => {

+ @@ -194,6 +218,28 @@ onMounted(() => {
+
+
+
+

+ + Escáner de Códigos de Barras +

+
+ +
+
+

+ Instrucciones: Coloca el código de barras frente a la cámara. + El producto se agregará automáticamente al carrito cuando se detecte. +

+
+
+
+