- Add search box for real-time event name filtering with 500ms debounce - Add date range filters (from/to) for filtering events by start date - Add pagination with customizable items per page (10, 25, 50, 100) - Add sortable table columns for status, name, date, capacity, sold, revenue - Update dashboard data handler to support all new query parameters - Create new JavaScript file for handling interactive features - Create new CSS file for enhanced dashboard styling - Maintain backward compatibility with existing status filters - Add URL state management for browser navigation - Add loading indicators and responsive design The dashboard now provides a comprehensive interface for trainers to efficiently manage and navigate their events with powerful filtering and sorting capabilities. Co-Authored-By: Ben Reed <ben@tealmaker.com>
397 lines
No EOL
15 KiB
PHP
397 lines
No EOL
15 KiB
PHP
<?php
|
||
/**
|
||
* Template Name: HVAC Trainer Dashboard
|
||
*
|
||
* This template handles the display of the HVAC Trainer Dashboard.
|
||
* It checks for user login and role, then displays stats and events.
|
||
*
|
||
* @package HVAC Community Events
|
||
* @subpackage Templates
|
||
* @author Roo
|
||
* @version 1.0.1
|
||
*/
|
||
|
||
// Exit if accessed directly.
|
||
if ( ! defined( 'ABSPATH' ) ) {
|
||
exit;
|
||
}
|
||
|
||
// --- 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( '/community-login/' ) );
|
||
exit;
|
||
}
|
||
|
||
// Check if user has permission to view dashboard
|
||
// Allow administrators and users with view_hvac_dashboard capability
|
||
if ( ! current_user_can( 'view_hvac_dashboard' ) && ! current_user_can( 'manage_options' ) ) {
|
||
// Show access denied message instead of redirect to prevent loops
|
||
get_header();
|
||
?>
|
||
<style>
|
||
.hvac-access-denied {
|
||
max-width: 600px;
|
||
margin: 60px auto;
|
||
padding: 40px;
|
||
text-align: center;
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
}
|
||
.hvac-access-denied h1 {
|
||
color: #d63638;
|
||
margin-bottom: 20px;
|
||
}
|
||
.hvac-access-denied p {
|
||
margin-bottom: 15px;
|
||
color: #666;
|
||
line-height: 1.6;
|
||
}
|
||
.hvac-access-denied .button {
|
||
background: #0073aa;
|
||
color: white;
|
||
padding: 12px 24px;
|
||
text-decoration: none;
|
||
border-radius: 4px;
|
||
display: inline-block;
|
||
margin-top: 20px;
|
||
}
|
||
.hvac-access-denied .button:hover {
|
||
background: #005a87;
|
||
color: white;
|
||
}
|
||
</style>
|
||
<div class="content-area primary ast-container">
|
||
<main class="site-main">
|
||
<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>
|
||
</main>
|
||
</div>
|
||
<?php
|
||
get_footer();
|
||
exit;
|
||
}
|
||
|
||
// Get the current user ID
|
||
$user_id = get_current_user_id();
|
||
|
||
// Include and instantiate the dashboard data class
|
||
require_once HVAC_CE_PLUGIN_DIR . 'includes/class-hvac-dashboard-data.php';
|
||
$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();
|
||
|
||
// --- Template Start ---
|
||
|
||
get_header(); // Use theme's header
|
||
|
||
?>
|
||
<div id="primary" class="content-area primary ast-container"> <!-- Use Astra container -->
|
||
<main id="main" class="site-main">
|
||
|
||
<!-- Dashboard Header & Navigation -->
|
||
<div class="hvac-dashboard-header">
|
||
<h1 class="entry-title">Trainer Dashboard</h1> <!-- Standard WP title class -->
|
||
<div class="hvac-dashboard-nav">
|
||
<?php // Link to the new page containing the TEC CE submission form shortcode ?>
|
||
<?php echo HVAC_Help_System::add_tooltip(
|
||
'<a href="' . esc_url( home_url( '/manage-event/' ) ) . '" class="ast-button ast-button-primary">Create Event</a>',
|
||
'Create a new training event with custom pricing and registration options'
|
||
); ?>
|
||
<?php echo HVAC_Help_System::add_tooltip(
|
||
'<a href="' . esc_url( home_url( '/generate-certificates/' ) ) . '" class="ast-button ast-button-primary">Generate Certificates</a>',
|
||
'Create professional certificates for attendees who completed your training'
|
||
); ?>
|
||
<?php echo HVAC_Help_System::add_tooltip(
|
||
'<a href="' . esc_url( home_url( '/certificate-reports/' ) ) . '" class="ast-button ast-button-primary">Certificate Reports</a>',
|
||
'View and manage all certificates you\'ve issued to attendees'
|
||
); ?>
|
||
<?php echo HVAC_Help_System::add_tooltip(
|
||
'<a href="' . esc_url( home_url( '/trainer-profile/' ) ) . '" class="ast-button ast-button-secondary">View Profile</a>',
|
||
'Update your professional credentials, business information, and training specialties'
|
||
); ?>
|
||
<a href="<?php echo esc_url( home_url( '/hvac-documentation/' ) ); ?>" class="ast-button ast-button-secondary">Help</a>
|
||
<a href="<?php echo esc_url( wp_logout_url( home_url( '/community-login/' ) ) ); ?>" class="ast-button ast-button-secondary">Logout</a>
|
||
</div>
|
||
</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><?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><?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><?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><?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>$<?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 = array(
|
||
'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 new page containing the TEC CE submission form shortcode
|
||
$edit_url = add_query_arg( 'event_id', $event['id'], home_url( '/manage-event/' ) );
|
||
// Link to the custom event summary page
|
||
$summary_url = add_query_arg( 'event_id', $event['id'], home_url( '/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>
|
||
|
||
<?php if ($pagination['total_pages'] > 1) : ?>
|
||
<div class="tablenav bottom">
|
||
<div class="tablenav-pages">
|
||
<span class="displaying-num"><?php echo esc_html($pagination['total_items']); ?> items</span>
|
||
<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>
|
||
|
||
</main> <!-- #main -->
|
||
</div> <!-- #primary -->
|
||
|
||
<?php
|
||
get_footer(); // Use theme's footer
|
||
?>
|