feat: Add Event Summary Page functionality
- Add event-summary page to required_pages array in main plugin file - Update render_event_summary() method to handle event ID from URL - Update template_include filter to load custom event summary template - Update dashboard event links to point to new event summary page - Create comprehensive event summary template with statistics and attendee info - Add E2E tests for Event Summary Page - Add documentation for Event Summary functionality 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		
							parent
							
								
									e59c2e5ccc
								
							
						
					
					
						commit
						1a563f3133
					
				
					 6 changed files with 732 additions and 5 deletions
				
			
		
							
								
								
									
										171
									
								
								wordpress-dev/tests/e2e/event-summary.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								wordpress-dev/tests/e2e/event-summary.spec.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,171 @@ | |||
| import { test, expect } from '@playwright/test'; | ||||
| import { LoginPage } from './pages/LoginPage'; | ||||
| import { DashboardPage } from './pages/DashboardPage'; | ||||
| 
 | ||||
| test.describe('Event Summary Page', () => { | ||||
|   // Define test variables
 | ||||
|   const testTrainerUsername = 'test_trainer'; | ||||
|   const testTrainerPassword = 'Test123!'; | ||||
|    | ||||
|   // We'll need to figure out a test event ID during the test
 | ||||
|   let testEventId: string; | ||||
|    | ||||
|   test.beforeEach(async ({ page }) => { | ||||
|     // Log in before each test
 | ||||
|     const loginPage = new LoginPage(page); | ||||
|     await loginPage.navigate(); | ||||
|     await loginPage.login(testTrainerUsername, testTrainerPassword); | ||||
|      | ||||
|     // Navigate to dashboard to find an event to use for testing
 | ||||
|     const dashboardPage = new DashboardPage(page); | ||||
|     await dashboardPage.navigate(); | ||||
|      | ||||
|     // Find the first event in the dashboard and get its ID
 | ||||
|     // We'll extract the event ID from the "Summary" link's href
 | ||||
|     const summaryLink = page.locator('.column-actions a:has-text("Summary")').first(); | ||||
|      | ||||
|     // Check if there's at least one event
 | ||||
|     const linkCount = await summaryLink.count(); | ||||
|     if (linkCount === 0) { | ||||
|       // No events available for testing, we'll need to skip the tests
 | ||||
|       test.skip(true, 'No events available for testing'); | ||||
|       return; | ||||
|     } | ||||
|      | ||||
|     // Get the href attribute from the summary link
 | ||||
|     const summaryUrl = await summaryLink.getAttribute('href'); | ||||
|      | ||||
|     // Extract the event ID from the URL
 | ||||
|     if (summaryUrl) { | ||||
|       const match = summaryUrl.match(/event_id=(\d+)/); | ||||
|       if (match && match[1]) { | ||||
|         testEventId = match[1]; | ||||
|       } else { | ||||
|         test.skip(true, 'Could not extract event ID from summary link'); | ||||
|       } | ||||
|     } else { | ||||
|       test.skip(true, 'Summary link has no href attribute'); | ||||
|     } | ||||
|   }); | ||||
|    | ||||
|   test('should be accessible from dashboard', async ({ page }) => { | ||||
|     // Navigate to dashboard
 | ||||
|     const dashboardPage = new DashboardPage(page); | ||||
|     await dashboardPage.navigate(); | ||||
|      | ||||
|     // Find and click the first summary link
 | ||||
|     const summaryLink = page.locator('.column-actions a:has-text("Summary")').first(); | ||||
|     await expect(summaryLink).toBeVisible(); | ||||
|     await summaryLink.click(); | ||||
|      | ||||
|     // Verify we're on the event summary page
 | ||||
|     await expect(page).toHaveURL(/.*\/event-summary\/.*event_id=.*/); | ||||
|     await expect(page.locator('h1')).toContainText('Summary'); | ||||
|   }); | ||||
|    | ||||
|   test('should display event overview information', async ({ page }) => { | ||||
|     // Navigate directly to the event summary page
 | ||||
|     await page.goto(`/event-summary/?event_id=${testEventId}`); | ||||
|      | ||||
|     // Check for event overview section
 | ||||
|     await expect(page.locator('h2:has-text("Event Overview")')).toBeVisible(); | ||||
|      | ||||
|     // Check for basic event details
 | ||||
|     const detailsTable = page.locator('.hvac-details-table'); | ||||
|     await expect(detailsTable).toBeVisible(); | ||||
|      | ||||
|     // Check for specific fields
 | ||||
|     const dateRow = detailsTable.locator('tr', { hasText: 'Date & Time' }); | ||||
|     const statusRow = detailsTable.locator('tr', { hasText: 'Status' }); | ||||
|      | ||||
|     await expect(dateRow).toBeVisible(); | ||||
|     await expect(statusRow).toBeVisible(); | ||||
|   }); | ||||
|    | ||||
|   test('should display event statistics', async ({ page }) => { | ||||
|     // Navigate directly to the event summary page
 | ||||
|     await page.goto(`/event-summary/?event_id=${testEventId}`); | ||||
|      | ||||
|     // Check for statistics section
 | ||||
|     await expect(page.locator('h2:has-text("Event Statistics")')).toBeVisible(); | ||||
|      | ||||
|     // Check for statistics cards
 | ||||
|     const statsRow = page.locator('.hvac-stats-row'); | ||||
|     await expect(statsRow).toBeVisible(); | ||||
|      | ||||
|     // Look for specific metric cards
 | ||||
|     const totalTicketsCard = page.locator('.hvac-stat-card h3:has-text("Total Tickets")'); | ||||
|     const totalRevenueCard = page.locator('.hvac-stat-card h3:has-text("Total Revenue")'); | ||||
|      | ||||
|     await expect(totalTicketsCard).toBeVisible(); | ||||
|     await expect(totalRevenueCard).toBeVisible(); | ||||
|   }); | ||||
|    | ||||
|   test('should display ticket sales and attendees information', async ({ page }) => { | ||||
|     // Navigate directly to the event summary page
 | ||||
|     await page.goto(`/event-summary/?event_id=${testEventId}`); | ||||
|      | ||||
|     // Check for ticket sales section
 | ||||
|     await expect(page.locator('h2:has-text("Ticket Sales & Attendees")')).toBeVisible(); | ||||
|      | ||||
|     // The table might not be visible if there are no attendees, so check for either
 | ||||
|     // the table or the "No ticket sales" message
 | ||||
|     const attendeesTable = page.locator('.hvac-transactions-table'); | ||||
|     const noAttendeesMessage = page.locator('text=No ticket sales or attendees found'); | ||||
|      | ||||
|     const hasTable = await attendeesTable.count() > 0; | ||||
|     if (hasTable) { | ||||
|       // Check table headers
 | ||||
|       const attendeeHeader = attendeesTable.locator('th', { hasText: 'Attendee' }); | ||||
|       const emailHeader = attendeesTable.locator('th', { hasText: 'Email' }); | ||||
|       const ticketTypeHeader = attendeesTable.locator('th', { hasText: 'Ticket Type' }); | ||||
|        | ||||
|       await expect(attendeeHeader).toBeVisible(); | ||||
|       await expect(emailHeader).toBeVisible(); | ||||
|       await expect(ticketTypeHeader).toBeVisible(); | ||||
|     } else { | ||||
|       // Check for no attendees message
 | ||||
|       await expect(noAttendeesMessage).toBeVisible(); | ||||
|     } | ||||
|   }); | ||||
|    | ||||
|   test('should display event description', async ({ page }) => { | ||||
|     // Navigate directly to the event summary page
 | ||||
|     await page.goto(`/event-summary/?event_id=${testEventId}`); | ||||
|      | ||||
|     // Check for event description section
 | ||||
|     await expect(page.locator('h2:has-text("Event Description")')).toBeVisible(); | ||||
|      | ||||
|     // Check for description content
 | ||||
|     const descriptionContainer = page.locator('.hvac-event-description'); | ||||
|     await expect(descriptionContainer).toBeVisible(); | ||||
|   }); | ||||
|    | ||||
|   test('should have working navigation links', async ({ page }) => { | ||||
|     // Navigate directly to the event summary page
 | ||||
|     await page.goto(`/event-summary/?event_id=${testEventId}`); | ||||
|      | ||||
|     // Check for dashboard navigation link
 | ||||
|     const dashboardLink = page.locator('a[href*="/hvac-dashboard/"]'); | ||||
|     await expect(dashboardLink).toBeVisible(); | ||||
|      | ||||
|     // Check for edit event link (may not be visible if user doesn't have permission)
 | ||||
|     const editEventLink = page.locator('a[href*="/manage-event/"]'); | ||||
|      | ||||
|     // Check for view public page link
 | ||||
|     const viewPublicLink = page.locator('a[href*="/event/"]'); | ||||
|     await expect(viewPublicLink).toBeVisible(); | ||||
|   }); | ||||
|    | ||||
|   test('should redirect to login page when not logged in', async ({ page }) => { | ||||
|     // Log out first
 | ||||
|     await page.goto('/wp-login.php?action=logout'); | ||||
|     await page.waitForURL(/.*\/community-login.*/); | ||||
|      | ||||
|     // Try to access event summary page directly
 | ||||
|     await page.goto(`/event-summary/?event_id=${testEventId}`); | ||||
|      | ||||
|     // Should redirect to login page
 | ||||
|     await expect(page).toHaveURL(/.*\/community-login.*/); | ||||
|   }); | ||||
| }); | ||||
|  | @ -0,0 +1,102 @@ | |||
| # Event Summary Functionality | ||||
| 
 | ||||
