';
+
+// Navigation MUST be inside wrapper
+if (class_exists('HVAC_Master_Menu_System')) {
+ $master_menu = HVAC_Master_Menu_System::instance();
+ $master_menu->render_master_menu();
+}
+```
+
+**2. Add CSS to force single-column layout:**
+Create `assets/css/hvac-master-dashboard.css`:
+```css
+/* Force single column layout for master dashboard */
+.hvac-master-dashboard-page {
+ width: 100% !important;
+ max-width: 100% !important;
+}
+
+/* Ensure navigation doesn't create sidebar */
+.hvac-master-dashboard-page .hvac-trainer-menu-wrapper {
+ width: 100% !important;
+ display: block !important;
+ float: none !important;
+ position: relative !important;
+ margin-bottom: 20px !important;
+}
+
+/* Force horizontal menu layout */
+.hvac-master-dashboard-page .hvac-trainer-menu {
+ display: flex !important;
+ flex-direction: row !important;
+ flex-wrap: wrap !important;
+}
+
+/* Hide any theme sidebars */
+.hvac-master-dashboard-page #secondary,
+.hvac-master-dashboard-page .widget-area,
+.hvac-master-dashboard-page .sidebar {
+ display: none !important;
+}
+```
+
+**3. Enqueue the CSS conditionally:**
+```php
+// In class-hvac-scripts-styles.php
+if ($this->is_master_dashboard_page()) {
+ wp_enqueue_style(
+ 'hvac-master-dashboard',
+ HVAC_PLUGIN_URL . 'assets/css/hvac-master-dashboard.css',
+ array('hvac-consolidated-dashboard'),
+ $this->version
+ );
+}
+```
+
#### Dashboard Dropdown Menus Not Working
**Symptoms:**
- Dropdown menus don't open on click
diff --git a/includes/class-hvac-community-events.php b/includes/class-hvac-community-events.php
index c90363df..0322747e 100644
--- a/includes/class-hvac-community-events.php
+++ b/includes/class-hvac-community-events.php
@@ -436,10 +436,7 @@ class HVAC_Community_Events {
// Initialize communication system
$this->init_communication_system();
- // Initialize access control system
- if (class_exists('HVAC_Access_Control')) {
- new HVAC_Access_Control();
- }
+ // Access control system initialized in main plugin class (HVAC_Plugin)
// Initialize approval workflow
if (class_exists('HVAC_Approval_Workflow')) {
@@ -830,17 +827,23 @@ class HVAC_Community_Events {
// Check for trainer dashboard page - force correct template
- if (is_page('trainer/dashboard')) {
+ // Fix: Use get_page_by_path for hierarchical URLs as is_page() doesn't work with paths
+ $trainer_dashboard_page = get_page_by_path('trainer/dashboard');
+ if ($trainer_dashboard_page && is_page($trainer_dashboard_page->ID)) {
$custom_template = HVAC_PLUGIN_DIR . 'templates/page-trainer-dashboard.php';
}
// For master dashboard, force our template regardless of WordPress template assignment
- if (is_page('master-trainer/master-dashboard')) {
+ // Fix: Use get_page_by_path for hierarchical URLs as is_page() doesn't work with paths
+ $master_dashboard_page = get_page_by_path('master-trainer/master-dashboard');
+ if ($master_dashboard_page && is_page($master_dashboard_page->ID)) {
$custom_template = HVAC_PLUGIN_DIR . 'templates/page-master-dashboard.php';
}
// Check for google-sheets page
- if (is_page('master-trainer/google-sheets')) {
+ // Fix: Use get_page_by_path for hierarchical URLs
+ $google_sheets_page = get_page_by_path('master-trainer/google-sheets');
+ if ($google_sheets_page && is_page($google_sheets_page->ID)) {
$custom_template = HVAC_PLUGIN_DIR . 'templates/template-google-sheets.php';
}
diff --git a/includes/class-hvac-scripts-styles.php b/includes/class-hvac-scripts-styles.php
index ba870f10..87c8ac90 100644
--- a/includes/class-hvac-scripts-styles.php
+++ b/includes/class-hvac-scripts-styles.php
@@ -333,6 +333,16 @@ class HVAC_Scripts_Styles {
array('hvac-consolidated-core'),
$this->version
);
+
+ // Load master dashboard specific styles to fix layout issues
+ if ($this->is_master_dashboard_page()) {
+ wp_enqueue_style(
+ 'hvac-master-dashboard',
+ HVAC_PLUGIN_URL . 'assets/css/hvac-master-dashboard.css',
+ array('hvac-consolidated-dashboard'),
+ $this->version
+ );
+ }
}
// Load fixed forms bundle for registration/profile pages
@@ -1022,6 +1032,29 @@ class HVAC_Scripts_Styles {
return false;
}
+ /**
+ * Check if current page is master dashboard page specifically
+ *
+ * @return bool
+ */
+ private function is_master_dashboard_page() {
+ // Check by page slug
+ $master_pages = array(
+ 'master-trainer/master-dashboard',
+ 'master-dashboard'
+ );
+
+ foreach ($master_pages as $page_slug) {
+ if (is_page($page_slug)) {
+ return true;
+ }
+ }
+
+ // Also check by URL path
+ $current_path = $_SERVER['REQUEST_URI'];
+ return (strpos($current_path, 'master-trainer/master-dashboard') !== false);
+ }
+
/**
* Check if current page is registration page
*
diff --git a/templates/page-master-dashboard.php b/templates/page-master-dashboard.php
index 16154d9e..ab04e350 100644
--- a/templates/page-master-dashboard.php
+++ b/templates/page-master-dashboard.php
@@ -11,46 +11,41 @@ if (!defined('HVAC_IN_PAGE_TEMPLATE')) {
get_header();
-// Check master trainer permissions FIRST
-$user = wp_get_current_user();
-if (!in_array('hvac_master_trainer', $user->roles) && !current_user_can('manage_options')) {
- ?>
-
-
-
Access Denied
-
You do not have permission to access this page.
-
If you believe this is an error, please contact an administrator.
-
Return to Home
-
-
';
+
+// Render master trainer navigation inside the wrapper
if (class_exists('HVAC_Master_Menu_System')) {
$master_menu = HVAC_Master_Menu_System::instance();
$master_menu->render_master_menu();
}
-// Render breadcrumbs
+// Render breadcrumbs inside the wrapper
if (class_exists('HVAC_Breadcrumbs')) {
- HVAC_Breadcrumbs::render();
+ // Fix: The method is render_breadcrumbs(), not render()
+ $breadcrumbs_instance = HVAC_Breadcrumbs::instance();
+ echo $breadcrumbs_instance->render_breadcrumbs();
}
-echo '
';
-echo '
';
+// Render the master dashboard content with output buffering
+$template_path = HVAC_PLUGIN_DIR . 'templates/template-hvac-master-dashboard.php';
-// Render the master dashboard content with output buffering to ensure proper rendering
ob_start();
-include HVAC_PLUGIN_DIR . 'templates/template-hvac-master-dashboard.php';
+if (file_exists($template_path)) {
+ include $template_path;
+} else {
+ // Log error for admins only
+ if (current_user_can('manage_options')) {
+ echo '
Template file not found. Please contact support.
';
+ }
+}
$dashboard_content = ob_get_clean();
-// Output the dashboard content with debug info
-echo '';
+// Output the dashboard content
echo $dashboard_content;
-echo '';
echo '
'; // .container
echo '
'; // .hvac-page-wrapper
diff --git a/templates/page-master-trainers.php b/templates/page-master-trainers.php
index 1cc9f8c5..fc6920be 100644
--- a/templates/page-master-trainers.php
+++ b/templates/page-master-trainers.php
@@ -11,22 +11,8 @@ if (!defined('HVAC_IN_PAGE_TEMPLATE')) {
get_header();
-// Check master trainer permissions FIRST
-$user = wp_get_current_user();
-if (!in_array('hvac_master_trainer', $user->roles) && !current_user_can('manage_options')) {
- ?>
-
-
-
Access Denied
-
You do not have permission to access this page.
-
If you believe this is an error, please contact an administrator.
-
Return to Home
-
-
- roles ) && ! current_user_can( 'manage_options' ) ) {
- // Show access denied message using existing styles
- get_header();
- ?>
-
-
-
-
-
-
-
-
You do not have permission to view the Master Dashboard.
-
This dashboard is only available to Master Trainers and Administrators.
-
Go to Your Dashboard
-
Return to Home
-
-
-
-
-
-
- {
+ console.log('š Checking if master dashboard page exists in WordPress...');
+
+ const browser = await chromium.launch({
+ headless: false,
+ slowMo: 500
+ });
+
+ const page = await browser.newPage();
+
+ try {
+ // First check what happens with a simple direct URL access
+ console.log('š Testing direct URL access...');
+ const response = await page.goto('https://upskill-staging.measurequick.com/master-trainer/master-dashboard/', {
+ waitUntil: 'networkidle'
+ });
+
+ console.log('- Response status:', response.status());
+ console.log('- Response URL:', response.url());
+
+ // Check page structure
+ const pageInfo = await page.evaluate(() => {
+ const bodyClasses = document.body.className;
+ const pageId = bodyClasses.match(/page-id-(\d+)/)?.[1];
+
+ // Check for WordPress's own 404 indicators
+ const is404 = bodyClasses.includes('error404');
+ const hasContent = document.querySelector('.entry-content, .site-main, #main, .hvac-page-wrapper');
+
+ // Check what template WordPress thinks it's using
+ const templateClass = bodyClasses.match(/page-template-[\w-]+/)?.[0];
+
+ // Check if there's a title element
+ const title = document.querySelector('h1, .entry-title');
+
+ return {
+ pageId: pageId || 'none',
+ is404: is404,
+ hasContent: hasContent !== null,
+ contentSelector: hasContent ? hasContent.tagName + (hasContent.id ? '#' + hasContent.id : '') + (hasContent.className ? '.' + hasContent.className.split(' ')[0] : '') : 'none',
+ templateClass: templateClass || 'none',
+ pageTitle: title ? title.textContent.trim() : 'none',
+ bodyClassList: bodyClasses
+ };
+ });
+
+ console.log('\nš Page Analysis:');
+ console.log('- WordPress Page ID:', pageInfo.pageId);
+ console.log('- Is 404 Page:', pageInfo.is404);
+ console.log('- Has Content Area:', pageInfo.hasContent);
+ console.log('- Content Selector:', pageInfo.contentSelector);
+ console.log('- Template Class:', pageInfo.templateClass);
+ console.log('- Page Title:', pageInfo.pageTitle);
+
+ // Try alternate URL formats
+ console.log('\nš Testing alternate URL formats...');
+
+ // Try without trailing slash
+ const response2 = await page.goto('https://upskill-staging.measurequick.com/master-trainer/master-dashboard', {
+ waitUntil: 'networkidle'
+ });
+ console.log('- Without trailing slash - Status:', response2.status(), 'URL:', response2.url());
+
+ // Try the old dashboard URL
+ const response3 = await page.goto('https://upskill-staging.measurequick.com/master-trainer/dashboard/', {
+ waitUntil: 'networkidle'
+ });
+ console.log('- Old dashboard URL - Status:', response3.status(), 'URL:', response3.url());
+
+ // Check what's in the HTML source
+ const htmlContent = await page.content();
+ console.log('\nš HTML Content Analysis:');
+ console.log('- Contains "Master Dashboard":', htmlContent.includes('Master Dashboard'));
+ console.log('- Contains "System Overview":', htmlContent.includes('System Overview'));
+ console.log('- Contains template debug comment:', htmlContent.includes('DEBUG: template-hvac-master-dashboard.php loaded'));
+ console.log('- Contains hvac-page-wrapper:', htmlContent.includes('hvac-page-wrapper'));
+
+ // Look for any PHP errors in the source
+ const phpErrors = htmlContent.match(/Fatal error:|Warning:|Notice:|Parse error:/gi);
+ if (phpErrors) {
+ console.log('\nā ļø PHP Errors found:', phpErrors);
+ }
+
+ // Take screenshot
+ await page.screenshot({
+ path: '/tmp/playwright-mcp-output/wp-page-check.png',
+ fullPage: false
+ });
+ console.log('\nšø Screenshot saved to /tmp/playwright-mcp-output/wp-page-check.png');
+
+ console.log('\nš Keeping browser open for 10 seconds...');
+ await page.waitForTimeout(10000);
+
+ } catch (error) {
+ console.error('Error during testing:', error);
+ } finally {
+ await browser.close();
+ console.log('ā
Test completed');
+ }
+})();
\ No newline at end of file
diff --git a/test-logged-in-master.js b/test-logged-in-master.js
new file mode 100644
index 00000000..37d899a8
--- /dev/null
+++ b/test-logged-in-master.js
@@ -0,0 +1,95 @@
+const { chromium } = require('playwright');
+
+(async () => {
+ console.log('š Testing master dashboard with logged-in session...');
+
+ const browser = await chromium.launch({
+ headless: false,
+ slowMo: 500
+ });
+
+ const page = await browser.newPage();
+
+ try {
+ // Login first
+ console.log('š Logging in as master trainer...');
+ await page.goto('https://upskill-staging.measurequick.com/training-login/');
+ await page.waitForTimeout(2000);
+
+ // Fill login form
+ await page.fill('#user_login', 'test_master');
+ await page.fill('#user_pass', 'TestMaster123!');
+ await page.click('#wp-submit');
+
+ // Wait for login to complete
+ await page.waitForTimeout(3000);
+
+ // Now try to access master dashboard
+ console.log('š Navigating to master dashboard...');
+ const response = await page.goto('https://upskill-staging.measurequick.com/master-trainer/master-dashboard/', {
+ waitUntil: 'networkidle'
+ });
+
+ console.log('- Response status:', response.status());
+ console.log('- Final URL:', page.url());
+
+ // Check page structure
+ const pageInfo = await page.evaluate(() => {
+ const bodyClasses = document.body.className;
+ const pageId = bodyClasses.match(/page-id-(\d+)/)?.[1];
+
+ // Check for content areas
+ const mainContent = document.querySelector('#main, .site-main');
+ const hvacWrapper = document.querySelector('.hvac-page-wrapper');
+ const dashboardContent = document.querySelector('.hvac-dashboard-stats, .hvac-stat-card');
+
+ // Get any visible text content
+ const visibleText = document.body.innerText.substring(0, 500);
+
+ return {
+ pageId: pageId || 'none',
+ templateClass: bodyClasses.match(/page-template-[\w-]+/)?.[0] || 'none',
+ hasMainContent: mainContent !== null,
+ hasHvacWrapper: hvacWrapper !== null,
+ hasDashboardContent: dashboardContent !== null,
+ mainContentHTML: mainContent ? mainContent.innerHTML.substring(0, 200) : 'none',
+ visibleTextSnippet: visibleText
+ };
+ });
+
+ console.log('\nš Page Analysis:');
+ console.log('- WordPress Page ID:', pageInfo.pageId);
+ console.log('- Template Class:', pageInfo.templateClass);
+ console.log('- Has Main Content:', pageInfo.hasMainContent);
+ console.log('- Has HVAC Wrapper:', pageInfo.hasHvacWrapper);
+ console.log('- Has Dashboard Content:', pageInfo.hasDashboardContent);
+ console.log('\n- Main Content HTML (first 200 chars):');
+ console.log(pageInfo.mainContentHTML);
+ console.log('\n- Visible Text (first 500 chars):');
+ console.log(pageInfo.visibleTextSnippet);
+
+ // Check HTML source
+ const htmlContent = await page.content();
+ console.log('\nš HTML Source Analysis:');
+ console.log('- Contains "Master Dashboard":', htmlContent.includes('Master Dashboard'));
+ console.log('- Contains "System Overview":', htmlContent.includes('System Overview'));
+ console.log('- Contains debug comment:', htmlContent.includes('DEBUG: template-hvac-master-dashboard.php loaded'));
+ console.log('- Page length:', htmlContent.length, 'characters');
+
+ // Take screenshot
+ await page.screenshot({
+ path: '/tmp/playwright-mcp-output/master-logged-in.png',
+ fullPage: false
+ });
+ console.log('\nšø Screenshot saved');
+
+ console.log('\nš Keeping browser open for 15 seconds...');
+ await page.waitForTimeout(15000);
+
+ } catch (error) {
+ console.error('Error during testing:', error);
+ } finally {
+ await browser.close();
+ console.log('ā
Test completed');
+ }
+})();
\ No newline at end of file
diff --git a/test-master-page-exists.js b/test-master-page-exists.js
new file mode 100644
index 00000000..2070e500
--- /dev/null
+++ b/test-master-page-exists.js
@@ -0,0 +1,98 @@
+const { chromium } = require('playwright');
+
+(async () => {
+ console.log('š Testing master dashboard page existence and template...');
+
+ const browser = await chromium.launch({
+ headless: false,
+ slowMo: 500
+ });
+
+ const page = await browser.newPage();
+
+ try {
+ // Login first
+ console.log('š Logging in as master trainer...');
+ await page.goto('https://upskill-staging.measurequick.com/training-login/');
+ await page.waitForTimeout(2000);
+
+ await page.fill('#user_login', 'test_master');
+ await page.fill('#user_pass', 'TestMaster123!');
+ await page.click('#wp-submit');
+ await page.waitForTimeout(3000);
+
+ // Go directly to master dashboard
+ console.log('š Navigating to master dashboard...');
+ await page.goto('https://upskill-staging.measurequick.com/master-trainer/master-dashboard/');
+ await page.waitForTimeout(3000);
+
+ // Check for debug comments in source
+ const htmlSource = await page.content();
+ console.log('\nš Debug Comments Check:');
+ console.log('- Contains "DEBUG: template-hvac-master-dashboard.php loaded":', htmlSource.includes('DEBUG: template-hvac-master-dashboard.php loaded'));
+ console.log('- Contains "Master Dashboard" heading:', htmlSource.includes('
Master Dashboard
') || htmlSource.includes('
Master Dashboard
'));
+ console.log('- Contains "System Overview":', htmlSource.includes('System Overview'));
+
+ // Check if we're getting the right template
+ const bodyClasses = await page.evaluate(() => document.body.className);
+ console.log('\nš Body Classes:', bodyClasses);
+
+ // Check for hvac-page-wrapper
+ const hasWrapper = await page.evaluate(() => {
+ return document.querySelector('.hvac-page-wrapper') !== null;
+ });
+ console.log('- Has .hvac-page-wrapper:', hasWrapper);
+
+ // Check for main content
+ const hasMain = await page.evaluate(() => {
+ return document.querySelector('#main') !== null;
+ });
+ console.log('- Has #main:', hasMain);
+
+ // Check what's actually in the main area
+ const mainContent = await page.evaluate(() => {
+ const main = document.querySelector('#main, .site-main, .content-area');
+ if (main) {
+ return {
+ tagName: main.tagName,
+ id: main.id,
+ className: main.className,
+ innerHTMLLength: main.innerHTML.length,
+ firstChars: main.innerHTML.substring(0, 200)
+ };
+ }
+ return null;
+ });
+ console.log('\nš Main Content Area:', mainContent);
+
+ // Check if WordPress thinks this is a page
+ const isPage = await page.evaluate(() => {
+ const bodyClasses = document.body.className;
+ return {
+ hasPageClass: bodyClasses.includes('page'),
+ hasPageId: /page-id-\d+/.test(bodyClasses),
+ pageId: bodyClasses.match(/page-id-(\d+)/)?.[1] || null,
+ hasTemplateClass: bodyClasses.includes('page-template'),
+ templateClass: bodyClasses.match(/page-template-[\w-]+/)?.[0] || null
+ };
+ });
+ console.log('\nš WordPress Page Detection:', isPage);
+
+ // Take a screenshot for visual reference
+ await page.screenshot({
+ path: '/tmp/playwright-mcp-output/master-dashboard-debug.png',
+ fullPage: false
+ });
+ console.log('\nšø Screenshot saved to /tmp/playwright-mcp-output/master-dashboard-debug.png');
+
+ // Keep browser open for manual inspection
+ console.log('\nš Keeping browser open for 15 seconds...');
+ await page.waitForTimeout(15000);
+
+ } catch (error) {
+ console.error('Error during testing:', error);
+ } finally {
+ await browser.close();
+ console.log('ā
Test completed');
+ }
+})();
\ No newline at end of file