From 5bcd8a48a8fa9319ac4b6a140f223c49cff4a24b Mon Sep 17 00:00:00 2001 From: bengizmo Date: Mon, 19 May 2025 18:54:52 -0300 Subject: [PATCH] feat: Improve dashboard UI and interactivity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change 'Your Stats' section to row layout for better visual display - Add dynamic event filtering without page reload - Create AJAX endpoint for event filtering - Add loading animation and UI feedback - Improve mobile responsiveness 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../assets/css/hvac-dashboard.css | 53 +++++- .../assets/js/hvac-dashboard.js | 111 ++++++++++++ .../includes/class-hvac-dashboard.php | 159 +++++++++++++++--- .../templates/template-hvac-dashboard.php | 18 +- 4 files changed, 310 insertions(+), 31 deletions(-) create mode 100644 wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/js/hvac-dashboard.js diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/css/hvac-dashboard.css b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/css/hvac-dashboard.css index 2d789e74..759d2ea1 100644 --- a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/css/hvac-dashboard.css +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/css/hvac-dashboard.css @@ -24,7 +24,23 @@ margin-bottom: 2em; } -/* Target column padding specifically within the stats section */ +/* Row layout for stats */ +.hvac-stats-row { + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin: -10px; /* Counteract the padding on columns */ + justify-content: space-between; + align-items: stretch; +} + +.hvac-stat-col { + flex: 1; + min-width: 160px; /* Ensure minimum width for readability */ + padding: 10px; +} + +/* Target column padding specifically within the stats section - maintain compatibility */ .hvac-dashboard-stats .ast-row > [class*="ast-col-"] { padding: 10px; /* Replicates removed inline style */ display: flex; /* Ensure cards fill height if needed */ @@ -38,6 +54,7 @@ text-align: center; width: 100%; /* Make card fill column */ flex-grow: 1; /* Allow card to grow if needed */ + height: 100%; /* Ensure equal height */ /* Add box-shadow or other theme-consistent styling if desired */ } @@ -79,6 +96,8 @@ /* Events Table */ .hvac-events-table-wrapper { overflow-x: auto; /* Add horizontal scroll for smaller screens */ + position: relative; /* For loading indicator positioning */ + min-height: 100px; /* Ensure space for loading indicator */ } /* Ensure table uses standard WP/Theme styling */ @@ -88,4 +107,36 @@ .events-table .column-actions a { margin-right: 0.5em; +} + +/* Loading indicator */ +.hvac-loading { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(255, 255, 255, 0.8); + display: flex; + justify-content: center; + align-items: center; + font-weight: bold; + padding: 20px; + z-index: 10; + animation: fadeIn 0.3s ease-in-out; +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +/* Error message */ +.hvac-error { + color: #d63638; + padding: 10px; + border: 1px solid #ffb8bb; + background-color: #ffebe9; + margin: 10px 0; + border-radius: 4px; } \ No newline at end of file diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/js/hvac-dashboard.js b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/js/hvac-dashboard.js new file mode 100644 index 00000000..6d9c07f9 --- /dev/null +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/assets/js/hvac-dashboard.js @@ -0,0 +1,111 @@ +/** + * HVAC Trainer Dashboard JavaScript + * + * Handles dynamic filtering of events table and other interactive features. + */ +(function($) { + 'use strict'; + + // Initialize the dashboard when DOM is ready + $(document).ready(function() { + initEventFilters(); + }); + + /** + * Initialize event filters to work without page reload + */ + function initEventFilters() { + // Get the events table wrapper element + const $eventsTableWrapper = $('.hvac-events-table-wrapper'); + + // Add click handler to filter links + $('.hvac-event-filters a').on('click', function(e) { + e.preventDefault(); // Prevent default link behavior (page reload) + + // Get the status filter from the link URL + const url = new URL($(this).attr('href'), window.location.origin); + const status = url.searchParams.get('event_status') || 'all'; + + // Update active class + $('.hvac-event-filters a').removeClass('hvac-filter-active ast-button-primary').addClass('ast-button-secondary'); + $(this).addClass('hvac-filter-active ast-button-primary').removeClass('ast-button-secondary'); + + // Show loading indicator + $eventsTableWrapper.append('
Filtering events...
'); + + // Make AJAX request to get filtered events + $.ajax({ + url: hvac_dashboard.ajax_url, + type: 'POST', + data: { + action: 'hvac_filter_events', + status: status, + nonce: hvac_dashboard.nonce + }, + success: function(response) { + if (response.success) { + // Replace the table HTML with the filtered results + $eventsTableWrapper.html(response.data.html); + + // Update the URL without reloading the page + if (history.pushState) { + const newUrl = status === 'all' + ? removeURLParameter(window.location.href, 'event_status') + : addURLParameter(window.location.href, 'event_status', status); + window.history.pushState({ path: newUrl }, '', newUrl); + } + } else { + // Show error message + $eventsTableWrapper.find('.hvac-loading').remove(); + $eventsTableWrapper.append('
Error loading events: ' + response.data.message + '
'); + } + }, + error: function() { + // Show error message + $eventsTableWrapper.find('.hvac-loading').remove(); + $eventsTableWrapper.append('
Error communicating with server.
'); + } + }); + }); + } + + /** + * Helper function to add a URL parameter + */ + function addURLParameter(url, key, value) { + const re = new RegExp("([?&])" + key + "=.*?(&|$)", "i"); + const separator = url.indexOf('?') !== -1 ? "&" : "?"; + + if (url.match(re)) { + return url.replace(re, '$1' + key + "=" + value + '$2'); + } else { + return url + separator + key + "=" + value; + } + } + + /** + * Helper function to remove a URL parameter + */ + function removeURLParameter(url, parameter) { + const urlParts = url.split('?'); + if (urlParts.length < 2) { + return url; + } + + const urlBase = urlParts[0]; + const queryString = urlParts[1]; + const prefix = encodeURIComponent(parameter) + '='; + const parts = queryString.split(/[&;]/g); + + // Reverse iteration to safely remove items + for (let i = parts.length; i-- > 0;) { + if (parts[i].lastIndexOf(prefix, 0) !== -1) { + parts.splice(i, 1); + } + } + + const newQueryString = parts.join('&'); + return newQueryString.length > 0 ? urlBase + '?' + newQueryString : urlBase; + } + +})(jQuery); \ No newline at end of file diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/class-hvac-dashboard.php b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/class-hvac-dashboard.php index 787a8b21..317e2409 100644 --- a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/class-hvac-dashboard.php +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/includes/class-hvac-dashboard.php @@ -21,7 +21,10 @@ class HVAC_Dashboard { add_action('init', array($this, 'register_shortcode')); // Use higher priority to run after shortcode processing add_filter('the_content', array($this, 'render_dashboard_content'), 99); - add_action('wp_enqueue_scripts', array($this, 'enqueue_dashboard_styles')); + add_action('wp_enqueue_scripts', array($this, 'enqueue_dashboard_assets')); + + // AJAX handler for events filtering + add_action('wp_ajax_hvac_filter_events', array($this, 'ajax_filter_events')); } /** @@ -104,39 +107,39 @@ class HVAC_Dashboard {

Your Stats

-
+
-
+

Total Events

-
+
-
+

Upcoming Events

-
+
-
+

Past Events

-
+
-
+

Tickets Sold

-
+
-
+

Total Revenue

$

Target: $ -
+
@@ -152,9 +155,9 @@ class HVAC_Dashboard { $filter_statuses = array('all', 'publish', 'draft', 'pending', 'private'); foreach ($filter_statuses as $status) : $url = ($status === 'all') ? remove_query_arg('event_status', $dashboard_url) : add_query_arg('event_status', $status, $dashboard_url); - $class = ($status === $data['current_filter']) ? 'hvac-filter-active' : ''; + $class = ($status === $data['current_filter']) ? 'hvac-filter hvac-filter-active ast-button-primary' : 'hvac-filter ast-button-secondary'; ?> - + @@ -215,13 +218,118 @@ class HVAC_Dashboard { } /** - * Enqueue dashboard styles + * Handle AJAX request for filtered events table */ - public function enqueue_dashboard_styles() { - if (!is_page('hvac-dashboard')) { + public function ajax_filter_events() { + // Check nonce + if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'hvac_dashboard_nonce')) { + wp_send_json_error(array('message' => 'Security check failed.')); return; } + // Get current user ID + $user_id = get_current_user_id(); + if (!$user_id || !current_user_can('view_hvac_dashboard')) { + wp_send_json_error(array('message' => 'Access denied.')); + return; + } + + // Get status filter + $status = isset($_POST['status']) ? sanitize_key($_POST['status']) : 'all'; + + // Include dashboard data class + require_once HVAC_CE_PLUGIN_DIR . 'includes/class-hvac-dashboard-data.php'; + $dashboard_data = new HVAC_Dashboard_Data($user_id); + + // Get filtered events data + $events = $dashboard_data->get_events_table_data($status); + + // Build HTML for events table + ob_start(); + + if (!empty($events)) : ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StatusEvent NameDateOrganizerCapacitySoldRevenueActions
+ + $ + + Edit | + Summary +
+ +

No events found.

+ $html, + 'count' => count($events), + 'status' => $status + )); + } + + /** + * Enqueue dashboard assets (CSS and JavaScript) + */ + public function enqueue_dashboard_assets() { + // Check if we're on the dashboard page + global $post; + if (!is_a($post, 'WP_Post') || !has_shortcode($post->post_content, 'hvac_trainer_dashboard')) { + return; + } + + // Enqueue dashboard JavaScript + wp_enqueue_script( + 'hvac-dashboard-js', + HVAC_CE_PLUGIN_URL . 'assets/js/hvac-dashboard.js', + array('jquery'), + HVAC_CE_VERSION, + true + ); + + // Localize script with AJAX URL and nonce + wp_localize_script('hvac-dashboard-js', 'hvac_dashboard', array( + 'ajax_url' => admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce('hvac_dashboard_nonce') + )); + // Inline CSS for now - can be moved to external file later $css = ' .hvac-dashboard-wrapper { @@ -274,13 +382,22 @@ class HVAC_Dashboard { margin-bottom: 40px; } - .hvac-stats-grid { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 20px; + .hvac-stats-row { + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin: -10px; /* Counteract the padding on columns */ + justify-content: space-between; + align-items: stretch; margin-top: 20px; } + .hvac-stat-col { + flex: 1; + min-width: 160px; /* Ensure minimum width for readability */ + padding: 10px; + } + .hvac-stat-card { background: #f8f9fa; border: 1px solid #e9ecef; diff --git a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/templates/template-hvac-dashboard.php b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/templates/template-hvac-dashboard.php index eb0d78f3..e6b9d681 100644 --- a/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/templates/template-hvac-dashboard.php +++ b/wordpress-dev/wordpress/wp-content/plugins/hvac-community-events/templates/template-hvac-dashboard.php @@ -64,10 +64,10 @@ get_header(); // Use theme's header

Your Stats

-
+
-
+

Total Events

@@ -75,7 +75,7 @@ get_header(); // Use theme's header
-
+

Upcoming Events

@@ -83,7 +83,7 @@ get_header(); // Use theme's header
-
+

Past Events

@@ -91,7 +91,7 @@ get_header(); // Use theme's header
-
+

Tickets Sold

@@ -99,7 +99,7 @@ get_header(); // Use theme's header
-
+

Total Revenue

$

@@ -126,18 +126,18 @@ get_header(); // Use theme's header Filter: - +