Files
formipay/src/admin/pages/Access.js
dwindown 057611ef40 feat: add WPCFTO-inspired design system and React navigation
- Add WPCFTO-inspired design system CSS (colors, spacing, typography)
- Add reusable React components matching WPCFTO visual language
- Implement client-side navigation with hash-based routing
- Add NavigationMenu component for on-page navigation (no SSR)
- Update WordPress submenu highlighting based on current React page
- Add Refresh button to DataTable toolbar
- Fix icon imports in VariationPricingTable
- Remove page headers from all table pages (consistent UX)
- Convert Orders page to use DataTable for consistency

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 05:58:44 +07:00

167 lines
6.0 KiB
JavaScript

/**
* Access Page - Access items management with full table features
*/
import { __ } from '@wordpress/i18n';
import DataTable from '../components/shared/DataTable';
import './AdminPages.css';
// SweetAlert2 is loaded via WordPress (global scope)
const Swal = window.Swal;
export default function AccessPage() {
const ajaxUrl = window.formipayAdmin?.ajaxUrl || '/wp-admin/admin-ajax.php';
const nonce = window.formipayAdmin?.nonce || '';
const handleDelete = async (id) => {
const result = await Swal.fire({
icon: 'info',
html: __('Do you want to delete this item?', 'formipay'),
showCancelButton: true,
confirmButtonText: __('Delete Permanently', 'formipay'),
cancelButtonText: __('Cancel', 'formipay'),
});
if (result.isConfirmed) {
await fetch(`${ajaxUrl}?action=formipay-delete-access-item`, {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
id,
_wpnonce: nonce,
}),
});
window.location.reload();
}
};
const handleDuplicate = async (id) => {
const result = await Swal.fire({
icon: 'info',
html: __('Do you want to duplicate this item?', 'formipay'),
showCancelButton: true,
confirmButtonText: __('Confirm', 'formipay'),
cancelButtonText: __('Cancel', 'formipay'),
});
if (result.isConfirmed) {
await fetch(`${ajaxUrl}?action=formipay-duplicate-access-item`, {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
id,
_wpnonce: nonce,
}),
});
window.location.reload();
}
};
const columns = [
{
key: 'ID',
label: __('ID', 'formipay'),
render: (row) => <strong>#{row.ID}</strong>
},
{
key: 'title',
label: __('Title', 'formipay'),
render: (row) => (
<>
<a href={`${window.formipayAdmin?.siteUrl || ''}/wp-admin/post.php?post=${row.ID}&action=edit`}>
<strong>{row.title || row.post_title || __('Untitled', 'formipay')}</strong>
</a>
<span className="row-actions">
<a href={`${window.formipayAdmin?.siteUrl || ''}/wp-admin/post.php?post=${row.ID}&action=edit`}>{__('edit', 'formipay')}</a>
{' | '}
<button
className="button-link delete"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
handleDelete(row.ID);
}}
>
{__('delete', 'formipay')}
</button>
{' | '}
<button
className="button-link duplicate"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
handleDuplicate(row.ID);
}}
>
{__('duplicate', 'formipay')}
</button>
</span>
</>
)
},
{
key: 'product_name',
label: __('Product', 'formipay'),
},
{
key: 'status',
label: __('Status', 'formipay'),
render: (row) => {
const status = row.post_status || row.status || 'unknown';
const statusLabel = {
publish: __('Published', 'formipay'),
draft: __('Draft', 'formipay'),
}[status] || status;
return (
<span className={`status-label ${status}`}>
{statusLabel}
</span>
);
}
},
{
key: 'date',
label: __('Date', 'formipay'),
render: (row) => {
const date = row.post_date || row.date;
if (!date) return '-';
return new Date(date).toLocaleDateString();
}
},
];
return (
<div className="formipay-page-access">
<DataTable
columns={columns}
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>
);
}