# Training Leads Management System Documentation **Version**: 2.0.0 **Last Updated**: August 28, 2025 **Component**: HVAC_Training_Leads **Status**: ✅ Production Ready ## Table of Contents 1. [Overview](#overview) 2. [Features](#features) 3. [User Interface](#user-interface) 4. [Lead Lifecycle](#lead-lifecycle) 5. [Technical Architecture](#technical-architecture) 6. [Database Schema](#database-schema) 7. [API Reference](#api-reference) 8. [Security Considerations](#security-considerations) 9. [Best Practices](#best-practices) 10. [Troubleshooting](#troubleshooting) ## Overview The Training Leads Management System captures and manages contact requests from potential training clients through the "Find a Trainer" directory. This system provides trainers with a centralized hub to track, manage, and respond to inbound training inquiries. ### Key Benefits - **Lead Capture**: Automated collection from public profiles - **Status Tracking**: Monitor lead progress through stages - **Communication Hub**: Direct contact links and message viewing - **Conversion Tracking**: Monitor lead-to-client conversion - **Privacy Protection**: Secure handling of contact information ## Features ### Core Functionality #### Lead Dashboard (`/trainer/profile/training-leads/`) - **Comprehensive Table View**: All leads in one place - **Status Management**: New, Read, Replied, Archived states - **Contact Information**: Email and phone with direct links - **Message Viewing**: Full message with modal display - **Quick Actions**: Status updates with single click - **Empty State**: Helpful guidance when no leads ### Lead Information Display #### Data Fields - **Submission Date**: When the lead was received - **Contact Name**: First and last name - **Email Address**: Clickable mailto link - **Phone Number**: Clickable tel link (if provided) - **Location**: City and state/province - **Message**: Inquiry details with preview/full view - **Status Badge**: Visual status indicator ### Status Management #### Lead States 1. **New**: Unread incoming lead (yellow badge) 2. **Read**: Lead has been viewed (blue badge) 3. **Replied**: Trainer has responded (green badge) 4. **Archived**: Lead closed/completed (red badge) ### Advanced Features #### Message Handling - **Preview Display**: First 8 words with ellipsis - **Modal View**: Full message in popup - **Line Break Preservation**: Maintains formatting - **Character Limit**: Handles long messages gracefully #### Call-to-Action - **Profile Promotion**: Encourage profile sharing - **Lead Generation**: Tips for attracting more leads - **Visual Appeal**: Gradient background CTA card ## User Interface ### Lead Management Table ``` ┌──────────────────────────────────────────────────────┐ │ Training Leads │ │ Manage contact requests from potential clients │ ├──────────────────────────────────────────────────────┤ │ Date │ Name │ Email │ Phone │ Location │ Status │ ├──────┼──────┼───────┼───────┼──────────┼────────────┤ │ Aug │ John │ john@ │ 555- │ NYC, NY │ [New] │ │ 28 │ Doe │ │ 0123 │ │ │ │ │ │ │ │ │ [Mark Read]│ └──────────────────────────────────────────────────────┘ ``` ### Message Modal ``` ┌─────────────────────────────────────┐ │ Full Message [X] │ ├─────────────────────────────────────┤ │ │ │ I am interested in scheduling HVAC │ │ training for my team of 15 │ │ technicians. We need EPA 608 │ │ certification preparation. │ │ │ │ Please contact me to discuss │ │ available dates and pricing. │ │ │ ├─────────────────────────────────────┤ │ [Close] │ └─────────────────────────────────────┘ ``` ### Empty State ``` ┌─────────────────────────────────────┐ │ 📧 │ │ │ │ No inbound training requests │ │ │ │ When potential clients contact │ │ you through the "Find a Trainer" │ │ directory, their messages will │ │ appear here. │ └─────────────────────────────────────┘ ``` ### Call-to-Action Card ``` ┌─────────────────────────────────────┐ │ Want more training leads? │ │ │ │ Share your profile with the world │ │ to attract more potential clients! │ │ │ │ [Share your profile with world!] │ └─────────────────────────────────────┘ ``` ## Lead Lifecycle ### 1. Lead Generation ``` Public Profile Page ↓ Contact Form Submission ↓ Database Storage ↓ Trainer Notification (optional) ``` ### 2. Lead Processing ``` NEW Lead ↓ Trainer Views → READ ↓ Trainer Contacts → REPLIED ↓ Lead Closed → ARCHIVED ``` ### 3. Status Transitions ```mermaid stateDiagram-v2 [*] --> New: Form Submission New --> Read: Mark Read New --> Replied: Mark Replied Read --> Replied: Mark Replied Read --> Archived: Archive Replied --> Archived: Archive Archived --> [*] ``` ## Technical Architecture ### Class Structure ```php class HVAC_Training_Leads { // Singleton pattern private static $instance = null; public static function instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } // Core methods public function render_training_leads_page() private function get_trainer_submissions() public function ajax_update_lead_status() public function ajax_mark_lead_replied() private function verify_lead_ownership() } ``` ### File Structure ``` includes/ ├── class-hvac-training-leads.php # Main leads class ├── database/ │ └── class-hvac-contact-submissions-table.php templates/ └── page-trainer-training-leads.php # Leads page template ``` ### AJAX Endpoints #### Update Lead Status - **Action**: `wp_ajax_hvac_update_lead_status` - **Nonce**: `hvac_ajax_nonce` - **Parameters**: `lead_id`, `status` - **Response**: Success/error message #### Mark Lead as Replied - **Action**: `wp_ajax_hvac_mark_lead_replied` - **Nonce**: `hvac_ajax_nonce` - **Parameters**: `lead_id` - **Response**: Success/error message ## Database Schema ### Contact Submissions Table ```sql CREATE TABLE wp_hvac_contact_submissions ( id INT AUTO_INCREMENT PRIMARY KEY, trainer_id INT NOT NULL, first_name VARCHAR(100), last_name VARCHAR(100), email VARCHAR(100), phone VARCHAR(20), city VARCHAR(100), state_province VARCHAR(100), message TEXT, status VARCHAR(20) DEFAULT 'new', submission_date DATETIME DEFAULT CURRENT_TIMESTAMP, updated_date DATETIME ON UPDATE CURRENT_TIMESTAMP, KEY trainer_id (trainer_id), KEY status (status), KEY submission_date (submission_date) ); ``` ### Status Values - `new` - Unread submission - `read` - Viewed by trainer - `replied` - Trainer has responded - `archived` - Closed/completed ## API Reference ### PHP Functions #### Retrieving Leads ```php // Get leads for specific trainer $leads = HVAC_Contact_Submissions_Table::get_submissions([ 'trainer_id' => $trainer_id, 'limit' => 100, 'orderby' => 'submission_date', 'order' => 'DESC' ]); // Get single submission $lead = HVAC_Contact_Submissions_Table::get_submission($lead_id); // Get leads by status $new_leads = HVAC_Contact_Submissions_Table::get_submissions([ 'trainer_id' => $trainer_id, 'status' => 'new' ]); ``` #### Updating Lead Status ```php // Update status HVAC_Contact_Submissions_Table::update_status($lead_id, 'read'); // Mark as replied HVAC_Contact_Submissions_Table::update_status($lead_id, 'replied'); // Archive lead HVAC_Contact_Submissions_Table::update_status($lead_id, 'archived'); ``` #### Creating Test Leads ```php // Insert test submission global $wpdb; $wpdb->insert( $wpdb->prefix . 'hvac_contact_submissions', [ 'trainer_id' => $trainer_id, 'first_name' => 'John', 'last_name' => 'Doe', 'email' => 'john@example.com', 'phone' => '555-0123', 'city' => 'New York', 'state_province' => 'NY', 'message' => 'Interested in training', 'status' => 'new' ] ); ``` ### JavaScript Functions #### Update Status via AJAX ```javascript jQuery.ajax({ url: hvac_ajax.url, type: 'POST', data: { action: 'hvac_update_lead_status', lead_id: leadId, status: 'read', nonce: hvac_ajax.nonce }, success: function(response) { if (response.success) { location.reload(); // Refresh to show updated status } else { alert('Error: ' + response.data.message); } } }); ``` #### Display Message Modal ```javascript // Show full message in modal $('.hvac-view-message').on('click', function(e) { e.preventDefault(); var message = $(this).data('message'); $('#hvac-full-message').html(message.replace(/\n/g, '
')); $('#hvac-message-modal').fadeIn(); }); // Close modal $('.hvac-modal-close').on('click', function(e) { e.preventDefault(); $('#hvac-message-modal').fadeOut(); }); ``` ## Security Considerations ### Access Control - **View Leads**: Only lead owner can view - **Update Status**: Only lead owner can update - **Delete Leads**: Not implemented (data retention) - **Export Leads**: Not implemented (privacy) ### Data Protection ```php // Verify lead ownership private function verify_lead_ownership($lead_id, $user_id) { $submission = HVAC_Contact_Submissions_Table::get_submission($lead_id); return $submission && $submission->trainer_id == $user_id; } // Check before any operation if (!$this->verify_lead_ownership($lead_id, get_current_user_id())) { wp_send_json_error(['message' => 'Access denied']); } ``` ### Input Sanitization ```php // Sanitize all inputs $lead_id = absint($_POST['lead_id']); $status = sanitize_text_field($_POST['status']); // Validate status values $allowed_statuses = ['new', 'read', 'replied', 'archived']; if (!in_array($status, $allowed_statuses)) { wp_send_json_error(['message' => 'Invalid status']); } ``` ### Nonce Verification ```php // All AJAX requests require nonce check_ajax_referer('hvac_ajax_nonce', 'nonce'); ``` ## Best Practices ### Performance Optimization - **Pagination**: Limit to 100 leads per page - **Indexing**: Database indexes on key fields - **Caching**: Query results cached when possible - **Lazy Loading**: Modal content loads on demand ### User Experience - **Real-time Updates**: AJAX status changes - **Visual Feedback**: Loading indicators - **Clear CTAs**: Obvious action buttons - **Responsive Design**: Mobile-optimized ### Data Management - **Retention Policy**: Keep leads for analytics - **Export Capability**: Future CSV export - **Backup Strategy**: Regular database backups - **GDPR Compliance**: Data protection measures ### Email Integration ```php // Future enhancement: Email notifications function notify_trainer_new_lead($lead_id) { $lead = HVAC_Contact_Submissions_Table::get_submission($lead_id); $trainer = get_user_by('id', $lead->trainer_id); $subject = 'New Training Lead Received'; $message = sprintf( 'You have a new training lead from %s %s', $lead->first_name, $lead->last_name ); wp_mail($trainer->user_email, $subject, $message); } ``` ## Troubleshooting ### Common Issues #### No Leads Appearing **Problem**: Dashboard shows empty state despite submissions **Solutions**: 1. Verify trainer_id matches current user 2. Check database table exists 3. Confirm submissions have correct trainer_id ```sql -- Check submissions SELECT * FROM wp_hvac_contact_submissions WHERE trainer_id = [USER_ID]; ``` #### Status Not Updating **Problem**: Clicking status buttons doesn't work **Solutions**: 1. Check JavaScript console for errors 2. Verify AJAX URL is correct 3. Confirm nonce is valid ```javascript // Debug AJAX console.log('AJAX URL:', hvac_ajax.url); console.log('Nonce:', hvac_ajax.nonce); ``` #### Modal Not Opening **Problem**: View Full button doesn't show message **Solutions**: 1. Check message data attribute 2. Verify modal HTML exists 3. Check for JavaScript errors ```javascript // Debug modal console.log('Message data:', $(this).data('message')); console.log('Modal exists:', $('#hvac-message-modal').length); ``` ### Error Messages | Error | Meaning | Solution | |-------|---------|----------| | "Unauthorized" | Not logged in or wrong role | Check authentication | | "Access denied" | Not lead owner | Verify trainer_id | | "Invalid parameters" | Missing required data | Check AJAX request | | "Failed to update" | Database error | Check table structure | ### Database Verification ```sql -- Check table structure DESCRIBE wp_hvac_contact_submissions; -- Verify data integrity SELECT status, COUNT(*) as count FROM wp_hvac_contact_submissions GROUP BY status; -- Find orphaned leads SELECT * FROM wp_hvac_contact_submissions WHERE trainer_id NOT IN ( SELECT ID FROM wp_users ); ``` ## Analytics and Reporting ### Key Metrics ```php // Lead statistics function get_lead_stats($trainer_id) { global $wpdb; $table = $wpdb->prefix . 'hvac_contact_submissions'; return [ 'total' => $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM $table WHERE trainer_id = %d", $trainer_id )), 'new' => $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM $table WHERE trainer_id = %d AND status = 'new'", $trainer_id )), 'replied' => $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM $table WHERE trainer_id = %d AND status = 'replied'", $trainer_id )) ]; } ``` ### Conversion Tracking ```php // Calculate conversion rate function get_conversion_rate($trainer_id) { $stats = get_lead_stats($trainer_id); if ($stats['total'] == 0) return 0; return round(($stats['replied'] / $stats['total']) * 100, 2); } ``` ## Future Enhancements ### Planned Features - **Email Notifications**: Real-time lead alerts - **SMS Integration**: Text message notifications - **Lead Scoring**: Automatic quality rating - **Follow-up Reminders**: Scheduled reminders - **Lead Notes**: Private trainer notes - **Tags/Categories**: Lead classification - **Bulk Actions**: Mass status updates - **Export**: CSV download capability - **Analytics Dashboard**: Conversion metrics - **CRM Integration**: Salesforce, HubSpot ### API Extensions - **REST API**: Lead management endpoints - **Webhooks**: Real-time notifications - **GraphQL**: Advanced queries - **Mobile App**: Native app support ### UI Improvements - **Kanban Board**: Drag-drop interface - **Calendar View**: Time-based display - **Quick Reply**: In-line responses - **Rich Filters**: Advanced search --- *For additional support, see [TROUBLESHOOTING.md](TROUBLESHOOTING.md) or contact the development team.*