146 lines
4.7 KiB
TypeScript
146 lines
4.7 KiB
TypeScript
// Dynamic SPA menu tree (reads from backend via window.WNW_NAV_TREE)
|
|
export const NAV_TREE_VERSION = 'navTree-2025-10-28-dynamic';
|
|
|
|
export type NodeMode = 'spa' | 'bridge';
|
|
export type SubItem = {
|
|
label: string;
|
|
mode: NodeMode;
|
|
path?: string; // for SPA routes
|
|
href?: string; // for classic admin URLs
|
|
exact?: boolean;
|
|
};
|
|
export type MainKey = string; // Changed from union to string to support dynamic keys
|
|
export type MainNode = {
|
|
key: MainKey;
|
|
label: string;
|
|
path: string; // main path
|
|
icon?: string; // lucide icon name
|
|
children: SubItem[]; // will be frozen at runtime
|
|
};
|
|
|
|
/**
|
|
* Get navigation tree from backend (dynamic)
|
|
* Falls back to static tree if backend data not available
|
|
*/
|
|
function getNavTreeFromBackend(): MainNode[] {
|
|
const backendTree = (window as any).WNW_NAV_TREE;
|
|
|
|
if (Array.isArray(backendTree) && backendTree.length > 0) {
|
|
return backendTree;
|
|
}
|
|
|
|
// Fallback to static tree (for development/safety)
|
|
return getStaticFallbackTree();
|
|
}
|
|
|
|
/**
|
|
* Static fallback tree (used if backend data not available)
|
|
*/
|
|
function getStaticFallbackTree(): MainNode[] {
|
|
const admin =
|
|
(window as any).wnw?.adminUrl ??
|
|
(window as any).woonoow?.adminUrl ??
|
|
'/wp-admin/admin.php';
|
|
|
|
return [
|
|
{
|
|
key: 'dashboard',
|
|
label: 'Dashboard',
|
|
path: '/dashboard',
|
|
icon: 'layout-dashboard',
|
|
children: [
|
|
{ label: 'Overview', mode: 'spa', path: '/dashboard', exact: true },
|
|
{ label: 'Revenue', mode: 'spa', path: '/dashboard/revenue' },
|
|
{ label: 'Orders', mode: 'spa', path: '/dashboard/orders' },
|
|
{ label: 'Products', mode: 'spa', path: '/dashboard/products' },
|
|
{ label: 'Customers', mode: 'spa', path: '/dashboard/customers' },
|
|
{ label: 'Coupons', mode: 'spa', path: '/dashboard/coupons' },
|
|
{ label: 'Taxes', mode: 'spa', path: '/dashboard/taxes' },
|
|
],
|
|
},
|
|
{
|
|
key: 'orders',
|
|
label: 'Orders',
|
|
path: '/orders',
|
|
icon: 'receipt-text',
|
|
children: [],
|
|
},
|
|
{
|
|
key: 'products',
|
|
label: 'Products',
|
|
path: '/products',
|
|
icon: 'package',
|
|
children: [
|
|
{ label: 'All products', mode: 'spa', path: '/products' },
|
|
{ label: 'New', mode: 'spa', path: '/products/new' },
|
|
{ label: 'Categories', mode: 'spa', path: '/products/categories' },
|
|
{ label: 'Tags', mode: 'spa', path: '/products/tags' },
|
|
{ label: 'Attributes', mode: 'spa', path: '/products/attributes' },
|
|
],
|
|
},
|
|
{
|
|
key: 'coupons',
|
|
label: 'Coupons',
|
|
path: '/coupons',
|
|
icon: 'tag',
|
|
children: [
|
|
{ label: 'All coupons', mode: 'spa', path: '/coupons' },
|
|
{ label: 'New', mode: 'spa', path: '/coupons/new' },
|
|
],
|
|
},
|
|
{
|
|
key: 'customers',
|
|
label: 'Customers',
|
|
path: '/customers',
|
|
icon: 'users',
|
|
children: [
|
|
{ label: 'All customers', mode: 'spa', path: '/customers' },
|
|
],
|
|
},
|
|
{
|
|
key: 'settings',
|
|
label: 'Settings',
|
|
path: '/settings',
|
|
icon: 'settings',
|
|
// Settings submenu available in all modes for consistent experience
|
|
children: [
|
|
// WooNooW Settings
|
|
{ label: 'WooNooW', mode: 'spa' as const, path: '/settings' },
|
|
|
|
// WooCommerce Settings (Most Used First)
|
|
{ label: 'General', mode: 'spa' as const, path: '/settings/general' },
|
|
{ label: 'Payments', mode: 'spa' as const, path: '/settings/payments' },
|
|
{ label: 'Shipping', mode: 'spa' as const, path: '/settings/shipping' },
|
|
{ label: 'Products', mode: 'spa' as const, path: '/settings/products' },
|
|
{ label: 'Tax', mode: 'spa' as const, path: '/settings/tax' },
|
|
{ label: 'Accounts & Privacy', mode: 'spa' as const, path: '/settings/accounts' },
|
|
{ label: 'Emails', mode: 'spa' as const, path: '/settings/emails' },
|
|
|
|
// Less Common (Bridge to WP Admin for now)
|
|
{ label: 'Advanced', mode: 'bridge' as const, href: `${admin}?page=wc-settings&tab=advanced` },
|
|
{ label: 'Integration', mode: 'bridge' as const, href: `${admin}?page=wc-settings&tab=integration` },
|
|
{ label: 'Status', mode: 'bridge' as const, href: `${admin}?page=wc-status` },
|
|
{ label: 'Extensions', mode: 'bridge' as const, href: `${admin}?page=wc-addons` },
|
|
],
|
|
},
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Deep freeze tree for immutability
|
|
*/
|
|
function deepFreezeTree(src: MainNode[]): MainNode[] {
|
|
return src.map((n) =>
|
|
Object.freeze({
|
|
...n,
|
|
children: Object.freeze([...(n.children ?? [])]),
|
|
}) as MainNode
|
|
) as unknown as MainNode[];
|
|
}
|
|
|
|
/**
|
|
* Export the navigation tree (reads from backend, falls back to static)
|
|
*/
|
|
export const navTree: MainNode[] = Object.freeze(
|
|
deepFreezeTree(getNavTreeFromBackend())
|
|
) as unknown as MainNode[]; |