diff --git a/resources/js/components/StrukOverlay.vue b/resources/js/components/StrukOverlay.vue index b2560dd..af849b0 100644 --- a/resources/js/components/StrukOverlay.vue +++ b/resources/js/components/StrukOverlay.vue @@ -33,7 +33,7 @@
Alamat :
- +
No.Hp :
diff --git a/resources/js/components/StrukView.vue b/resources/js/components/StrukView.vue index 94218df..aa94e82 100644 --- a/resources/js/components/StrukView.vue +++ b/resources/js/components/StrukView.vue @@ -1,178 +1,128 @@ diff --git a/resources/js/composables/usePrintStruk.js b/resources/js/composables/usePrintStruk.js new file mode 100644 index 0000000..f6ead89 --- /dev/null +++ b/resources/js/composables/usePrintStruk.js @@ -0,0 +1,181 @@ +// resources/js/composables/usePrintStruk.js +import { computed, nextTick } from "vue"; + +export function usePrintStruk( + transaksi, + itemsWithMinimal, + formatDate, + formatNumber +) { + const handlePrint = async () => { + const printWindow = window.open("", "_blank", "width=900,height=600"); + + // Filter item yang valid + const items = itemsWithMinimal.value.filter((i) => i.harga_deal > 0); + const imageUrls = items + .map((i) => i.produk?.foto?.[0]?.url) + .filter(Boolean); + + // 1. Kompresi & encode semua gambar ke base64 (40x40, JPEG 80%) + const compressedImages = await Promise.all( + imageUrls.map((url) => compressImageToBase64(url, 40, 40, 0.8)) + ); + + // Ganti URL dengan base64 (fallback ke placeholder jika gagal) + const imageMap = {}; + imageUrls.forEach((url, i) => { + imageMap[url] = + compressedImages[i] || + "https://via.placeholder.com/40x40?text=No+Img"; + }); + + const item = itemsWithMinimal.value[0] + const imgSrc = imageMap[item.produk?.foto?.[0]?.url] || 'https://via.placeholder.com/100x100?text=No+Img' + +const printContent = ` + + + + + Struk #${transaksi.value.kode_transaksi || 'N/A'} + + + +
+ + +
${escapeHtml(transaksi.value.kode_transaksi || 'N/A')}
+ + +
+
${formatDate(transaksi.value.created_at)}
+
${escapeHtml(transaksi.value.nama_pembeli || '-')}
+
${escapeHtml(transaksi.value.alamat || '-')}
+
${escapeHtml(transaksi.value.no_hp || '-')}
+
+ + +
+
1
+ Produk +
+ ${escapeHtml(item.produk?.nama || '')} +
+ ${escapeHtml(item.posisi_asal || 'Brankas')} + ${item.produk?.berat ? formatNumber(item.produk.berat)+'g' : ''} + ${item.produk?.kadar ? item.produk.kadar+'k' : ''} + Rp${formatNumber(item.harga_deal)} +
+
+
+ + +
+
${escapeHtml(transaksi.value.nama_sales || '-')}
+
+ + +
+
${(transaksi.value.ongkos_bikin||0).toLocaleString()},-
+
${(transaksi.value.total_harga||0).toLocaleString()},-
+
+ +
+ + +`; + + printWindow.document.write(printContent); + printWindow.document.close(); + + printWindow.onload = () => { + setTimeout(() => { + printWindow.focus(); + printWindow.print(); + printWindow.close(); + }, 300); + }; + }; + + return { handlePrint }; +} + +// === Helper: Kompresi Gambar ke Base64 === +async function compressImageToBase64(url, width, height, quality = 0.8) { + return new Promise((resolve) => { + const img = new Image(); + img.crossOrigin = "anonymous"; + + img.onload = () => { + const canvas = document.createElement("canvas"); + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext("2d"); + + ctx.drawImage(img, 0, 0, width, height); + + const base64 = canvas.toDataURL("image/jpeg", quality); + resolve(base64); + }; + + img.onerror = () => resolve(null); + img.src = url + (url.includes("?") ? "&" : "?") + "t=" + Date.now(); + }); +} + +function escapeHtml(text) { + if (!text) return ""; + const div = document.createElement("div"); + div.textContent = text; + return div.innerHTML; +} diff --git a/resources/js/pages/Home.vue b/resources/js/pages/Home.vue index 0100f54..093f679 100644 --- a/resources/js/pages/Home.vue +++ b/resources/js/pages/Home.vue @@ -1,27 +1,61 @@ \ No newline at end of file +// === Dummy Data === +const dummyTransaksi = { + kode_transaksi: 'TRX20250001', + created_at: '2025-10-28T10:30:00', + nama_pembeli: 'Budi Santoso', + alamat: 'Jl. Merdeka', + no_hp: '08123456789', + nama_sales: 'Rina', + ongkos_bikin: 100000, + total_harga: 2600000, + itemTransaksi: [ + { + id: 1, + harga_deal: 2500000, + posisi_asal: 'Etalase Depan', + produk: { + nama: 'Gelang rantai 5 buah clover merah', + berat: 5.2, + kadar: 18, + foto: [ + { url: 'http://localhost:8000/storage/foto/hVmf9TF2AfnsNUELXtW3F7q30QVCb0S9L1zWnicY.jpg'} + ] + } + }, + // { + // id: 2, + // harga_deal: 100000, + // posisi_asal: 'Brankas', + // produk: { + // nama: 'Gelang serut daun shimmer mp (mas putih)', + // berat: 1.0, + // kadar: 24, + // foto: [ + // { url: 'http://localhost:8000/storage/foto/dF0UWskzLYnuOH8ch8DEjz7ZeBWa8wXbyhtYRjRy.jpg'} + // ] + // } + // } + ] +} + +// === Modal State === +const isOpen = ref(false) +