| ## Overview | ||||
| 
 | ||||
| The Event Summary page provides trainers with detailed information about their events, including ticket sales, attendee data, and revenue tracking. This page is designed to be a central hub for monitoring event performance and managing attendees. | ||||
| 
 | ||||
| ## Access & Navigation | ||||
| 
 | ||||
| - **Access Path**: The Event Summary page can be accessed from the Trainer Dashboard by clicking the "Summary" link next to any event in the events table. | ||||
| - **URL Structure**: `/event-summary/?event_id={id}` where `{id}` is the event post ID. | ||||
| - **Authentication**: Only logged-in users with appropriate permissions (event creators or administrators) can access this page. | ||||
| 
 | ||||
| ## Page Components | ||||
| 
 | ||||
| ### 1. Header & Navigation | ||||
| 
 | ||||
| The header section contains: | ||||
| - The event title with "Summary" suffix | ||||
| - Navigation links to: | ||||
|   - Dashboard | ||||
|   - Edit Event (if user has permission) | ||||
|   - View Public Page (opens in new tab) | ||||
|   - Email Attendees (Phase 2 feature, currently a placeholder) | ||||
| 
 | ||||
| ### 2. Event Overview | ||||
| 
 | ||||
| This section provides basic event information including: | ||||
| - Date & Time (start and end) | ||||
| - Event Status (Published, Draft, etc.) | ||||
| - Cost | ||||
| - Venue information (if available) | ||||
| - Organizer details (if available) | ||||
| 
 | ||||
