# Organizer Management System Documentation

**Version**: 2.0.0  
**Last Updated**: August 28, 2025  
**Component**: HVAC_Organizers  
**Status**: ✅ Production Ready

## Table of Contents
1. [Overview](#overview)
2. [Features](#features)
3. [User Interface](#user-interface)
4. [Technical Architecture](#technical-architecture)
5. [Logo Management](#logo-management)
6. [Database Schema](#database-schema)
7. [API Reference](#api-reference)
8. [Security Considerations](#security-considerations)
9. [Troubleshooting](#troubleshooting)

## Overview

The Organizer Management System enables trainers to create and manage organizations that host training events. This system integrates seamlessly with The Events Calendar (TEC) and provides professional branding capabilities through logo uploads and headquarters tracking.

### Key Benefits
- **Professional Branding**: Logo upload for organization identity
- **Headquarters Tracking**: Document organization locations
- **Contact Management**: Centralized contact information
- **Event Association**: Link organizations to multiple events
- **TEC Integration**: Native organizer support in events

## Features

### Core Functionality

#### 1. Organizer Directory (`/trainer/organizer/list/`)
- **Searchable Listing**: Find organizers by name
- **Logo Display**: Visual organization identification
- **Contact Information**: Email and phone at a glance
- **Headquarters Location**: City, state, country display
- **Quick Actions**: Edit buttons for management
- **Pagination**: 20 organizers per page

#### 2. Organizer Management (`/trainer/organizer/manage/`)
- **Create Organizations**: Complete profile creation
- **Edit Profiles**: Update all organization details
- **Logo Upload**: Professional branding support
- **Delete Organizations**: Safe removal with checks
- **Rich Profiles**: Comprehensive information fields

### Data Fields

#### Organization Information
- **Organization Name** (Required)
- **Description**: Detailed organization information
- **Logo**: Upload organization branding (JPG, PNG, GIF, WebP)

#### Headquarters Location
- **City** (Required)
- **State/Province** (Required)
- **Country** (Required): Selected from supported countries

#### Contact Information
- **Phone Number**: Organization telephone
- **Email Address**: Contact email
- **Website URL**: Organization website

### Advanced Features

#### Logo Management
- **Upload Support**: JPG, PNG, GIF, WebP formats
- **Size Limit**: 5MB maximum file size
- **Recommended**: 300x300px for best display
- **Fallback**: Letter-based placeholder when no logo
- **Media Library**: Integration with WordPress media

#### Access Control
- **Role-Based**: Master trainers see all, trainers see own
- **Edit Permissions**: Only organizer creators can edit
- **Delete Protection**: Check for event associations

## User Interface

### Organizer List Page
```
┌─────────────────────────────────────────────────┐
│ Training Organizers      [Add New Organizer]    │
├─────────────────────────────────────────────────┤
│ [Search: ___________]  [Search] [Clear]         │
├─────────────────────────────────────────────────┤
│ Logo │ Name │ HQ │ Contact │ Website │ Actions │
├──────┼──────┼────┼─────────┼─────────┼─────────┤
│ [◼]  │ ACME │NYC │email@   │[Visit]  │ [Edit]  │
│      │ Corp │USA │555-0123 │         │         │
└─────────────────────────────────────────────────┘
```

### Organizer Management Form
```
┌─────────────────────────────────────────────────┐
│ Create New Organizer / Edit Organizer           │
├─────────────────────────────────────────────────┤
│ Organization Logo                               │
│ ┌─────────┐                                    │
│ │  [Logo] │ [Upload Logo] [Remove Logo]        │
│ └─────────┘ Recommended: 300x300px, Max: 5MB   │
│                                                 │
│ Organization Information                        │
│ ├─ Organization Name: [____________] *          │
│ └─ Description: [__________________]           │
│                                                 │
│ Headquarters Location                           │
│ ├─ City: [__________] *                        │
│ ├─ State/Province: [_______] *                 │
│ └─ Country: [United States ▼] *                │
│                                                 │
│ Contact Information                             │
│ ├─ Phone: [___________]                        │
│ ├─ Email: [___________]                        │
│ └─ Website: [_________]                        │
│                                                 │
│ [Save Organizer] [Cancel] [Delete]             │
└─────────────────────────────────────────────────┘
```

## Technical Architecture

### Class Structure

```php
class HVAC_Organizers {
    // 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_organizers_list()
    public function render_organizer_manage()
    public function ajax_save_organizer()
    public function ajax_delete_organizer()
    public function ajax_upload_org_logo()
}
```

### File Structure
```
includes/
├── class-hvac-organizers.php      # Main organizer class
assets/
├── css/
│   └── hvac-organizers.css       # Organizer styles
└── js/
    └── hvac-organizers.js        # Organizer JavaScript
templates/
├── page-trainer-organizer-list.php   # List template
└── page-trainer-organizer-manage.php # Manage template
```

### AJAX Endpoints

#### Save Organizer
- **Action**: `wp_ajax_hvac_save_organizer`
- **Nonce**: `hvac_organizers_nonce`
- **Parameters**: Organization data fields
- **Response**: Success/error with organizer ID

#### Delete Organizer
- **Action**: `wp_ajax_hvac_delete_organizer`
- **Nonce**: `hvac_organizers_nonce`
- **Parameters**: `organizer_id`
- **Response**: Success/error message

#### Upload Logo
- **Action**: `wp_ajax_hvac_upload_org_logo`
- **Nonce**: `hvac_organizers_nonce`
- **Parameters**: `org_logo` file
- **Response**: Attachment ID and URL

## Logo Management

### Upload Process

```javascript
// JavaScript implementation
var formData = new FormData();
formData.append('org_logo', fileInput.files[0]);
formData.append('action', 'hvac_upload_org_logo');
formData.append('nonce', hvacOrganizers.nonce);

jQuery.ajax({
    url: hvacOrganizers.ajax_url,
    type: 'POST',
    data: formData,
    processData: false,
    contentType: false,
    success: function(response) {
        if (response.success) {
            // Update logo display
            updateLogoDisplay(response.data.url);
            // Store attachment ID
            $('#org_logo_id').val(response.data.attachment_id);
        }
    }
});
```

### File Validation

```php
// Server-side validation
$allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
$max_size = 5 * 1024 * 1024; // 5MB

// Check file type
$file_type = wp_check_filetype($_FILES['org_logo']['name']);
if (!in_array($file_type['type'], $allowed_types)) {
    wp_send_json_error('Invalid file type');
}

// Check file size
if ($_FILES['org_logo']['size'] > $max_size) {
    wp_send_json_error('File too large. Maximum size is 5MB.');
}
```

### WordPress Media Integration

```php
// Handle upload through WordPress media
require_once(ABSPATH . 'wp-admin/includes/media.php');
$attachment_id = media_handle_upload('org_logo', 0);

// Set as post thumbnail
set_post_thumbnail($organizer_id, $attachment_id);
```

## Database Schema

### Post Type
- **Type**: `tribe_organizer`
- **Status**: `publish`
- **Author**: Current user ID

### Post Meta Fields
```sql
_OrganizerPhone           -- Phone number
_OrganizerEmail           -- Email address
_OrganizerWebsite         -- Website URL
_hvac_headquarters_city   -- HQ city
_hvac_headquarters_state  -- HQ state/province
_hvac_headquarters_country -- HQ country
_thumbnail_id             -- Logo attachment ID
```

### User Meta
```sql
organizer_id              -- Primary organizer for user
```

## API Reference

### PHP Functions

#### Creating an Organizer
```php
// Using TEC function
$organizer_id = tribe_create_organizer([
    'Organizer' => 'ACME Corporation',
    'Description' => 'Leading HVAC training organization',
    'Phone' => '555-0123',
    'Email' => 'contact@acme.com',
    'Website' => 'https://acme.com'
]);

// Add headquarters information
update_post_meta($organizer_id, '_hvac_headquarters_city', 'New York');
update_post_meta($organizer_id, '_hvac_headquarters_state', 'NY');
update_post_meta($organizer_id, '_hvac_headquarters_country', 'United States');
```

#### Retrieving Organizers
```php
// Get all organizers
$organizers = get_posts([
    'post_type' => 'tribe_organizer',
    'posts_per_page' => -1,
    'post_status' => 'publish'
]);

// Get user's organizers
$user_organizers = get_posts([
    'post_type' => 'tribe_organizer',
    'author' => get_current_user_id(),
    'posts_per_page' => -1
]);

// Get organizer details
$organizer = get_post($organizer_id);
$phone = get_post_meta($organizer_id, '_OrganizerPhone', true);
$logo_id = get_post_thumbnail_id($organizer_id);
```

#### Updating an Organizer
```php
// Using TEC function
tribe_update_organizer($organizer_id, [
    'Organizer' => 'Updated Name',
    'Email' => 'newemail@acme.com'
]);

// Update headquarters
update_post_meta($organizer_id, '_hvac_headquarters_city', 'Boston');

// Update logo
set_post_thumbnail($organizer_id, $new_logo_id);
```

### JavaScript Functions

#### Save Organizer via AJAX
```javascript
jQuery.ajax({
    url: hvacOrganizers.ajax_url,
    type: 'POST',
    data: {
        action: 'hvac_save_organizer',
        nonce: hvacOrganizers.nonce,
        org_name: 'ACME Corporation',
        org_description: 'Description',
        hq_city: 'New York',
        hq_state: 'NY',
        hq_country: 'United States',
        org_phone: '555-0123',
        org_email: 'contact@acme.com',
        org_website: 'https://acme.com',
        org_logo_id: 123
    },
    success: function(response) {
        if (response.success) {
            console.log('Organizer saved:', response.data.organizer_id);
        }
    }
});
```

## Security Considerations

### Access Control Matrix

| Action | Trainer | Master Trainer | Admin |
|--------|---------|----------------|-------|
| View All | No | Yes | Yes |
| View Own | Yes | Yes | Yes |
| Create | Yes | Yes | Yes |
| Edit Own | Yes | Yes | Yes |
| Edit Any | No | No | Yes |
| Delete Own | Yes | Yes | Yes |
| Delete Any | No | No | Yes |

### Data Validation
```php
// Input sanitization
$org_name = sanitize_text_field($_POST['org_name']);
$org_email = sanitize_email($_POST['org_email']);
$org_website = esc_url_raw($_POST['org_website']);
$org_description = wp_kses_post($_POST['org_description']);
```

### File Upload Security
```php
// Validate file upload
if (!is_uploaded_file($_FILES['org_logo']['tmp_name'])) {
    wp_send_json_error('Security error: Invalid file upload.');
}

// Check MIME type
$file_info = wp_check_filetype_and_ext(
    $_FILES['org_logo']['tmp_name'],
    $_FILES['org_logo']['name']
);
if (!$file_info['type']) {
    wp_send_json_error('Invalid file type.');
}
```

### Nonce Verification
```php
// All actions require nonce
check_ajax_referer('hvac_organizers_nonce', 'nonce');
```

## Troubleshooting

### Common Issues

#### Logo Not Uploading
**Problem**: Logo upload fails  
**Solutions**:
1. Check file size (max 5MB)
2. Verify file type (JPG, PNG, GIF, WebP)
3. Check upload directory permissions
```bash
# Fix permissions
chmod 755 wp-content/uploads
```

#### Cannot Delete Organizer
**Problem**: Delete button doesn't work  
**Solution**: Organizer is being used by events
```php
// Check for events using organizer
$events = get_posts([
    'post_type' => 'tribe_events',
    'meta_key' => '_EventOrganizerID',
    'meta_value' => $organizer_id
]);
if (!empty($events)) {
    // Cannot delete - organizer in use
}
```

#### Organizer Not in Event Dropdown
**Problem**: Created organizer missing from event creation  
**Solution**: Check post status
```php
// Ensure organizer is published
wp_update_post([
    'ID' => $organizer_id,
    'post_status' => 'publish'
]);
```

### Error Messages

| Error | Meaning | Solution |
|-------|---------|----------|
| "Unauthorized" | User not logged in or wrong role | Check user authentication |
| "Invalid file type" | Wrong image format | Use JPG, PNG, GIF, or WebP |
| "File too large" | Exceeds 5MB limit | Reduce file size |
| "Cannot delete organizer" | In use by events | Remove from events first |
| "Organization name required" | Missing required field | Provide organization name |

## Best Practices

### Performance Optimization
- **Image Optimization**: Compress logos before upload
- **Caching**: Organizer queries are cached
- **Lazy Loading**: Logos load on scroll
- **Pagination**: Large lists are paginated

### User Experience
- **Visual Feedback**: Loading indicators during upload
- **Error Handling**: Clear error messages
- **Placeholder Images**: Letter-based when no logo
- **Responsive Design**: Mobile-optimized interface

### Development Guidelines
- **Singleton Pattern**: Use `HVAC_Organizers::instance()`
- **WordPress APIs**: Use native functions when available
- **Security First**: Always validate and sanitize
- **Media Library**: Leverage WordPress media handling

## Integration with Events

### Event Creation
```php
// Organizers automatically available in TEC
// Dropdown populated with published organizers
```

### Multiple Organizers
```php
// Events can have multiple organizers
$event_organizers = tribe_get_organizer_ids($event_id);
```

### Display on Event Pages
```php
// Organizer information displayed automatically
// Logo, name, contact info shown on event details
```

## Future Enhancements

### Planned Features
- **Bulk Import**: CSV organizer upload
- **Social Media**: Social profile links
- **Certifications**: Organization credentials
- **Branch Offices**: Multiple locations
- **Team Members**: Staff directory
- **Event History**: Past events by organizer
- **Rating System**: Trainer feedback

### API Extensions
- **REST API**: Full CRUD operations
- **GraphQL**: Query support
- **Webhooks**: Organization updates
- **Third-party Integration**: CRM systems

### UI Improvements
- **Drag-and-drop**: Logo upload
- **Rich Text Editor**: Enhanced descriptions
- **Map Integration**: HQ location display
- **Quick Edit**: Inline editing

---

*For additional support, see [TROUBLESHOOTING.md](TROUBLESHOOTING.md) or contact the development team.*