# Iframe Integration Guide

This guide explains how to integrate Corrad workflow forms into external applications using iframes. This enables seamless embedding of business processes into customer portals, external websites, or any web application.

## Table of Contents

- [Overview](#overview)
- [Basic Integration](#basic-integration)
- [Advanced Configuration](#advanced-configuration)
- [Multi-Process Workflows](#multi-process-workflows)
- [Error Handling](#error-handling)
- [Security Considerations](#security-considerations)
- [Examples](#examples)
- [Troubleshooting](#troubleshooting)

## Overview

Corrad provides a powerful iframe integration system that allows you to embed workflow forms into external applications. The system supports:

- **Clean UI Mode**: Hide all debug information and UI chrome
- **Seamless Multi-Process**: Chain multiple workflows together
- **Real-time Communication**: Parent-child message passing
- **Error Handling**: Graceful error management
- **Progress Tracking**: Monitor workflow completion

## Basic Integration

### Simple Iframe Embedding

```html
<!-- Basic iframe integration -->
<iframe 
  src="/workflow/your-process-id?debug=false" 
  width="100%" 
  height="600px"
  style="border: none;">
</iframe>
```

### URL Parameters

| Parameter | Description | Example |
|-----------|-------------|---------|
| `debug=false` | Enable iframe mode (hide UI chrome) | `?debug=false` |
| `hideComplete=true` | Hide completion message | `?hideComplete=true` |
| `theme=dark` | Apply custom theme (if supported) | `?theme=dark` |

### Complete Example

```html
<!DOCTYPE html>
<html>
<head>
    <title>Workflow Integration</title>
    <style>
        .workflow-container {
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        .workflow-iframe {
            width: 100%;
            height: 600px;
            border: 1px solid #ddd;
            border-radius: 8px;
        }
    </style>
</head>
<body>
    <div class="workflow-container">
        <h1>Complete Your Application</h1>
        <iframe 
            id="workflow-iframe"
            src="/workflow/application-form?debug=false&hideComplete=true"
            class="workflow-iframe">
        </iframe>
    </div>

    <script>
        // Listen for workflow completion
        window.addEventListener('message', (event) => {
            if (event.data.type === 'workflow-complete') {
                console.log('Workflow completed:', event.data);
                // Handle completion
                showSuccessMessage('Application submitted successfully!');
            } else if (event.data.type === 'workflow-error') {
                console.error('Workflow error:', event.data);
                showErrorMessage(event.data.error);
            }
        });

        function showSuccessMessage(message) {
            alert(message);
        }

        function showErrorMessage(error) {
            alert('Error: ' + error);
        }
    </script>
</body>
</html>
```

## Advanced Configuration

### Message Event Structure

The workflow sends the following message types to the parent iframe:

#### Completion Message
```javascript
{
  type: 'workflow-complete',
  processId: 'application-form',
  processName: 'Application Form',
  hideCompletionMessage: true,
  timestamp: '2024-01-15T10:30:00.000Z'
}
```

#### Error Message
```javascript
{
  type: 'workflow-error',
  processId: 'application-form',
  processName: 'Application Form',
  error: 'API call failed: Network error',
  timestamp: '2024-01-15T10:30:00.000Z'
}
```

### Advanced Integration Example

```html
<!DOCTYPE html>
<html>
<head>
    <title>Advanced Workflow Integration</title>
    <style>
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        .header {
            background: #f8f9fa;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }
        .progress-bar {
            width: 100%;
            height: 8px;
            background: #e9ecef;
            border-radius: 4px;
            overflow: hidden;
        }
        .progress-fill {
            height: 100%;
            background: #007bff;
            transition: width 0.3s ease;
        }
        .workflow-iframe {
            width: 100%;
            height: 600px;
            border: 1px solid #ddd;
            border-radius: 8px;
        }
        .status {
            margin-top: 10px;
            font-size: 14px;
            color: #6c757d;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>Employee Onboarding</h1>
            <div class="progress-bar">
                <div id="progress-fill" class="progress-fill" style="width: 0%"></div>
            </div>
            <div id="status" class="status">Starting process...</div>
        </div>
        
        <iframe 
            id="workflow-iframe"
            src="/workflow/personal-info?debug=false&hideComplete=true"
            class="workflow-iframe">
        </iframe>
    </div>

    <script>
        let currentStep = 0;
        const totalSteps = 5;
        
        // Workflow steps configuration
        const workflowSteps = [
            { id: 'personal-info', name: 'Personal Information' },
            { id: 'employment', name: 'Employment Details' },
            { id: 'documents', name: 'Document Upload' },
            { id: 'benefits', name: 'Benefits Selection' },
            { id: 'final', name: 'Final Review' }
        ];

        // Listen for workflow messages
        window.addEventListener('message', (event) => {
            if (event.data.type === 'workflow-complete') {
                console.log('Workflow step completed:', event.data);
                
                if (event.data.hideCompletionMessage) {
                    // Auto-advance to next step
                    setTimeout(() => {
                        loadNextStep();
                    }, 100);
                }
            } else if (event.data.type === 'workflow-error') {
                console.error('Workflow error:', event.data);
                showError(event.data.error);
            }
        });

        function loadNextStep() {
            currentStep++;
            
            if (currentStep >= workflowSteps.length) {
                // All steps complete
                showFinalSuccess();
                return;
            }
            
            const step = workflowSteps[currentStep];
            const iframe = document.getElementById('workflow-iframe');
            
            // Update iframe source
            iframe.src = `/workflow/${step.id}?debug=false&hideComplete=true`;
            
            // Update progress
            updateProgress();
        }

        function updateProgress() {
            const progress = ((currentStep + 1) / totalSteps) * 100;
            document.getElementById('progress-fill').style.width = progress + '%';
            document.getElementById('status').textContent = 
                `Step ${currentStep + 1} of ${totalSteps}: ${workflowSteps[currentStep].name}`;
        }

        function showFinalSuccess() {
            document.getElementById('workflow-iframe').style.display = 'none';
            document.querySelector('.header').innerHTML = `
                <h1>🎉 Onboarding Complete!</h1>
                <p>All required information has been submitted successfully.</p>
                <button onclick="downloadReport()">Download Report</button>
            `;
        }

        function showError(error) {
            document.getElementById('status').textContent = `Error: ${error}`;
            document.getElementById('status').style.color = '#dc3545';
        }

        function downloadReport() {
            // Implement report download logic
            alert('Report download functionality would be implemented here');
        }

        // Initialize progress
        updateProgress();
    </script>
</body>
</html>
```

## Multi-Process Workflows

### Seamless Multi-Step Process

For complex workflows with multiple steps, you can chain processes together seamlessly:

```javascript
// Multi-process workflow configuration
const processes = [
    { id: 'personal-info', name: 'Personal Information' },
    { id: 'employment', name: 'Employment Details' },
    { id: 'documents', name: 'Document Upload' },
    { id: 'references', name: 'References' },
    { id: 'background', name: 'Background Check' },
    { id: 'medical', name: 'Medical Information' },
    { id: 'emergency', name: 'Emergency Contacts' },
    { id: 'benefits', name: 'Benefits Selection' },
    { id: 'payroll', name: 'Payroll Information' },
    { id: 'final', name: 'Final Review' }
];

let currentProcessIndex = 0;

function loadProcess(processIndex) {
    if (processIndex >= processes.length) {
        // All processes complete
        showFinalSuccess();
        return;
    }
    
    const process = processes[processIndex];
    const iframe = document.getElementById('workflow-iframe');
    
    // Load process with hidden completion message
    iframe.src = `/workflow/${process.id}?debug=false&hideComplete=true`;
    currentProcessIndex = processIndex;
    
    // Update progress indicator
    updateProgress(processIndex + 1, processes.length);
}

// Listen for completion and auto-advance
window.addEventListener('message', (event) => {
    if (event.data.type === 'workflow-complete') {
        console.log(`Process ${event.data.processName} completed`);
        
        if (event.data.hideCompletionMessage) {
            // Seamlessly move to next process
            setTimeout(() => {
                loadProcess(currentProcessIndex + 1);
            }, 100);
        }
    } else if (event.data.type === 'workflow-error') {
        console.error('Process failed:', event.data.error);
        showErrorMessage(event.data.error);
    }
});

// Start the first process
loadProcess(0);
```

## Error Handling

### Comprehensive Error Management

```javascript
// Enhanced error handling
window.addEventListener('message', (event) => {
    if (event.data.type === 'workflow-complete') {
        handleWorkflowComplete(event.data);
    } else if (event.data.type === 'workflow-error') {
        handleWorkflowError(event.data);
    }
});

function handleWorkflowComplete(data) {
    console.log('Workflow completed:', data);
    
    // Store completion data
    localStorage.setItem('workflow-completion', JSON.stringify(data));
    
    // Update UI
    updateCompletionUI(data);
    
    // Auto-advance if configured
    if (data.hideCompletionMessage) {
        setTimeout(() => {
            loadNextProcess();
        }, 100);
    }
}

function handleWorkflowError(data) {
    console.error('Workflow error:', data);
    
    // Log error for debugging
    console.error('Error details:', {
        processId: data.processId,
        processName: data.processName,
        error: data.error,
        timestamp: data.timestamp
    });
    
    // Show user-friendly error message
    showErrorMessage(data.error);
    
    // Optionally retry or allow manual restart
    showRetryOptions();
}

function showErrorMessage(error) {
    // Create error notification
    const errorDiv = document.createElement('div');
    errorDiv.className = 'error-notification';
    errorDiv.innerHTML = `
        <div class="error-content">
            <h3>⚠️ An error occurred</h3>
            <p>${error}</p>
            <button onclick="retryCurrentProcess()">Retry</button>
            <button onclick="skipCurrentProcess()">Skip</button>
        </div>
    `;
    
    document.body.appendChild(errorDiv);
}

function retryCurrentProcess() {
    const iframe = document.getElementById('workflow-iframe');
    iframe.src = iframe.src; // Reload current process
}

function skipCurrentProcess() {
    // Move to next process
    loadNextProcess();
}
```

## Security Considerations

### Cross-Origin Communication

When integrating iframes, consider these security aspects:

1. **Origin Validation**: Verify message origin
2. **Content Security Policy**: Configure appropriate CSP headers
3. **Sandbox Attributes**: Use iframe sandbox for additional security

```html
<!-- Secure iframe configuration -->
<iframe 
    src="/workflow/process-id?debug=false"
    sandbox="allow-scripts allow-same-origin allow-forms"
    referrerpolicy="no-referrer">
</iframe>
```

### Message Validation

```javascript
// Validate message origin
window.addEventListener('message', (event) => {
    // Verify origin (replace with your domain)
    if (event.origin !== 'https://your-workflow-domain.com') {
        console.warn('Message from unauthorized origin:', event.origin);
        return;
    }
    
    // Validate message structure
    if (!event.data || typeof event.data.type !== 'string') {
        console.warn('Invalid message structure:', event.data);
        return;
    }
    
    // Process valid message
    handleWorkflowMessage(event.data);
});
```

## Examples

### Customer Portal Integration

```html
<!-- Customer portal with workflow integration -->
<div class="customer-portal">
    <header>
        <h1>Welcome, {{ customer.name }}</h1>
        <nav>
            <a href="#dashboard">Dashboard</a>
            <a href="#applications">Applications</a>
            <a href="#documents">Documents</a>
        </nav>
    </header>
    
    <main>
        <div class="application-section">
            <h2>Complete Your Application</h2>
            <div class="progress-indicator">
                <span id="progress-text">Step 1 of 5</span>
                <div class="progress-bar">
                    <div id="progress-fill"></div>
                </div>
            </div>
            
            <iframe 
                id="application-iframe"
                src="/workflow/customer-application?debug=false&hideComplete=true"
                style="width: 100%; height: 600px; border: none;">
            </iframe>
        </div>
    </main>
</div>

<script>
    // Customer portal integration
    const applicationSteps = [
        'personal-info',
        'employment-history', 
        'document-upload',
        'references',
        'final-submission'
    ];
    
    let currentStep = 0;
    
    window.addEventListener('message', (event) => {
        if (event.data.type === 'workflow-complete') {
            currentStep++;
            updateProgress();
            
            if (currentStep < applicationSteps.length) {
                // Load next step
                const iframe = document.getElementById('application-iframe');
                iframe.src = `/workflow/${applicationSteps[currentStep]}?debug=false&hideComplete=true`;
            } else {
                // Application complete
                showApplicationComplete();
            }
        }
    });
    
    function updateProgress() {
        const progress = ((currentStep + 1) / applicationSteps.length) * 100;
        document.getElementById('progress-fill').style.width = progress + '%';
        document.getElementById('progress-text').textContent = `Step ${currentStep + 1} of ${applicationSteps.length}`;
    }
    
    function showApplicationComplete() {
        document.getElementById('application-iframe').style.display = 'none';
        document.querySelector('.application-section').innerHTML = `
            <div class="completion-message">
                <h2>🎉 Application Submitted!</h2>
                <p>Your application has been successfully submitted. We'll review it and contact you soon.</p>
                <button onclick="downloadApplication()">Download Application</button>
            </div>
        `;
    }
</script>
```

### Employee Onboarding System

```html
<!-- Employee onboarding with multiple workflows -->
<div class="onboarding-system">
    <div class="onboarding-header">
        <h1>Employee Onboarding</h1>
        <div class="step-indicator">
            <div class="step active" data-step="1">Personal Info</div>
            <div class="step" data-step="2">Employment</div>
            <div class="step" data-step="3">Documents</div>
            <div class="step" data-step="4">Benefits</div>
            <div class="step" data-step="5">Final</div>
        </div>
    </div>
    
    <div class="workflow-container">
        <iframe 
            id="onboarding-iframe"
            src="/workflow/personal-info?debug=false&hideComplete=true"
            style="width: 100%; height: 700px; border: none;">
        </iframe>
    </div>
</div>

<script>
    // Employee onboarding integration
    const onboardingSteps = [
        { id: 'personal-info', name: 'Personal Information' },
        { id: 'employment', name: 'Employment Details' },
        { id: 'documents', name: 'Document Upload' },
        { id: 'benefits', name: 'Benefits Selection' },
        { id: 'final', name: 'Final Review' }
    ];
    
    let currentStepIndex = 0;
    
    window.addEventListener('message', (event) => {
        if (event.data.type === 'workflow-complete') {
            console.log(`Step ${event.data.processName} completed`);
            
            if (event.data.hideCompletionMessage) {
                // Auto-advance to next step
                setTimeout(() => {
                    loadNextStep();
                }, 200);
            }
        } else if (event.data.type === 'workflow-error') {
            handleOnboardingError(event.data);
        }
    });
    
    function loadNextStep() {
        currentStepIndex++;
        
        if (currentStepIndex >= onboardingSteps.length) {
            // Onboarding complete
            showOnboardingComplete();
            return;
        }
        
        const step = onboardingSteps[currentStepIndex];
        const iframe = document.getElementById('onboarding-iframe');
        
        // Update iframe
        iframe.src = `/workflow/${step.id}?debug=false&hideComplete=true`;
        
        // Update step indicator
        updateStepIndicator(currentStepIndex + 1);
    }
    
    function updateStepIndicator(activeStep) {
        document.querySelectorAll('.step').forEach((step, index) => {
            if (index + 1 <= activeStep) {
                step.classList.add('active');
            } else {
                step.classList.remove('active');
            }
        });
    }
    
    function showOnboardingComplete() {
        document.getElementById('onboarding-iframe').style.display = 'none';
        document.querySelector('.workflow-container').innerHTML = `
            <div class="completion-message">
                <h2>🎉 Onboarding Complete!</h2>
                <p>Welcome to the team! Your onboarding process has been completed successfully.</p>
                <div class="next-steps">
                    <h3>Next Steps:</h3>
                    <ul>
                        <li>Check your email for login credentials</li>
                        <li>Complete your first-day orientation</li>
                        <li>Meet with your manager</li>
                    </ul>
                </div>
            </div>
        `;
    }
    
    function handleOnboardingError(data) {
        console.error('Onboarding error:', data);
        // Show error message and retry options
        showErrorModal(data.error);
    }
</script>
```

## Troubleshooting

### Common Issues and Solutions

#### 1. Iframe Not Loading

**Problem**: Iframe shows blank or doesn't load
**Solution**: Check URL parameters and CORS settings

```javascript
// Debug iframe loading
const iframe = document.getElementById('workflow-iframe');
iframe.onload = () => {
    console.log('Iframe loaded successfully');
};
iframe.onerror = () => {
    console.error('Iframe failed to load');
};
```

#### 2. Messages Not Received

**Problem**: Parent iframe not receiving completion messages
**Solution**: Verify event listener and origin settings

```javascript
// Debug message reception
window.addEventListener('message', (event) => {
    console.log('Message received:', event.data);
    // Your message handling logic
});
```

#### 3. Cross-Origin Issues

**Problem**: CORS errors when loading iframe
**Solution**: Configure proper CORS headers on the workflow server

```nginx
# Nginx configuration example
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type";
```

#### 4. URL Parameter Issues

**Problem**: URL parameters not working as expected
**Solution**: Verify parameter encoding

```javascript
// Proper URL construction
const baseUrl = '/workflow/process-id';
const params = new URLSearchParams({
    debug: 'false',
    hideComplete: 'true'
});
const fullUrl = `${baseUrl}?${params.toString()}`;
```

### Debug Checklist

- [ ] Iframe source URL is correct
- [ ] URL parameters are properly encoded
- [ ] Event listener is attached to window
- [ ] Origin validation is configured
- [ ] CORS headers are set on server
- [ ] Console shows no JavaScript errors
- [ ] Network tab shows successful iframe load

### Support

For additional support with iframe integration:

1. Check the browser console for error messages
2. Verify network connectivity to the workflow server
3. Test with different browsers
4. Review server logs for any backend issues
5. Contact support with specific error details

---

This documentation provides comprehensive guidance for integrating Corrad workflows into external applications. The iframe system is designed to be flexible, secure, and easy to implement while providing a seamless user experience. 