| ### 3. Event Statistics | ||||
| 
 | ||||
| A visual representation of key metrics: | ||||
| - Total Tickets Sold | ||||
| - Total Revenue | ||||
| - Ticket Type Distribution (with count and revenue for each type) | ||||
| 
 | ||||
| Statistics are displayed in card format for easy scanning, with the same visual style as the dashboard stats. | ||||
| 
 | ||||
| ### 4. Ticket Sales & Attendees | ||||
| 
 | ||||
| A comprehensive table showing all attendee information: | ||||
| - Attendee name | ||||
| - Email address | ||||
| - Ticket type | ||||
| - Price paid | ||||
| - Order ID | ||||
| - Check-in status | ||||
| 
 | ||||
| This table provides a complete overview of all registrations and can be used for attendee management. | ||||
| 
 | ||||
| ### 5. Event Description | ||||
| 
 | ||||
| The full event description is displayed for reference. | ||||
| 
 | ||||
| ## Technical Implementation | ||||
| 
 | ||||
| ### Files & Classes | ||||
| 
 | ||||
| - **Template**: `templates/template-event-summary.php` | ||||
| - **Data Handler**: `includes/community/class-event-summary-data.php` | ||||
| - **Shortcode**: `[hvac_event_summary]` (registered in main plugin class) | ||||
| - **Styling**: Inline CSS in the template (consistent with dashboard styling) | ||||
| 
 | ||||
| ### Data Flow | ||||
| 
 | ||||
| 1. The `render_event_summary()` method in the main plugin class: | ||||
|    - Retrieves the event ID from the URL parameter | ||||
|    - Verifies user permissions | ||||
|    - Includes the event summary template | ||||
| 
 | ||||
| 2. The template: | ||||
|    - Initializes the `HVAC_Event_Summary_Data` class with the event ID | ||||
|    - Retrieves event details, venue info, organizer info, and transaction data | ||||
|    - Calculates statistics from the transaction data | ||||
|    - Renders the UI with the retrieved data | ||||
| 
 | ||||
| 3. The `HVAC_Event_Summary_Data` class: | ||||
|    - Provides methods to retrieve all necessary event data | ||||
|    - Integrates with The Events Calendar API for event details | ||||
|    - Integrates with Event Tickets for transaction data | ||||
| 
 | ||||
| ## Testing | ||||
| 
 | ||||
| The Event Summary page is verified by E2E tests in `tests/e2e/event-summary.spec.ts`. The tests cover: | ||||
| - Page accessibility from the dashboard | ||||
| - Display of event overview information | ||||
| - Display of event statistics | ||||
| - Display of ticket sales and attendees data | ||||
| - Display of event description | ||||
| - Proper navigation links | ||||
| - Authentication requirements | ||||
| 
 | ||||
| ## Future Enhancements (Planned) | ||||
| 
 | ||||
