diff --git a/src/pages/wallet/wallet-statement/blocks/ListToolbar.tsx b/src/pages/wallet/wallet-statement/blocks/ListToolbar.tsx index d76c1a8..f9a21b0 100644 --- a/src/pages/wallet/wallet-statement/blocks/ListToolbar.tsx +++ b/src/pages/wallet/wallet-statement/blocks/ListToolbar.tsx @@ -171,8 +171,8 @@ const ListToolbar = ({ - diff --git a/src/pages/wallet/wallet-statement/blocks/ShowDetailDialog.tsx b/src/pages/wallet/wallet-statement/blocks/ShowDetailDialog.tsx index 90501b1..4c4bd2c 100644 --- a/src/pages/wallet/wallet-statement/blocks/ShowDetailDialog.tsx +++ b/src/pages/wallet/wallet-statement/blocks/ShowDetailDialog.tsx @@ -245,7 +245,7 @@ const ShowDetailWalletDialog = () => { [''], ['Wallet Statement Details'], [`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`], - [`Wallet ID: ${selectedWallet?.ID || '-'}`], + [`Wallet Name: ${selectedWallet?.name || '-'}`], [''] ]; @@ -478,10 +478,10 @@ const ShowDetailWalletDialog = () => { } }; - const doExportPDF = async () => { - try { - const allData = await getAllTransactionData(); - const formattedData = formatTransactionData(allData); + const doExportPDF = async () => { + try { + const allData = await getAllTransactionData(); + const formattedData = formatTransactionData(allData); const pdf = new jsPDF({ orientation: 'landscape', @@ -489,10 +489,70 @@ const ShowDetailWalletDialog = () => { format: 'a4' }); + // Pindahkan deklarasi variabel ke luar block try-catch + const pageWidth = pdf.internal.pageSize.getWidth(); + const pageHeight = pdf.internal.pageSize.getHeight(); + const headerImageUrl = toAbsoluteUrl('/media/avatars/KopDetailWalletStatement.png'); + // Definisikan table configuration yang akan digunakan berkali-kali + const tableHeaders = [ + 'Transaction Code', + 'MSISDN Reffer', + 'Transaction Type', + 'Type', + 'Pre Amount', + 'Amount', + 'Post Amount', + 'Category', + 'Date', + 'Purpose', + 'Notes' + ]; + + const tableData = formattedData.map((item) => [ + item['Transaction Code'], + item['MSISDN Reffer'], + item['Transaction Type'], + item['Type'], + item['Pre Amount'], + item['Amount'], + item['Post Amount'], + item['Category'], + item['Date'], + item['Purpose'], + item['Notes'] + ]); + + const columnStyles = { + 0: { cellWidth: 25, halign: 'left' as const }, + 1: { cellWidth: 20, halign: 'left' as const }, + 2: { cellWidth: 25, halign: 'left' as const }, + 3: { cellWidth: 15, halign: 'left' as const }, + 4: { cellWidth: 18, halign: 'left' as const }, + 5: { cellWidth: 18, halign: 'left' as const }, + 6: { cellWidth: 18, halign: 'left' as const }, + 7: { cellWidth: 20, halign: 'left' as const }, + 8: { cellWidth: 30, halign: 'left' as const }, + 9: { cellWidth: 25, halign: 'left' as const }, + 10: { cellWidth: 25, halign: 'left' as const } + }; + + const calculateLeftMargin = ( + columnStyles: Record, + pageWidth: number + ): number => { + const totalTableWidth = Object.values(columnStyles).reduce( + (sum, col) => sum + col.cellWidth, + 0 + ); + return (pageWidth - totalTableWidth) / 2; + }; + + const leftMargin = calculateLeftMargin(columnStyles, pageWidth); + try { - const pageWidth = pdf.internal.pageSize.getWidth(); + // Coba tambahkan header image const imageWidth = 250; const imageHeight = 40; const xPosition = (pageWidth - imageWidth) / 2; @@ -501,18 +561,21 @@ const ShowDetailWalletDialog = () => { let currentY = 55; + // Garis pemisah pdf.setDrawColor(0, 0, 0); pdf.setLineWidth(0.5); pdf.line(20, currentY, pageWidth - 20, currentY); currentY += 10; + // Title pdf.setFontSize(16); pdf.setFont('helvetica', 'bold'); pdf.text('Wallet Statement Details', pageWidth / 2, currentY, { align: 'center' }); currentY += 10; + // Info export pdf.setFontSize(10); pdf.setFont('helvetica', 'normal'); pdf.text(`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`, 20, currentY); @@ -520,70 +583,71 @@ const ShowDetailWalletDialog = () => { currentY += 20; - const tableHeaders = [ - 'Transaction Code', - 'MSISDN Reffer', - 'Transaction Type', - 'Type', - 'Pre Amount', - 'Amount', - 'Post Amount', - 'Category', - 'Date', - 'Purpose', - 'Notes' - ]; - - const tableData = formattedData.map((item) => [ - item['Transaction Code'], - item['MSISDN Reffer'], - item['Transaction Type'], - item['Type'], - item['Pre Amount'], - item['Amount'], - item['Post Amount'], - item['Category'], - item['Date'], - item['Purpose'], - item['Notes'] - ]); - - const calculateLeftMargin = ( - columnStyles: Record, - pageWidth: number - ): number => { - const totalTableWidth = Object.values(columnStyles).reduce( - (sum, col) => sum + col.cellWidth, - 0 - ); - - return (pageWidth - totalTableWidth) / 2; - }; - const columnStyles = { - 0: { cellWidth: 25, halign: 'left' as const }, - 1: { cellWidth: 20, halign: 'left' as const }, - 2: { cellWidth: 25, halign: 'left' as const }, - 3: { cellWidth: 15, halign: 'center' as const }, - 4: { cellWidth: 18, halign: 'right' as const }, - 5: { cellWidth: 18, halign: 'right' as const }, - 6: { cellWidth: 18, halign: 'right' as const }, - 7: { cellWidth: 20, halign: 'left' as const }, - 8: { cellWidth: 30, halign: 'left' as const }, - 9: { cellWidth: 25, halign: 'left' as const }, - 10: { cellWidth: 25, halign: 'left' as const } - }; - - const leftMargin = calculateLeftMargin(columnStyles, pageWidth); - + // Render table dengan header image autoTable(pdf, { head: [tableHeaders], body: tableData, startY: currentY, styles: { fontSize: 7, - cellPadding: 2, + cellPadding: 1.5, overflow: 'linebreak', - halign: 'center' + halign: 'left', + lineWidth: 0.1, + lineColor: [200, 200, 200] + }, + headStyles: { + fillColor: [68, 114, 196], + textColor: [255, 255, 255], + fontStyle: 'bold', + halign: 'center', + cellPadding: 1.5 + }, + columnStyles: columnStyles, + tableWidth: 'wrap', + margin: { + left: leftMargin, + right: leftMargin, + top: 10, + bottom: 10 + }, + didDrawPage: (data: any) => { + if (data.pageNumber > 1) { + pdf.setFontSize(10); + pdf.setFont('helvetica', 'normal'); + } + }, + theme: 'grid', + didDrawCell: (data: any) => { + if (data.section === 'body') { + pdf.setDrawColor(200, 200, 200); + pdf.setLineWidth(0.1); + } + }, + showHead: 'everyPage' + }); + } catch (imageError) { + console.error('Error loading header image:', imageError); + + // Fallback tanpa gambar header + pdf.setFontSize(16); + pdf.setFont('helvetica', 'bold'); + pdf.text('Wallet Statement Details', pageWidth / 2, 20, { align: 'center' }); + + pdf.setFontSize(10); + pdf.setFont('helvetica', 'normal'); + pdf.text(`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`, 20, 30); + pdf.text(`Wallet ID: ${selectedWallet?.ID || '-'}`, 20, 36); + + autoTable(pdf, { + head: [tableHeaders], + body: tableData, + startY: 45, + styles: { + fontSize: 7, + cellPadding: 1.5, + overflow: 'linebreak', + halign: 'left' }, headStyles: { fillColor: [68, 114, 196], @@ -591,22 +655,22 @@ const ShowDetailWalletDialog = () => { fontStyle: 'bold', halign: 'center' }, - columnStyles, + columnStyles: columnStyles, tableWidth: 'wrap', - margin: { top: currentY, left: leftMargin }, - didDrawCell: (data: any) => { - if (data.section === 'body') { - pdf.setDrawColor(200, 200, 200); - pdf.setLineWidth(0.1); + margin: { left: leftMargin, right: leftMargin, top: 10, bottom: 10 }, + theme: 'grid', + showHead: 'everyPage', + didDrawPage: (data: any) => { + if (data.pageNumber > 1) { + pdf.setFontSize(10); + pdf.setFont('helvetica', 'normal'); } } }); - - const fileName = `wallet_statement_${selectedWallet?.ID}_${format(new Date(), 'yyyyMMdd_HHmmss')}.pdf`; - pdf.save(fileName); - } catch (imageError) { - console.error('Error loading header image:', imageError); } + + const fileName = `wallet_statement_${selectedWallet?.ID}_${format(new Date(), 'yyyyMMdd_HHmmss')}.pdf`; + pdf.save(fileName); } catch (error) { console.error('Error exporting to PDF:', error); toast.error('Failed to export PDF'); @@ -663,7 +727,7 @@ const ShowDetailWalletDialog = () => { - Details Walletsss Statementssss + Details Wallets Statement @@ -695,4 +759,4 @@ const ShowDetailWalletDialog = () => { ); }; -export default ShowDetailWalletDialog; +export default ShowDetailWalletDialog; \ No newline at end of file