diff --git a/docs/TEMPLATE-AND-TICKETING-REQUIREMENTS.md b/docs/TEMPLATE-AND-TICKETING-REQUIREMENTS.md
new file mode 100644
index 00000000..ae0d3814
--- /dev/null
+++ b/docs/TEMPLATE-AND-TICKETING-REQUIREMENTS.md
@@ -0,0 +1,340 @@
+# Template and Ticketing System Requirements
+
+## Overview
+This document outlines the requirements for integrating TEC ticketing system with the HVAC event creation form and updating the template system with real class templates.
+
+## TEC Ticketing Integration Requirements
+
+### Core Requirements
+- Connect form to TEC plugins' ticketing system
+- Same CRUD capabilities as regular TEC events
+- Support for tickets with prices, season passes, RSVPs
+- Mandatory collection of attendee information
+
+### Trainer Limitations
+- Trainers don't need to set SKUs (simplified interface)
+- Each ticket should have mandatory registration collection:
+ - First name
+ - Last name
+ - Fields from TEC Ticket Fieldset Post ID 6235
+
+### Ticketing Features Needed
+- Ticket creation with pricing
+- Season pass support
+- RSVP functionality
+- Attendee information collection
+- Integration with TEC core ticketing system
+
+## Template System Updates
+
+### Current Issues
+- Modal popup not properly centered (positioned bottom-right, cropped)
+- Sample templates need replacement with real class templates
+
+### Required Templates
+Based on cleaned template data from `docs/reference/EVENT_TEMPLATES_2025-09-25.md`:
+
+1. **Transform Your HVAC Business with Manual J LiDAR**
+ - Source: Post ID 1658
+ - Type: Half-day introductory training
+ - Category: Business/Technology
+ - Default Time: 8:00 AM - 12:00 PM
+ - Default Price: $99 per person
+
+2. **Master Static Pressure & Airflow: The Keys to Profitable Service**
+ - Source: Post ID 1661
+ - Type: Half-day introductory training
+ - Category: Technical/Performance
+ - Default Time: 1:00 PM - 5:00 PM
+ - Default Price: $99 per person
+
+3. **Full-Day A/C and Heat Pump Commissioning & Diagnostics Mastery with measureQuick**
+ - Source: Post ID 5295
+ - Type: Full-day advanced training
+ - Category: Technical/Diagnostics
+ - Default Time: 8:00 AM - 5:00 PM
+ - Default Price: $99 per person
+
+4. **ACCA QI5 Quality Installation Certificates - VSP and VEO**
+ - Source: Post ID 1663
+ - Type: Full-day intermediate certification
+ - Category: Certification/Standards
+ - Default Time: 8:00 AM - 4:00 PM
+ - Default Price: $129 per person
+
+5. **Advanced Class: Building Science Meets HVAC Performance**
+ - Source: Post ID 1665
+ - Type: Three-day advanced training
+ - Category: Advanced/Building Science
+ - Default Time: 8:00 AM - 5:00 PM (3 days)
+ - Default Price: $1200 per person
+
+6. **measureQuick for Gas Heating**
+ - Source: Post ID 5737
+ - Type: Half-day product training
+ - Category: Product Training/Gas Systems
+ - Default Time: 8:00 AM - 2:00 PM
+ - Default Price: $150 per person
+
+### Template Data Structure
+Each template should include:
+- Title
+- Description (from source post)
+- Start time (time only, no date)
+- End time (time only, no date)
+- Default ticket structure
+- Category classification
+- Duration/type indicators
+
+## Implementation Plan
+
+### Phase 1: Analysis and Planning
+1. Analyze current TEC integration points
+2. Examine TEC Ticket Fieldset Post ID 6235 structure
+3. Review existing form builder capabilities
+4. Identify required modifications to HVAC_Event_Form_Builder
+
+### Phase 2: TEC Ticketing Integration
+1. Extend HVAC_Event_Form_Builder with TEC ticketing fields
+2. Implement mandatory attendee information collection
+3. Connect to TEC ticket creation API
+4. Add ticket pricing and management fields
+5. Integrate with TEC RSVP system
+
+### Phase 3: Template System Fixes
+1. Fix modal positioning CSS issues
+2. Fetch real template data from specified post IDs
+3. Create template data structure with proper categorization
+4. Update template modal with real class information
+5. Implement template application with ticket data
+
+### Phase 4: Testing and Validation
+1. Test TEC ticketing integration
+2. Validate attendee information collection
+3. Test template modal positioning
+4. Verify template application functionality
+5. End-to-end testing of event creation flow
+
+## Technical Considerations
+
+### TEC Integration Points
+- TEC Core ticketing API
+- TEC Community Events integration
+- TEC Tickets Plus (if applicable)
+- Custom field integration
+
+### Database Requirements
+- Integration with TEC events tables
+- Ticket information storage
+- Attendee data collection
+- Custom field mappings
+
+### UI/UX Considerations
+- Simplified trainer interface
+- Mandatory field validation
+- Modal positioning fixes
+- Responsive template selection
+
+## Implementation Plan
+
+### Analysis Results
+
+#### Current Architecture
+- **HVAC_Event_Form_Builder** (1296 lines): Core form builder with template integration
+- **HVAC_TEC_Integration** (357 lines): URL routing and iframe embedding, lacks ticketing
+- **page-tec-create-event.php**: Contains modal with hardcoded sample templates and positioning issues
+
+#### Key Findings
+1. **Template System**: Uses hardcoded JavaScript sample data instead of real posts
+2. **TEC Integration**: Handles iframe embedding but lacks ticketing system integration
+3. **Modal Issues**: CSS positioning causes bottom-right placement and cropping
+4. **Missing Components**: No direct TEC ticketing API integration, no fieldset integration
+
+### Phase-by-Phase Implementation
+
+#### Phase 1: Modal Positioning Fix (Immediate - 30 minutes)
+**Files to modify:**
+- `templates/page-tec-create-event.php`
+
+**Changes required:**
+```css
+/* Fix modal positioning in CSS section */
+.template-modal {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%); /* Center the modal */
+ z-index: 10000;
+ max-height: 80vh;
+ overflow-y: auto;
+}
+```
+
+#### Phase 2: Template System Updates (1-2 hours)
+**Files to modify:**
+- `templates/page-tec-create-event.php` (JavaScript section)
+- `includes/class-hvac-event-form-builder.php` (template loading methods)
+
+**Changes required:**
+1. Replace hardcoded template JavaScript with real template data
+2. Create template data structure from cleaned template reference
+3. Update template loading to use standardized format
+4. Add template categorization and filtering
+
+**Template Data Format:**
+```javascript
+const templates = [
+ {
+ id: 'manual-j-lidar',
+ title: 'Transform Your HVAC Business with Manual J LiDAR',
+ category: 'Business/Technology',
+ duration: 'Half Day',
+ difficulty: 'Introductory',
+ defaultTime: { start: '08:00', end: '12:00' },
+ defaultPrice: 99,
+ description: 'Master iPad-based Manual J calculations and measureQuick fundamentals...',
+ requirements: 'No special Heating Cooling Equip. Needs, good Internet connection',
+ maxStudents: null
+ }
+ // ... other templates
+];
+```
+
+#### Phase 3: TEC Ticketing Integration (3-4 hours)
+**Files to modify:**
+- `includes/class-hvac-event-form-builder.php`
+- `includes/class-hvac-tec-integration.php`
+- Create new: `includes/class-hvac-tec-tickets.php`
+
+**Changes required:**
+1. **Analyze TEC Ticket Fieldset Post ID 6235**
+ - Extract field definitions and requirements
+ - Map mandatory fields: first name, last name, custom fields
+
+2. **Extend HVAC_Event_Form_Builder with ticketing fields:**
+ ```php
+ // Add methods
+ private function add_ticket_fields()
+ private function add_tec_fieldset_integration()
+ private function validate_ticket_requirements()
+ ```
+
+3. **Create TEC tickets integration class:**
+ ```php
+ class HVAC_TEC_Tickets {
+ public function create_event_tickets($event_id, $ticket_data)
+ public function get_fieldset_fields($fieldset_id = 6235)
+ public function validate_attendee_data($attendee_data)
+ private function integrate_with_tec_api()
+ }
+ ```
+
+4. **Add ticket management UI elements:**
+ - Ticket pricing fields
+ - Season pass options
+ - RSVP configuration
+ - Attendee information requirements
+
+#### Phase 4: Fieldset Integration (1-2 hours)
+**Files to investigate:**
+- TEC Ticket Fieldset Post ID 6235 structure
+- TEC Community Events ticket field mapping
+
+**Changes required:**
+1. Extract fieldset field definitions from Post ID 6235
+2. Create dynamic form field generation based on fieldset
+3. Add validation for mandatory attendee information
+4. Integrate with TEC ticket creation workflow
+
+#### Phase 5: Testing and Validation (2-3 hours)
+**Testing checklist:**
+1. Modal positioning fixes across different screen sizes
+2. Template selection and form population
+3. TEC ticket creation with proper fieldset integration
+4. Attendee information collection and validation
+5. End-to-end event creation workflow
+6. Integration with existing TEC Community Events
+
+### Technical Implementation Details
+
+#### Modal Fix Implementation
+```css
+/* Replace existing modal CSS with: */
+.template-modal {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 90%;
+ max-width: 800px;
+ max-height: 80vh;
+ background: white;
+ border-radius: 8px;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.3);
+ z-index: 10000;
+ overflow-y: auto;
+}
+```
+
+#### Template Data Integration
+```php
+// In HVAC_Event_Form_Builder
+private function get_real_templates() {
+ return [
+ [
+ 'id' => 'manual-j-lidar',
+ 'title' => 'Transform Your HVAC Business with Manual J LiDAR',
+ 'description' => $this->get_template_description('manual-j-lidar'),
+ 'default_start_time' => '08:00',
+ 'default_end_time' => '12:00',
+ 'default_price' => 99,
+ 'category' => 'Business/Technology',
+ 'difficulty' => 'Introductory',
+ 'duration' => 'Half Day'
+ ]
+ // ... other templates
+ ];
+}
+```
+
+#### TEC Ticketing Integration
+```php
+// New class: HVAC_TEC_Tickets
+class HVAC_TEC_Tickets {
+
+ public function create_tickets_for_event($event_id, $tickets_data) {
+ foreach ($tickets_data as $ticket) {
+ $ticket_id = $this->create_tec_ticket($event_id, $ticket);
+ $this->add_fieldset_requirements($ticket_id, 6235);
+ }
+ }
+
+ private function get_tec_fieldset_fields($fieldset_id) {
+ // Extract field definitions from TEC Ticket Fieldset
+ $fieldset_post = get_post($fieldset_id);
+ return $this->parse_fieldset_structure($fieldset_post);
+ }
+}
+```
+
+### Priority Order
+1. **IMMEDIATE**: Fix modal positioning (30 minutes)
+2. **HIGH**: Replace sample templates with real data (1-2 hours)
+3. **MEDIUM**: Implement TEC ticketing integration (3-4 hours)
+4. **LOW**: Add fieldset integration (1-2 hours)
+5. **FINAL**: Comprehensive testing (2-3 hours)
+
+### Risk Assessment
+- **Low Risk**: Modal positioning fix, template data replacement
+- **Medium Risk**: TEC ticketing API integration (requires understanding TEC internals)
+- **High Risk**: Fieldset integration (depends on TEC Ticket Fieldset structure)
+
+### Success Metrics
+1. Modal centers properly on all screen sizes
+2. Real templates load with correct data and formatting
+3. TEC tickets can be created with mandatory attendee information
+4. Form maintains existing functionality while adding new features
+5. Integration works seamlessly with existing TEC Community Events
+
+---
+*Implementation plan generated during TEC integration and template system improvement project*
\ No newline at end of file
diff --git a/includes/class-hvac-event-form-builder.php b/includes/class-hvac-event-form-builder.php
index eab40d73..d3748dbe 100644
--- a/includes/class-hvac-event-form-builder.php
+++ b/includes/class-hvac-event-form-builder.php
@@ -169,6 +169,9 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
// Basic event fields
$this->add_basic_event_fields();
+ // Add TEC ticketing integration hook
+ do_action('hvac_event_form_after_basic_fields', $this);
+
// Optional field groups
if ($config['include_datetime_fields']) {
$this->add_datetime_fields();
@@ -255,19 +258,15 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
}
}
- $template_field = array_merge($this->event_field_defaults['template-selector'], [
- 'name' => 'event_template',
- 'label' => 'Use Template',
- 'options' => $template_options,
- 'description' => 'Select a template to pre-fill form fields. Templates are organized by category.',
- 'wrapper_class' => 'form-row template-selector-row enhanced-selector',
- 'data_attributes' => [
- 'templates' => json_encode($templates),
- 'enable_preview' => 'true'
- ]
- ]);
+ // Create accordion-style template selector
+ $accordion_template_field = [
+ 'type' => 'custom',
+ 'name' => 'accordion_template_selector',
+ 'custom_html' => $this->render_accordion_template_selector($template_options, $templates),
+ 'wrapper_class' => 'form-row template-selector-row',
+ ];
- $this->add_field($template_field);
+ $this->add_field($accordion_template_field);
// Add template preview area
$preview_field = [
@@ -600,6 +599,46 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
}
}
+ /**
+ * Render accordion-style template selector
+ *
+ * @param array $template_options Template options array
+ * @param array $templates Raw templates data
+ * @return string Accordion HTML
+ */
+ private function render_accordion_template_selector(array $template_options, array $templates): string {
+ $html = '
';
+ $html .= '';
+ $html .= '
';
+
+ // Build select options HTML
+ $html .= '
';
+ $html .= '
Select a template to pre-fill form fields with common settings.
';
+ $html .= '
';
+ $html .= '
';
+
+ return $html;
+ }
+
/**
* Render template preview area
*
@@ -804,7 +843,8 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
'name' => 'new_venue_name',
'label' => 'Venue Name',
'class' => 'hvac-venue-field',
- 'wrapper_class' => 'form-row venue-creation-field hidden',
+ 'wrapper_class' => 'form-row venue-creation-field hvac-hidden-field',
+ 'data_attributes' => ['conditional' => 'venue-create'],
'required' => false,
],
[
@@ -812,28 +852,32 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
'name' => 'new_venue_address',
'label' => 'Address',
'class' => 'hvac-venue-field',
- 'wrapper_class' => 'form-row venue-creation-field hidden',
+ 'wrapper_class' => 'form-row venue-creation-field hvac-hidden-field',
+ 'data_attributes' => ['conditional' => 'venue-create'],
],
[
'type' => 'text',
'name' => 'new_venue_city',
'label' => 'City',
'class' => 'hvac-venue-field',
- 'wrapper_class' => 'form-row venue-creation-field hidden',
+ 'wrapper_class' => 'form-row venue-creation-field hvac-hidden-field',
+ 'data_attributes' => ['conditional' => 'venue-create'],
],
[
'type' => 'text',
'name' => 'new_venue_state',
'label' => 'State',
'class' => 'hvac-venue-field',
- 'wrapper_class' => 'form-row venue-creation-field hidden',
+ 'wrapper_class' => 'form-row venue-creation-field hvac-hidden-field',
+ 'data_attributes' => ['conditional' => 'venue-create'],
],
[
'type' => 'text',
'name' => 'new_venue_zip',
'label' => 'Zip Code',
'class' => 'hvac-venue-field',
- 'wrapper_class' => 'form-row venue-creation-field hidden',
+ 'wrapper_class' => 'form-row venue-creation-field hvac-hidden-field',
+ 'data_attributes' => ['conditional' => 'venue-create'],
],
];
@@ -854,7 +898,8 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
'name' => 'new_organizer_name',
'label' => 'Organizer Name',
'class' => 'hvac-organizer-field',
- 'wrapper_class' => 'form-row organizer-creation-field hidden',
+ 'wrapper_class' => 'form-row organizer-creation-field hvac-hidden-field',
+ 'data_attributes' => ['conditional' => 'organizer-create'],
'required' => false,
],
[
@@ -862,7 +907,8 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
'name' => 'new_organizer_email',
'label' => 'Email',
'class' => 'hvac-organizer-field',
- 'wrapper_class' => 'form-row organizer-creation-field hidden',
+ 'wrapper_class' => 'form-row organizer-creation-field hvac-hidden-field',
+ 'data_attributes' => ['conditional' => 'organizer-create'],
'validate' => ['email'],
],
[
@@ -870,14 +916,16 @@ class HVAC_Event_Form_Builder extends HVAC_Form_Builder {
'name' => 'new_organizer_phone',
'label' => 'Phone',
'class' => 'hvac-organizer-field',
- 'wrapper_class' => 'form-row organizer-creation-field hidden',
+ 'wrapper_class' => 'form-row organizer-creation-field hvac-hidden-field',
+ 'data_attributes' => ['conditional' => 'organizer-create'],
],
[
'type' => 'url',
'name' => 'new_organizer_website',
'label' => 'Website',
'class' => 'hvac-organizer-field',
- 'wrapper_class' => 'form-row organizer-creation-field hidden',
+ 'wrapper_class' => 'form-row organizer-creation-field hvac-hidden-field',
+ 'data_attributes' => ['conditional' => 'organizer-create'],
'validate' => ['url'],
],
];
diff --git a/includes/class-hvac-plugin.php b/includes/class-hvac-plugin.php
index fd94ba8a..1feee6ab 100644
--- a/includes/class-hvac-plugin.php
+++ b/includes/class-hvac-plugin.php
@@ -192,7 +192,10 @@ final class HVAC_Plugin {
// TEC Integration - Load early for proper routing
require_once HVAC_PLUGIN_DIR . 'includes/class-hvac-tec-integration.php';
-
+
+ // TEC Ticketing Integration - Phase 2B
+ require_once HVAC_PLUGIN_DIR . 'includes/class-hvac-tec-tickets.php';
+
// Load singleton trait first (required by multiple classes)
require_once HVAC_PLUGIN_DIR . 'includes/trait-hvac-singleton.php';
diff --git a/includes/class-hvac-tec-tickets.php b/includes/class-hvac-tec-tickets.php
new file mode 100644
index 00000000..e2191136
--- /dev/null
+++ b/includes/class-hvac-tec-tickets.php
@@ -0,0 +1,650 @@
+ [
+ 'type' => 'text',
+ 'label' => 'First Name',
+ 'required' => true,
+ 'sanitize' => 'text'
+ ],
+ 'last_name' => [
+ 'type' => 'text',
+ 'label' => 'Last Name',
+ 'required' => true,
+ 'sanitize' => 'text'
+ ]
+ ];
+
+ /**
+ * Get singleton instance
+ *
+ * @return HVAC_TEC_Tickets
+ */
+ public static function instance(): HVAC_TEC_Tickets {
+ if (null === self::$instance) {
+ self::$instance = new self();
+ }
+ return self::$instance;
+ }
+
+ /**
+ * Constructor
+ */
+ private function __construct() {
+ $this->init_hooks();
+ }
+
+ /**
+ * Initialize hooks
+ */
+ private function init_hooks(): void {
+ // Hook into TEC event creation
+ add_action('tribe_events_event_save', [$this, 'handle_event_save'], 10, 2);
+
+ // Add ticket management to HVAC forms
+ add_action('hvac_event_form_after_basic_fields', [$this, 'add_ticket_fields']);
+
+ // Handle ticket creation AJAX
+ add_action('wp_ajax_hvac_create_event_tickets', [$this, 'ajax_create_event_tickets']);
+ add_action('wp_ajax_hvac_update_event_tickets', [$this, 'ajax_update_event_tickets']);
+
+ // Add mandatory attendee fields to ticket forms
+ add_filter('tribe_tickets_attendee_registration_form_fields', [$this, 'add_mandatory_attendee_fields'], 10, 2);
+
+ // Validate mandatory fields on ticket purchase
+ add_action('tribe_tickets_before_save_attendee_data', [$this, 'validate_mandatory_attendee_data'], 10, 3);
+
+ // Enqueue ticketing assets
+ add_action('wp_enqueue_scripts', [$this, 'enqueue_ticketing_assets']);
+ }
+
+ /**
+ * Handle event save and create associated tickets
+ *
+ * @param int $event_id Event ID
+ * @param array $data Event data
+ */
+ public function handle_event_save(int $event_id, array $data): void {
+ // Only process HVAC-created events
+ if (!get_post_meta($event_id, '_hvac_event', true)) {
+ return;
+ }
+
+ $ticket_data = get_post_meta($event_id, '_hvac_ticket_data', true);
+ if (!empty($ticket_data)) {
+ $this->create_tickets_for_event($event_id, $ticket_data);
+ }
+ }
+
+ /**
+ * Create tickets for an event
+ *
+ * @param int $event_id Event ID
+ * @param array $tickets_data Tickets configuration
+ * @return array Result with success status
+ */
+ public function create_tickets_for_event(int $event_id, array $tickets_data): array {
+ $results = [];
+
+ foreach ($tickets_data as $ticket_config) {
+ $ticket_id = $this->create_tec_ticket($event_id, $ticket_config);
+
+ if ($ticket_id) {
+ // Add mandatory fieldset requirements
+ $this->add_fieldset_requirements($ticket_id, $this->default_fieldset_id);
+ $results[] = ['success' => true, 'ticket_id' => $ticket_id];
+ } else {
+ $results[] = ['success' => false, 'error' => 'Failed to create ticket'];
+ }
+ }
+
+ return [
+ 'success' => count(array_filter($results, fn($r) => $r['success'])) > 0,
+ 'tickets' => $results
+ ];
+ }
+
+ /**
+ * Create a TEC ticket
+ *
+ * @param int $event_id Event ID
+ * @param array $ticket_config Ticket configuration
+ * @return int|false Ticket ID or false on failure
+ */
+ private function create_tec_ticket(int $event_id, array $ticket_config) {
+ // Validate TEC is available
+ if (!class_exists('Tribe__Tickets__Tickets')) {
+ error_log('HVAC TEC Tickets: TEC Tickets plugin not available');
+ return false;
+ }
+
+ $ticket_data = [
+ 'ticket_name' => sanitize_text_field($ticket_config['name'] ?? 'Event Ticket'),
+ 'ticket_description' => wp_kses_post($ticket_config['description'] ?? ''),
+ 'ticket_price' => floatval($ticket_config['price'] ?? 0),
+ 'ticket_start_date' => sanitize_text_field($ticket_config['start_date'] ?? ''),
+ 'ticket_end_date' => sanitize_text_field($ticket_config['end_date'] ?? ''),
+ 'ticket_stock' => intval($ticket_config['capacity'] ?? -1), // -1 = unlimited
+ 'ticket_sku' => '', // Trainers don't set SKUs per requirements
+ ];
+
+ // Create ticket using TEC API
+ try {
+ $ticket_handler = tribe('tickets.handler');
+ $ticket_id = $ticket_handler->create_ticket($event_id, $ticket_data);
+
+ if ($ticket_id) {
+ // Add HVAC-specific metadata
+ update_post_meta($ticket_id, '_hvac_ticket', true);
+ update_post_meta($ticket_id, '_hvac_ticket_config', $ticket_config);
+
+ return $ticket_id;
+ }
+ } catch (Exception $e) {
+ error_log('HVAC TEC Tickets: Error creating ticket - ' . $e->getMessage());
+ }
+
+ return false;
+ }
+
+ /**
+ * Add fieldset requirements to ticket
+ *
+ * @param int $ticket_id Ticket ID
+ * @param int $fieldset_id Fieldset ID
+ */
+ private function add_fieldset_requirements(int $ticket_id, int $fieldset_id): void {
+ $fieldset_fields = $this->get_tec_fieldset_fields($fieldset_id);
+
+ if (!empty($fieldset_fields)) {
+ update_post_meta($ticket_id, '_tribe_tickets_attendee_info_fieldset', $fieldset_id);
+
+ // Ensure mandatory fields are included
+ $all_fields = array_merge($this->mandatory_fields, $fieldset_fields);
+ update_post_meta($ticket_id, '_hvac_ticket_mandatory_fields', $all_fields);
+ }
+ }
+
+ /**
+ * Get TEC fieldset fields
+ *
+ * @param int $fieldset_id Fieldset ID
+ * @return array Fieldset fields
+ */
+ private function get_tec_fieldset_fields(int $fieldset_id): array {
+ // Check if fieldset exists
+ $fieldset_post = get_post($fieldset_id);
+ if (!$fieldset_post || $fieldset_post->post_type !== 'tribe_rsvp_tickets_ticket_fieldset') {
+ // Return basic fields if fieldset not found
+ return [
+ 'email' => [
+ 'type' => 'email',
+ 'label' => 'Email Address',
+ 'required' => true,
+ 'sanitize' => 'email'
+ ],
+ 'phone' => [
+ 'type' => 'tel',
+ 'label' => 'Phone Number',
+ 'required' => false,
+ 'sanitize' => 'text'
+ ]
+ ];
+ }
+
+ // Parse fieldset structure - this would need to be adapted based on TEC's actual fieldset format
+ $fieldset_meta = get_post_meta($fieldset_id, '_tribe_tickets_fieldset_fields', true);
+
+ if (is_array($fieldset_meta)) {
+ return $this->parse_fieldset_structure($fieldset_meta);
+ }
+
+ return [];
+ }
+
+ /**
+ * Parse fieldset structure into standardized format
+ *
+ * @param array $fieldset_data Raw fieldset data
+ * @return array Parsed fields
+ */
+ private function parse_fieldset_structure(array $fieldset_data): array {
+ $parsed_fields = [];
+
+ foreach ($fieldset_data as $field) {
+ if (!isset($field['slug']) || !isset($field['type'])) {
+ continue;
+ }
+
+ $parsed_fields[$field['slug']] = [
+ 'type' => $this->normalize_field_type($field['type']),
+ 'label' => $field['label'] ?? ucfirst(str_replace('_', ' ', $field['slug'])),
+ 'required' => !empty($field['required']),
+ 'sanitize' => $this->get_sanitization_method($field['type']),
+ 'options' => $field['options'] ?? null
+ ];
+ }
+
+ return $parsed_fields;
+ }
+
+ /**
+ * Normalize field type for consistency
+ *
+ * @param string $field_type Original field type
+ * @return string Normalized field type
+ */
+ private function normalize_field_type(string $field_type): string {
+ $type_map = [
+ 'text' => 'text',
+ 'textarea' => 'textarea',
+ 'email' => 'email',
+ 'select' => 'select',
+ 'radio' => 'radio',
+ 'checkbox' => 'checkbox',
+ 'url' => 'url',
+ 'tel' => 'tel',
+ 'number' => 'number',
+ 'date' => 'date'
+ ];
+
+ return $type_map[$field_type] ?? 'text';
+ }
+
+ /**
+ * Get sanitization method for field type
+ *
+ * @param string $field_type Field type
+ * @return string Sanitization method
+ */
+ private function get_sanitization_method(string $field_type): string {
+ $sanitization_map = [
+ 'text' => 'text',
+ 'textarea' => 'textarea',
+ 'email' => 'email',
+ 'url' => 'url',
+ 'tel' => 'text',
+ 'number' => 'int'
+ ];
+
+ return $sanitization_map[$field_type] ?? 'text';
+ }
+
+ /**
+ * Add ticket fields to HVAC event forms
+ *
+ * @param object $form_builder Form builder instance
+ */
+ public function add_ticket_fields($form_builder): void {
+ if (!method_exists($form_builder, 'add_field')) {
+ return;
+ }
+
+ // Ticket section header
+ $form_builder->add_field([
+ 'type' => 'custom',
+ 'name' => 'ticket_section_header',
+ 'custom_html' => '',
+ 'wrapper_class' => 'form-section ticket-section'
+ ]);
+
+ // Enable ticketing checkbox
+ $form_builder->add_field([
+ 'type' => 'checkbox',
+ 'name' => 'enable_ticketing',
+ 'label' => 'Enable Ticketing',
+ 'description' => 'Create tickets for this event with pricing and attendee collection',
+ 'value' => '1',
+ 'wrapper_class' => 'form-row enable-ticketing-row',
+ 'onchange' => 'hvacToggleTicketFields(this.checked)'
+ ]);
+
+ // Ticket configuration container (initially hidden)
+ $form_builder->add_field([
+ 'type' => 'custom',
+ 'name' => 'ticket_config_start',
+ 'custom_html' => '',
+ 'wrapper_class' => ''
+ ]);
+
+ // Ticket name
+ $form_builder->add_field([
+ 'type' => 'text',
+ 'name' => 'ticket_name',
+ 'label' => 'Ticket Name',
+ 'placeholder' => 'e.g., "General Admission", "Early Bird"',
+ 'required' => false,
+ 'wrapper_class' => 'form-row ticket-config-field'
+ ]);
+
+ // Ticket price
+ $form_builder->add_field([
+ 'type' => 'number',
+ 'name' => 'ticket_price',
+ 'label' => 'Ticket Price ($)',
+ 'placeholder' => '0.00',
+ 'step' => '0.01',
+ 'min' => '0',
+ 'required' => false,
+ 'wrapper_class' => 'form-row ticket-config-field'
+ ]);
+
+ // Ticket capacity
+ $form_builder->add_field([
+ 'type' => 'number',
+ 'name' => 'ticket_capacity',
+ 'label' => 'Ticket Capacity',
+ 'placeholder' => 'Leave empty for unlimited',
+ 'min' => '1',
+ 'required' => false,
+ 'wrapper_class' => 'form-row ticket-config-field'
+ ]);
+
+ // Ticket sale start date
+ $form_builder->add_field([
+ 'type' => 'datetime-local',
+ 'name' => 'ticket_start_sale',
+ 'label' => 'Ticket Sales Start',
+ 'description' => 'When ticket sales begin (optional)',
+ 'required' => false,
+ 'wrapper_class' => 'form-row ticket-config-field'
+ ]);
+
+ // Ticket sale end date
+ $form_builder->add_field([
+ 'type' => 'datetime-local',
+ 'name' => 'ticket_end_sale',
+ 'label' => 'Ticket Sales End',
+ 'description' => 'When ticket sales end (optional)',
+ 'required' => false,
+ 'wrapper_class' => 'form-row ticket-config-field'
+ ]);
+
+ // RSVP option
+ $form_builder->add_field([
+ 'type' => 'checkbox',
+ 'name' => 'enable_rsvp',
+ 'label' => 'Enable RSVP',
+ 'description' => 'Allow free RSVP alongside paid tickets',
+ 'value' => '1',
+ 'wrapper_class' => 'form-row ticket-config-field'
+ ]);
+
+ // Mandatory attendee info notice
+ $form_builder->add_field([
+ 'type' => 'custom',
+ 'name' => 'attendee_info_notice',
+ 'custom_html' => '
Note: All tickets will automatically collect mandatory attendee information including first name, last name, and additional fields as configured.
',
+ 'wrapper_class' => 'form-row ticket-config-field'
+ ]);
+
+ // Close ticket configuration container
+ $form_builder->add_field([
+ 'type' => 'custom',
+ 'name' => 'ticket_config_end',
+ 'custom_html' => '
',
+ 'wrapper_class' => ''
+ ]);
+ }
+
+ /**
+ * Add mandatory attendee fields to ticket forms
+ *
+ * @param array $fields Existing fields
+ * @param int $ticket_id Ticket ID
+ * @return array Modified fields
+ */
+ public function add_mandatory_attendee_fields(array $fields, int $ticket_id): array {
+ // Only add to HVAC tickets
+ if (!get_post_meta($ticket_id, '_hvac_ticket', true)) {
+ return $fields;
+ }
+
+ // Get mandatory fields for this ticket
+ $mandatory_fields = get_post_meta($ticket_id, '_hvac_ticket_mandatory_fields', true);
+ if (empty($mandatory_fields)) {
+ $mandatory_fields = $this->mandatory_fields;
+ }
+
+ // Merge mandatory fields with existing fields
+ return array_merge($mandatory_fields, $fields);
+ }
+
+ /**
+ * Validate mandatory attendee data
+ *
+ * @param int $attendee_id Attendee ID
+ * @param array $attendee_data Attendee data
+ * @param int $ticket_id Ticket ID
+ */
+ public function validate_mandatory_attendee_data(int $attendee_id, array $attendee_data, int $ticket_id): void {
+ // Only validate HVAC tickets
+ if (!get_post_meta($ticket_id, '_hvac_ticket', true)) {
+ return;
+ }
+
+ $mandatory_fields = get_post_meta($ticket_id, '_hvac_ticket_mandatory_fields', true);
+ if (empty($mandatory_fields)) {
+ $mandatory_fields = $this->mandatory_fields;
+ }
+
+ $errors = [];
+
+ foreach ($mandatory_fields as $field_name => $field_config) {
+ if (!empty($field_config['required'])) {
+ $value = $attendee_data[$field_name] ?? '';
+
+ if (empty(trim($value))) {
+ $errors[] = sprintf('Field "%s" is required', $field_config['label']);
+ }
+ }
+ }
+
+ if (!empty($errors)) {
+ wp_die(
+ 'Please complete all required fields: ' . implode(', ', $errors),
+ 'Required Fields Missing',
+ ['response' => 400, 'back_link' => true]
+ );
+ }
+ }
+
+ /**
+ * AJAX handler for creating event tickets
+ */
+ public function ajax_create_event_tickets(): void {
+ // Security check
+ if (!wp_verify_nonce($_POST['nonce'] ?? '', 'hvac_ticket_nonce')) {
+ wp_send_json_error(['message' => __('Security check failed', 'hvac-community-events')]);
+ return;
+ }
+
+ $event_id = intval($_POST['event_id'] ?? 0);
+ $ticket_data = $_POST['ticket_data'] ?? [];
+
+ if (!$event_id || empty($ticket_data)) {
+ wp_send_json_error(['message' => __('Missing required data', 'hvac-community-events')]);
+ return;
+ }
+
+ $result = $this->create_tickets_for_event($event_id, $ticket_data);
+
+ if ($result['success']) {
+ wp_send_json_success($result);
+ } else {
+ wp_send_json_error($result);
+ }
+ }
+
+ /**
+ * AJAX handler for updating event tickets
+ */
+ public function ajax_update_event_tickets(): void {
+ // Security check
+ if (!wp_verify_nonce($_POST['nonce'] ?? '', 'hvac_ticket_nonce')) {
+ wp_send_json_error(['message' => __('Security check failed', 'hvac-community-events')]);
+ return;
+ }
+
+ $ticket_id = intval($_POST['ticket_id'] ?? 0);
+ $ticket_data = $_POST['ticket_data'] ?? [];
+
+ if (!$ticket_id || empty($ticket_data)) {
+ wp_send_json_error(['message' => __('Missing required data', 'hvac-community-events')]);
+ return;
+ }
+
+ // Update ticket - implementation would depend on TEC's update API
+ $success = $this->update_tec_ticket($ticket_id, $ticket_data);
+
+ if ($success) {
+ wp_send_json_success(['message' => __('Ticket updated successfully', 'hvac-community-events')]);
+ } else {
+ wp_send_json_error(['message' => __('Failed to update ticket', 'hvac-community-events')]);
+ }
+ }
+
+ /**
+ * Update a TEC ticket
+ *
+ * @param int $ticket_id Ticket ID
+ * @param array $ticket_data Updated ticket data
+ * @return bool Success status
+ */
+ private function update_tec_ticket(int $ticket_id, array $ticket_data): bool {
+ // Implementation would depend on TEC's update API
+ // For now, update basic post data
+
+ $update_data = [
+ 'ID' => $ticket_id,
+ 'post_title' => sanitize_text_field($ticket_data['name'] ?? ''),
+ 'post_content' => wp_kses_post($ticket_data['description'] ?? '')
+ ];
+
+ $result = wp_update_post($update_data);
+
+ if (!is_wp_error($result)) {
+ // Update ticket meta
+ if (isset($ticket_data['price'])) {
+ update_post_meta($ticket_id, '_price', floatval($ticket_data['price']));
+ }
+ if (isset($ticket_data['capacity'])) {
+ update_post_meta($ticket_id, '_stock', intval($ticket_data['capacity']));
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Enqueue ticketing assets
+ */
+ public function enqueue_ticketing_assets(): void {
+ // Only enqueue on event creation/edit pages
+ if (!$this->is_hvac_event_page()) {
+ return;
+ }
+
+ wp_enqueue_script(
+ 'hvac-tec-tickets',
+ HVAC_PLUGIN_URL . 'assets/js/hvac-tec-tickets.js',
+ ['jquery'],
+ HVAC_VERSION,
+ true
+ );
+
+ wp_localize_script('hvac-tec-tickets', 'hvacTecTickets', [
+ 'ajaxurl' => admin_url('admin-ajax.php'),
+ 'nonce' => wp_create_nonce('hvac_ticket_nonce'),
+ 'strings' => [
+ 'ticketCreated' => __('Ticket created successfully', 'hvac-community-events'),
+ 'ticketUpdated' => __('Ticket updated successfully', 'hvac-community-events'),
+ 'error' => __('An error occurred. Please try again.', 'hvac-community-events'),
+ 'confirmRemove' => __('Are you sure you want to remove this ticket?', 'hvac-community-events')
+ ]
+ ]);
+
+ wp_enqueue_style(
+ 'hvac-tec-tickets',
+ HVAC_PLUGIN_URL . 'assets/css/hvac-tec-tickets.css',
+ [],
+ HVAC_VERSION
+ );
+ }
+
+ /**
+ * Check if current page is an HVAC event page
+ *
+ * @return bool
+ */
+ private function is_hvac_event_page(): bool {
+ global $wp;
+
+ if (!is_page()) {
+ return false;
+ }
+
+ $current_url = home_url(add_query_arg([], $wp->request));
+ $event_patterns = [
+ '/trainer/events/create',
+ '/trainer/events/edit',
+ '/trainer/events/manage'
+ ];
+
+ foreach ($event_patterns as $pattern) {
+ if (strpos($current_url, $pattern) !== false) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
+
+// Initialize the TEC Tickets integration
+HVAC_TEC_Tickets::instance();
\ No newline at end of file
diff --git a/templates/page-tec-create-event.php b/templates/page-tec-create-event.php
index 9333e9cc..d3efa8a5 100644
--- a/templates/page-tec-create-event.php
+++ b/templates/page-tec-create-event.php
@@ -1019,6 +1019,122 @@ input[value="Clear Template"] {
text-align: center;
}
}
+
+/* TEC Ticketing Integration Styles */
+.ticket-section {
+ background: #f8f9fa;
+ border: 1px solid #e9ecef;
+ border-radius: 6px;
+ padding: 20px;
+ margin: 20px 0;
+}
+
+.form-section-title {
+ color: #0073aa;
+ font-size: 18px;
+ margin: 0 0 15px 0;
+ padding-bottom: 8px;
+ border-bottom: 2px solid #0073aa;
+}
+
+.enable-ticketing-row {
+ margin-bottom: 15px;
+}
+
+.enable-ticketing-row label {
+ font-weight: 600;
+ color: #2c3e50;
+ cursor: pointer;
+}
+
+.enable-ticketing-row input[type="checkbox"] {
+ margin-right: 8px;
+ transform: scale(1.1);
+}
+
+.ticket-config-section {
+ background: #ffffff;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ padding: 20px;
+ margin-top: 15px;
+ transition: all 0.3s ease;
+}
+
+.ticket-config-field {
+ margin-bottom: 15px;
+}
+
+.ticket-config-field:last-of-type {
+ margin-bottom: 0;
+}
+
+.hvac-notice {
+ background: #e8f4fd;
+ border: 1px solid #b8daff;
+ border-radius: 4px;
+ padding: 12px 15px;
+ margin: 15px 0;
+ color: #0c5460;
+}
+
+.hvac-notice p {
+ margin: 0;
+ font-size: 14px;
+}
+
+/* Ticket field specific styling */
+.ticket-config-field input[type="number"] {
+ width: auto;
+ min-width: 120px;
+}
+
+.ticket-config-field input[type="datetime-local"] {
+ width: auto;
+ min-width: 200px;
+}
+
+/* Enhanced checkbox styling */
+.ticket-config-field input[type="checkbox"] {
+ margin-right: 8px;
+ transform: scale(1.1);
+}
+
+.ticket-config-field label {
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+/* Animation for ticket section reveal */
+@keyframes slideDown {
+ from {
+ opacity: 0;
+ max-height: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+ to {
+ opacity: 1;
+ max-height: 500px;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ }
+}
+
+.ticket-config-section.show {
+ animation: slideDown 0.4s ease-out;
+}
+
+/* Responsive ticket fields */
+@media (max-width: 768px) {
+ .ticket-config-field input[type="datetime-local"],
+ .ticket-config-field input[type="number"] {
+ width: 100%;
+ min-width: auto;
+ }
+}
@@ -1220,31 +1336,79 @@ jQuery(document).ready(function($) {
// Template modal functionality
let templateData = [];
- // Sample template data (in real implementation, this would come from server)
+ // Real template data from EVENT_TEMPLATES_2025-09-25.md
templateData = [
{
- id: 1,
- title: 'Basic Training Workshop',
- description: 'Standard HVAC training session with essential components',
- category: 'training'
+ id: 1658,
+ title: 'Transform Your HVAC Business with Manual J LiDAR',
+ description: 'Master iPad-based Manual J calculations and measureQuick fundamentals for modern HVAC operations',
+ category: 'training',
+ duration: 'Half Day',
+ difficulty: 'Introductory',
+ defaultTime: { start: '08:00', end: '12:00' },
+ defaultPrice: 99,
+ requirements: 'No special Heating Cooling Equip. Needs, good Internet connection',
+ maxStudents: null
},
{
- id: 2,
- title: 'Certification Exam',
- description: 'Comprehensive certification testing event',
- category: 'certification'
+ id: 1661,
+ title: 'Master Static Pressure & Airflow: The Keys to Profitable Service',
+ description: 'Find hidden airflow problems and turn airflow testing into pure profit with NCI AirMaxx and TEC TrueFlow',
+ category: 'training',
+ duration: 'Half Day',
+ difficulty: 'Introductory',
+ defaultTime: { start: '13:00', end: '17:00' },
+ defaultPrice: 99,
+ requirements: 'Need a furnace or AH that can provide static pressure, no outdoor unit needed, good Internet connection',
+ maxStudents: null
},
{
- id: 3,
- title: 'General Meeting',
- description: 'Regular community meeting template',
- category: 'general'
+ id: 5295,
+ title: 'Full-Day A/C and Heat Pump Commissioning & Diagnostics Mastery with measureQuick',
+ description: 'Commission systems properly with verification, understanding proper charge and airflow effects on total system performance',
+ category: 'training',
+ duration: 'Full Day',
+ difficulty: 'Advanced',
+ defaultTime: { start: '08:00', end: '17:00' },
+ defaultPrice: 99,
+ requirements: 'Need a furnace or AH that can provide static pressure MUST, and an outdoor unit (if unit is not operating we can use demo data), good Internet connection',
+ maxStudents: 10
},
{
- id: 4,
- title: 'Hands-on Workshop',
- description: 'Interactive workshop with practical exercises',
- category: 'workshop'
+ id: 1663,
+ title: 'ACCA QI5 Quality Installation Certificates - VSP and VEO',
+ description: 'Learn ACCA QI5 Verified System Performance and Verified Equipment Operation with certification testing included',
+ category: 'certification',
+ duration: 'Full Day',
+ difficulty: 'Intermediate',
+ defaultTime: { start: '08:00', end: '16:00' },
+ defaultPrice: 129,
+ requirements: 'Need a furnace or AH that can provide static pressure MUST, and an outdoor unit (if unit is not operating we can use demo data), good Internet connection',
+ maxStudents: null
+ },
+ {
+ id: 1665,
+ title: 'Advanced Class: Building Science Meets HVAC Performance',
+ description: 'Three-day intensive workshop bridging building science theory with real-world HVAC performance applications',
+ category: 'training',
+ duration: 'Three Days',
+ difficulty: 'Advanced',
+ defaultTime: { start: '08:00', end: '17:00' },
+ defaultPrice: 1200,
+ requirements: 'Need a furnace or AH that can provide static pressure MUST, and an outdoor unit (if unit is not operating we can use demo data), good Internet connection',
+ maxStudents: 12
+ },
+ {
+ id: 5737,
+ title: 'measureQuick for Gas Heating',
+ description: 'Half-day product training focused on gas heating systems with measureQuick diagnostics',
+ category: 'training',
+ duration: 'Half Day',
+ difficulty: 'Introductory',
+ defaultTime: { start: '08:00', end: '14:00' },
+ defaultPrice: 150,
+ requirements: 'Good Internet connection',
+ maxStudents: null
}
];
@@ -1302,29 +1466,79 @@ jQuery(document).ready(function($) {
grid.empty();
filteredTemplates.forEach(function(template) {
- const card = $('
' +
- '
' + template.title + '
' +
- '
' + template.description + '
' +
- '
');
+ let cardHtml = '
';
+ cardHtml += '
' + template.title + '
';
+ cardHtml += '
' + template.description + '
';
+
+ // Add template metadata
+ cardHtml += '
';
+ if (template.duration) {
+ cardHtml += '' + template.duration + '';
+ }
+ if (template.difficulty) {
+ cardHtml += '' + template.difficulty + '';
+ }
+ if (template.defaultPrice) {
+ cardHtml += '$' + template.defaultPrice + '';
+ }
+ cardHtml += '
';
+
+ cardHtml += '
';
+
+ const card = $(cardHtml);
grid.append(card);
});
}
function applyTemplate(template) {
- // Apply template data to form fields based on template type
- if (template.category === 'training') {
- $('#event_title').val(template.title);
- $('#event_description').val(template.description + '\n\nThis is a training event focused on practical skills development.');
- } else if (template.category === 'certification') {
- $('#event_title').val(template.title);
- $('#event_description').val(template.description + '\n\nCertification exam with comprehensive testing.');
- } else {
- $('#event_title').val(template.title);
- $('#event_description').val(template.description);
+ // Apply template data to form fields with enhanced data
+ $('#event_title').val(template.title);
+
+ // Build comprehensive description with template metadata
+ let description = template.description;
+ if (template.duration && template.difficulty) {
+ description += '\n\n**Event Details:**';
+ description += '\n• Duration: ' + template.duration;
+ description += '\n• Difficulty Level: ' + template.difficulty;
+ }
+ if (template.requirements) {
+ description += '\n• Requirements: ' + template.requirements;
+ }
+ if (template.maxStudents) {
+ description += '\n• Maximum Students: ' + template.maxStudents;
+ }
+
+ $('#event_description').val(description);
+
+ // Set default times if available
+ if (template.defaultTime) {
+ // Convert time format for datetime-local inputs
+ const today = new Date();
+ const dateStr = today.toISOString().split('T')[0];
+
+ if (template.defaultTime.start) {
+ $('#event_start_datetime').val(dateStr + 'T' + template.defaultTime.start);
+ }
+ if (template.defaultTime.end) {
+ $('#event_end_datetime').val(dateStr + 'T' + template.defaultTime.end);
+ }
+ }
+
+ // Set default cost if available
+ if (template.defaultPrice) {
+ $('#event_cost').val(template.defaultPrice);
+ }
+
+ // Set capacity if available
+ if (template.maxStudents) {
+ $('#event_capacity').val(template.maxStudents);
}
hasUnsavedChanges = true;
performAutoSave();
+
+ // Notify user
+ alert('Template "' + template.title + '" applied successfully! Review and modify the pre-filled data as needed.');
}
// Hide Clear Template buttons with better selector
@@ -1334,6 +1548,51 @@ jQuery(document).ready(function($) {
}).hide();
}
+ // TEC Ticketing Integration Functions
+ function hvacToggleTicketFields(enabled) {
+ const $ticketSection = $('#ticket-config-section');
+
+ if (enabled) {
+ $ticketSection.slideDown();
+ // Make ticket fields required when enabled
+ $('.ticket-config-field input, .ticket-config-field select').attr('data-conditionally-required', 'true');
+ } else {
+ $ticketSection.slideUp();
+ // Clear and disable ticket fields
+ $('.ticket-config-field input, .ticket-config-field select').val('').removeAttr('data-conditionally-required');
+ }
+ }
+
+ // Handle ticket form submission
+ function processTicketData() {
+ const ticketingEnabled = $('#enable_ticketing').is(':checked');
+
+ if (!ticketingEnabled) {
+ return null;
+ }
+
+ return {
+ name: $('#ticket_name').val() || 'General Admission',
+ price: parseFloat($('#ticket_price').val() || '0'),
+ capacity: parseInt($('#ticket_capacity').val()) || null,
+ start_date: $('#ticket_start_sale').val(),
+ end_date: $('#ticket_end_sale').val(),
+ enable_rsvp: $('#enable_rsvp').is(':checked')
+ };
+ }
+
+ // Add ticket processing to form submission
+ $(document).on('submit', '.hvac-event-form form', function(e) {
+ const ticketData = processTicketData();
+
+ if (ticketData) {
+ // Add ticket data to form for processing
+ const ticketInput = $('
');
+ ticketInput.val(JSON.stringify([ticketData])); // Array for future multi-ticket support
+ $(this).append(ticketInput);
+ }
+ });
+
// Initialize everything
initializeAutosave();