- Add comprehensive Training Leads system for HVAC trainers * New /trainer/training-leads/ page with tabular contact submission display * HVAC_Training_Leads class with AJAX status updates and filtering * Empty state messaging and profile sharing CTA * Database integration with existing contact forms system - Restructure trainer navigation menu for better UX * Rename "Customize" to "Profile" with logical groupings * Move "Logout" under "Profile" submenu * Change "Personal Profile" to "Trainer Profile" * Add "Training Leads" under Profile section * Update help menu to show only question mark icon positioned far right - Enhance documentation system * Fix /trainer/documentation/ page styling and navigation integration * Update content to reflect current platform features * Add Training Leads documentation and navigation guide * Implement proper WordPress template structure - Update user management * Change joe@upskillhvac.com display name to "Joe Medosch" * Assign Joe as author of measureQuick headquarters venue * Assign Joe as author of measureQuick and Upskill HVAC organizers 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
	
	
		
			27 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	HVAC Trainer System Documentation
This document provides comprehensive documentation for all functionality related to the HVAC Trainer custom post type and Find A Trainer page in the HVAC Community Events plugin.
Table of Contents
- System Overview
- Trainer Profile Custom Post Type
- Find A Trainer Page
- MapGeo Integration
- User Roles & Permissions
- API Reference
- Frontend Components
- Database Schema
- Performance Optimizations
- Troubleshooting
System Overview
The HVAC Trainer System is a comprehensive solution for managing trainer profiles and providing a public directory with interactive map functionality. The system consists of:
- Custom Post Type: trainer_profilefor storing trainer information
- Find A Trainer Page: Public-facing directory with search and filtering
- MapGeo Integration: Interactive map with trainer markers and modals
- Profile Management: Complete CRUD operations for trainer profiles
- Taxonomy System: Categorization for business types, training formats, etc.
Architecture Diagram
WordPress Users (hvac_trainer/hvac_master_trainer)
    ↓
Trainer Profile Custom Post Type (trainer_profile)
    ↓
Find A Trainer Page ← MapGeo Integration → Interactive Map
    ↓
Search/Filter System → AJAX Handlers → Database Queries
Trainer Profile Custom Post Type
Overview
The trainer_profile custom post type stores comprehensive information about HVAC trainers, including personal details, certifications, business information, and location data.
Core Files
- Main Handler: includes/class-hvac-trainer-profile-manager.php
- Settings: includes/class-hvac-trainer-profile-settings.php
- Status Management: includes/class-hvac-trainer-status.php
Custom Fields Reference
Personal Information
| Field Name | Type | Description | Example | 
|---|---|---|---|
| trainer_first_name | string | First name | "John" | 
| trainer_last_name | string | Last name | "Smith" | 
| trainer_display_name | string | Public display name | "John Smith" | 
| trainer_city | string | City location | "Chicago" | 
| trainer_state | string | State/Province | "Illinois" | 
| trainer_country | string | Country | "USA" | 
| profile_image_url | string | Profile photo URL | "https://..." | 
| linkedin_profile_url | string | LinkedIn profile | "https://linkedin..." | 
Certification Details
| Field Name | Type | Description | Values | 
|---|---|---|---|
| certification_type | string | Certification level | "Certified measureQuick Trainer", "Certified measureQuick Champion" | 
| certification_status | string | Current status | "Active", "Expired", "Pending", "Disabled" | 
| certification_color | string | Hex color for MapGeo | "#5077bb", "#f19a42", "#f0f7e8" | 
| date_certified | string | Certification date | "2024-01-15" | 
| personal_accreditation | string | Additional certifications | Free text | 
Business Information
| Field Name | Type | Description | 
|---|---|---|
| annual_revenue_target | string | Revenue goals | 
| application_details | string | Registration application details | 
System Fields
| Field Name | Type | Description | 
|---|---|---|
| user_id | integer | WordPress user ID | 
| is_public_profile | string | Visibility flag ("1" or "0") | 
| _last_geocode_attempt | string | Last geocoding timestamp | 
| geocoded_lat | string | Latitude coordinate | 
| geocoded_lng | string | Longitude coordinate | 
Taxonomies
Business Type (business_type)
- Manufacturer
- Distributor
- Contractor
- Consultant
- Educator
- Government
- Other
Training Audience (training_audience)
- Anyone (open to the public)
- Industry professionals
- Internal staff in my company
- Registered students/members of my org/institution
Training Formats (training_formats)
- In-person
- Virtual
- Hybrid
- On-demand
Training Locations (training_locations)
- Online
- Local
- Regional Travel
- National Travel
- International Travel
Training Resources (training_resources)
- Classroom
- Training Lab
- Ducted Furnace(s)
- Ducted Air Handler(s)
- Ducted Air Conditioner(s)
- Ducted Heat Pump(s)
- Ductless Heat Pump(s)
- Training Manuals
- Presentation Slides
- LMS Platform / SCORM Files
- Custom Curriculum
- Other
Profile Creation Workflow
- User Registration: User completes registration form
- Role Assignment: User assigned hvac_trainerorhvac_master_trainerrole
- Profile Creation: System automatically creates trainer_profilepost
- Data Population: Registration data mapped to profile fields
- Geocoding: System attempts to geocode trainer location
- Approval Process: Admin reviews and approves profile for public display
Profile Management
Creating Profiles Programmatically
$profile_manager = HVAC_Trainer_Profile_Manager::get_instance();
$profile_data = [
    'trainer_first_name' => 'John',
    'trainer_last_name' => 'Smith',
    'trainer_city' => 'Chicago',
    'trainer_state' => 'Illinois',
    'certification_type' => 'Certified measureQuick Trainer',
    'user_id' => 123,
    'is_public_profile' => '1'
];
$profile_id = $profile_manager->create_profile($profile_data);
Updating Profiles
$profile_manager->update_profile($profile_id, $updated_data);
Retrieving Profiles
// Get single profile
$profile = $profile_manager->get_profile($profile_id);
// Get all public profiles
$public_profiles = $profile_manager->get_public_profiles();
// Get profiles by criteria
$filtered_profiles = $profile_manager->get_profiles_by_criteria([
    'state' => 'Illinois',
    'certification_type' => 'Certified measureQuick Trainer'
]);
Find A Trainer Page
Overview
The Find A Trainer page (/find-a-trainer/) provides a public directory of approved trainer profiles with interactive search, filtering, and map functionality.
Core Files
- Page Handler: includes/find-trainer/class-hvac-find-trainer-page.php
- Directory Query: includes/find-trainer/class-hvac-trainer-directory-query.php
- Contact Handler: includes/find-trainer/class-hvac-contact-form-handler.php
- Template: templates/page-find-trainer.php
Features
Search Functionality
- Text Search: Search by trainer name, city, or state
- Real-time Results: AJAX-powered instant search results
- Autocomplete: Suggestions as user types
Filtering System
- State/Province Filter: Location-based filtering
- Business Type Filter: Filter by trainer business type
- Training Format Filter: Filter by available training formats
- Training Resources Filter: Filter by available resources
- Multiple Filters: Combine multiple filter criteria
Directory Display
- Card Layout: Clean trainer cards with essential information
- Pagination: Performance-optimized pagination system
- Sorting: Certified Trainers first, then Champions, then alphabetical
- Champion Distinction: Special styling for measureQuick Champions
Contact Integration
- Contact Forms: Direct contact forms for each trainer
- Email Integration: Automated email delivery to trainers
- Lead Tracking: Track contact form submissions
AJAX Endpoints
| Endpoint | Purpose | Parameters | 
|---|---|---|
| hvac_filter_trainers | Filter trainers | filters,page,per_page | 
| hvac_search_trainers | Search trainers | search,page,per_page | 
| hvac_get_filter_options | Get filter options | None | 
| hvac_submit_contact_form | Submit contact form | trainer_id,name,email,message | 
Frontend Implementation
JavaScript Integration
// Initialize Find A Trainer functionality
jQuery(document).ready(function($) {
    HVAC_FindTrainer.init({
        ajax_url: hvac_find_trainer.ajax_url,
        nonce: hvac_find_trainer.nonce,
        filters: {
            state: [],
            business_type: [],
            training_format: []
        }
    });
});
CSS Classes
| Class | Purpose | 
|---|---|
| .hvac-trainer-card | Individual trainer card container | 
| .hvac-trainer-card-certified | Certified trainer styling | 
| .hvac-champion-card | Champion trainer styling | 
| .hvac-trainer-filters | Filter panel container | 
| .hvac-search-box | Search input container | 
| .hvac-trainer-modal | Trainer profile modal | 
MapGeo Integration
Overview
The MapGeo integration provides an interactive map showing trainer locations with clickable markers that open detailed trainer modals.
Core Files
- Integration Handler: includes/find-trainer/class-hvac-mapgeo-integration.php
- Map Configuration: Integrated in Find A Trainer page template
Features
Interactive Map
- Map ID: 5872 (configured in MapGeo plugin)
- Marker Display: Trainers with geocoded coordinates appear as markers
- Color Coding: Different colors based on certification type
- Click Handlers: Custom click actions for trainer markers
Performance Optimizations
- Request Deduplication: Prevents duplicate AJAX calls
- Caching System: Caches trainer data for instant subsequent access
- Click Throttling: Prevents rapid-fire clicking issues
- Fallback Handling: Graceful degradation when data unavailable
Modal System
- Trainer Profiles: Complete trainer information in popup modals
- Champion Filtering: Champions don't show modals (directory-only display)
- Contact Integration: Direct contact forms within modals
- Responsive Design: Mobile-optimized modal display
Technical Implementation
MapGeo Marker Configuration
public function modify_map_layout($meta, $map_id = null) {
    // Only process for our specific map (5872)
    if ($map_id && $map_id != $this->map_id) {
        return $meta;
    }
    
    // Configure markers with trainer profile data
    foreach ($meta['markers'] as &$marker) {
        $trainer_profile_id = $this->find_trainer_profile_by_name($marker['title']);
        if ($trainer_profile_id) {
            $marker['action'] = 'hvac_show_trainer_modal';
            $marker['hvac_profile_id'] = $trainer_profile_id;
            $marker['id'] = 'trainer_' . $trainer_profile_id;
        }
    }
    
    return $meta;
}
JavaScript Modal Handler
window.hvac_show_trainer_modal = function(markerData) {
    var profileId = markerData.hvac_profile_id;
    
    // Check cache first for immediate response
    if (window.hvacTrainerDataCache[profileId]) {
        var cachedData = window.hvacTrainerDataCache[profileId];
        if (typeof window.showTrainerModal === 'function') {
            window.showTrainerModal(cachedData);
        }
        return;
    }
    
    // Fetch profile data via AJAX if not cached
    // Implementation handles caching, error handling, and modal display
};
Certification Color Coding
| Certification Type | Color | Usage | 
|---|---|---|
| Certified measureQuick Trainer | #5077bb | Primary trainer markers | 
| Certified measureQuick Champion | #f19a42 | Champion markers (no modals) | 
| Default/Other | #f0f7e8 | Fallback color | 
User Roles & Permissions
HVAC Trainer (hvac_trainer)
Core Capabilities
- read- Basic WordPress read access
- upload_files- File upload capability
- edit_hvac_profile- Edit own trainer profile
- view_hvac_dashboard- Access trainer dashboard
- manage_hvac_events- Manage own events
- manage_attendees- Manage event attendees
- email_attendees- Send emails to attendees
Events Calendar Integration
- publish_tribe_events- Create and publish events
- edit_tribe_events- Edit events
- delete_tribe_events- Delete events
- edit_published_tribe_events- Edit published events
- delete_published_tribe_events- Delete published events
- read_private_tribe_events- View private events
HVAC Master Trainer (hvac_master_trainer)
Extended Capabilities
- All trainer capabilities
- Access to master dashboard with analytics
- View aggregate trainer statistics
- Enhanced reporting capabilities
Permission Checks
// Check if user can edit trainer profiles
if (current_user_can('edit_hvac_profile')) {
    // Allow profile editing
}
// Check for master trainer capabilities
if (current_user_can('hvac_master_trainer')) {
    // Show master trainer features
}
API Reference
AJAX Handlers
Get Trainer Profile
Endpoint: hvac_get_trainer_profile
Method: POST
Parameters:
- profile_id(integer) - Trainer profile ID
- nonce(string) - Security nonce
Response:
{
    "success": true,
    "data": {
        "profile_id": 5840,
        "user_id": "31",
        "name": "Jeremy Begley",
        "city": "Knoxville",
        "state": "Tennessee",
        "certification_type": "Certified measureQuick Trainer",
        "profile_image": "https://...",
        "business_type": "Independent Contractor",
        "event_count": 5,
        "training_formats": "In-Person, Virtual",
        "training_locations": "On-site, Remote",
        "upcoming_events": []
    }
}
Filter Trainers
Endpoint: hvac_filter_trainers
Method: POST
Parameters:
- filters(array) - Filter criteria
- page(integer) - Page number
- per_page(integer) - Results per page
- nonce(string) - Security nonce
Response:
{
    "success": true,
    "data": {
        "html": "<div class='hvac-trainer-card'>...</div>",
        "pagination": "<div class='hvac-pagination'>...</div>",
        "count": 25,
        "page": 1,
        "max_pages": 3
    }
}
Search Trainers
Endpoint: hvac_search_trainers
Method: POST
Parameters:
- search(string) - Search query
- page(integer) - Page number
- per_page(integer) - Results per page
- nonce(string) - Security nonce
Response: Same format as filter trainers
PHP API Methods
HVAC_Trainer_Profile_Manager Methods
// Get instance
$manager = HVAC_Trainer_Profile_Manager::get_instance();
// Create profile
$profile_id = $manager->create_profile($data);
// Update profile
$manager->update_profile($profile_id, $data);
// Get profile
$profile = $manager->get_profile($profile_id);
// Get public profiles
$profiles = $manager->get_public_profiles();
// Delete profile
$manager->delete_profile($profile_id);
HVAC_Find_Trainer_Page Methods
// Get instance
$page = HVAC_Find_Trainer_Page::get_instance();
// Render trainer cards
$page->render_trainer_cards($trainers);
// Get filter options
$options = $page->get_filter_options();
// Build query args
$args = $page->build_query_args($filters);
Frontend Components
CSS Architecture
Find A Trainer Styles (assets/css/find-trainer.css)
/* Main container */
.hvac-find-trainer-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
}
/* Search and filters */
.hvac-search-filters {
    display: flex;
    gap: 20px;
    margin-bottom: 30px;
    flex-wrap: wrap;
}
/* Trainer cards */
.hvac-trainer-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 20px;
    margin-bottom: 30px;
}
.hvac-trainer-card {
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 20px;
    background: white;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    transition: transform 0.2s, box-shadow 0.2s;
}
.hvac-trainer-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
/* Certified trainer styling */
.hvac-trainer-card-certified {
    border-color: #5077bb;
}
.hvac-trainer-card-certified::before {
    content: "✓ Certified Trainer";
    background: #5077bb;
    color: white;
    padding: 4px 8px;
    border-radius: 4px;
    font-size: 12px;
    position: absolute;
    top: -8px;
    right: 10px;
}
/* Champion styling */
.hvac-champion-card {
    border-color: #f19a42;
    background: linear-gradient(135deg, #fff 0%, #fef9f5 100%);
}
.hvac-champion-card .hvac-trainer-name {
    color: #f19a42;
    font-weight: bold;
}
MapGeo Integration Styles
/* MapGeo modal styling */
.hvac-trainer-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: white;
    border-radius: 8px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.3);
    max-width: 500px;
    width: 90%;
    max-height: 80vh;
    overflow-y: auto;
    z-index: 10000;
}
.hvac-modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0,0,0,0.5);
    z-index: 9999;
}
/* Map markers */
.hvac-trainer-marker {
    cursor: pointer;
    transition: all 0.2s;
}
.hvac-trainer-marker:hover {
    transform: scale(1.1);
}
JavaScript Components
Find A Trainer JavaScript (assets/js/find-trainer.js)
var HVAC_FindTrainer = {
    // Configuration
    config: {
        ajax_url: '',
        nonce: '',
        filters: {},
        current_page: 1,
        per_page: 12
    },
    
    // Initialize
    init: function(options) {
        this.config = Object.assign(this.config, options);
        this.bindEvents();
        this.loadInitialResults();
    },
    
    // Event bindings
    bindEvents: function() {
        // Search functionality
        jQuery('#hvac-trainer-search').on('input', this.handleSearch.bind(this));
        
        // Filter changes
        jQuery('.hvac-filter-select').on('change', this.handleFilterChange.bind(this));
        
        // Pagination
        jQuery(document).on('click', '.hvac-page-link', this.handlePagination.bind(this));
        
        // Trainer card clicks
        jQuery(document).on('click', '.hvac-open-profile', this.openTrainerModal.bind(this));
    },
    
    // Handle search input
    handleSearch: function(e) {
        var query = jQuery(e.target).val();
        this.performSearch(query);
    },
    
    // Handle filter changes
    handleFilterChange: function(e) {
        var $filter = jQuery(e.target);
        var filterType = $filter.data('filter');
        var value = $filter.val();
        
        this.config.filters[filterType] = value;
        this.applyFilters();
    },
    
    // Perform AJAX search
    performSearch: function(query) {
        jQuery.ajax({
            url: this.config.ajax_url,
            method: 'POST',
            data: {
                action: 'hvac_search_trainers',
                search: query,
                page: 1,
                per_page: this.config.per_page,
                nonce: this.config.nonce
            },
            success: this.updateResults.bind(this)
        });
    },
    
    // Apply filters
    applyFilters: function() {
        jQuery.ajax({
            url: this.config.ajax_url,
            method: 'POST',
            data: {
                action: 'hvac_filter_trainers',
                filters: this.config.filters,
                page: 1,
                per_page: this.config.per_page,
                nonce: this.config.nonce
            },
            success: this.updateResults.bind(this)
        });
    },
    
    // Update results display
    updateResults: function(response) {
        if (response.success) {
            jQuery('.hvac-trainer-cards').html(response.data.html);
            jQuery('.hvac-pagination').html(response.data.pagination);
            this.updateResultsCount(response.data.count);
        }
    },
    
    // Open trainer modal
    openTrainerModal: function(e) {
        e.preventDefault();
        var profileId = jQuery(e.target).data('profile-id');
        this.showTrainerProfile(profileId);
    }
};
Database Schema
Trainer Profile Posts Table
-- wp_posts table entries for trainer_profile post type
SELECT 
    ID,
    post_title,
    post_status,
    post_type,
    post_date
FROM wp_posts 
WHERE post_type = 'trainer_profile';
Trainer Profile Meta Data
-- wp_postmeta table entries for trainer profiles
SELECT 
    post_id,
    meta_key,
    meta_value
FROM wp_postmeta 
WHERE post_id IN (
    SELECT ID FROM wp_posts WHERE post_type = 'trainer_profile'
)
ORDER BY post_id, meta_key;
Taxonomy Relationships
-- Get trainer profiles with business type taxonomy
SELECT 
    p.ID,
    p.post_title,
    t.name as business_type
FROM wp_posts p
LEFT JOIN wp_term_relationships tr ON p.ID = tr.object_id
LEFT JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN wp_terms t ON tt.term_id = t.term_id
WHERE p.post_type = 'trainer_profile'
AND tt.taxonomy = 'business_type';
Key Database Queries
Get Public Trainer Profiles
$args = [
    'post_type' => 'trainer_profile',
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'meta_query' => [
        'relation' => 'AND',
        [
            'key' => 'is_public_profile',
            'value' => '1',
            'compare' => '='
        ],
        [
            'key' => 'user_id',
            'value' => $approved_user_ids,
            'compare' => 'IN'
        ]
    ]
];
$query = new WP_Query($args);
Get Geocoded Trainers for Map
$args = [
    'post_type' => 'trainer_profile',
    'post_status' => 'publish',
    'posts_per_page' => -1,
    'meta_query' => [
        'relation' => 'AND',
        [
            'key' => 'is_public_profile',
            'value' => '1',
            'compare' => '='
        ],
        [
            'key' => 'geocoded_lat',
            'compare' => 'EXISTS'
        ],
        [
            'key' => 'geocoded_lng',
            'compare' => 'EXISTS'
        ]
    ]
];
Performance Optimizations
MapGeo Integration Optimizations
Request Deduplication
// Prevent duplicate AJAX requests
window.hvacTrainerDataCache = {};
window.hvacPendingRequests = {};
function getTrainerProfile(profileId) {
    // Check cache first
    if (window.hvacTrainerDataCache[profileId]) {
        return Promise.resolve(window.hvacTrainerDataCache[profileId]);
    }
    
    // Check if request already pending
    if (window.hvacPendingRequests[profileId]) {
        return window.hvacPendingRequests[profileId];
    }
    
    // Make new request and cache promise
    window.hvacPendingRequests[profileId] = makeAjaxRequest(profileId)
        .then(function(data) {
            window.hvacTrainerDataCache[profileId] = data;
            delete window.hvacPendingRequests[profileId];
            return data;
        });
    
    return window.hvacPendingRequests[profileId];
}
Click Throttling
// Prevent rapid-fire clicking
var lastClickTime = 0;
function handleMarkerClick(e) {
    var now = Date.now();
    if (now - lastClickTime < 500) {
        return; // Throttle clicks to 500ms intervals
    }
    lastClickTime = now;
    
    // Process click
    processMarkerClick(e);
}
Database Query Optimization
Efficient Trainer Queries
// Use meta_query for better performance with indexes
$args = [
    'post_type' => 'trainer_profile',
    'posts_per_page' => 12,
    'paged' => $page,
    'meta_query' => [
        'relation' => 'AND',
        [
            'key' => 'is_public_profile',
            'value' => '1',
            'compare' => '='
        ]
    ],
    'fields' => 'ids' // Only get IDs when possible
];
// Add user status filter efficiently
$user_query = new WP_User_Query([
    'meta_query' => [
        [
            'key' => 'account_status',
            'value' => ['approved', 'active', 'inactive'],
            'compare' => 'IN'
        ]
    ],
    'fields' => 'ID'
]);
$approved_user_ids = $user_query->get_results();
if (!empty($approved_user_ids)) {
    $args['meta_query'][] = [
        'key' => 'user_id',
        'value' => $approved_user_ids,
        'compare' => 'IN'
    ];
}
Caching Strategies
// Cache expensive queries
$cache_key = 'hvac_public_trainers_' . md5(serialize($args));
$trainers = wp_cache_get($cache_key, 'hvac_trainers');
if (false === $trainers) {
    $query = new WP_Query($args);
    $trainers = $query->posts;
    wp_cache_set($cache_key, $trainers, 'hvac_trainers', HOUR_IN_SECONDS);
}
Troubleshooting
Common Issues
Trainers Not Appearing on Map
Symptoms: Trainers visible in directory but not on MapGeo map Causes:
- Missing geocoding data (latitude/longitude)
- MapGeo configuration issues
- Profile not public
Solutions:
// Check geocoding status
$lat = get_post_meta($profile_id, 'geocoded_lat', true);
$lng = get_post_meta($profile_id, 'geocoded_lng', true);
if (empty($lat) || empty($lng)) {
    // Trigger geocoding
    $geocoding_service = HVAC_Geocoding_Service::get_instance();
    $geocoding_service->geocode_trainer($profile_id);
}
// Check public status
$is_public = get_post_meta($profile_id, 'is_public_profile', true);
if ($is_public !== '1') {
    update_post_meta($profile_id, 'is_public_profile', '1');
}
Modal Not Opening
Symptoms: Clicking map markers doesn't open trainer modal Causes:
- JavaScript errors preventing modal system
- Missing trainer data
- Champion profiles (intentionally no modal)
Solutions:
// Debug modal system
console.log('MapGeo integration loaded:', typeof window.hvac_show_trainer_modal);
console.log('Modal function available:', typeof window.showTrainerModal);
// Check if trainer is Champion (no modal should show)
if (trainerData.certification_type === 'Certified measureQuick Champion') {
    console.log('Champion detected - no modal shown');
    return;
}
Search/Filter Not Working
Symptoms: Search and filters not returning results Causes:
- AJAX endpoint errors
- Nonce verification failures
- Database query issues
Solutions:
// Debug AJAX handlers
add_action('wp_ajax_hvac_filter_trainers', function() {
    error_log('Filter trainers AJAX called');
    error_log('POST data: ' . print_r($_POST, true));
    
    // Verify nonce
    if (!wp_verify_nonce($_POST['nonce'], 'hvac_find_trainer')) {
        error_log('Nonce verification failed');
        wp_send_json_error('Invalid nonce');
        return;
    }
    
    // Continue with handler...
});
Performance Issues
Symptoms: Slow loading times, multiple AJAX requests Causes:
- Duplicate requests not prevented
- Missing caching
- Inefficient database queries
Solutions:
- Implement request deduplication
- Add caching layers
- Optimize database queries with proper indexes
- Use pagination for large datasets
Debug Mode
Enable debug logging for troubleshooting:
// Add to wp-config.php
define('HVAC_DEBUG', true);
// In plugin code
if (defined('HVAC_DEBUG') && HVAC_DEBUG) {
    error_log('HVAC Debug: ' . $message);
}
Performance Monitoring
Monitor system performance:
// Track AJAX request timing
var startTime = performance.now();
jQuery.ajax({
    // ... ajax config
    success: function(response) {
        var endTime = performance.now();
        console.log('AJAX request took:', (endTime - startTime), 'milliseconds');
    }
});
Conclusion
The HVAC Trainer System provides a comprehensive solution for managing trainer profiles and presenting them through an interactive Find A Trainer directory. The system is designed for performance, scalability, and user experience, with extensive customization options and robust error handling.
For additional support or feature requests, refer to the main plugin documentation or contact the development team.