| - **Phase 2**: Integration with the Email Attendees feature | ||||
| - **Phase 2**: CSV export of attendee data | ||||
| - **Phase 3**: Enhanced visualization of event statistics | ||||
| - **Phase 3**: Integration with certificate generation | ||||
|  | @ -59,6 +59,10 @@ function hvac_ce_create_required_pages() { | |||
|             'title' => 'Trainer Profile', | ||||
|             'content' => '<!-- wp:shortcode -->[hvac_trainer_profile]<!-- /wp:shortcode -->', | ||||
|         ], | ||||
|         'event-summary' => [ // Add event summary page
 | ||||
|             'title' => 'Event Summary', | ||||
|             'content' => '<!-- wp:shortcode -->[hvac_event_summary]<!-- /wp:shortcode -->', | ||||
|         ], | ||||
|         // REMOVED: 'submit-event' page creation. Will link to default TEC CE page.
 | ||||
|         // 'submit-event' => [
 | ||||
|         //     'title' => 'Submit Event',
 | ||||
|  |  | |||
|  | @ -241,8 +241,34 @@ class HVAC_Community_Events { | |||
| 	 * Render event summary content | ||||
| 	 */ | ||||
| 	public function render_event_summary() { | ||||
| 		// This can be used to display custom event summary content
 | ||||
| 		return '<div class="hvac-event-summary">Event Summary Content Here</div>'; | ||||
| 		// Check if user is logged in
 | ||||
| 		if (!is_user_logged_in()) { | ||||
| 			return '<p>Please log in to view the event summary.</p>'; | ||||
| 		} | ||||
| 		 | ||||
| 		// Get event ID from URL parameter
 | ||||
| 		$event_id = isset($_GET['event_id']) ? absint($_GET['event_id']) : 0; | ||||
| 		 | ||||
| 		if ($event_id <= 0) { | ||||
| 			return '<div class="hvac-error">No event ID provided. Please access this page from your dashboard.</div>'; | ||||
| 		} | ||||
| 		 | ||||
| 		// Check if the event exists and user has permission to view it
 | ||||
| 		$event = get_post($event_id); | ||||
| 		if (!$event || get_post_type($event) !== Tribe__Events__Main::POSTTYPE) { | ||||
| 			return '<div class="hvac-error">Event not found or invalid.</div>'; | ||||
| 		} | ||||
| 		 | ||||
| 		// Check if the current user has permission to view this event
 | ||||
| 		// For now, we'll check if they're the post author or have edit_posts capability
 | ||||
| 		if ($event->post_author != get_current_user_id() && !current_user_can('edit_posts')) { | ||||
| 			return '<div class="hvac-error">You do not have permission to view this event summary.</div>'; | ||||
| 		} | ||||
| 		 | ||||
| 		// Include the event summary template
 | ||||
| 		ob_start(); | ||||
| 		include HVAC_CE_PLUGIN_DIR . 'templates/event-summary/template-event-summary.php'; | ||||
| 		return ob_get_clean(); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
|  | @ -295,6 +321,14 @@ class HVAC_Community_Events { | |||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		// Check for event-summary page
 | ||||
| 		if (is_page('event-summary')) { | ||||
| 			$custom_template = HVAC_CE_PLUGIN_DIR . 'templates/template-event-summary.php'; | ||||
| 			if (file_exists($custom_template)) { | ||||
| 				return $custom_template; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// Check for single event view (temporary)
 | ||||
| 		if ( is_singular( 'tribe_events' ) ) { | ||||
| 			$custom_template = HVAC_CE_PLUGIN_DIR . 'templates/single-tribe_events.php'; | ||||
|  |  | |||
|  | @ -0,0 +1,413 @@ | |||
| <?php | ||||
| /** | ||||
|  * Template Name: HVAC Event Summary | ||||
|  * | ||||
|  * This template handles the display of the HVAC Event Summary page. | ||||
|  * It shows detailed information about a specific event, including ticket sales, | ||||
|  * attendee information, and revenue tracking. | ||||
|  * | ||||
|  * @package    HVAC Community Events | ||||
|  * @subpackage Templates | ||||
|  * @author     HVAC Community Events | ||||
|  * @version    1.0.0 | ||||
|  */ | ||||
| 
 | ||||
| // Exit if accessed directly.
 | ||||
| if ( ! defined( 'ABSPATH' ) ) { | ||||
|     exit; | ||||
| } | ||||
| 
 | ||||
| // Get the event ID from the URL parameter
 | ||||
| $event_id = isset( $_GET['event_id'] ) ? absint( $_GET['event_id'] ) : 0; | ||||
| 
 | ||||
| // Ensure the data class is available
 | ||||
| if ( ! class_exists( 'HVAC_Event_Summary_Data' ) ) { | ||||
|     // Attempt to include it if not loaded
 | ||||
|     $class_path = plugin_dir_path( __FILE__ ) . '../includes/community/class-event-summary-data.php'; | ||||
|     if ( file_exists( $class_path ) ) { | ||||
|         require_once $class_path; | ||||
|     } else { | ||||
|         // Handle error: Class not found, cannot display summary
 | ||||
|         echo "<p>Error: Event Summary data handler not found.</p>"; | ||||
|         return; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Initialize the event summary data handler
 | ||||
| $summary_data_handler = new HVAC_Event_Summary_Data( $event_id ); | ||||
| 
 | ||||
| // Check if the event is valid
 | ||||
| if ( ! $summary_data_handler->is_valid_event() ) { | ||||
|     // Redirect to dashboard if the event doesn't exist or user doesn't have permission
 | ||||
|     wp_safe_redirect( home_url( '/hvac-dashboard/' ) ); | ||||
|     exit; | ||||
| } | ||||
| 
 | ||||
| // Fetch all the required event data
 | ||||
| $event_details = $summary_data_handler->get_event_details(); | ||||
| $venue_details = $summary_data_handler->get_event_venue_details(); | ||||
| $organizer_details = $summary_data_handler->get_event_organizer_details(); | ||||
| $transactions = $summary_data_handler->get_event_transactions(); | ||||
| 
 | ||||
| // Calculate ticket sales summary data
 | ||||
| $total_tickets = 0; | ||||
| $total_revenue = 0; | ||||
| $ticket_types = array(); | ||||
| 
 | ||||
| // Process transactions data
 | ||||
| if ( ! empty( $transactions ) ) { | ||||
|     foreach ( $transactions as $txn ) { | ||||
|         $total_tickets++; | ||||
|         if ( isset( $txn['price'] ) ) { | ||||
|             $total_revenue += floatval( $txn['price'] ); | ||||
|         } | ||||
| 
 | ||||
|         // Count ticket types
 | ||||
|         $ticket_type = $txn['ticket_type_name'] ?? 'Unknown'; | ||||
|         if ( isset( $ticket_types[$ticket_type] ) ) { | ||||
|             $ticket_types[$ticket_type]['count']++; | ||||
|             if ( isset( $txn['price'] ) ) { | ||||
|                 $ticket_types[$ticket_type]['revenue'] += floatval( $txn['price'] ); | ||||
|             } | ||||
|         } else { | ||||
|             $ticket_types[$ticket_type] = array( | ||||
|                 'count' => 1, | ||||
|                 'revenue' => isset( $txn['price'] ) ? floatval( $txn['price'] ) : 0, | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Start the template
 | ||||
| get_header(); | ||||
| ?>
 | ||||
| 
 | ||||
| <div id="primary" class="content-area primary ast-container"> | ||||
|     <main id="main" class="site-main"> | ||||
|          | ||||
|         <!-- Event Summary Header & Navigation --> | ||||
|         <div class="hvac-dashboard-header"> | ||||
|             <h1 class="entry-title"><?php echo esc_html( $event_details['title'] ); ?> - Summary</h1>
 | ||||
|             <div class="hvac-dashboard-nav"> | ||||
|                 <a href="<?php echo esc_url( home_url( '/hvac-dashboard/' ) ); ?>" class="ast-button ast-button-primary">Dashboard</a> | ||||
|                 <?php | ||||
|                 // Edit event link (if user has permission)
 | ||||
|                 if ( current_user_can( 'edit_post', $event_id ) ) { | ||||
|                     $edit_url = add_query_arg( 'event_id', $event_id, home_url( '/manage-event/' ) ); | ||||
|                     echo '<a href="' . esc_url( $edit_url ) . '" class="ast-button ast-button-primary">Edit Event</a>'; | ||||
|                 } | ||||
|                  | ||||
|                 // View public event page
 | ||||
|                 echo '<a href="' . esc_url( $event_details['permalink'] ) . '" class="ast-button ast-button-secondary" target="_blank">View Public Page</a>'; | ||||
|                  | ||||
|                 // Email attendees link (future feature)
 | ||||
|                 if ( current_user_can( 'edit_post', $event_id ) ) { | ||||
|                     // TODO: Link to actual Email Attendees page when implemented (Phase 2)
 | ||||
|                     $email_url = '#'; // Placeholder for now
 | ||||
|                     echo '<a href="' . esc_url( $email_url ) . '" class="ast-button ast-button-secondary">Email Attendees</a>'; | ||||
|                 } | ||||
|                 ?>
 | ||||
|             </div> | ||||
|         </div> | ||||
|          | ||||
|         <!-- Event Overview Section --> | ||||
|         <section class="hvac-event-summary-section"> | ||||
|             <h2>Event Overview</h2> | ||||
|             <div class="hvac-event-summary-content"> | ||||
|                 <!-- Event Details --> | ||||
|                 <div class="hvac-event-details"> | ||||
|                     <table class="hvac-details-table"> | ||||
|                         <tr> | ||||
|                             <th>Date & Time:</th> | ||||
|                             <td> | ||||
|                                 <?php  | ||||
|                                 if ( function_exists( 'tribe_get_start_date' ) && function_exists( 'tribe_get_end_date' ) ) { | ||||
|                                     echo esc_html( tribe_get_start_date( $event_id, false ) ); | ||||
|                                     if ( ! $event_details['is_all_day'] ) { | ||||
|                                         echo ' @ ' . esc_html( tribe_get_start_date( $event_id, false, 'g:i a' ) ); | ||||
|                                     } | ||||
|                                     // Show end date/time if different from start date
 | ||||
|                                     $start_date = tribe_get_start_date( $event_id, false, 'Y-m-d' ); | ||||
|                                     $end_date = tribe_get_end_date( $event_id, false, 'Y-m-d' ); | ||||
|                                     if ( $start_date !== $end_date ) { | ||||
|                                         echo ' - ' . esc_html( tribe_get_end_date( $event_id, false ) ); | ||||
|                                         if ( ! $event_details['is_all_day'] ) { | ||||
|                                             echo ' @ ' . esc_html( tribe_get_end_date( $event_id, false, 'g:i a' ) ); | ||||
|                                         } | ||||
|                                     } elseif ( ! $event_details['is_all_day'] ) { | ||||
|                                         echo ' - ' . esc_html( tribe_get_end_date( $event_id, false, 'g:i a' ) ); | ||||
|                                     } | ||||
|                                 } else { | ||||
|                                     echo esc_html( $event_details['start_date'] ?? 'N/A' ); | ||||
|                                     echo ' - '; | ||||
|                                     echo esc_html( $event_details['end_date'] ?? 'N/A' ); | ||||
|                                 } | ||||
|                                 ?>
 | ||||
|                             </td> | ||||
|                         </tr> | ||||
|                         <tr> | ||||
|                             <th>Status:</th> | ||||
|                             <td><?php echo esc_html( ucfirst( get_post_status( $event_id ) ) ); ?></td>
 | ||||
|                         </tr> | ||||
|                         <tr> | ||||
|                             <th>Cost:</th> | ||||
|                             <td><?php echo esc_html( $event_details['cost'] ?? 'N/A' ); ?></td>
 | ||||
|                         </tr> | ||||
|                         <?php if ( $venue_details && ! empty( $venue_details['name'] ) ) : ?>
 | ||||
|                         <tr> | ||||
|                             <th>Venue:</th> | ||||
|                             <td> | ||||
|                                 <?php echo esc_html( $venue_details['name'] ); ?>
 | ||||
|                                 <?php if ( ! empty( $venue_details['address'] ) ) : ?>
 | ||||
|                                     <div class="hvac-detail-subtext"><?php echo esc_html( $venue_details['address'] ); ?></div>
 | ||||
|                                 <?php endif; ?>
 | ||||
|                             </td> | ||||
|                         </tr> | ||||
|                         <?php endif; ?>
 | ||||
|                         <?php if ( $organizer_details && ! empty( $organizer_details['name'] ) ) : ?>
 | ||||
|                         <tr> | ||||
|                             <th>Organizer:</th> | ||||
|                             <td> | ||||
|                                 <?php echo esc_html( $organizer_details['name'] ); ?>
 | ||||
|                                 <?php if ( ! empty( $organizer_details['email'] ) ) : ?>
 | ||||
|                                     <div class="hvac-detail-subtext"><?php echo esc_html( $organizer_details['email'] ); ?></div>
 | ||||
|                                 <?php endif; ?>
 | ||||
|                             </td> | ||||
|                         </tr> | ||||
|                         <?php endif; ?>
 | ||||
|                     </table> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </section> | ||||
|          | ||||
|         <!-- Event Statistics Section --> | ||||
|         <section class="hvac-event-summary-section"> | ||||
|             <h2>Event Statistics</h2> | ||||
|             <div class="hvac-stats-row"> | ||||
|                 <!-- Total Tickets Stat Card --> | ||||
|                 <div class="hvac-stat-col"> | ||||
|                     <div class="hvac-stat-card"> | ||||
|                         <h3>Total Tickets</h3> | ||||
|                         <p class="metric-value"><?php echo esc_html( $total_tickets ); ?></p>
 | ||||
|                     </div> | ||||
|                 </div> | ||||
|                  | ||||
|                 <!-- Total Revenue Stat Card --> | ||||
|                 <div class="hvac-stat-col"> | ||||
|                     <div class="hvac-stat-card"> | ||||
|                         <h3>Total Revenue</h3> | ||||
|                         <p class="metric-value">$<?php echo esc_html( number_format( $total_revenue, 2 ) ); ?></p>
 | ||||
|                     </div> | ||||
|                 </div> | ||||
|                  | ||||
|                 <!-- Ticket Types / Distribution --> | ||||
|                 <?php foreach ( $ticket_types as $type => $data ) : ?>
 | ||||
|                 <div class="hvac-stat-col"> | ||||
|                     <div class="hvac-stat-card"> | ||||
|                         <h3><?php echo esc_html( $type ); ?></h3>
 | ||||
|                         <p class="metric-value"><?php echo esc_html( $data['count'] ); ?></p>
 | ||||
|                         <small>$<?php echo esc_html( number_format( $data['revenue'], 2 ) ); ?></small>
 | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <?php endforeach; ?>
 | ||||
|             </div> | ||||
|         </section> | ||||
|          | ||||
|         <!-- Ticket Sales / Attendees Section --> | ||||
|         <section class="hvac-event-summary-section"> | ||||
|             <h2>Ticket Sales & Attendees</h2> | ||||
|             <?php if ( ! empty( $transactions ) ) : ?>
 | ||||
|             <div class="hvac-event-summary-content"> | ||||
|                 <table class="hvac-transactions-table"> | ||||
|                     <thead> | ||||
|                         <tr> | ||||
|                             <th>Attendee</th> | ||||
|                             <th>Email</th> | ||||
|                             <th>Ticket Type</th> | ||||
|                             <th>Price</th> | ||||
|                             <th>Order ID</th> | ||||
|                             <th>Checked In</th> | ||||
|                         </tr> | ||||
|                     </thead> | ||||
|                     <tbody> | ||||
|                         <?php foreach ( $transactions as $txn ) : ?>
 | ||||
|                         <tr> | ||||
|                             <td><?php echo esc_html( $txn['purchaser_name'] ?? 'N/A' ); ?></td>
 | ||||
|                             <td><?php echo esc_html( $txn['purchaser_email'] ?? 'N/A' ); ?></td>
 | ||||
|                             <td><?php echo esc_html( $txn['ticket_type_name'] ?? 'N/A' ); ?></td>
 | ||||
|                             <td>$<?php echo esc_html( number_format( $txn['price'] ?? 0, 2 ) ); ?></td>
 | ||||
|                             <td><?php echo esc_html( $txn['order_id'] ?? 'N/A' ); ?></td>
 | ||||
|                             <td><?php echo $txn['checked_in'] ? 'Yes' : 'No'; ?></td>
 | ||||
|                         </tr> | ||||
|                         <?php endforeach; ?>
 | ||||
|                     </tbody> | ||||
|                 </table> | ||||
|             </div> | ||||
|             <?php else : ?>
 | ||||
|             <p>No ticket sales or attendees found for this event.</p> | ||||
|             <?php endif; ?>
 | ||||
|         </section> | ||||
|          | ||||
|         <!-- Event Description Section --> | ||||
|         <section class="hvac-event-summary-section"> | ||||
|             <h2>Event Description</h2> | ||||
|             <div class="hvac-event-summary-content"> | ||||
|                 <div class="hvac-event-description"> | ||||
|                     <?php echo wp_kses_post( $event_details['description'] ); ?>
 | ||||
|                 </div> | ||||
|             </div> | ||||
|         </section> | ||||
|          | ||||
|     </main> | ||||
| </div> | ||||
| 
 | ||||
| <!-- Include CSS for the Event Summary page --> | ||||
| <style> | ||||
|     /* Event Summary Specific Styles */ | ||||
|     .hvac-event-summary-section { | ||||
|         margin-bottom: 40px; | ||||
|         background: #f8f9fa;
 | ||||
|         border-radius: 8px; | ||||
|         padding: 20px; | ||||
|         border: 1px solid #e9ecef;
 | ||||
|     } | ||||
|      | ||||
|     .hvac-event-summary-section h2 { | ||||
|         margin-top: 0; | ||||
|         margin-bottom: 20px; | ||||
|         border-bottom: 1px solid #eee;
 | ||||
|         padding-bottom: 10px; | ||||
|     } | ||||
|      | ||||
|     .hvac-event-summary-content { | ||||
|         margin-top: 20px; | ||||
|     } | ||||
|      | ||||
|     /* Details Table */ | ||||
|     .hvac-details-table { | ||||
|         width: 100%; | ||||
|         border-collapse: collapse; | ||||
|     } | ||||
|      | ||||
|     .hvac-details-table th, | ||||
|     .hvac-details-table td { | ||||
|         padding: 10px; | ||||
|         text-align: left; | ||||
|         border-bottom: 1px solid #eee;
 | ||||
|         vertical-align: top; | ||||
|     } | ||||
|      | ||||
|     .hvac-details-table th { | ||||
|         width: 150px; | ||||
|         font-weight: bold; | ||||
|     } | ||||
|      | ||||
|     .hvac-detail-subtext { | ||||
|         font-size: 0.9em; | ||||
|         color: #666;
 | ||||
|         margin-top: 5px; | ||||
|     } | ||||
|      | ||||
|     /* Transactions Table */ | ||||
|     .hvac-transactions-table { | ||||
|         width: 100%; | ||||
|         border-collapse: collapse; | ||||
|         margin-top: 20px; | ||||
|     } | ||||
|      | ||||
|     .hvac-transactions-table th, | ||||
|     .hvac-transactions-table td { | ||||
|         padding: 10px; | ||||
|         text-align: left; | ||||
|         border-bottom: 1px solid #eee;
 | ||||
|     } | ||||
|      | ||||
|     .hvac-transactions-table th { | ||||
|         background-color: #f1f1f1;
 | ||||
|         font-weight: bold; | ||||
|     } | ||||
|      | ||||
|     .hvac-transactions-table tr:nth-child(even) { | ||||
|         background-color: #f9f9f9;
 | ||||
|     } | ||||
|      | ||||
|     .hvac-transactions-table tr:hover { | ||||
|         background-color: #f0f0f0;
 | ||||
|     } | ||||
|      | ||||
|     /* Stats Row (reused from dashboard) */ | ||||
|     .hvac-stats-row { | ||||
|         display: flex; | ||||
|         flex-direction: row; | ||||
|         flex-wrap: wrap; | ||||
|         margin: -10px; | ||||
|         justify-content: space-between; | ||||
|         align-items: stretch; | ||||
|     } | ||||
|      | ||||
|     .hvac-stat-col { | ||||
|         flex: 1; | ||||
|         min-width: 160px; | ||||
|         padding: 10px; | ||||
|     } | ||||
|      | ||||
|     .hvac-stat-card { | ||||
|         border: 1px solid #eee;
 | ||||
|         padding: 15px; | ||||
|         background: #fff;
 | ||||
|         text-align: center; | ||||
|         width: 100%; | ||||
|         flex-grow: 1; | ||||
|         height: 100%; | ||||
|     } | ||||
|      | ||||
|     .hvac-stat-card h3 { | ||||
|         margin: 0 0 10px; | ||||
|         font-size: 16px; | ||||
|         font-weight: normal; | ||||
|         color: #666;
 | ||||
|     } | ||||
|      | ||||
|     .hvac-stat-card .metric-value { | ||||
|         font-size: 32px; | ||||
|         font-weight: bold; | ||||
|         color: #E9AF28;
 | ||||
|         margin: 0; | ||||
|     } | ||||
|      | ||||
|     .hvac-stat-card small { | ||||
|         display: block; | ||||
|         margin-top: 5px; | ||||
|         color: #666;
 | ||||
|     } | ||||
|      | ||||
|     @media (max-width: 768px) { | ||||
|         .hvac-dashboard-header { | ||||
|             flex-direction: column; | ||||
|             align-items: flex-start; | ||||
|         } | ||||
|          | ||||
|         .hvac-dashboard-nav { | ||||
|             margin-top: 15px; | ||||
|             display: flex; | ||||
|             flex-wrap: wrap; | ||||
|         } | ||||
|          | ||||
|         .hvac-dashboard-nav a { | ||||
|             margin: 5px 5px 5px 0; | ||||
|         } | ||||
|          | ||||
|         .hvac-details-table th { | ||||
|             width: 100px; | ||||
|         } | ||||
|          | ||||
|         .hvac-transactions-table { | ||||
|             display: block; | ||||
|             overflow-x: auto; | ||||
|         } | ||||
|     } | ||||
| </style> | ||||
| 
 | ||||
| <?php | ||||
| get_footer(); | ||||
| ?>
 | ||||
|  | @ -186,11 +186,14 @@ get_header(); // Use theme's header | |||
| 										<?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 standard WP single event view (handled by our custom template)
 | ||||
| 										$summary_url = get_permalink( $event['id'] ); | ||||
| 										// 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( $summary_url ); ?>">Summary</a> | | ||||
| 										<a href="<?php echo esc_url( $view_url ); ?>" target="_blank">View</a> | ||||
| 									</td> | ||||
| 								</tr> | ||||
| 							<?php endforeach; ?>
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue