From 8e4ab5dd6914fe8f0c3a4add61ac048efc0bc5ec Mon Sep 17 00:00:00 2001 From: efrilm Date: Tue, 25 Nov 2025 15:29:28 +0700 Subject: [PATCH] update report --- .../dashboards/daily-report/page.tsx | 119 ++++++++++++------ 1 file changed, 81 insertions(+), 38 deletions(-) diff --git a/src/app/[lang]/(dashboard)/(private)/dashboards/daily-report/page.tsx b/src/app/[lang]/(dashboard)/(private)/dashboards/daily-report/page.tsx index 8a9ddcd..6ea4699 100644 --- a/src/app/[lang]/(dashboard)/(private)/dashboards/daily-report/page.tsx +++ b/src/app/[lang]/(dashboard)/(private)/dashboards/daily-report/page.tsx @@ -27,12 +27,12 @@ const DailyPOSReport = () => { // PDF Font Size Configuration const PDF_FONT_SIZES = { - heading: 20, - subheading: 20, - tableContent: 14, - tableHeader: 14, - tableFooter: 14, - grandTotal: 18, + heading: 18, + subheading: 16, + tableContent: 12, + tableHeader: 12, + tableFooter: 12, + grandTotal: 16, footer: 11 } @@ -106,7 +106,6 @@ const DailyPOSReport = () => { const handleGeneratePDF = async () => { const reportElement = reportRef.current - if (!reportElement) { alert('Report element tidak ditemukan') return @@ -153,7 +152,7 @@ const DailyPOSReport = () => { pdf.text('Ringkasan', 14, currentY) currentY += 15 - // Summary table + // Summary table - TETAP PLAIN (TANPA BORDER) autoTable(pdf, { startY: currentY, head: [], @@ -164,7 +163,10 @@ const DailyPOSReport = () => { ['Total', formatCurrency(profitLoss?.summary.total_revenue ?? 0)] ], theme: 'plain', - styles: { fontSize: PDF_FONT_SIZES.tableContent, cellPadding: PDF_SPACING.cellPadding }, + styles: { + fontSize: PDF_FONT_SIZES.subheading, + cellPadding: PDF_SPACING.cellPadding + }, columnStyles: { 0: { fontStyle: 'normal', textColor: [60, 60, 60] }, 1: { halign: 'right', fontStyle: 'bold', textColor: [60, 60, 60] } @@ -174,7 +176,7 @@ const DailyPOSReport = () => { currentY = (pdf as any).lastAutoTable.finalY + 20 - // Invoice section + // Invoice section - TETAP PLAIN (TANPA BORDER) pdf.setFontSize(PDF_FONT_SIZES.heading) pdf.text('Invoice', 14, currentY) currentY += 15 @@ -184,7 +186,10 @@ const DailyPOSReport = () => { head: [], body: [['Total Invoice', String(profitLoss?.summary.total_orders ?? 0)]], theme: 'plain', - styles: { fontSize: PDF_FONT_SIZES.tableContent, cellPadding: PDF_SPACING.cellPadding }, + styles: { + fontSize: PDF_FONT_SIZES.subheading, + cellPadding: PDF_SPACING.cellPadding + }, columnStyles: { 0: { fontStyle: 'normal', textColor: [60, 60, 60] }, 1: { halign: 'right', fontStyle: 'bold', textColor: [60, 60, 60] } @@ -194,7 +199,8 @@ const DailyPOSReport = () => { pdf.addPage() currentY = 20 - // Payment Method Summary + + // Payment Method Summary - DENGAN BORDER HITAM pdf.setFontSize(PDF_FONT_SIZES.heading) pdf.text('Ringkasan Metode Pembayaran', 14, currentY) currentY += 15 @@ -202,7 +208,6 @@ const DailyPOSReport = () => { const paymentBody = paymentAnalytics?.data?.map(payment => [ payment.payment_method_name, - payment.payment_method_type.toUpperCase(), String(payment.order_count), formatCurrency(payment.total_amount), `${(payment.percentage ?? 0).toFixed(1)}%` @@ -210,30 +215,39 @@ const DailyPOSReport = () => { autoTable(pdf, { startY: currentY, - head: [['Metode Pembayaran', 'Tipe', 'Jumlah Order', 'Total Amount', 'Persentase']], + head: [['Metode', 'Jumlah', 'Total', 'Persentase']], body: paymentBody, foot: [ [ 'TOTAL', - '', String(paymentAnalytics?.summary.total_orders ?? 0), formatCurrency(paymentAnalytics?.summary.total_amount ?? 0), '' ] ], - theme: 'striped', - styles: { fontSize: PDF_FONT_SIZES.tableContent, cellPadding: PDF_SPACING.cellPadding }, + theme: 'grid', + styles: { + fontSize: PDF_FONT_SIZES.tableContent, + cellPadding: PDF_SPACING.cellPadding, + lineColor: [0, 0, 0], + lineWidth: 0.1 + }, headStyles: { fillColor: [54, 23, 94], textColor: 255, fontStyle: 'bold', - fontSize: PDF_FONT_SIZES.tableHeader + fontSize: PDF_FONT_SIZES.tableHeader, + lineColor: [0, 0, 0], + lineWidth: 0.1 }, footStyles: { fillColor: [220, 220, 220], textColor: [60, 60, 60], fontStyle: 'bold', - fontSize: PDF_FONT_SIZES.tableFooter + fontSize: PDF_FONT_SIZES.tableFooter, + lineColor: [0, 0, 0], + lineWidth: 0.1, + halign: 'center' }, columnStyles: { 1: { halign: 'center' }, @@ -246,7 +260,7 @@ const DailyPOSReport = () => { currentY = (pdf as any).lastAutoTable.finalY + 20 - // Category Summary + // Category Summary - DENGAN BORDER HITAM pdf.setFontSize(PDF_FONT_SIZES.heading) pdf.text('Ringkasan Kategori', 14, currentY) currentY += 15 @@ -261,19 +275,29 @@ const DailyPOSReport = () => { foot: [ ['TOTAL', String(categorySummary?.totalQuantity ?? 0), formatCurrency(categorySummary?.totalRevenue ?? 0)] ], - theme: 'striped', - styles: { fontSize: PDF_FONT_SIZES.tableContent, cellPadding: PDF_SPACING.cellPadding }, + theme: 'grid', + styles: { + fontSize: PDF_FONT_SIZES.tableContent, + cellPadding: PDF_SPACING.cellPadding, + lineColor: [0, 0, 0], + lineWidth: 0.1 + }, headStyles: { fillColor: [54, 23, 94], textColor: 255, fontStyle: 'bold', - fontSize: PDF_FONT_SIZES.tableHeader + fontSize: PDF_FONT_SIZES.tableHeader, + lineColor: [0, 0, 0], + lineWidth: 0.1 }, footStyles: { fillColor: [220, 220, 220], textColor: [60, 60, 60], fontStyle: 'bold', - fontSize: PDF_FONT_SIZES.tableFooter + fontSize: PDF_FONT_SIZES.tableFooter, + lineColor: [0, 0, 0], + lineWidth: 0.1, + halign: 'center' }, columnStyles: { 1: { halign: 'center' }, @@ -320,6 +344,7 @@ const DailyPOSReport = () => { const skuB = b.product_sku || '' return skuA.localeCompare(skuB) }) + const categoryTotalQty = categoryProducts.reduce((sum, item) => sum + (item.quantity_sold || 0), 0) const categoryTotalRevenue = categoryProducts.reduce((sum, item) => sum + (item.revenue || 0), 0) @@ -337,27 +362,42 @@ const DailyPOSReport = () => { } // Category header - pdf.setFontSize(20) + pdf.setFontSize(PDF_FONT_SIZES.subheading) pdf.setFont('helvetica', 'bold') pdf.setTextColor(54, 23, 94) pdf.text(categoryName.toUpperCase(), 16, currentY) currentY += 15 - // Category table + // Category table - DENGAN BORDER HITAM autoTable(pdf, { startY: currentY, head: [['Produk', 'Qty', 'Pendapatan']], body: productBody, foot: [[`Subtotal ${categoryName}`, String(categoryTotalQty), formatCurrency(categoryTotalRevenue)]], - theme: 'striped', - styles: { fontSize: PDF_FONT_SIZES.tableContent, cellPadding: PDF_SPACING.cellPadding }, + theme: 'grid', + styles: { + fontSize: PDF_FONT_SIZES.tableContent, + cellPadding: PDF_SPACING.cellPadding, + lineColor: [0, 0, 0], + lineWidth: 0.1 + }, headStyles: { fillColor: [54, 23, 94], textColor: 255, fontStyle: 'bold', - fontSize: PDF_FONT_SIZES.tableHeader + fontSize: PDF_FONT_SIZES.tableHeader, + lineColor: [0, 0, 0], + lineWidth: 0.1 + }, + footStyles: { + fillColor: [200, 200, 200], + textColor: [60, 60, 60], + fontStyle: 'bold', + fontSize: PDF_FONT_SIZES.tableFooter, + lineColor: [0, 0, 0], + lineWidth: 0.1, + halign: 'center' }, - footStyles: { fillColor: [200, 200, 200], textColor: [60, 60, 60], fontStyle: 'bold', fontSize: 20 }, columnStyles: { 0: { cellWidth: 90 }, 1: { halign: 'center', cellWidth: 40 }, @@ -369,7 +409,7 @@ const DailyPOSReport = () => { currentY = (pdf as any).lastAutoTable.finalY + 15 }) - // Grand Total + // Grand Total - DENGAN BORDER HITAM if (currentY > 250) { pdf.addPage() currentY = 20 @@ -381,18 +421,21 @@ const DailyPOSReport = () => { body: [ ['TOTAL KESELURUHAN', String(productSummary.totalQuantitySold), formatCurrency(productSummary.totalRevenue)] ], - theme: 'plain', - styles: { fontSize: PDF_FONT_SIZES.grandTotal, cellPadding: 6, fontStyle: 'bold', textColor: [54, 23, 94] }, + theme: 'grid', + styles: { + fontSize: PDF_FONT_SIZES.grandTotal, + cellPadding: 6, + fontStyle: 'bold', + textColor: [54, 23, 94], + lineColor: [0, 0, 0], + lineWidth: 0.2 + }, columnStyles: { 0: { cellWidth: 90 }, 1: { halign: 'center', cellWidth: 40 }, 2: { halign: 'right', cellWidth: 52 } }, - margin: { left: 14, right: 14 }, - didDrawCell: data => { - pdf.setDrawColor(54, 23, 94) - pdf.setLineWidth(0.5) - } + margin: { left: 14, right: 14 } }) // Footer