upskill-event-manager/templates/page-find-trainer.php
bengizmo 705e6b563c feat: Implement Training Leads system and restructure navigation menu
- 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>
2025-08-05 16:02:57 -03:00

655 lines
No EOL
31 KiB
PHP

<?php
/**
* Template Name: Find a Trainer
* Template for displaying the Find a Trainer page
*
* @package HVAC_Plugin
* @since 1.0.0
*/
// Define constant to identify we're in a page template
define('HVAC_IN_PAGE_TEMPLATE', true);
// Get header
get_header();
// Initialize required classes
if (class_exists('HVAC_Find_Trainer_Page')) {
$find_trainer = HVAC_Find_Trainer_Page::get_instance();
}
if (class_exists('HVAC_Trainer_Directory_Query')) {
$directory_query = HVAC_Trainer_Directory_Query::get_instance();
}
// Check if we have a direct profile URL pattern
$qr_generator = HVAC_QR_Generator::instance();
$direct_profile_id = $qr_generator->parse_profile_id_from_url();
$show_direct_profile = false;
$direct_profile_data = null;
if ($direct_profile_id) {
// Get the specific profile data
$direct_profile_data = $qr_generator->get_trainer_share_data($direct_profile_id);
if ($direct_profile_data) {
$show_direct_profile = true;
// Get additional profile data for full display
$profile_post = get_post($direct_profile_id);
$user_id = get_post_meta($direct_profile_id, 'user_id', true);
$user = get_userdata($user_id);
// Get profile metadata
$profile_meta = [];
if ($profile_post) {
$all_meta = get_post_meta($direct_profile_id);
foreach ($all_meta as $key => $value) {
$profile_meta[$key] = is_array($value) ? $value[0] : $value;
}
}
// Get event count
$event_count = 0;
if ($user_id && function_exists('tribe_get_events')) {
$events = tribe_get_events([
'author' => $user_id,
'eventDisplay' => 'all',
'posts_per_page' => -1,
'fields' => 'ids'
]);
$event_count = count($events);
}
// Get upcoming events
$upcoming_events = [];
if ($user_id && function_exists('tribe_get_events')) {
$events = tribe_get_events([
'author' => $user_id,
'eventDisplay' => 'list',
'posts_per_page' => 5,
'start_date' => 'now'
]);
foreach ($events as $event) {
$upcoming_events[] = [
'title' => $event->post_title,
'date' => tribe_get_start_date($event->ID, false, 'M j, Y'),
'url' => get_permalink($event->ID)
];
}
}
// Add additional data to the profile data array
$direct_profile_data['profile_meta'] = $profile_meta;
$direct_profile_data['user'] = $user;
$direct_profile_data['event_count'] = $event_count;
$direct_profile_data['upcoming_events'] = $upcoming_events;
$direct_profile_data['profile_content'] = $profile_post ? $profile_post->post_content : '';
}
}
// Get trainers for initial display with user status filtering
$trainers = [];
$total_pages = 1;
// Get approved user IDs first
$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)) {
// Query trainer profiles for approved users only
$args = [
'post_type' => 'trainer_profile',
'posts_per_page' => 12,
'post_status' => 'publish',
'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);
$total_pages = $query->max_num_pages;
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$profile_id = get_the_ID();
$user_id = get_post_meta($profile_id, 'user_id', true);
// Get real event count for this trainer
$event_count = 0;
if ($user_id && function_exists('tribe_get_events')) {
$events = tribe_get_events([
'author' => $user_id,
'eventDisplay' => 'all',
'posts_per_page' => -1,
'fields' => 'ids'
]);
$event_count = count($events);
}
$trainers[] = [
'profile_id' => $profile_id,
'user_id' => $user_id,
'name' => get_post_meta($profile_id, 'trainer_display_name', true),
'city' => get_post_meta($profile_id, 'trainer_city', true),
'state' => get_post_meta($profile_id, 'trainer_state', true),
'certification' => get_post_meta($profile_id, 'certification_type', true),
'profile_image' => get_post_meta($profile_id, 'profile_image_url', true),
'event_count' => $event_count
];
}
}
wp_reset_postdata();
// Sort trainers: Certified measureQuick Trainers first, Champions last
usort($trainers, function($a, $b) {
$a_cert = $a['certification'];
$b_cert = $b['certification'];
// Define sort order: Trainers = 1, Champions = 2, Others = 3
$a_priority = 3; // Default for others
$b_priority = 3; // Default for others
if ($a_cert === 'Certified measureQuick Trainer') {
$a_priority = 1;
} elseif ($a_cert === 'Certified measureQuick Champion') {
$a_priority = 2;
}
if ($b_cert === 'Certified measureQuick Trainer') {
$b_priority = 1;
} elseif ($b_cert === 'Certified measureQuick Champion') {
$b_priority = 2;
}
// Primary sort by certification priority
if ($a_priority !== $b_priority) {
return $a_priority - $b_priority;
}
// Secondary sort by name (alphabetical)
return strcasecmp($a['name'], $b['name']);
});
}
// Enqueue required scripts and styles
wp_enqueue_style('hvac-find-trainer', HVAC_PLUGIN_URL . 'assets/css/find-trainer.css', [], HVAC_VERSION);
wp_enqueue_script('hvac-find-trainer', HVAC_PLUGIN_URL . 'assets/js/find-trainer.js', ['jquery'], HVAC_VERSION, true);
wp_enqueue_style('dashicons');
// Enqueue profile sharing assets if showing direct profile
if ($show_direct_profile) {
wp_enqueue_style('hvac-profile-sharing', HVAC_PLUGIN_URL . 'assets/css/hvac-profile-sharing.css', ['hvac-find-trainer'], HVAC_VERSION);
wp_enqueue_script('hvac-profile-sharing', HVAC_PLUGIN_URL . 'assets/js/hvac-profile-sharing.js', ['jquery', 'hvac-find-trainer'], HVAC_VERSION, true);
// Localize sharing script with nonce and AJAX URL
wp_localize_script('hvac-profile-sharing', 'hvac_sharing', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('hvac_profile_sharing'),
'profile_id' => $direct_profile_id
]);
}
// Localize script with necessary data
wp_localize_script('hvac-find-trainer', 'hvac_find_trainer', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('hvac_find_trainer'),
'map_id' => '5872',
'direct_profile_id' => $direct_profile_id ?: null,
'show_direct_profile' => $show_direct_profile,
'messages' => [
'loading' => __('Loading...', 'hvac'),
'error' => __('An error occurred. Please try again.', 'hvac'),
'no_results' => __('No trainers found matching your criteria.', 'hvac'),
'form_error' => __('Please check the form and try again.', 'hvac'),
'form_success' => __('Your message has been sent! Check your inbox for more details.', 'hvac')
]
]);
?>
<div class="hvac-find-trainer-page">
<div class="ast-container">
<!-- Page Title -->
<h1 class="hvac-page-title"><?php echo $show_direct_profile ? 'Trainer Profile' : 'Find a Trainer'; ?></h1>
<!-- Direct Profile Display -->
<?php if ($show_direct_profile && $direct_profile_data): ?>
<div class="hvac-direct-profile-container">
<div class="hvac-direct-profile-header">
<a href="<?php echo esc_url(remove_query_arg('', get_permalink())); ?>" class="hvac-back-to-directory">
<span class="dashicons dashicons-arrow-left-alt2"></span> Back to Trainer Directory
</a>
</div>
<!-- Full Trainer Profile Display -->
<div class="hvac-trainer-profile-full">
<!-- Profile Header Section -->
<div class="hvac-trainer-profile-header">
<div class="hvac-trainer-image-section">
<?php if (!empty($direct_profile_data['profile_image'])): ?>
<img src="<?php echo esc_url($direct_profile_data['profile_image']); ?>" alt="<?php echo esc_attr($direct_profile_data['trainer_name']); ?>" class="hvac-trainer-main-image">
<?php else: ?>
<div class="hvac-trainer-avatar-large">
<span class="dashicons dashicons-businessperson"></span>
</div>
<?php endif; ?>
<!-- mQ Certified Badge -->
<?php if ($direct_profile_data['certification_type'] === 'Certified measureQuick Trainer'): ?>
<div class="hvac-mq-badge-overlay">
<img src="/wp-content/uploads/2025/08/mQ-Certified-trainer.png" alt="measureQuick Certified Trainer" class="hvac-mq-badge">
</div>
<?php endif; ?>
</div>
<div class="hvac-trainer-header-info">
<h2 class="hvac-trainer-name"><?php echo esc_html($direct_profile_data['trainer_name']); ?></h2>
<p class="hvac-trainer-location">
<?php echo esc_html($direct_profile_data['trainer_city'] . ', ' . $direct_profile_data['trainer_state']); ?>
</p>
<p class="hvac-trainer-certification"><?php echo esc_html($direct_profile_data['certification_type'] ?: 'HVAC Trainer'); ?></p>
<?php if (!empty($direct_profile_data['business_name'])): ?>
<p class="hvac-trainer-business"><?php echo esc_html($direct_profile_data['business_name']); ?></p>
<?php endif; ?>
<p class="hvac-trainer-events-stat">Total Training Events: <strong><?php echo esc_html($direct_profile_data['event_count']); ?></strong></p>
</div>
</div>
<!-- Training Details Section -->
<div class="hvac-trainer-details-section">
<h3>Training Information</h3>
<div class="hvac-training-details-grid">
<?php
$profile_meta = $direct_profile_data['profile_meta'] ?? [];
$training_formats = $profile_meta['training_formats'] ?? 'In-Person, Virtual';
$training_locations = $profile_meta['training_locations'] ?? 'On-site, Remote';
?>
<div class="hvac-training-detail">
<strong>Training Formats:</strong>
<span><?php echo esc_html($training_formats); ?></span>
</div>
<div class="hvac-training-detail">
<strong>Training Locations:</strong>
<span><?php echo esc_html($training_locations); ?></span>
</div>
<?php if (!empty($profile_meta['training_audience'])): ?>
<div class="hvac-training-detail">
<strong>Training Audience:</strong>
<span><?php echo esc_html($profile_meta['training_audience']); ?></span>
</div>
<?php endif; ?>
<?php if (!empty($profile_meta['years_experience'])): ?>
<div class="hvac-training-detail">
<strong>Years Experience:</strong>
<span><?php echo esc_html($profile_meta['years_experience']); ?> years</span>
</div>
<?php endif; ?>
</div>
</div>
<!-- Upcoming Events Section -->
<div class="hvac-upcoming-events-section">
<h3>Upcoming Events</h3>
<?php if (!empty($direct_profile_data['upcoming_events'])): ?>
<ul class="hvac-events-list">
<?php foreach ($direct_profile_data['upcoming_events'] as $event): ?>
<li>
<a href="<?php echo esc_url($event['url']); ?>" target="_blank">
<?php echo esc_html($event['title']); ?>
</a>
- <?php echo esc_html($event['date']); ?>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>No upcoming events scheduled</p>
<?php endif; ?>
</div>
<!-- About Section -->
<?php if (!empty($direct_profile_data['profile_content'])): ?>
<div class="hvac-trainer-about-section">
<h3>About</h3>
<div class="hvac-trainer-bio">
<?php echo wp_kses_post(wpautop($direct_profile_data['profile_content'])); ?>
</div>
</div>
<?php endif; ?>
<!-- Contact Section -->
<div class="hvac-contact-section">
<h3>Contact</h3>
<form id="hvac-direct-contact-form" class="hvac-contact-form">
<div class="hvac-form-row">
<input type="text" name="first_name" placeholder="First Name" required>
<input type="text" name="last_name" placeholder="Last Name" required>
</div>
<div class="hvac-form-row">
<input type="email" name="email" placeholder="Email" required>
<input type="tel" name="phone" placeholder="Phone Number">
</div>
<div class="hvac-form-row">
<input type="text" name="city" placeholder="City">
<input type="text" name="state_province" placeholder="State/Province">
</div>
<div class="hvac-form-full">
<input type="text" name="company" placeholder="Company">
</div>
<div class="hvac-form-full">
<textarea name="message" placeholder="Message" rows="4"></textarea>
</div>
<input type="hidden" name="trainer_id" value="<?php echo esc_attr($direct_profile_data['user_id']); ?>">
<input type="hidden" name="trainer_profile_id" value="<?php echo esc_attr($direct_profile_id); ?>">
<button type="submit" class="hvac-form-submit">Send Message</button>
</form>
<!-- Success/Error Messages -->
<div class="hvac-form-message hvac-form-success" style="display: none;">
Your message has been sent! Check your inbox for more details.
</div>
<div class="hvac-form-message hvac-form-error" style="display: none;">
There was an error sending your message. Please try again.
</div>
</div>
</div>
</div>
<?php endif; ?>
<!-- Container 1: Summary (hidden for direct profiles) -->
<?php if (!$show_direct_profile): ?>
<div class="hvac-summary-container">
<p>Upskill HVAC is proud to be the only training body offering Certified measureQuick training.</p>
<p><strong>Certified measureQuick Trainers</strong> have demonstrated their skills and mastery of HVAC science and the measureQuick app, and are authorized to provide measureQuick training to the industry.</p>
<p><strong>measureQuick Certified Champions</strong> have also demonstrated mastery of HVAC science and the measureQuick app, but they do not offer public training.</p>
<p>Use the interactive map and filters below to discover trainers who match your specific needs. Click on any <strong>Certified measureQuick Trainer</strong> to view their profile and contact them directly about training opportunities.</p>
</div>
<?php endif; ?>
<!-- Container 2: Map & Filters (hidden for direct profiles) -->
<?php if (!$show_direct_profile): ?>
<div class="hvac-map-filters-container">
<!-- Container 3: Map (2/3 width) -->
<div class="hvac-map-section">
<?php
// Display MapGeo map
if (shortcode_exists('display-map')) {
echo do_shortcode('[display-map id="5872"]');
} else {
// Fallback if MapGeo is not installed
?>
<div class="hvac-map-placeholder" style="height: 450px; background: #f5f5f5; display: flex; align-items: center; justify-content: center; color: #666;">
<p>Map plugin not installed</p>
</div>
<?php
}
?>
</div>
<!-- Container 4: Filters (1/3 width) -->
<div class="hvac-filters-section">
<!-- Search Box -->
<div class="hvac-search-box">
<input type="text" id="hvac-trainer-search" placeholder="Search..." aria-label="Search trainers">
<span class="dashicons dashicons-search"></span>
</div>
<!-- Filter Label with Clear Button -->
<div class="hvac-filters-header">
<span class="hvac-filters-label">Filters:</span>
<button class="hvac-clear-filters" type="button" style="display: none;">
Clear All
</button>
</div>
<!-- Filter Buttons -->
<button class="hvac-filter-btn" data-filter="state" type="button">
State / Province
<span class="dashicons dashicons-arrow-down-alt2"></span>
</button>
<button class="hvac-filter-btn" data-filter="business_type" type="button">
Business Type
<span class="dashicons dashicons-arrow-down-alt2"></span>
</button>
<button class="hvac-filter-btn" data-filter="training_format" type="button">
Training Format
<span class="dashicons dashicons-arrow-down-alt2"></span>
</button>
<button class="hvac-filter-btn" data-filter="training_resources" type="button">
Training Resources
<span class="dashicons dashicons-arrow-down-alt2"></span>
</button>
<!-- Active Filters Display -->
<div class="hvac-active-filters"></div>
</div>
</div>
<?php endif; ?>
<!-- Container 5: Trainer Directory (hidden for direct profiles) -->
<?php if (!$show_direct_profile): ?>
<div class="hvac-trainer-directory-container">
<div class="hvac-trainer-grid">
<?php if (!empty($trainers)) : ?>
<?php foreach ($trainers as $trainer) :
// Get featured image or use default avatar
$featured_image = !empty($trainer['profile_image']) ? $trainer['profile_image'] : false;
?>
<div class="hvac-trainer-card<?php
if ($trainer['certification'] === 'Certified measureQuick Champion') {
echo ' hvac-champion-card';
} elseif ($trainer['certification'] === 'Certified measureQuick Trainer') {
echo ' hvac-trainer-card-certified';
}
?>" data-profile-id="<?php echo esc_attr($trainer['profile_id']); ?>" data-event-count="<?php echo esc_attr($trainer['event_count']); ?>">
<div class="hvac-trainer-card-content">
<!-- Featured Image -->
<div class="hvac-trainer-image">
<?php if ($featured_image) : ?>
<img src="<?php echo esc_url($featured_image); ?>" alt="<?php echo esc_attr($trainer['name']); ?>">
<?php else : ?>
<div class="hvac-trainer-avatar">
<span class="dashicons dashicons-businessperson"></span>
</div>
<?php endif; ?>
<!-- mQ Certified Trainer Badge Overlay -->
<?php if ($trainer['certification'] === 'Certified measureQuick Trainer') : ?>
<div class="hvac-mq-badge-overlay">
<img src="/wp-content/uploads/2025/08/mQ-Certified-trainer.png" alt="measureQuick Certified Trainer" class="hvac-mq-badge">
</div>
<?php endif; ?>
</div>
<!-- Trainer Info -->
<div class="hvac-trainer-details">
<!-- Name (conditional clickable) -->
<h3 class="hvac-trainer-name">
<?php if ($trainer['certification'] === 'Certified measureQuick Champion') : ?>
<!-- Champions are not clickable -->
<span class="hvac-champion-name"><?php echo esc_html($trainer['name']); ?></span>
<?php else : ?>
<!-- Trainers are clickable -->
<a href="#" class="hvac-open-profile" data-profile-id="<?php echo esc_attr($trainer['profile_id']); ?>">
<?php echo esc_html($trainer['name']); ?>
</a>
<?php endif; ?>
</h3>
<!-- Location -->
<p class="hvac-trainer-location">
<?php echo esc_html($trainer['city']); ?>, <?php echo esc_html($trainer['state']); ?>
</p>
<!-- Certification -->
<p class="hvac-trainer-certification">
<?php echo esc_html($trainer['certification'] ?: 'HVAC Trainer'); ?>
</p>
<!-- See Events (hidden for v1) -->
<!--
<a href="#" class="hvac-see-events" data-trainer-id="<?php echo esc_attr($trainer['user_id']); ?>">
<span class="dashicons dashicons-calendar-alt"></span> See Events
</a>
-->
</div>
</div>
</div>
<?php endforeach; ?>
<?php else : ?>
<div class="hvac-no-trainers">
<p>No trainers found. Please try adjusting your search or filters.</p>
</div>
<?php endif; ?>
</div>
<!-- Pagination -->
<?php if ($total_pages > 1) : ?>
<div class="hvac-pagination">
<?php
echo paginate_links([
'total' => $total_pages,
'current' => 1,
'prev_text' => '&laquo;',
'next_text' => '&raquo;',
'type' => 'plain'
]);
?>
</div>
<?php endif; ?>
</div>
<!-- Container 6: CTA Section (hidden for direct profiles) -->
<?php endif; ?>
<?php if (!$show_direct_profile): ?>
<div class="hvac-cta-container">
<p class="hvac-cta-text">Are you an HVAC Trainer that wants to be listed in our directory?</p>
<a href="/trainer-registration/" class="hvac-cta-button">Become A Trainer</a>
</div>
<?php endif; ?>
</div>
</div>
<!-- Filter Modal Template -->
<div id="hvac-filter-modal" class="hvac-filter-modal" style="display: none;">
<div class="hvac-filter-modal-content">
<h3 class="hvac-filter-modal-title"></h3>
<div class="hvac-filter-options"></div>
<button class="hvac-filter-apply">Apply</button>
</div>
</div>
<!-- Trainer Profile Modal Template -->
<div id="hvac-trainer-modal" class="hvac-trainer-modal" style="display: none;">
<div class="hvac-trainer-modal-content">
<!-- Close Button -->
<button class="hvac-modal-close" aria-label="Close">
<span class="dashicons dashicons-no"></span>
</button>
<!-- Modal Title -->
<h2 class="hvac-modal-title">[Trainer Name]</h2>
<!-- Container 1: Profile Info -->
<div class="hvac-modal-profile">
<div class="hvac-modal-image">
<img src="" alt="">
</div>
<div class="hvac-modal-info">
<p class="hvac-modal-location">[trainer_city], [trainer_state]</p>
<p class="hvac-modal-certification">[certification_type]</p>
<p class="hvac-modal-business">[business_type]</p>
<p class="hvac-modal-events">Total Training Events: <span>[#]</span></p>
</div>
</div>
<!-- Container 2: Training Details -->
<div class="hvac-modal-training">
<div class="hvac-training-row">
<strong>Training Formats:</strong> <span class="hvac-training-formats">[training_formats]</span>
</div>
<div class="hvac-training-row">
<strong>Training Locations:</strong> <span class="hvac-training-locations">[training_locations]</span>
</div>
<div class="hvac-training-events">
<strong>Upcoming Events:</strong>
<ul class="hvac-events-list">
<!-- Events populated via JS -->
</ul>
</div>
</div>
<!-- Container 3: Contact Form -->
<div class="hvac-modal-contact">
<h3>Contact</h3>
<form id="hvac-contact-form" class="hvac-contact-form">
<div class="hvac-form-row">
<input type="text" name="first_name" placeholder="First Name" required>
<input type="text" name="last_name" placeholder="Last Name" required>
</div>
<div class="hvac-form-row">
<input type="email" name="email" placeholder="Email" required>
<input type="tel" name="phone" placeholder="Phone Number">
</div>
<div class="hvac-form-row">
<input type="text" name="city" placeholder="City">
<input type="text" name="state_province" placeholder="State/Province">
</div>
<div class="hvac-form-full">
<input type="text" name="company" placeholder="Company">
</div>
<div class="hvac-form-full">
<textarea name="message" placeholder="Message" rows="4"></textarea>
</div>
<input type="hidden" name="trainer_id" value="">
<input type="hidden" name="trainer_profile_id" value="">
<button type="submit" class="hvac-form-submit">Submit</button>
</form>
<!-- Success/Error Messages -->
<div class="hvac-form-message hvac-form-success" style="display: none;">
Your message has been sent! Check your inbox for more details.
</div>
<div class="hvac-form-message hvac-form-error" style="display: none;">
There was an error sending your message. Please try again.
</div>
</div>
</div>
</div>
<?php
// Get footer
get_footer();
?>