- 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>
167 lines
6.0 KiB
JavaScript
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>
|
|
);
|
|
}
|