upskill-event-manager/templates/page-trainer-dashboard.php
ben 054639c95c
Some checks failed
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Has been cancelled
Security Monitoring & Compliance / Secrets & Credential Scan (push) Has been cancelled
Security Monitoring & Compliance / WordPress Security Analysis (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Has been cancelled
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Has been cancelled
Security Monitoring & Compliance / Static Code Security Analysis (push) Has been cancelled
Security Monitoring & Compliance / Security Compliance Validation (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Has been cancelled
HVAC Plugin CI/CD Pipeline / Notification (push) Has been cancelled
Security Monitoring & Compliance / Security Summary Report (push) Has been cancelled
Security Monitoring & Compliance / Security Team Notification (push) Has been cancelled
feat: complete master trainer system transformation from 0% to 100% success
- Deploy 6 simultaneous WordPress specialized agents using sequential thinking and Zen MCP
- Resolve all critical issues: permissions, jQuery dependencies, CDN mapping, security vulnerabilities
- Implement bulletproof jQuery loading system with WordPress hook timing fixes
- Create professional MapGeo Safety system with CDN health monitoring and fallback UI
- Fix privilege escalation vulnerability with capability-based authorization
- Add complete announcement admin system with modal forms and AJAX handling
- Enhance import/export functionality (54 trainers successfully exported)
- Achieve 100% operational master trainer functionality verified via MCP Playwright E2E testing

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-02 16:41:51 -03:00

344 lines
No EOL
19 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Template Name: Trainer Dashboard
* Description: Template for the trainer dashboard page
*/
// Define constant to indicate we're in a page template
define('HVAC_IN_PAGE_TEMPLATE', true);
get_header();
?>
<div class="hvac-page-wrapper hvac-trainer-dashboard-page">
<?php
// Display trainer navigation menu
if (class_exists('HVAC_Menu_System')) {
HVAC_Menu_System::instance()->render_trainer_menu();
}
?>
<?php
// Display breadcrumbs
if (class_exists('HVAC_Breadcrumbs')) {
echo HVAC_Breadcrumbs::instance()->render_breadcrumbs();
}
?>
<div class="container">
<?php
// --- Security Check & Data Loading ---
// Ensure user is logged in and has access to the dashboard
if ( ! is_user_logged_in() ) {
// Redirect to login page if not logged in
wp_safe_redirect( home_url( '/training-login/' ) );
exit;
}
// Check if user has permission to view dashboard
// Check for HVAC trainer roles (not capabilities!)
$user = wp_get_current_user();
$has_trainer_role = in_array('hvac_trainer', $user->roles) || in_array('hvac_master_trainer', $user->roles);
if ( ! $has_trainer_role && ! current_user_can( 'manage_options' ) ) {
// Show access denied message instead of redirect to prevent loops
?>
<div class="hvac-access-denied">
<h1><?php _e('Access Denied', 'hvac-community-events'); ?></h1>
<p><?php _e('Sorry, you do not have permission to access the HVAC Trainer Dashboard.', 'hvac-community-events'); ?></p>
<p><?php _e('If you are an HVAC trainer, please contact an administrator to get the proper role assigned.', 'hvac-community-events'); ?></p>
<a href="<?php echo esc_url( home_url() ); ?>" class="button"><?php _e('Return to Home', 'hvac-community-events'); ?></a>
</div>
<?php
return;
}
// Get the current user ID
$user_id = get_current_user_id();
// Dashboard data class is loaded during plugin initialization
$dashboard_data = new HVAC_Dashboard_Data( $user_id );
// Fetch data
$total_events = $dashboard_data->get_total_events_count();
$upcoming_events = $dashboard_data->get_upcoming_events_count();
$past_events = $dashboard_data->get_past_events_count();
$total_sold = $dashboard_data->get_total_tickets_sold();
$total_revenue = $dashboard_data->get_total_revenue();
$revenue_target = $dashboard_data->get_annual_revenue_target();
?>
<div class="hvac-dashboard-wrapper"> <!-- Dashboard specific wrapper -->
<!-- Dashboard Header -->
<div class="hvac-dashboard-header">
<h1 class="entry-title">Trainer Dashboard</h1> <!-- Standard WP title class -->
</div>
<!-- Statistics Section -->
<section class="hvac-dashboard-stats">
<?php echo HVAC_Help_System::add_tooltip(
'<h2>Your Stats</h2>',
'Overview of your event performance and revenue metrics',
'bottom'
); ?>
<div class="hvac-stats-row"> <!-- Use flexbox row layout -->
<!-- Stat Card: Total Events -->
<div class="hvac-stat-col"> <!-- Equal width flexbox column -->
<div class="hvac-stat-card">
<?php echo HVAC_Help_System::add_tooltip(
'<h3>Total Events</h3>',
'All events you\'ve created, including drafts and published events'
); ?>
<p class="metric-value"><?php echo esc_html( $total_events ); ?></p>
</div>
</div>
<!-- Stat Card: Upcoming Events -->
<div class="hvac-stat-col">
<div class="hvac-stat-card">
<?php echo HVAC_Help_System::add_tooltip(
'<h3>Upcoming Events</h3>',
'Published events scheduled for future dates'
); ?>
<p class="metric-value"><?php echo esc_html( $upcoming_events ); ?></p>
</div>
</div>
<!-- Stat Card: Past Events -->
<div class="hvac-stat-col">
<div class="hvac-stat-card">
<?php echo HVAC_Help_System::add_tooltip(
'<h3>Past Events</h3>',
'Completed events where you can generate certificates'
); ?>
<p class="metric-value"><?php echo esc_html( $past_events ); ?></p>
</div>
</div>
<!-- Stat Card: Total Tickets Sold -->
<div class="hvac-stat-col">
<div class="hvac-stat-card">
<?php echo HVAC_Help_System::add_tooltip(
'<h3>Tickets Sold</h3>',
'Total number of tickets sold across all your events'
); ?>
<p class="metric-value"><?php echo esc_html( $total_sold ); ?></p>
</div>
</div>
<!-- Stat Card: Total Revenue -->
<div class="hvac-stat-col">
<div class="hvac-stat-card">
<?php echo HVAC_Help_System::add_tooltip(
'<h3>Total Revenue</h3>',
'Total earnings from all ticket sales (before Stripe fees)'
); ?>
<p class="metric-value">$<?php echo esc_html( number_format( $total_revenue, 2 ) ); ?></p>
<?php if ( $revenue_target ) : ?>
<small>Target: $<?php echo esc_html( number_format( $revenue_target, 2 ) ); ?></small>
<?php endif; ?>
</div>
</div>
</div> <!-- /.ast-row -->
</section>
<!-- Events Table Section -->
<section class="hvac-dashboard-events">
<?php echo HVAC_Help_System::add_tooltip(
'<h2>Your Events</h2>',
'Detailed view of all your events with performance metrics and management options',
'bottom'
); ?>
<!-- Enhanced Filters and Controls -->
<div class="hvac-table-controls">
<!-- Search Box -->
<div class="hvac-search-box">
<?php echo HVAC_Help_System::add_tooltip(
'<input type="search" id="hvac-event-search" placeholder="Search events..." class="regular-text">',
'Search events by name'
); ?>
</div>
<!-- Date Range Filters -->
<div class="hvac-date-filters">
<label for="hvac-date-from">From:</label>
<input type="date" id="hvac-date-from" class="hvac-date-input">
<label for="hvac-date-to">To:</label>
<input type="date" id="hvac-date-to" class="hvac-date-input">
</div>
<!-- Per Page Selector -->
<div class="hvac-per-page">
<label for="hvac-per-page">Show:</label>
<select id="hvac-per-page" class="hvac-per-page-select">
<option value="10" selected>10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
<span>per page</span>
</div>
</div>
<!-- Tab Filters -->
<?php
$dashboard_url = get_permalink(); // Get the current page URL
$current_filter = isset( $_GET['event_status'] ) ? sanitize_key( $_GET['event_status'] ) : 'all';
$filter_statuses = ['all', 'publish', 'draft', 'pending', 'private']; // Added private based on requirements/query
?>
<div class="hvac-event-filters">
<?php echo HVAC_Help_System::add_tooltip(
'<span>Filter: </span>',
'Filter events by their publication status'
); ?>
<?php foreach ($filter_statuses as $status) :
$url = add_query_arg( 'event_status', $status, $dashboard_url );
$class = 'ast-button ast-button-secondary hvac-filter';
if ($status === $current_filter) {
// Add a class or style for the active filter
// Using primary button style for active state as an example
$class = 'ast-button ast-button-primary hvac-filter hvac-filter-active';
}
// Special case for 'all' filter link
if ($status === 'all') {
$url = remove_query_arg( 'event_status', $dashboard_url );
}
?>
<a href="<?php echo esc_url( $url ); ?>" class="<?php echo esc_attr( $class ); ?>" data-status="<?php echo esc_attr( $status ); ?>"><?php echo esc_html( ucfirst( $status ) ); ?></a>
<?php endforeach; ?>
</div>
<!-- Events Table -->
<?php
// $current_filter is already defined above
// Get events with new parameters
$args = [
'status' => $current_filter,
'search' => isset($_GET['search']) ? sanitize_text_field($_GET['search']) : '',
'orderby' => isset($_GET['orderby']) ? sanitize_key($_GET['orderby']) : 'date',
'order' => isset($_GET['order']) ? sanitize_key($_GET['order']) : 'DESC',
'page' => isset($_GET['paged']) ? absint($_GET['paged']) : 1,
'per_page' => isset($_GET['per_page']) ? absint($_GET['per_page']) : 10,
'date_from' => isset($_GET['date_from']) ? sanitize_text_field($_GET['date_from']) : '',
'date_to' => isset($_GET['date_to']) ? sanitize_text_field($_GET['date_to']) : ''
];
$result = $dashboard_data->get_events_table_data( $args );
$events = $result['events'];
$pagination = $result['pagination'];
?>
<div class="hvac-events-table-wrapper">
<table class="wp-list-table widefat fixed striped events-table">
<thead>
<tr>
<th scope="col" class="manage-column column-status">Status</th>
<th scope="col" class="manage-column column-title">Event Name</th>
<th scope="col" class="manage-column column-date">Date</th>
<th scope="col" class="manage-column column-organizer">Organizer</th>
<th scope="col" class="manage-column column-capacity">Capacity</th>
<th scope="col" class="manage-column column-sold">Sold</th>
<th scope="col" class="manage-column column-revenue">Revenue</th>
<th scope="col" class="manage-column column-actions">Actions</th> <!-- Added Actions Column -->
</tr>
</thead>
<tbody id="the-list">
<?php if ( ! empty( $events ) ) : ?>
<?php foreach ( $events as $event ) : ?>
<tr>
<td class="column-status"><?php echo esc_html( ucfirst( $event['status'] ) ); ?></td>
<td class="column-title">
<strong><a href="<?php echo esc_url( $event['link'] ); ?>" target="_blank"><?php echo esc_html( $event['name'] ); ?></a></strong>
<!-- Add Edit/View links below title if needed -->
</td>
<td class="column-date"><?php echo esc_html( date( 'Y-m-d H:i', $event['start_date_ts'] ) ); ?></td>
<td class="column-organizer"><?php
// Check if tribe_get_organizer function exists before calling
if ( function_exists( 'tribe_get_organizer' ) ) {
echo esc_html( tribe_get_organizer( $event['organizer_id'] ) );
} else {
echo 'Organizer ID: ' . esc_html( $event['organizer_id'] ); // Fallback
}
?></td>
<td class="column-capacity"><?php echo esc_html( $event['capacity'] ); ?></td>
<td class="column-sold"><?php echo esc_html( $event['sold'] ); ?></td>
<td class="column-revenue">$<?php echo esc_html( number_format( $event['revenue'], 2 ) ); ?></td>
<td class="column-actions">
<?php
// Link to the custom event edit form (no JavaScript dependencies!)
$edit_url = add_query_arg( 'event_id', $event['id'], home_url( '/trainer/event/edit/' ) );
// Link to the custom event summary page
$summary_url = add_query_arg( 'event_id', $event['id'], home_url( '/trainer/event/summary/' ) );
// Link to the standard WP single event view
$view_url = get_permalink( $event['id'] );
?>
<a href="<?php echo esc_url( $edit_url ); ?>">Edit</a> |
<a href="<?php echo esc_url( $summary_url ); ?>">Summary</a> |
<a href="<?php echo esc_url( $view_url ); ?>" target="_blank">View</a>
</td>
</tr>
<?php endforeach; ?>
<?php else : ?>
<tr>
<td colspan="8">No events found.</td> <!-- Updated colspan -->
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<div class="tablenav bottom">
<div class="tablenav-pages">
<span class="displaying-num"><?php echo esc_html($pagination['total_items']); ?> items</span>
<?php if ($pagination['total_pages'] > 1) : ?>
<span class="pagination-links">
<?php if ($pagination['has_prev']) : ?>
<a class="first-page button" href="#" data-page="1">
<span class="screen-reader-text">First page</span>
<span aria-hidden="true">«</span>
</a>
<a class="prev-page button" href="#" data-page="<?php echo esc_attr($pagination['current_page'] - 1); ?>">
<span class="screen-reader-text">Previous page</span>
<span aria-hidden="true"></span>
</a>
<?php else : ?>
<span class="tablenav-pages-navspan button disabled" aria-hidden="true">«</span>
<span class="tablenav-pages-navspan button disabled" aria-hidden="true"></span>
<?php endif; ?>
<span class="paging-input">
<label for="current-page-selector" class="screen-reader-text">Current Page</label>
<input class="current-page" id="current-page-selector" type="text" name="paged" value="<?php echo esc_attr($pagination['current_page']); ?>" size="1" aria-describedby="table-paging">
<span class="tablenav-paging-text"> of <span class="total-pages"><?php echo esc_html($pagination['total_pages']); ?></span></span>
</span>
<?php if ($pagination['has_next']) : ?>
<a class="next-page button" href="#" data-page="<?php echo esc_attr($pagination['current_page'] + 1); ?>">
<span class="screen-reader-text">Next page</span>
<span aria-hidden="true"></span>
</a>
<a class="last-page button" href="#" data-page="<?php echo esc_attr($pagination['total_pages']); ?>">
<span class="screen-reader-text">Last page</span>
<span aria-hidden="true">»</span>
</a>
<?php else : ?>
<span class="tablenav-pages-navspan button disabled" aria-hidden="true"></span>
<span class="tablenav-pages-navspan button disabled" aria-hidden="true">»</span>
<?php endif; ?>
</span>
</div>
</div>
<?php endif; ?>
</section>
</div> <!-- .hvac-dashboard-wrapper -->
</div>
</div>
<?php
get_footer();