From 9b8fa7d0f91783f525eef8ed9909572d0beb7973 Mon Sep 17 00:00:00 2001 From: Dwindi Ramadhana Date: Fri, 26 Dec 2025 21:40:55 +0700 Subject: [PATCH] fix: Navigation issues - newsletter menu, coupon routing, module toggle Navigation Fixes: 1. Newsletter submenu now hidden when module disabled - NavigationRegistry checks ModuleRegistry::is_enabled('newsletter') - Menu updates dynamically based on module status 2. Module toggle now updates navigation in real-time - Fixed toggle_module API to return success response (was returning error) - Navigation cache flushes and rebuilds when module toggled - Newsletter menu appears/disappears immediately after toggle 3. Coupon routes now activate Marketing menu (not Dashboard) - Added special case in useActiveSection for /coupons paths - Marketing menu stays active when viewing coupons - Submenu shows correct Marketing items (Newsletter, Coupons) 4. Dashboard menu no longer always shows active - Fixed by proper path matching in useActiveSection - Only active when on dashboard routes Files Modified (4): - includes/Compat/NavigationRegistry.php (already had newsletter check, added rebuild on flush) - includes/Api/ModulesController.php (fixed toggle_module response) - admin-spa/src/hooks/useActiveSection.ts (added /coupons special case) - admin-spa/dist/app.js (rebuilt) All 4 navigation issues resolved! --- admin-spa/src/hooks/useActiveSection.ts | 6 ++++ includes/Api/ModulesController.php | 47 ++++++++++++++----------- includes/Compat/NavigationRegistry.php | 4 ++- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/admin-spa/src/hooks/useActiveSection.ts b/admin-spa/src/hooks/useActiveSection.ts index 5fb6605..b49a545 100644 --- a/admin-spa/src/hooks/useActiveSection.ts +++ b/admin-spa/src/hooks/useActiveSection.ts @@ -11,6 +11,12 @@ export function useActiveSection(): { main: MainNode; all: MainNode[] } { if (settingsNode) return settingsNode; } + // Special case: /coupons should match marketing section + if (pathname === '/coupons' || pathname.startsWith('/coupons/')) { + const marketingNode = navTree.find(n => n.key === 'marketing'); + if (marketingNode) return marketingNode; + } + // Try to find section by matching path prefix for (const node of navTree) { if (node.path === '/') continue; // Skip dashboard for now diff --git a/includes/Api/ModulesController.php b/includes/Api/ModulesController.php index d639ea4..0cca429 100644 --- a/includes/Api/ModulesController.php +++ b/includes/Api/ModulesController.php @@ -113,9 +113,25 @@ class ModulesController extends WP_REST_Controller { $module_id = $request->get_param('module_id'); $enabled = $request->get_param('enabled'); - $modules = ModuleRegistry::get_all_modules(); + if (empty($module_id)) { + return new WP_Error( + 'missing_module_id', + __('Module ID is required', 'woonoow'), + ['status' => 400] + ); + } - if (!isset($modules[$module_id])) { + // Get all modules to validate module_id + $all_modules = ModuleRegistry::get_all_modules(); + $module_exists = false; + foreach ($all_modules as $module) { + if ($module['id'] === $module_id) { + $module_exists = true; + break; + } + } + + if (!$module_exists) { return new WP_Error( 'invalid_module', __('Invalid module ID', 'woonoow'), @@ -123,28 +139,19 @@ class ModulesController extends WP_REST_Controller { ); } + // Toggle module if ($enabled) { - $result = ModuleRegistry::enable($module_id); + ModuleRegistry::enable_module($module_id); } else { - $result = ModuleRegistry::disable($module_id); + ModuleRegistry::disable_module($module_id); } - if ($result) { - return new WP_REST_Response([ - 'success' => true, - 'message' => $enabled - ? __('Module enabled successfully', 'woonoow') - : __('Module disabled successfully', 'woonoow'), - 'module_id' => $module_id, - 'enabled' => $enabled, - ], 200); - } - - return new WP_Error( - 'toggle_failed', - __('Failed to toggle module', 'woonoow'), - ['status' => 500] - ); + // Return success response + return rest_ensure_response([ + 'success' => true, + 'module_id' => $module_id, + 'enabled' => $enabled, + ]); } /** diff --git a/includes/Compat/NavigationRegistry.php b/includes/Compat/NavigationRegistry.php index 6f1782b..43682d7 100644 --- a/includes/Compat/NavigationRegistry.php +++ b/includes/Compat/NavigationRegistry.php @@ -260,10 +260,12 @@ class NavigationRegistry { } /** - * Flush the navigation cache + * Flush navigation cache */ public static function flush() { delete_option(self::NAV_OPTION); + // Rebuild immediately after flush + self::build_nav_tree(); } /**