feat: migrate Coupons, Access, Customers, Licenses pages to full DataTable

Update all admin listing pages to use the full-featured DataTable component:

Coupons page:
- All columns (ID, code, type, amount, usages, date limit, status)
- Status filter (All, Active, Inactive)
- Inline actions and bulk delete
- Add New modal

Access page:
- All columns (ID, title, product, status, date)
- Status filter (All, Published, Draft)
- Inline actions and bulk delete
- Add New modal

Customers page:
- All columns (ID, name, email, phone, total orders, date)
- Read-only (no selection or inline actions)
- Search and pagination

Licenses page:
- All columns (ID, license key, product, order, email, status)
- Status labels (Active, Inactive, Expired)
- Read-only (no selection or inline actions)
- Search and pagination

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-18 17:13:09 +07:00
parent 8529cfa2c0
commit 128e396040
15 changed files with 103 additions and 162 deletions

View File

@@ -1,43 +1,17 @@
/**
* Access Page - Access items management
* Access Page - Access items management with full table features
*/
import { __ } from '@wordpress/i18n';
import { useState, useCallback, useEffect } from '@wordpress/element';
import { Button } from '@wordpress/components';
import { accessApi } from '../api/client';
import DataTable from '../components/shared/DataTable';
import './AdminPages.css';
export default function AccessPage({ initialData }) {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(true);
const loadItems = useCallback(() => {
setLoading(true);
accessApi.list()
.then(result => {
// Handle both WordPress format and direct format
const items = result.data?.results || result.results || result.data || [];
setItems(items);
})
.catch(error => {
console.error('Load access items error:', error);
})
.finally(() => {
setLoading(false);
});
}, []);
useEffect(() => {
loadItems();
}, [loadItems]);
export default function AccessPage() {
const columns = [
{
key: 'id',
key: 'ID',
label: __('ID', 'formipay'),
render: (row) => <strong>#{row.id}</strong>
render: (row) => <strong>#{row.ID}</strong>
},
{
key: 'title',
@@ -57,7 +31,7 @@ export default function AccessPage({ initialData }) {
draft: __('Draft', 'formipay'),
}[status] || status;
return (
<span className={`status-badge status-${status}`}>
<span className={`status-label ${status}`}>
{statusLabel}
</span>
);
@@ -78,15 +52,33 @@ export default function AccessPage({ initialData }) {
<div className="formipay-page-access">
<div className="formipay-page-header">
<h1>{ __('Access Items', 'formipay') }</h1>
<Button variant="primary" href={window.formipayAdmin?.siteUrl + '/wp-admin/post-new.php?post_type=formipay-access'}>
{ __('+ Add New Item', 'formipay') }
</Button>
</div>
<DataTable
columns={columns}
data={items}
loading={loading}
ajaxUrl={window.formipayAdmin?.ajaxUrl || '/wp-admin/admin-ajax.php'}
nonce={window.formipayAdmin?.nonce || ''}
tableAction="formipay-tabledata-access-items"
deleteAction="formipay-delete-access-item"
duplicateAction="formipay-duplicate-access-item"
filterOptions={{
key: 'post_status',
options: [
{ value: 'all', label: __('All', 'formipay') },
{ value: 'publish', label: __('Published', 'formipay') },
{ value: 'draft', label: __('Draft', 'formipay') },
]
}}
actions={{
addNew: {
label: __('+ Add New Item', 'formipay'),
action: 'formipay-create-access-item-post',
},
bulkDelete: {
action: 'formipay-bulk-delete-access-item',
},
inline: true,
}}
emptyMessage={__('No access items found', 'formipay')}
/>
</div>