Implementasi API table face dan ktp
This commit is contained in:
parent
7996568d74
commit
daf0e7e54d
@ -1 +1 @@
|
||||
Subproject commit addaac2b9a73b75761c7449341ecc23bfbe63cc2
|
||||
Subproject commit e15616c8ba2cd26017469382b0f58121b07e8cac
|
0
SingleMessage.js
Normal file
0
SingleMessage.js
Normal file
@ -3,6 +3,7 @@ import { FaChevronLeft, FaChevronRight, FaFastBackward, FaFastForward, FaSort, F
|
||||
import { NoAvailable } from '../../../assets/icon';
|
||||
|
||||
const BASE_URL = process.env.REACT_APP_BASE_URL
|
||||
const LOCAL_URL = 'http://127.0.0.1:8000'
|
||||
const API_KEY = process.env.REACT_APP_API_KEY
|
||||
// Pagination Component
|
||||
const Pagination = ({ currentPage, totalPages, onPageChange }) => {
|
||||
@ -126,7 +127,7 @@ const Transaction = () => {
|
||||
const fetchTransactionData = async (page, limit, search = '', sortColumn = 'tf.id', sortOrder = 'asc') => {
|
||||
try {
|
||||
console.log(`Fetching data for page: ${page}, limit: ${limit}, search: ${search}, sortColumn: ${sortColumn}, sortOrder: ${sortOrder}`); // Log page, limit, and search
|
||||
const response = await fetch(`${BASE_URL}/trx_face/table-log?search=${search}&sortColumn=${sortColumn}&sortOrder=${sortOrder}&limit=${limit}&page=${page}`, {
|
||||
const response = await fetch(`${LOCAL_URL}/trx_face/table-log?search=${search}&sortColumn=${sortColumn}&sortOrder=${sortOrder}`, {
|
||||
method: 'GET',
|
||||
headers: { 'accept': 'application/json', 'x-api-key': API_KEY },
|
||||
});
|
||||
|
@ -2,6 +2,9 @@ import React, { useState, useEffect } from 'react';
|
||||
import { FaChevronLeft, FaChevronRight, FaFastBackward, FaFastForward, FaSort, FaSortUp, FaSortDown } from 'react-icons/fa'; // Icons for sorting
|
||||
import { NoAvailable } from '../../../assets/icon';
|
||||
|
||||
const BASE_URL = process.env.REACT_APP_BASE_URL
|
||||
const LOCAL_URL = 'http://127.0.0.1:8000'
|
||||
const API_KEY = process.env.REACT_APP_API_KEY
|
||||
// Pagination Component
|
||||
const Pagination = ({ currentPage, totalPages, onPageChange }) => {
|
||||
const handlePrev = () => {
|
||||
@ -106,6 +109,10 @@ const Transaction = () => {
|
||||
const [transactionData, setTransactionData] = useState([]);
|
||||
const [sortConfig, setSortConfig] = useState({ key: null, direction: 'asc' }); // Sorting state
|
||||
const dataPerPage = 10; // Data per page (10 data per page)
|
||||
const [totalPages, setTotalPages] = useState(1); // Total pages from API
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [sortColumn, setSortColumn] = useState('tf.id');
|
||||
const [sortOrder, setSortOrder] = useState('asc');
|
||||
|
||||
const buttonData = [
|
||||
{ label: 'Copy', enabled: true },
|
||||
@ -116,30 +123,51 @@ const Transaction = () => {
|
||||
{ label: 'Column Visibility', enabled: true },
|
||||
];
|
||||
|
||||
|
||||
// Generate 691 dummy transactions
|
||||
const generateDummyData = (numOfItems) => {
|
||||
const transactionData = [];
|
||||
|
||||
for (let i = 1; i <= numOfItems; i++) {
|
||||
transactionData.push({
|
||||
transactionId: `TX${String(i).padStart(3, '0')}`,
|
||||
applicationName: `App ${Math.floor(Math.random() * 5) + 1}`,
|
||||
createdAt: new Date(2023, Math.floor(Math.random() * 12), Math.floor(Math.random() * 28) + 1).toLocaleDateString(), // Random date
|
||||
referenceId: `REF${String(i).padStart(3, '0')}`,
|
||||
status: ['Completed', 'Pending', 'Failed'][Math.floor(Math.random() * 3)],
|
||||
mode: Math.random() > 0.5 ? 'Online' : 'Offline',
|
||||
// Fetch transaction data from API
|
||||
const fetchTransactionData = async (page, limit, search = '', sortColumn = 'tf.id', sortOrder = 'asc') => {
|
||||
try {
|
||||
console.log(`Fetching data for page: ${page}, limit: ${limit}, search: ${search}, sortColumn: ${sortColumn}, sortOrder: ${sortOrder}`); // Log page, limit, and search
|
||||
const response = await fetch(`${LOCAL_URL}/ocr-ktp/table-transactions?search=${search}&sortColumn=${sortColumn}&sortOrder=${sortOrder}`, {
|
||||
method: 'GET',
|
||||
headers: { 'accept': 'application/json', 'x-api-key': API_KEY },
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const result = await response.json();
|
||||
const { data, total } = result.details.details.data;
|
||||
setTransactionData(data);
|
||||
setTotalPages(Math.ceil(total / dataPerPage));
|
||||
} catch (error) {
|
||||
console.error('Error fetching transaction data:', error);
|
||||
}
|
||||
|
||||
return transactionData;
|
||||
};
|
||||
|
||||
const fetchPaginationData = async (page, limit, search = '') => {
|
||||
try {
|
||||
console.log(`Fetching pagination data for page: ${page}, limit: ${limit}, search: ${search}`); // Log page, limit, and search
|
||||
const url = `${BASE_URL}/header_detail_param/paging?header_id=1&page=${page}&limit=${limit}&search=${search}`;
|
||||
console.log(`Fetching URL: ${url}`); // Log the URL
|
||||
const response = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: { 'accept': 'application/json', 'x-api-key': API_KEY },
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const result = await response.json();
|
||||
const { data } = result.details;
|
||||
setTotalPages(Math.ceil(data.length / dataPerPage));
|
||||
} catch (error) {
|
||||
console.error('Error fetching pagination data:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// Set the generated transaction data
|
||||
// Fetch data when component mounts and when currentPage changes
|
||||
useEffect(() => {
|
||||
setTransactionData(generateDummyData(3113)); // count data dummy transactions
|
||||
}, []);
|
||||
fetchTransactionData(currentPage, dataPerPage, searchTerm, sortColumn, sortOrder);
|
||||
fetchPaginationData(currentPage, dataPerPage);
|
||||
}, [currentPage, searchTerm, sortColumn, sortOrder]);
|
||||
|
||||
// Sorting function
|
||||
const sortData = (data, config) => {
|
||||
@ -177,8 +205,14 @@ const Transaction = () => {
|
||||
setCurrentPage(page);
|
||||
};
|
||||
|
||||
// Calculate total pages based on the data and data per page
|
||||
const totalPages = Math.ceil(transactionData.length / dataPerPage);
|
||||
// Handle search
|
||||
const handleSearch = async (event) => {
|
||||
const searchQuery = event.target.value;
|
||||
setSearchTerm(searchQuery);
|
||||
setCurrentPage(1); // Reset to first page on new search
|
||||
await fetchPaginationData(1, dataPerPage, searchQuery);
|
||||
await fetchTransactionData(1, dataPerPage, searchQuery);
|
||||
};
|
||||
|
||||
// Paginated data
|
||||
const paginatedData = getPaginatedData(transactionData, currentPage, dataPerPage);
|
||||
@ -258,11 +292,12 @@ const Transaction = () => {
|
||||
</div>
|
||||
|
||||
{/* Search Bar with Icon */}
|
||||
<div className="input-group" style={{ width: '250px', display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>
|
||||
<div className="input-group" style={{ width: '350px', display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
placeholder="Search Application Name or Subject ID" // Placeholder text
|
||||
className="form-control"
|
||||
onChange={handleSearch} // Add onChange handler
|
||||
/>
|
||||
<span className="input-group-text">
|
||||
<i className="fas fa-search"></i> {/* FontAwesome search icon */}
|
||||
@ -276,59 +311,58 @@ const Transaction = () => {
|
||||
<table className="table table-bordered" style={styles.tableContainer}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No.</th> {/* Kolom untuk Nomor Urut */}
|
||||
<th>
|
||||
<button className="btn" onClick={() => handleSort('transactionId')}>
|
||||
<button className="btn" onClick={() => handleSort('transaction_id')}>
|
||||
Transaction ID
|
||||
{sortConfig.key === 'transactionId' &&
|
||||
{sortConfig.key === 'transaction_id' &&
|
||||
(sortConfig.direction === 'asc' ? <FaSortUp style={styles.iconMarginLeft} /> : <FaSortDown style={styles.iconMarginLeft} />)
|
||||
}
|
||||
{sortConfig.key !== 'transactionId' && <FaSort style={styles.iconMarginLeft} />}
|
||||
{sortConfig.key !== 'transaction_id' && <FaSort style={styles.iconMarginLeft} />}
|
||||
</button>
|
||||
</th>
|
||||
<th>
|
||||
<button className="btn" onClick={() => handleSort('applicationName')}>
|
||||
<button className="btn" onClick={() => handleSort('app_name')}>
|
||||
Application Name
|
||||
{sortConfig.key === 'applicationName' &&
|
||||
{sortConfig.key === 'app_name' &&
|
||||
(sortConfig.direction === 'asc' ? <FaSortUp style={styles.iconMarginLeft} /> : <FaSortDown style={styles.iconMarginLeft} />)
|
||||
}
|
||||
{sortConfig.key !== 'applicationName' && <FaSort style={styles.iconMarginLeft} />}
|
||||
{sortConfig.key !== 'app_name' && <FaSort style={styles.iconMarginLeft} />}
|
||||
</button>
|
||||
</th>
|
||||
<th>
|
||||
<button className="btn" onClick={() => handleSort('createdAt')}>
|
||||
<button className="btn" onClick={() => handleSort('created_at')}>
|
||||
Created At
|
||||
{sortConfig.key === 'createdAt' &&
|
||||
{sortConfig.key === 'created_at' &&
|
||||
(sortConfig.direction === 'asc' ? <FaSortUp style={styles.iconMarginLeft} /> : <FaSortDown style={styles.iconMarginLeft} />)
|
||||
}
|
||||
{sortConfig.key !== 'createdAt' && <FaSort style={styles.iconMarginLeft} />}
|
||||
{sortConfig.key !== 'created_at' && <FaSort style={styles.iconMarginLeft} />}
|
||||
</button>
|
||||
</th>
|
||||
<th>
|
||||
<button className="btn" onClick={() => handleSort('referenceId')}>
|
||||
Reference ID
|
||||
{sortConfig.key === 'referenceId' &&
|
||||
<button className="btn" onClick={() => handleSort('service_name')}>
|
||||
Service Name
|
||||
{sortConfig.key === 'service_name' &&
|
||||
(sortConfig.direction === 'asc' ? <FaSortUp style={styles.iconMarginLeft} /> : <FaSortDown style={styles.iconMarginLeft} />)
|
||||
}
|
||||
{sortConfig.key !== 'referenceId' && <FaSort style={styles.iconMarginLeft} />}
|
||||
{sortConfig.key !== 'service_name' && <FaSort style={styles.iconMarginLeft} />}
|
||||
</button>
|
||||
</th>
|
||||
<th>
|
||||
<button className="btn" onClick={() => handleSort('status')}>
|
||||
Status
|
||||
{sortConfig.key === 'status' &&
|
||||
(sortConfig.direction === 'asc' ? <FaSortUp style={styles.iconMarginLeft} /> : <FaSortDown style={styles.iconMarginLeft} />)
|
||||
}
|
||||
{sortConfig.key !== 'status' && <FaSort style={styles.iconMarginLeft} />}
|
||||
</button>
|
||||
</th>
|
||||
<th>
|
||||
<button className="btn" onClick={() => handleSort('mode')}>
|
||||
<button className="btn" onClick={() => handleSort('mode_name')}>
|
||||
Mode
|
||||
{sortConfig.key === 'mode' &&
|
||||
{sortConfig.key === 'mode_name' &&
|
||||
(sortConfig.direction === 'asc' ? <FaSortUp style={styles.iconMarginLeft} /> : <FaSortDown style={styles.iconMarginLeft} />)
|
||||
}
|
||||
{sortConfig.key !== 'mode' && <FaSort style={styles.iconMarginLeft} />}
|
||||
{sortConfig.key !== 'mode_name' && <FaSort style={styles.iconMarginLeft} />}
|
||||
</button>
|
||||
</th>
|
||||
<th>
|
||||
<button className="btn" onClick={() => handleSort('status_name')}>
|
||||
Status
|
||||
{sortConfig.key === 'status_name' &&
|
||||
(sortConfig.direction === 'asc' ? <FaSortUp style={styles.iconMarginLeft} /> : <FaSortDown style={styles.iconMarginLeft} />)
|
||||
}
|
||||
{sortConfig.key !== 'status_name' && <FaSort style={styles.iconMarginLeft} />}
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
@ -338,19 +372,17 @@ const Transaction = () => {
|
||||
{paginatedData.length > 0 ? (
|
||||
paginatedData.map((transaction, index) => (
|
||||
<tr key={index}>
|
||||
{/* Kolom Nomor Urut */}
|
||||
<td>{(currentPage - 1) * dataPerPage + index + 1}</td> {/* Nomor urut berdasarkan halaman dan index */}
|
||||
<td>{transaction.transactionId}</td>
|
||||
<td>{transaction.applicationName}</td>
|
||||
<td>{transaction.createdAt}</td>
|
||||
<td>{transaction.referenceId}</td>
|
||||
<td>{transaction.status}</td>
|
||||
<td>{transaction.mode}</td>
|
||||
<td>{transaction.transaction_id}</td>
|
||||
<td>{transaction.app_name}</td>
|
||||
<td>{transaction.service_name}</td>
|
||||
<td>{new Date(transaction.created_at).toLocaleString()}</td>
|
||||
<td>{transaction.mode_name}</td>
|
||||
<td>{transaction.status_name}</td>
|
||||
</tr>
|
||||
))
|
||||
) : (
|
||||
<tr>
|
||||
<td colSpan="7" className="text-center">
|
||||
<td colSpan="6" className="text-center">
|
||||
<div className="d-flex flex-column align-items-center mt-5">
|
||||
<img src={NoAvailable} alt="No Data Available" className="mb-3" style={styles.iconStyle} />
|
||||
<p>Data not available</p>
|
||||
@ -397,4 +429,3 @@ const styles = {
|
||||
marginLeft: '0.7rem', // Adjust as needed
|
||||
},
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user