diff --git a/public/media/avatars/KopDetailWalletStatement.png b/public/media/avatars/KopDetailWalletStatement.png
new file mode 100644
index 0000000..a2c150b
Binary files /dev/null and b/public/media/avatars/KopDetailWalletStatement.png differ
diff --git a/src/pages/notification/blocks/AddDialog.tsx b/src/pages/notification/blocks/AddDialog.tsx
index 3477d9b..2e9322c 100644
--- a/src/pages/notification/blocks/AddDialog.tsx
+++ b/src/pages/notification/blocks/AddDialog.tsx
@@ -119,7 +119,7 @@ const AddDialog = () => {
}
const response = await GetData(`${API_URL_CUSTOMER}/customer/list`, {
- limit: 100,
+ limit: 1000,
page: 1,
with_deleted: false,
order_field: 'fullname',
diff --git a/src/pages/notification/hooks/ManageNotificationContext.tsx b/src/pages/notification/hooks/ManageNotificationContext.tsx
index c4995f3..b6b7ca4 100644
--- a/src/pages/notification/hooks/ManageNotificationContext.tsx
+++ b/src/pages/notification/hooks/ManageNotificationContext.tsx
@@ -158,7 +158,7 @@ const ManageNotifContextProvider = ({ children }: { children: React.ReactNode })
const getNotificationList = async (page: number, limit: number, sorting: any, filter: any) => {
try {
const sortField = sorting.length > 0 ? sorting[0].id : 'created_at';
- const sortDirection = sorting.length > 0 ? (sorting[0].desc ? 'DESC' : 'ASC') : 'DESC';
+ const sortDirection = sorting.length > 0 ? (sorting[0].desc ? 'ASC' : 'DESC') : 'ASC';
// Initialize filter object
let filterParams: any = {};
@@ -219,7 +219,7 @@ const ManageNotifContextProvider = ({ children }: { children: React.ReactNode })
pagination={{ size: 10 }}
toolbar={}
layout={{ card: true }}
- sorting={[{ id: 'created_at', desc: true }]}
+ sorting={[{ id: 'created_at', desc: false }]}
serverSide={true}
onFetchData={({ pageIndex, pageSize, sorting, columnFilters }) =>
getNotificationList(pageIndex, pageSize, sorting, columnFilters)
diff --git a/src/pages/wallet/wallet-statement/blocks/ShowDetailDialog.tsx b/src/pages/wallet/wallet-statement/blocks/ShowDetailDialog.tsx
index 53e9047..2dc26a4 100644
--- a/src/pages/wallet/wallet-statement/blocks/ShowDetailDialog.tsx
+++ b/src/pages/wallet/wallet-statement/blocks/ShowDetailDialog.tsx
@@ -11,13 +11,19 @@ import { useCallApi } from '@/hooks';
import { apiConfig } from '@/config/api.config';
import { DataGridColumnHeader, DataGridProvider } from '@/components';
import { useManageStatementContext } from '../hooks/useManageWalletStatementContext';
-import { Toaster } from 'sonner';
+import { toast, Toaster } from 'sonner';
import { format } from 'date-fns';
import FilterSection from './FilterSection';
import * as XLSX from 'xlsx';
import jsPDF from 'jspdf';
import 'jspdf-autotable';
+interface AutoTableData {
+ pageNumber: number;
+ table: any;
+ doc: jsPDF;
+}
+
interface ContextProps {
doExportData: (sorting: any, filter: any) => Promise;
doExportExcel: () => Promise;
@@ -186,7 +192,7 @@ const ShowDetailWalletDialog = () => {
const response = await GetData(
`${apiConfig.service_wallet}/dashboard/balance/list-balance-detail/${selectedWallet?.ID}`,
{
- limit: 10000,
+ limit: 10000,
page: 1,
with_deleted: false,
order_field: 'amount',
@@ -233,19 +239,19 @@ const ShowDetailWalletDialog = () => {
const wb = XLSX.utils.book_new();
- const ws = XLSX.utils.json_to_sheet([]);
+ const ws = XLSX.utils.json_to_sheet([]);
const companyHeader = [
- ['T•PAY'],
+ ['T•PAY'],
['Telin Digital Solution'],
['Av. Pres. Nicolau Lobato, Dili'],
['Tel: (+670) 74147147 / 147'],
['www.t-pay.tl'],
- [''],
+ [''],
['Wallet Statement Details'],
[`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`],
[`Wallet ID: ${selectedWallet?.ID || '-'}`],
- ['']
+ ['']
];
const columnHeaders = [
@@ -273,17 +279,17 @@ const ShowDetailWalletDialog = () => {
XLSX.utils.sheet_add_aoa(ws, excelData);
const colWidths = [
- { wch: 20 },
- { wch: 15 },
- { wch: 25 },
- { wch: 10 },
- { wch: 12 },
- { wch: 12 },
- { wch: 12 },
- { wch: 15 },
- { wch: 20 },
- { wch: 25 },
- { wch: 25 }
+ { wch: 20 },
+ { wch: 15 },
+ { wch: 25 },
+ { wch: 10 },
+ { wch: 12 },
+ { wch: 12 },
+ { wch: 12 },
+ { wch: 15 },
+ { wch: 20 },
+ { wch: 25 },
+ { wch: 25 }
];
ws['!cols'] = colWidths;
@@ -292,7 +298,7 @@ const ShowDetailWalletDialog = () => {
ws[tpayCell].s = {
font: { bold: true, sz: 18, color: { rgb: '000000' } },
alignment: { horizontal: 'center' },
- fill: { fgColor: { rgb: 'F4C2C2' } }
+ fill: { fgColor: { rgb: 'F4C2C2' } }
};
}
@@ -302,7 +308,7 @@ const ShowDetailWalletDialog = () => {
ws[cellRef].s = {
font: { sz: 12, color: { rgb: '000000' } },
alignment: { horizontal: 'center' },
- fill: { fgColor: { rgb: 'F4C2C2' } }
+ fill: { fgColor: { rgb: 'F4C2C2' } }
};
}
}
@@ -336,7 +342,7 @@ const ShowDetailWalletDialog = () => {
if (ws[cellRef]) {
ws[cellRef].s = {
font: { bold: true, color: { rgb: 'FFFFFF' } },
- fill: { fgColor: { rgb: '4472C4' } },
+ fill: { fgColor: { rgb: '4472C4' } },
alignment: { horizontal: 'center' },
border: {
top: { style: 'thin', color: { rgb: '000000' } },
@@ -379,98 +385,137 @@ const ShowDetailWalletDialog = () => {
}
};
- const doExportPDF = async () => {
- try {
- const allData = await getAllTransactionData();
- const formattedData = formatTransactionData(allData);
+ // Perbaikan untuk fungsi doExportPDF
+const doExportPDF = async () => {
+ try {
+ // Import jsPDF dengan cara yang benar
+ const jsPDF = (await import('jspdf')).default;
+
+ // Import autoTable plugin
+ const autoTable = (await import('jspdf-autotable')).default;
+
+ const allData = await getAllTransactionData();
+ const formattedData = formatTransactionData(allData);
- const pdf = new jsPDF('l', 'mm', 'a4');
+ // Buat instance jsPDF
+ const pdf = new jsPDF({
+ orientation: 'landscape', // Ubah ke landscape untuk tabel yang lebar
+ unit: 'mm',
+ format: 'a4'
+ });
- pdf.setFontSize(20);
- pdf.setFont('helvetica', 'bold');
- pdf.text('T•PAY', 148, 20, { align: 'center' });
+ // Header perusahaan
+ pdf.setFontSize(18);
+ pdf.setFont('helvetica', 'bold');
+ pdf.text('T•PAY', pdf.internal.pageSize.getWidth() / 2, 20, { align: 'center' });
+
+ pdf.setFontSize(12);
+ pdf.setFont('helvetica', 'normal');
+ pdf.text('Telin Digital Solution', pdf.internal.pageSize.getWidth() / 2, 28, { align: 'center' });
+ pdf.text('Av. Pres. Nicolau Lobato, Dili', pdf.internal.pageSize.getWidth() / 2, 34, { align: 'center' });
+ pdf.text('Tel: (+670) 74147147 / 147', pdf.internal.pageSize.getWidth() / 2, 40, { align: 'center' });
+ pdf.text('www.t-pay.tl', pdf.internal.pageSize.getWidth() / 2, 46, { align: 'center' });
- pdf.setFontSize(12);
- pdf.setFont('helvetica', 'normal');
- pdf.text('Telin Digital Solution', 148, 30, { align: 'center' });
- pdf.text('Av. Pres. Nicolau Lobato, Dili', 148, 36, { align: 'center' });
- pdf.text('Tel : (+670) 7414747 / 147', 148, 42, { align: 'center' });
- pdf.text('www.t-pay.tl', 148, 48, { align: 'center' });
+ // Garis pemisah
+ pdf.setDrawColor(0, 0, 0);
+ pdf.setLineWidth(0.5);
+ pdf.line(20, 52, pdf.internal.pageSize.getWidth() - 20, 52);
- pdf.setFontSize(14);
- pdf.setFont('helvetica', 'bold');
- pdf.text('Wallet Statement Details', 148, 60, { align: 'center' });
+ // Judul laporan
+ pdf.setFontSize(16);
+ pdf.setFont('helvetica', 'bold');
+ pdf.text('Wallet Statement Details', pdf.internal.pageSize.getWidth() / 2, 62, { align: 'center' });
- pdf.setFontSize(10);
- pdf.setFont('helvetica', 'normal');
- pdf.text(`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`, 20, 70);
- pdf.text(`Wallet ID: ${selectedWallet?.ID || '-'}`, 20, 76);
+ // Informasi tambahan
+ pdf.setFontSize(10);
+ pdf.setFont('helvetica', 'normal');
+ pdf.text(`Export Date: ${format(new Date(), 'dd MMM yyyy HH:mm:ss')}`, 20, 72);
+ pdf.text(`Wallet ID: ${selectedWallet?.ID || '-'}`, 20, 78);
- 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']
- ]);
+ // Siapkan data tabel
+ const tableHeaders = [
+ 'Transaction Code',
+ 'MSISDN Reffer',
+ 'Transaction Type',
+ 'Type',
+ 'Pre Amount',
+ 'Amount',
+ 'Post Amount',
+ 'Category',
+ 'Date',
+ 'Purpose',
+ 'Notes'
+ ];
- (pdf as any).autoTable({
- head: [
- [
- 'Transaction Code',
- 'MSISDN Reffer',
- 'Transaction Type',
- 'Type',
- 'Pre Amount',
- 'Amount',
- 'Post Amount',
- 'Category',
- 'Date',
- 'Purpose',
- 'Notes'
- ]
- ],
- body: tableData,
- startY: 85,
- styles: {
- fontSize: 8,
- cellPadding: 2
- },
- headStyles: {
- fillColor: [66, 66, 66],
- textColor: [255, 255, 255],
- fontStyle: 'bold'
- },
- columnStyles: {
- 0: { cellWidth: 20 },
- 1: { cellWidth: 20 },
- 2: { cellWidth: 25 },
- 3: { cellWidth: 15 },
- 4: { cellWidth: 18 },
- 5: { cellWidth: 18 },
- 6: { cellWidth: 18 },
- 7: { cellWidth: 25 },
- 8: { cellWidth: 25 },
- 9: { cellWidth: 30 },
- 10: { cellWidth: 30 }
- },
- margin: { top: 85, left: 10, right: 10 }
- });
+ 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 fileName = `wallet_statement_${selectedWallet?.ID}_${format(new Date(), 'yyyyMMdd_HHmmss')}.pdf`;
- pdf.save(fileName);
+ // Gunakan autoTable dengan cara yang benar
+ autoTable(pdf, {
+ head: [tableHeaders],
+ body: tableData,
+ startY: 85,
+ styles: {
+ fontSize: 7,
+ cellPadding: 2,
+ overflow: 'linebreak',
+ halign: 'center'
+ },
+ headStyles: {
+ fillColor: [68, 114, 196],
+ textColor: [255, 255, 255],
+ fontStyle: 'bold',
+ halign: 'center'
+ },
+ columnStyles: {
+ 0: { cellWidth: 25, halign: 'left' }, // Transaction Code
+ 1: { cellWidth: 20, halign: 'left' }, // MSISDN Reffer
+ 2: { cellWidth: 25, halign: 'left' }, // Transaction Type
+ 3: { cellWidth: 15, halign: 'center' }, // Type
+ 4: { cellWidth: 18, halign: 'right' }, // Pre Amount
+ 5: { cellWidth: 18, halign: 'right' }, // Amount
+ 6: { cellWidth: 18, halign: 'right' }, // Post Amount
+ 7: { cellWidth: 20, halign: 'left' }, // Category
+ 8: { cellWidth: 30, halign: 'left' }, // Date
+ 9: { cellWidth: 25, halign: 'left' }, // Purpose
+ 10: { cellWidth: 25, halign: 'left' } // Notes
+ },
+ margin: { top: 85, left: 10, right: 10 },
+ tableWidth: 'auto',
+ // Callback untuk styling baris
+ didDrawCell: (data: any) => {
+ // Tambahkan border pada setiap cell
+ if (data.section === 'body') {
+ pdf.setDrawColor(200, 200, 200);
+ pdf.setLineWidth(0.1);
+ }
+ }
+ });
- // console.log('PDF export completed successfully');
- } catch (error) {
+ // Generate nama file
+ const fileName = `wallet_statement_${selectedWallet?.ID}_${format(new Date(), 'yyyyMMdd_HHmmss')}.pdf`;
+
+ // Save file
+ pdf.save(fileName);
+
+ toast.success('PDF exported successfully');
+
+ } catch (error) {
console.error('Error exporting to PDF:', error);
+ toast.error('Failed to export PDF');
}
- };
+};
const doExportData = async (sorting: any, filter: any) => {
const user = localStorage.getItem(