## Major Enhancements ### 🏗️ Architecture & Infrastructure - Implement comprehensive Docker testing infrastructure with hermetic environment - Add Forgejo Actions CI/CD pipeline for automated deployments - Create Page Object Model (POM) testing architecture reducing test duplication by 90% - Establish security-first development patterns with input validation and output escaping ### 🧪 Testing Framework Modernization - Migrate 146+ tests from 80 duplicate files to centralized architecture - Add comprehensive E2E test suites for all user roles and workflows - Implement WordPress error detection with automatic site health monitoring - Create robust browser lifecycle management with proper cleanup ### 📚 Documentation & Guides - Add comprehensive development best practices guide - Create detailed administrator setup documentation - Establish user guides for trainers and master trainers - Document security incident reports and migration guides ### 🔧 Core Plugin Features - Enhance trainer profile management with certification system - Improve find trainer functionality with advanced filtering - Strengthen master trainer area with content management - Add comprehensive venue and organizer management ### 🛡️ Security & Reliability - Implement security-first patterns throughout codebase - Add comprehensive input validation and output escaping - Create secure credential management system - Establish proper WordPress role-based access control ### 🎯 WordPress Integration - Strengthen singleton pattern implementation across all classes - Enhance template hierarchy with proper WordPress integration - Improve page manager with hierarchical URL structure - Add comprehensive shortcode and menu system ### 🔍 Developer Experience - Add extensive debugging and troubleshooting tools - Create comprehensive test data seeding scripts - Implement proper error handling and logging - Establish consistent code patterns and standards ### 📊 Performance & Optimization - Optimize database queries and caching strategies - Improve asset loading and script management - Enhance template rendering performance - Streamline user experience across all interfaces 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
558 lines
No EOL
16 KiB
Markdown
558 lines
No EOL
16 KiB
Markdown
# 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, '<br>'));
|
|
$('#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.* |