feat: Add comprehensive communication template management system
- Create HVAC_Communication_Templates class for managing email templates - Add template post type with categories and placeholders - Implement AJAX handlers for CRUD operations - Create responsive template management interface with modal forms - Add template manager widget for integration with email forms - Include placeholder system for dynamic content (attendee_name, event_title, etc.) - Add default templates for common scenarios (reminders, welcome, certificates) - Create template management page with category filtering - Add comprehensive E2E tests for template functionality - Integrate widget into email attendees page - Support template save/load/edit/delete operations - Include CSS styling with responsive design and accessibility features - Add JavaScript for interactive functionality and form handling 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
5425b4346e
commit
3da56c262a
9 changed files with 2520 additions and 1 deletions
34
wordpress-dev/bin/create-communication-templates-page.sh
Executable file
34
wordpress-dev/bin/create-communication-templates-page.sh
Executable file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Create Communication Templates page on staging server
|
||||||
|
|
||||||
|
echo "Creating Communication Templates page on staging server..."
|
||||||
|
|
||||||
|
# Check if the page already exists
|
||||||
|
PAGE_EXISTS=$(ssh roodev@146.190.76.204 "cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp post list --post_type=page --title='Communication Templates' --field=ID")
|
||||||
|
|
||||||
|
if [ -n "$PAGE_EXISTS" ]; then
|
||||||
|
echo "Communication Templates page already exists with ID: $PAGE_EXISTS"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the page with the shortcode
|
||||||
|
PAGE_ID=$(ssh roodev@146.190.76.204 "cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp post create --post_type=page --post_title='Communication Templates' --post_status=publish --post_content='[hvac_communication_templates]' --porcelain")
|
||||||
|
|
||||||
|
if [ $? -eq 0 ] && [ -n "$PAGE_ID" ]; then
|
||||||
|
echo "✓ Communication Templates page created successfully"
|
||||||
|
else
|
||||||
|
echo "✗ Failed to create Communication Templates page"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify the page was created
|
||||||
|
VERIFY_ID=$(ssh roodev@146.190.76.204 "cd /home/974670.cloudwaysapps.com/uberrxmprk/public_html && wp post list --post_type=page --name=communication-templates --field=ID")
|
||||||
|
|
||||||
|
if [ -n "$VERIFY_ID" ]; then
|
||||||
|
echo "✓ Page created with ID: $PAGE_ID"
|
||||||
|
echo "✓ URL: https://upskill-staging.measurequick.com/communication-templates/"
|
||||||
|
else
|
||||||
|
echo "✗ Failed to verify page creation"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
205
wordpress-dev/tests/e2e/communication-templates.test.ts
Normal file
205
wordpress-dev/tests/e2e/communication-templates.test.ts
Normal file
|
|
@ -0,0 +1,205 @@
|
||||||
|
import { test, expect } from './fixtures/auth';
|
||||||
|
import { CommonActions } from './utils/common-actions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Communication Templates E2E Tests
|
||||||
|
*
|
||||||
|
* Tests the email template management system for trainers
|
||||||
|
*/
|
||||||
|
|
||||||
|
test.describe('Communication Templates Tests', () => {
|
||||||
|
|
||||||
|
test('Templates page loads and displays correctly', async ({ authenticatedPage: page }) => {
|
||||||
|
test.setTimeout(25000);
|
||||||
|
const actions = new CommonActions(page);
|
||||||
|
|
||||||
|
// Navigate to communication templates page
|
||||||
|
await actions.navigateAndWait('/communication-templates/');
|
||||||
|
await actions.screenshot('templates-page-loaded');
|
||||||
|
|
||||||
|
// Check page title and heading
|
||||||
|
await expect(page.locator('h1')).toContainText('Communication Templates');
|
||||||
|
|
||||||
|
// Verify main elements are present
|
||||||
|
await expect(page.locator('.hvac-templates-wrapper')).toBeVisible();
|
||||||
|
await expect(page.locator('.hvac-templates-header')).toBeVisible();
|
||||||
|
|
||||||
|
console.log('✓ Communication Templates page loaded successfully');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Template manager widget displays in email attendees page', async ({ authenticatedPage: page }) => {
|
||||||
|
test.setTimeout(30000);
|
||||||
|
const actions = new CommonActions(page);
|
||||||
|
|
||||||
|
// First navigate to dashboard to get an event
|
||||||
|
await actions.navigateAndWait('/hvac-dashboard/');
|
||||||
|
await actions.screenshot('dashboard-for-event-selection');
|
||||||
|
|
||||||
|
// Look for events with attendees
|
||||||
|
const eventLinks = page.locator('a[href*="email-attendees"]');
|
||||||
|
const eventCount = await eventLinks.count();
|
||||||
|
|
||||||
|
if (eventCount > 0) {
|
||||||
|
// Navigate to email attendees page for first event
|
||||||
|
await eventLinks.first().click();
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
|
await actions.screenshot('email-attendees-page-loaded');
|
||||||
|
|
||||||
|
// Check that template manager widget is present
|
||||||
|
await expect(page.locator('.hvac-template-manager')).toBeVisible();
|
||||||
|
await expect(page.locator('.hvac-template-toggle')).toBeVisible();
|
||||||
|
|
||||||
|
// Check toggle functionality
|
||||||
|
const templateToggle = page.locator('.hvac-template-toggle');
|
||||||
|
await templateToggle.click();
|
||||||
|
await actions.screenshot('template-manager-opened');
|
||||||
|
|
||||||
|
// Template manager should now be visible
|
||||||
|
await expect(page.locator('.hvac-template-manager')).toBeVisible();
|
||||||
|
|
||||||
|
console.log('✓ Template manager widget working in email attendees page');
|
||||||
|
} else {
|
||||||
|
console.log('⚠ No events with email functionality found - skipping widget test');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Template creation functionality works', async ({ authenticatedPage: page }) => {
|
||||||
|
test.setTimeout(30000);
|
||||||
|
const actions = new CommonActions(page);
|
||||||
|
|
||||||
|
// Navigate to templates page
|
||||||
|
await actions.navigateAndWait('/communication-templates/');
|
||||||
|
await actions.screenshot('templates-page-for-creation');
|
||||||
|
|
||||||
|
// Look for create template button
|
||||||
|
const createButton = page.locator('button:has-text("Create New Template")');
|
||||||
|
|
||||||
|
if (await createButton.isVisible()) {
|
||||||
|
await createButton.click();
|
||||||
|
await actions.screenshot('template-form-opened');
|
||||||
|
|
||||||
|
// Check form elements are present
|
||||||
|
await expect(page.locator('#hvac_template_title')).toBeVisible();
|
||||||
|
await expect(page.locator('#hvac_template_content')).toBeVisible();
|
||||||
|
await expect(page.locator('#hvac_template_category')).toBeVisible();
|
||||||
|
|
||||||
|
// Check placeholder helper is present
|
||||||
|
await expect(page.locator('.hvac-placeholder-helper')).toBeVisible();
|
||||||
|
await expect(page.locator('.hvac-placeholder-grid')).toBeVisible();
|
||||||
|
|
||||||
|
console.log('✓ Template creation form displays correctly');
|
||||||
|
} else {
|
||||||
|
console.log('⚠ Template creation interface not found - may need default templates');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Default templates installation works for new trainers', async ({ authenticatedPage: page }) => {
|
||||||
|
test.setTimeout(25000);
|
||||||
|
const actions = new CommonActions(page);
|
||||||
|
|
||||||
|
// Navigate to templates page
|
||||||
|
await actions.navigateAndWait('/communication-templates/');
|
||||||
|
await actions.screenshot('templates-page-new-user');
|
||||||
|
|
||||||
|
// Check if this shows getting started section (for users without templates)
|
||||||
|
const gettingStarted = page.locator('.hvac-getting-started');
|
||||||
|
|
||||||
|
if (await gettingStarted.isVisible()) {
|
||||||
|
// New trainer setup detected
|
||||||
|
await expect(gettingStarted).toContainText('Welcome to Communication Templates');
|
||||||
|
|
||||||
|
// Check for install defaults button
|
||||||
|
const installButton = page.locator('a:has-text("Install Default Templates")');
|
||||||
|
await expect(installButton).toBeVisible();
|
||||||
|
|
||||||
|
console.log('✓ Getting started interface displays for new trainers');
|
||||||
|
} else {
|
||||||
|
// User already has templates
|
||||||
|
const templatesGrid = page.locator('.hvac-templates-grid');
|
||||||
|
if (await templatesGrid.isVisible()) {
|
||||||
|
// Check template cards exist
|
||||||
|
const templateCards = page.locator('.hvac-template-card');
|
||||||
|
const cardCount = await templateCards.count();
|
||||||
|
|
||||||
|
expect(cardCount).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
// Check template card structure
|
||||||
|
await expect(templateCards.first().locator('.hvac-template-card-title')).toBeVisible();
|
||||||
|
await expect(templateCards.first().locator('.hvac-template-card-actions')).toBeVisible();
|
||||||
|
|
||||||
|
console.log(`✓ Templates display correctly (${cardCount} templates found)`);
|
||||||
|
} else {
|
||||||
|
console.log('⚠ No templates found and no getting started section');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Template placeholders system works', async ({ authenticatedPage: page }) => {
|
||||||
|
test.setTimeout(20000);
|
||||||
|
const actions = new CommonActions(page);
|
||||||
|
|
||||||
|
// Navigate to templates page
|
||||||
|
await actions.navigateAndWait('/communication-templates/');
|
||||||
|
await actions.screenshot('templates-page-placeholders');
|
||||||
|
|
||||||
|
// Try to open template form to see placeholders
|
||||||
|
const createButton = page.locator('button:has-text("Create New Template")');
|
||||||
|
|
||||||
|
if (await createButton.isVisible()) {
|
||||||
|
await createButton.click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
// Check placeholder helper is loaded
|
||||||
|
const placeholderHelper = page.locator('.hvac-placeholder-helper');
|
||||||
|
await expect(placeholderHelper).toBeVisible();
|
||||||
|
|
||||||
|
// Check for some common placeholders
|
||||||
|
await expect(page.locator('.hvac-placeholder-item:has-text("{attendee_name}")')).toBeVisible();
|
||||||
|
await expect(page.locator('.hvac-placeholder-item:has-text("{event_title}")')).toBeVisible();
|
||||||
|
await expect(page.locator('.hvac-placeholder-item:has-text("{trainer_name}")')).toBeVisible();
|
||||||
|
|
||||||
|
console.log('✓ Template placeholders system working correctly');
|
||||||
|
} else {
|
||||||
|
console.log('⚠ Cannot test placeholders - template form not accessible');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('JavaScript functionality loads without errors', async ({ authenticatedPage: page }) => {
|
||||||
|
test.setTimeout(20000);
|
||||||
|
const actions = new CommonActions(page);
|
||||||
|
|
||||||
|
// Monitor console errors
|
||||||
|
const jsErrors: string[] = [];
|
||||||
|
page.on('console', (msg) => {
|
||||||
|
if (msg.type() === 'error') {
|
||||||
|
jsErrors.push(msg.text());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Navigate to templates page
|
||||||
|
await actions.navigateAndWait('/communication-templates/');
|
||||||
|
await actions.screenshot('templates-page-js-check');
|
||||||
|
|
||||||
|
// Check that HVACTemplates object is available
|
||||||
|
const hvacTemplatesExists = await page.evaluate(() => {
|
||||||
|
return typeof window.HVACTemplates !== 'undefined';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hvacTemplatesExists) {
|
||||||
|
console.log('✓ HVACTemplates JavaScript object loaded correctly');
|
||||||
|
} else {
|
||||||
|
console.log('⚠ HVACTemplates JavaScript object not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for critical JS errors
|
||||||
|
const criticalErrors = jsErrors.filter(error =>
|
||||||
|
error.includes('HVACTemplates') ||
|
||||||
|
error.includes('communication-templates') ||
|
||||||
|
error.includes('Uncaught')
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(criticalErrors.length).toBe(0);
|
||||||
|
console.log(`✓ No critical JavaScript errors found (${jsErrors.length} total console messages)`);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,512 @@
|
||||||
|
/**
|
||||||
|
* HVAC Communication Templates Styling
|
||||||
|
*
|
||||||
|
* Styles for the email template management system
|
||||||
|
*
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Template Management Container */
|
||||||
|
.hvac-template-manager {
|
||||||
|
background: var(--hvac-background-white);
|
||||||
|
border-radius: var(--hvac-radius-lg);
|
||||||
|
box-shadow: var(--hvac-shadow-md);
|
||||||
|
padding: var(--hvac-spacing-6);
|
||||||
|
margin-bottom: var(--hvac-spacing-6);
|
||||||
|
border: 1px solid var(--hvac-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-manager h3 {
|
||||||
|
color: var(--hvac-theme-text-dark);
|
||||||
|
font-size: var(--hvac-font-size-lg);
|
||||||
|
font-weight: var(--hvac-font-weight-semibold);
|
||||||
|
margin: 0 0 var(--hvac-spacing-4) 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--hvac-spacing-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-manager h3::before {
|
||||||
|
content: '📝';
|
||||||
|
font-size: var(--hvac-font-size-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Template Actions */
|
||||||
|
.hvac-template-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--hvac-spacing-3);
|
||||||
|
margin-bottom: var(--hvac-spacing-4);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-toggle {
|
||||||
|
background: var(--hvac-primary);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: var(--hvac-spacing-2) var(--hvac-spacing-4);
|
||||||
|
border-radius: var(--hvac-radius-md);
|
||||||
|
font-size: var(--hvac-font-size-sm);
|
||||||
|
font-weight: var(--hvac-font-weight-medium);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all var(--hvac-transition-fast);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--hvac-spacing-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-toggle:hover {
|
||||||
|
background: var(--hvac-primary-dark);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-toggle.active {
|
||||||
|
background: var(--hvac-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Template List */
|
||||||
|
.hvac-template-list {
|
||||||
|
margin-bottom: var(--hvac-spacing-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-selector {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--hvac-spacing-3);
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: var(--hvac-spacing-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-dropdown {
|
||||||
|
min-width: 200px;
|
||||||
|
padding: var(--hvac-spacing-2) var(--hvac-spacing-3);
|
||||||
|
border: 2px solid var(--hvac-border);
|
||||||
|
border-radius: var(--hvac-radius-md);
|
||||||
|
font-size: var(--hvac-font-size-sm);
|
||||||
|
background: var(--hvac-background-white);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color var(--hvac-transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-dropdown:focus {
|
||||||
|
border-color: var(--hvac-primary);
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 0 3px var(--hvac-primary-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-category-filter {
|
||||||
|
min-width: 150px;
|
||||||
|
padding: var(--hvac-spacing-2) var(--hvac-spacing-3);
|
||||||
|
border: 2px solid var(--hvac-border);
|
||||||
|
border-radius: var(--hvac-radius-md);
|
||||||
|
font-size: var(--hvac-font-size-sm);
|
||||||
|
background: var(--hvac-background-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-actions-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--hvac-spacing-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-load, .hvac-btn-edit, .hvac-btn-delete, .hvac-btn-save {
|
||||||
|
padding: var(--hvac-spacing-2) var(--hvac-spacing-3);
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--hvac-radius-sm);
|
||||||
|
font-size: var(--hvac-font-size-sm);
|
||||||
|
font-weight: var(--hvac-font-weight-medium);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all var(--hvac-transition-fast);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--hvac-spacing-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-load {
|
||||||
|
background: var(--hvac-accent);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-load:hover {
|
||||||
|
background: var(--hvac-accent-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-edit {
|
||||||
|
background: var(--hvac-warning);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-edit:hover {
|
||||||
|
background: var(--hvac-warning-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-delete {
|
||||||
|
background: var(--hvac-error);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-delete:hover {
|
||||||
|
background: var(--hvac-error-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-save {
|
||||||
|
background: var(--hvac-success);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-save:hover {
|
||||||
|
background: var(--hvac-success-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Template Form */
|
||||||
|
.hvac-template-form {
|
||||||
|
background: var(--hvac-background-subtle);
|
||||||
|
padding: var(--hvac-spacing-5);
|
||||||
|
border-radius: var(--hvac-radius-md);
|
||||||
|
border: 1px solid var(--hvac-border-light);
|
||||||
|
margin-bottom: var(--hvac-spacing-4);
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form.active {
|
||||||
|
display: block;
|
||||||
|
animation: hvac-fadeIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes hvac-fadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(-10px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form-row {
|
||||||
|
margin-bottom: var(--hvac-spacing-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form-row label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: var(--hvac-spacing-2);
|
||||||
|
font-weight: var(--hvac-font-weight-semibold);
|
||||||
|
color: var(--hvac-theme-text-dark);
|
||||||
|
font-size: var(--hvac-font-size-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form-row input[type="text"],
|
||||||
|
.hvac-template-form-row select,
|
||||||
|
.hvac-template-form-row textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: var(--hvac-spacing-3);
|
||||||
|
border: 2px solid var(--hvac-border);
|
||||||
|
border-radius: var(--hvac-radius-md);
|
||||||
|
font-size: var(--hvac-font-size-md);
|
||||||
|
font-family: var(--hvac-font-family);
|
||||||
|
background: var(--hvac-background-white);
|
||||||
|
transition: border-color var(--hvac-transition-fast);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form-row input[type="text"]:focus,
|
||||||
|
.hvac-template-form-row select:focus,
|
||||||
|
.hvac-template-form-row textarea:focus {
|
||||||
|
border-color: var(--hvac-primary);
|
||||||
|
outline: none;
|
||||||
|
box-shadow: 0 0 0 3px var(--hvac-primary-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form-row textarea {
|
||||||
|
min-height: 200px;
|
||||||
|
resize: vertical;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Required field indicator */
|
||||||
|
.hvac-required {
|
||||||
|
color: var(--hvac-error);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Placeholder Helper */
|
||||||
|
.hvac-placeholder-helper {
|
||||||
|
background: var(--hvac-info-light);
|
||||||
|
border: 1px solid var(--hvac-accent);
|
||||||
|
border-radius: var(--hvac-radius-md);
|
||||||
|
padding: var(--hvac-spacing-4);
|
||||||
|
margin-bottom: var(--hvac-spacing-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-placeholder-helper h4 {
|
||||||
|
color: var(--hvac-accent);
|
||||||
|
font-size: var(--hvac-font-size-md);
|
||||||
|
font-weight: var(--hvac-font-weight-semibold);
|
||||||
|
margin: 0 0 var(--hvac-spacing-3) 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--hvac-spacing-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-placeholder-helper h4::before {
|
||||||
|
content: '💡';
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-placeholder-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: var(--hvac-spacing-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-placeholder-item {
|
||||||
|
background: var(--hvac-background-white);
|
||||||
|
border: 1px solid var(--hvac-border-light);
|
||||||
|
border-radius: var(--hvac-radius-sm);
|
||||||
|
padding: var(--hvac-spacing-2) var(--hvac-spacing-3);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all var(--hvac-transition-fast);
|
||||||
|
font-size: var(--hvac-font-size-sm);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-placeholder-item:hover {
|
||||||
|
background: var(--hvac-primary-light);
|
||||||
|
border-color: var(--hvac-primary);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-placeholder-code {
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-weight: var(--hvac-font-weight-bold);
|
||||||
|
color: var(--hvac-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-placeholder-desc {
|
||||||
|
color: var(--hvac-theme-text-light);
|
||||||
|
font-size: var(--hvac-font-size-xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Form Actions */
|
||||||
|
.hvac-template-form-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--hvac-spacing-3);
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: var(--hvac-spacing-5);
|
||||||
|
padding-top: var(--hvac-spacing-4);
|
||||||
|
border-top: 1px solid var(--hvac-border-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form-actions button {
|
||||||
|
padding: var(--hvac-spacing-3) var(--hvac-spacing-5);
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--hvac-radius-md);
|
||||||
|
font-size: var(--hvac-font-size-md);
|
||||||
|
font-weight: var(--hvac-font-weight-semibold);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all var(--hvac-transition-fast);
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-primary {
|
||||||
|
background: var(--hvac-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-primary:hover {
|
||||||
|
background: var(--hvac-primary-dark);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: var(--hvac-shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-secondary {
|
||||||
|
background: var(--hvac-theme-text-light);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-btn-secondary:hover {
|
||||||
|
background: var(--hvac-theme-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loading State */
|
||||||
|
.hvac-loading {
|
||||||
|
opacity: 0.6;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-spinner {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||||
|
border-top: 2px solid white;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: hvac-spin 1s linear infinite;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: var(--hvac-spacing-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes hvac-spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Messages */
|
||||||
|
.hvac-template-message {
|
||||||
|
padding: var(--hvac-spacing-3) var(--hvac-spacing-4);
|
||||||
|
border-radius: var(--hvac-radius-md);
|
||||||
|
margin-bottom: var(--hvac-spacing-4);
|
||||||
|
font-size: var(--hvac-font-size-sm);
|
||||||
|
font-weight: var(--hvac-font-weight-medium);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--hvac-spacing-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-message.success {
|
||||||
|
background: var(--hvac-success-light);
|
||||||
|
color: var(--hvac-success-dark);
|
||||||
|
border: 1px solid var(--hvac-success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-message.success::before {
|
||||||
|
content: '✓';
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-message.error {
|
||||||
|
background: var(--hvac-error-light);
|
||||||
|
color: var(--hvac-error-dark);
|
||||||
|
border: 1px solid var(--hvac-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-message.error::before {
|
||||||
|
content: '⚠';
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Empty State */
|
||||||
|
.hvac-template-empty {
|
||||||
|
text-align: center;
|
||||||
|
padding: var(--hvac-spacing-8);
|
||||||
|
color: var(--hvac-theme-text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-empty-icon {
|
||||||
|
font-size: 3rem;
|
||||||
|
margin-bottom: var(--hvac-spacing-4);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-empty h4 {
|
||||||
|
font-size: var(--hvac-font-size-lg);
|
||||||
|
margin-bottom: var(--hvac-spacing-2);
|
||||||
|
color: var(--hvac-theme-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-empty p {
|
||||||
|
font-size: var(--hvac-font-size-md);
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive Design */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.hvac-template-selector {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-dropdown,
|
||||||
|
.hvac-template-category-filter {
|
||||||
|
min-width: auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-actions-buttons {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: var(--hvac-spacing-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-actions-buttons button {
|
||||||
|
flex: 1;
|
||||||
|
min-width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-placeholder-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form-actions {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form-actions button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.hvac-template-manager {
|
||||||
|
padding: var(--hvac-spacing-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form {
|
||||||
|
padding: var(--hvac-spacing-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-actions {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-toggle {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Integration with Email Form */
|
||||||
|
.hvac-email-form .hvac-template-manager {
|
||||||
|
margin-bottom: var(--hvac-spacing-6);
|
||||||
|
border: 2px solid var(--hvac-primary-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-email-form .hvac-template-manager h3 {
|
||||||
|
color: var(--hvac-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WordPress Editor Integration */
|
||||||
|
.hvac-template-content-wp-editor {
|
||||||
|
border: 2px solid var(--hvac-border);
|
||||||
|
border-radius: var(--hvac-radius-md);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-content-wp-editor iframe {
|
||||||
|
border: none;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accessibility Improvements */
|
||||||
|
.hvac-template-manager button:focus,
|
||||||
|
.hvac-template-manager select:focus,
|
||||||
|
.hvac-template-manager input:focus {
|
||||||
|
outline: 2px solid var(--hvac-primary);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-manager [aria-disabled="true"] {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print Styles */
|
||||||
|
@media print {
|
||||||
|
.hvac-template-manager {
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-actions,
|
||||||
|
.hvac-template-form-actions {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,489 @@
|
||||||
|
/**
|
||||||
|
* HVAC Communication Templates JavaScript
|
||||||
|
*
|
||||||
|
* Handles the frontend functionality for email template management
|
||||||
|
*
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Template Manager Object
|
||||||
|
const HVACTemplates = {
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
config: {
|
||||||
|
ajaxUrl: hvacTemplates.ajaxUrl,
|
||||||
|
nonce: hvacTemplates.nonce,
|
||||||
|
placeholders: hvacTemplates.placeholders,
|
||||||
|
categories: hvacTemplates.categories,
|
||||||
|
strings: hvacTemplates.strings
|
||||||
|
},
|
||||||
|
|
||||||
|
// Current state
|
||||||
|
currentTemplateId: null,
|
||||||
|
isEditing: false,
|
||||||
|
templates: [],
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
init: function() {
|
||||||
|
this.bindEvents();
|
||||||
|
this.loadTemplates();
|
||||||
|
this.setupPlaceholderHelper();
|
||||||
|
},
|
||||||
|
|
||||||
|
// Bind event handlers
|
||||||
|
bindEvents: function() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
// Toggle template manager
|
||||||
|
$(document).on('click', '.hvac-template-toggle', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
self.toggleTemplateManager();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Category filter change
|
||||||
|
$(document).on('change', '.hvac-template-category-filter', function() {
|
||||||
|
self.filterTemplatesByCategory($(this).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Template actions
|
||||||
|
$(document).on('click', '.hvac-btn-load', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const templateId = $('.hvac-template-dropdown').val();
|
||||||
|
if (templateId) {
|
||||||
|
self.loadTemplate(templateId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.hvac-btn-edit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const templateId = $('.hvac-template-dropdown').val();
|
||||||
|
if (templateId) {
|
||||||
|
self.editTemplate(templateId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.hvac-btn-delete', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const templateId = $('.hvac-template-dropdown').val();
|
||||||
|
if (templateId && confirm(self.config.strings.confirmDelete)) {
|
||||||
|
self.deleteTemplate(templateId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.hvac-btn-save', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
self.saveTemplate();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Form actions
|
||||||
|
$(document).on('click', '.hvac-template-form-save', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
self.saveTemplate();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.hvac-template-form-cancel', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
self.cancelTemplateForm();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Placeholder insertion
|
||||||
|
$(document).on('click', '.hvac-placeholder-item', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const placeholder = $(this).find('.hvac-placeholder-code').text();
|
||||||
|
self.insertPlaceholder(placeholder);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Auto-save prevention
|
||||||
|
$(document).on('beforeunload', function() {
|
||||||
|
if (self.isEditing && self.hasUnsavedChanges()) {
|
||||||
|
return 'You have unsaved changes. Are you sure you want to leave?';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Toggle template manager visibility
|
||||||
|
toggleTemplateManager: function() {
|
||||||
|
const $manager = $('.hvac-template-manager');
|
||||||
|
const $toggle = $('.hvac-template-toggle');
|
||||||
|
|
||||||
|
if ($manager.is(':visible')) {
|
||||||
|
$manager.slideUp();
|
||||||
|
$toggle.removeClass('active').text('📝 Use Template');
|
||||||
|
} else {
|
||||||
|
$manager.slideDown();
|
||||||
|
$toggle.addClass('active').text('📝 Hide Templates');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Load user templates
|
||||||
|
loadTemplates: function(category = '') {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: this.config.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'hvac_get_templates',
|
||||||
|
nonce: this.config.nonce,
|
||||||
|
category: category
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
self.templates = response.data.templates;
|
||||||
|
self.populateTemplateDropdown();
|
||||||
|
} else {
|
||||||
|
self.showMessage(response.data.message, 'error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
self.showMessage(self.config.strings.error, 'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Filter templates by category
|
||||||
|
filterTemplatesByCategory: function(category) {
|
||||||
|
this.loadTemplates(category);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Populate template dropdown
|
||||||
|
populateTemplateDropdown: function() {
|
||||||
|
const $dropdown = $('.hvac-template-dropdown');
|
||||||
|
$dropdown.empty();
|
||||||
|
|
||||||
|
if (this.templates.length === 0) {
|
||||||
|
$dropdown.append('<option value="">' + 'No templates found' + '</option>');
|
||||||
|
$('.hvac-template-actions-buttons button').prop('disabled', true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dropdown.append('<option value="">' + 'Select a template...' + '</option>');
|
||||||
|
|
||||||
|
this.templates.forEach(function(template) {
|
||||||
|
$dropdown.append(
|
||||||
|
'<option value="' + template.id + '">' +
|
||||||
|
template.title +
|
||||||
|
(template.category ? ' (' + template.category + ')' : '') +
|
||||||
|
'</option>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.hvac-template-actions-buttons button').prop('disabled', false);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Load template content into email form
|
||||||
|
loadTemplate: function(templateId) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: this.config.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'hvac_load_template',
|
||||||
|
nonce: this.config.nonce,
|
||||||
|
template_id: templateId
|
||||||
|
},
|
||||||
|
beforeSend: function() {
|
||||||
|
$('.hvac-btn-load').addClass('hvac-loading');
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
const template = response.data;
|
||||||
|
|
||||||
|
// Populate email form fields
|
||||||
|
$('#email_subject').val(template.title);
|
||||||
|
|
||||||
|
// Handle different content areas (WordPress editor or textarea)
|
||||||
|
if (typeof tinyMCE !== 'undefined' && tinyMCE.get('email_message')) {
|
||||||
|
tinyMCE.get('email_message').setContent(template.content);
|
||||||
|
} else {
|
||||||
|
$('#email_message').val(template.content);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.showMessage('Template loaded successfully', 'success');
|
||||||
|
|
||||||
|
// Optionally hide template manager after loading
|
||||||
|
// self.toggleTemplateManager();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self.showMessage(response.data.message, 'error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
$('.hvac-btn-load').removeClass('hvac-loading');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Edit template
|
||||||
|
editTemplate: function(templateId) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: this.config.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'hvac_load_template',
|
||||||
|
nonce: this.config.nonce,
|
||||||
|
template_id: templateId
|
||||||
|
},
|
||||||
|
beforeSend: function() {
|
||||||
|
$('.hvac-btn-edit').addClass('hvac-loading');
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
const template = response.data;
|
||||||
|
self.currentTemplateId = template.id;
|
||||||
|
self.isEditing = true;
|
||||||
|
|
||||||
|
// Populate template form
|
||||||
|
$('#hvac_template_title').val(template.title);
|
||||||
|
$('#hvac_template_content').val(template.content);
|
||||||
|
$('#hvac_template_category').val(template.category);
|
||||||
|
$('#hvac_template_description').val(template.description);
|
||||||
|
|
||||||
|
// Show template form
|
||||||
|
$('.hvac-template-form').addClass('active');
|
||||||
|
|
||||||
|
self.showMessage('Template loaded for editing', 'success');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self.showMessage(response.data.message, 'error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
$('.hvac-btn-edit').removeClass('hvac-loading');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Delete template
|
||||||
|
deleteTemplate: function(templateId) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: this.config.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'hvac_delete_template',
|
||||||
|
nonce: this.config.nonce,
|
||||||
|
template_id: templateId
|
||||||
|
},
|
||||||
|
beforeSend: function() {
|
||||||
|
$('.hvac-btn-delete').addClass('hvac-loading');
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
self.showMessage(response.data.message, 'success');
|
||||||
|
self.loadTemplates(); // Refresh template list
|
||||||
|
} else {
|
||||||
|
self.showMessage(response.data.message, 'error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
$('.hvac-btn-delete').removeClass('hvac-loading');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Save template
|
||||||
|
saveTemplate: function() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
const templateData = {
|
||||||
|
action: 'hvac_save_template',
|
||||||
|
nonce: this.config.nonce,
|
||||||
|
template_id: this.currentTemplateId || 0,
|
||||||
|
title: $('#hvac_template_title').val(),
|
||||||
|
content: $('#hvac_template_content').val(),
|
||||||
|
category: $('#hvac_template_category').val(),
|
||||||
|
description: $('#hvac_template_description').val()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Validation
|
||||||
|
if (!templateData.title || !templateData.content) {
|
||||||
|
this.showMessage('Template title and content are required', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: this.config.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: templateData,
|
||||||
|
beforeSend: function() {
|
||||||
|
$('.hvac-template-form-save').addClass('hvac-loading');
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
self.showMessage(response.data.message, 'success');
|
||||||
|
self.cancelTemplateForm();
|
||||||
|
self.loadTemplates(); // Refresh template list
|
||||||
|
} else {
|
||||||
|
self.showMessage(response.data.message, 'error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
$('.hvac-template-form-save').removeClass('hvac-loading');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Cancel template form
|
||||||
|
cancelTemplateForm: function() {
|
||||||
|
this.currentTemplateId = null;
|
||||||
|
this.isEditing = false;
|
||||||
|
|
||||||
|
// Clear form
|
||||||
|
$('#hvac_template_title').val('');
|
||||||
|
$('#hvac_template_content').val('');
|
||||||
|
$('#hvac_template_category').val('');
|
||||||
|
$('#hvac_template_description').val('');
|
||||||
|
|
||||||
|
// Hide form
|
||||||
|
$('.hvac-template-form').removeClass('active');
|
||||||
|
},
|
||||||
|
|
||||||
|
// Setup placeholder helper
|
||||||
|
setupPlaceholderHelper: function() {
|
||||||
|
const $helper = $('.hvac-placeholder-helper');
|
||||||
|
if ($helper.length === 0) return;
|
||||||
|
|
||||||
|
const $grid = $helper.find('.hvac-placeholder-grid');
|
||||||
|
|
||||||
|
Object.keys(this.config.placeholders).forEach(function(placeholder) {
|
||||||
|
const description = HVACTemplates.config.placeholders[placeholder];
|
||||||
|
|
||||||
|
const $item = $('<div class="hvac-placeholder-item">' +
|
||||||
|
'<span class="hvac-placeholder-code">' + placeholder + '</span>' +
|
||||||
|
'<span class="hvac-placeholder-desc">' + description + '</span>' +
|
||||||
|
'</div>');
|
||||||
|
|
||||||
|
$grid.append($item);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Insert placeholder into content
|
||||||
|
insertPlaceholder: function(placeholder) {
|
||||||
|
// Try to insert into WordPress editor first
|
||||||
|
if (typeof tinyMCE !== 'undefined' && tinyMCE.get('email_message')) {
|
||||||
|
const editor = tinyMCE.get('email_message');
|
||||||
|
editor.insertContent(placeholder);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try template content textarea
|
||||||
|
if ($('#hvac_template_content').length) {
|
||||||
|
const $textarea = $('#hvac_template_content');
|
||||||
|
const cursorPos = $textarea[0].selectionStart;
|
||||||
|
const textBefore = $textarea.val().substring(0, cursorPos);
|
||||||
|
const textAfter = $textarea.val().substring(cursorPos);
|
||||||
|
|
||||||
|
$textarea.val(textBefore + placeholder + textAfter);
|
||||||
|
$textarea[0].setSelectionRange(cursorPos + placeholder.length, cursorPos + placeholder.length);
|
||||||
|
$textarea.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to email message textarea
|
||||||
|
if ($('#email_message').length) {
|
||||||
|
const $textarea = $('#email_message');
|
||||||
|
const cursorPos = $textarea[0].selectionStart;
|
||||||
|
const textBefore = $textarea.val().substring(0, cursorPos);
|
||||||
|
const textAfter = $textarea.val().substring(cursorPos);
|
||||||
|
|
||||||
|
$textarea.val(textBefore + placeholder + textAfter);
|
||||||
|
$textarea[0].setSelectionRange(cursorPos + placeholder.length, cursorPos + placeholder.length);
|
||||||
|
$textarea.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Check for unsaved changes
|
||||||
|
hasUnsavedChanges: function() {
|
||||||
|
if (!this.isEditing) return false;
|
||||||
|
|
||||||
|
return $('#hvac_template_title').val() !== '' ||
|
||||||
|
$('#hvac_template_content').val() !== '' ||
|
||||||
|
$('#hvac_template_category').val() !== '' ||
|
||||||
|
$('#hvac_template_description').val() !== '';
|
||||||
|
},
|
||||||
|
|
||||||
|
// Show messages
|
||||||
|
showMessage: function(message, type) {
|
||||||
|
const $container = $('.hvac-template-manager');
|
||||||
|
|
||||||
|
// Remove existing messages
|
||||||
|
$container.find('.hvac-template-message').remove();
|
||||||
|
|
||||||
|
// Add new message
|
||||||
|
const $message = $('<div class="hvac-template-message ' + type + '">' + message + '</div>');
|
||||||
|
$container.prepend($message);
|
||||||
|
|
||||||
|
// Auto-hide success messages
|
||||||
|
if (type === 'success') {
|
||||||
|
setTimeout(function() {
|
||||||
|
$message.fadeOut(function() {
|
||||||
|
$message.remove();
|
||||||
|
});
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Create new template (helper method)
|
||||||
|
createNewTemplate: function() {
|
||||||
|
this.currentTemplateId = null;
|
||||||
|
this.isEditing = true;
|
||||||
|
|
||||||
|
// Clear and show form
|
||||||
|
this.cancelTemplateForm();
|
||||||
|
$('.hvac-template-form').addClass('active');
|
||||||
|
|
||||||
|
// Focus on title field
|
||||||
|
$('#hvac_template_title').focus();
|
||||||
|
},
|
||||||
|
|
||||||
|
// Utility: Get current email content
|
||||||
|
getCurrentEmailContent: function() {
|
||||||
|
if (typeof tinyMCE !== 'undefined' && tinyMCE.get('email_message')) {
|
||||||
|
return tinyMCE.get('email_message').getContent();
|
||||||
|
}
|
||||||
|
return $('#email_message').val() || '';
|
||||||
|
},
|
||||||
|
|
||||||
|
// Utility: Get current email subject
|
||||||
|
getCurrentEmailSubject: function() {
|
||||||
|
return $('#email_subject').val() || '';
|
||||||
|
},
|
||||||
|
|
||||||
|
// Save current email as template
|
||||||
|
saveCurrentEmailAsTemplate: function() {
|
||||||
|
const content = this.getCurrentEmailContent();
|
||||||
|
const subject = this.getCurrentEmailSubject();
|
||||||
|
|
||||||
|
if (!content && !subject) {
|
||||||
|
this.showMessage('No email content to save as template', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-fill form with current email content
|
||||||
|
$('#hvac_template_title').val(subject || 'New Template');
|
||||||
|
$('#hvac_template_content').val(content);
|
||||||
|
|
||||||
|
this.createNewTemplate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize when document is ready
|
||||||
|
$(document).ready(function() {
|
||||||
|
// Only initialize if template manager is present
|
||||||
|
if ($('.hvac-template-manager').length || $('.hvac-template-toggle').length) {
|
||||||
|
HVACTemplates.init();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Expose to global scope for external usage
|
||||||
|
window.HVACTemplates = HVACTemplates;
|
||||||
|
|
||||||
|
})(jQuery);
|
||||||
|
|
@ -78,7 +78,8 @@ class HVAC_Community_Events {
|
||||||
'community/class-email-debug.php', // Email debugging tools
|
'community/class-email-debug.php', // Email debugging tools
|
||||||
'certificates/test-rewrite-rules.php', // Rewrite rules testing (temporary)
|
'certificates/test-rewrite-rules.php', // Rewrite rules testing (temporary)
|
||||||
'google-sheets/class-google-sheets-auth.php', // Google Sheets authentication
|
'google-sheets/class-google-sheets-auth.php', // Google Sheets authentication
|
||||||
'google-sheets/class-google-sheets-manager.php' // Google Sheets management
|
'google-sheets/class-google-sheets-manager.php', // Google Sheets management
|
||||||
|
'communication/class-communication-templates.php' // Email template management
|
||||||
];
|
];
|
||||||
// Make sure Login_Handler is loaded first for shortcode registration
|
// Make sure Login_Handler is loaded first for shortcode registration
|
||||||
$login_handler_path = HVAC_CE_PLUGIN_DIR . 'includes/community/class-login-handler.php';
|
$login_handler_path = HVAC_CE_PLUGIN_DIR . 'includes/community/class-login-handler.php';
|
||||||
|
|
@ -386,6 +387,9 @@ class HVAC_Community_Events {
|
||||||
// Add Google Sheets admin shortcode
|
// Add Google Sheets admin shortcode
|
||||||
add_shortcode('hvac_google_sheets', array($this, 'render_google_sheets_admin'));
|
add_shortcode('hvac_google_sheets', array($this, 'render_google_sheets_admin'));
|
||||||
|
|
||||||
|
// Add communication templates shortcode
|
||||||
|
add_shortcode('hvac_communication_templates', array($this, 'render_communication_templates'));
|
||||||
|
|
||||||
// Removed shortcode override - let The Events Calendar Community Events handle this shortcode
|
// Removed shortcode override - let The Events Calendar Community Events handle this shortcode
|
||||||
// add_shortcode('tribe_community_events', array($this, 'render_tribe_community_events'));
|
// add_shortcode('tribe_community_events', array($this, 'render_tribe_community_events'));
|
||||||
|
|
||||||
|
|
@ -705,6 +709,11 @@ class HVAC_Community_Events {
|
||||||
$custom_template = HVAC_CE_PLUGIN_DIR . 'templates/template-edit-profile.php';
|
$custom_template = HVAC_CE_PLUGIN_DIR . 'templates/template-edit-profile.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for communication-templates page
|
||||||
|
if (is_page('communication-templates')) {
|
||||||
|
$custom_template = HVAC_CE_PLUGIN_DIR . 'templates/communication/template-communication-templates.php';
|
||||||
|
}
|
||||||
|
|
||||||
// Check for single event view (temporary)
|
// Check for single event view (temporary)
|
||||||
if (is_singular('tribe_events')) {
|
if (is_singular('tribe_events')) {
|
||||||
$custom_template = HVAC_CE_PLUGIN_DIR . 'templates/single-tribe_events.php';
|
$custom_template = HVAC_CE_PLUGIN_DIR . 'templates/single-tribe_events.php';
|
||||||
|
|
@ -779,4 +788,28 @@ class HVAC_Community_Events {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render communication templates content
|
||||||
|
*/
|
||||||
|
public function render_communication_templates() {
|
||||||
|
if (!is_user_logged_in()) {
|
||||||
|
return '<p>Please log in to manage communication templates.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user is a trainer or has permission to manage templates
|
||||||
|
$current_user = wp_get_current_user();
|
||||||
|
if (!in_array('hvac_trainer', $current_user->roles) && !current_user_can('edit_posts')) {
|
||||||
|
return '<p>You do not have permission to manage communication templates.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the communication templates class
|
||||||
|
if (!class_exists('HVAC_Communication_Templates')) {
|
||||||
|
require_once HVAC_CE_PLUGIN_DIR . 'includes/communication/class-communication-templates.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
include HVAC_CE_PLUGIN_DIR . 'templates/communication/template-communication-templates.php';
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
} // End class HVAC_Community_Events
|
} // End class HVAC_Community_Events
|
||||||
|
|
@ -0,0 +1,479 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* HVAC Community Events - Communication Templates Management
|
||||||
|
*
|
||||||
|
* Handles creation, storage, and management of email templates for trainers.
|
||||||
|
*
|
||||||
|
* @package HVAC_Community_Events
|
||||||
|
* @subpackage Communication
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Exit if accessed directly
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class HVAC_Communication_Templates
|
||||||
|
*
|
||||||
|
* Manages email templates for trainers to use when communicating with attendees.
|
||||||
|
*/
|
||||||
|
class HVAC_Communication_Templates {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template post type name
|
||||||
|
*/
|
||||||
|
const POST_TYPE = 'hvac_email_template';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available template placeholders
|
||||||
|
*/
|
||||||
|
const PLACEHOLDERS = array(
|
||||||
|
'{attendee_name}' => 'Attendee Name',
|
||||||
|
'{event_title}' => 'Event Title',
|
||||||
|
'{event_date}' => 'Event Date',
|
||||||
|
'{event_time}' => 'Event Time',
|
||||||
|
'{event_location}' => 'Event Location',
|
||||||
|
'{trainer_name}' => 'Trainer Name',
|
||||||
|
'{business_name}' => 'Business Name',
|
||||||
|
'{trainer_email}' => 'Trainer Email',
|
||||||
|
'{trainer_phone}' => 'Trainer Phone',
|
||||||
|
'{current_date}' => 'Current Date',
|
||||||
|
'{website_name}' => 'Website Name',
|
||||||
|
'{website_url}' => 'Website URL'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default template categories
|
||||||
|
*/
|
||||||
|
const DEFAULT_CATEGORIES = array(
|
||||||
|
'pre_event' => 'Pre-Event Communications',
|
||||||
|
'event_reminder' => 'Event Reminders',
|
||||||
|
'post_event' => 'Post-Event Follow-up',
|
||||||
|
'certificate' => 'Certificate Information',
|
||||||
|
'general' => 'General Communications'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
add_action( 'init', array( $this, 'register_post_type' ) );
|
||||||
|
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||||
|
add_action( 'wp_ajax_hvac_save_template', array( $this, 'ajax_save_template' ) );
|
||||||
|
add_action( 'wp_ajax_hvac_load_template', array( $this, 'ajax_load_template' ) );
|
||||||
|
add_action( 'wp_ajax_hvac_delete_template', array( $this, 'ajax_delete_template' ) );
|
||||||
|
add_action( 'wp_ajax_hvac_get_templates', array( $this, 'ajax_get_templates' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the email template custom post type
|
||||||
|
*/
|
||||||
|
public function register_post_type() {
|
||||||
|
$args = array(
|
||||||
|
'label' => __( 'Email Templates', 'hvac-community-events' ),
|
||||||
|
'public' => false,
|
||||||
|
'show_ui' => false,
|
||||||
|
'supports' => array( 'title', 'editor', 'author' ),
|
||||||
|
'capability_type' => 'post',
|
||||||
|
'capabilities' => array(
|
||||||
|
'create_posts' => 'edit_posts',
|
||||||
|
'delete_posts' => 'delete_posts',
|
||||||
|
'delete_others_posts' => 'delete_others_posts',
|
||||||
|
'delete_private_posts' => 'delete_private_posts',
|
||||||
|
'delete_published_posts' => 'delete_published_posts',
|
||||||
|
'edit_posts' => 'edit_posts',
|
||||||
|
'edit_others_posts' => 'edit_others_posts',
|
||||||
|
'edit_private_posts' => 'edit_private_posts',
|
||||||
|
'edit_published_posts' => 'edit_published_posts',
|
||||||
|
'publish_posts' => 'publish_posts',
|
||||||
|
'read_private_posts' => 'read_private_posts',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
register_post_type( self::POST_TYPE, $args );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue scripts for template management
|
||||||
|
*/
|
||||||
|
public function enqueue_scripts() {
|
||||||
|
global $post;
|
||||||
|
|
||||||
|
// Only enqueue on pages that use templates
|
||||||
|
if ( is_a( $post, 'WP_Post' ) && (
|
||||||
|
has_shortcode( $post->post_content, 'hvac_email_attendees' ) ||
|
||||||
|
has_shortcode( $post->post_content, 'hvac_template_manager' )
|
||||||
|
) ) {
|
||||||
|
wp_enqueue_script(
|
||||||
|
'hvac-communication-templates',
|
||||||
|
HVAC_CE_PLUGIN_URL . 'assets/js/communication-templates.js',
|
||||||
|
array( 'jquery' ),
|
||||||
|
HVAC_CE_VERSION,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_localize_script( 'hvac-communication-templates', 'hvacTemplates', array(
|
||||||
|
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||||
|
'nonce' => wp_create_nonce( 'hvac_templates_nonce' ),
|
||||||
|
'placeholders' => self::PLACEHOLDERS,
|
||||||
|
'categories' => self::DEFAULT_CATEGORIES,
|
||||||
|
'strings' => array(
|
||||||
|
'saveTemplate' => __( 'Save Template', 'hvac-community-events' ),
|
||||||
|
'templateSaved' => __( 'Template saved successfully', 'hvac-community-events' ),
|
||||||
|
'templateDeleted' => __( 'Template deleted successfully', 'hvac-community-events' ),
|
||||||
|
'confirmDelete' => __( 'Are you sure you want to delete this template?', 'hvac-community-events' ),
|
||||||
|
'error' => __( 'An error occurred. Please try again.', 'hvac-community-events' ),
|
||||||
|
'templateName' => __( 'Template Name', 'hvac-community-events' ),
|
||||||
|
'selectCategory' => __( 'Select Category', 'hvac-community-events' ),
|
||||||
|
'insertPlaceholder' => __( 'Insert Placeholder', 'hvac-community-events' ),
|
||||||
|
)
|
||||||
|
) );
|
||||||
|
|
||||||
|
wp_enqueue_style(
|
||||||
|
'hvac-communication-templates',
|
||||||
|
HVAC_CE_PLUGIN_URL . 'assets/css/communication-templates.css',
|
||||||
|
array(),
|
||||||
|
HVAC_CE_VERSION
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get templates for a specific user
|
||||||
|
*
|
||||||
|
* @param int $user_id User ID (defaults to current user)
|
||||||
|
* @param string $category Optional category filter
|
||||||
|
* @return array Array of templates
|
||||||
|
*/
|
||||||
|
public function get_user_templates( $user_id = 0, $category = '' ) {
|
||||||
|
if ( empty( $user_id ) ) {
|
||||||
|
$user_id = get_current_user_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = array(
|
||||||
|
'post_type' => self::POST_TYPE,
|
||||||
|
'author' => $user_id,
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'posts_per_page' => -1,
|
||||||
|
'orderby' => 'title',
|
||||||
|
'order' => 'ASC',
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( ! empty( $category ) ) {
|
||||||
|
$args['meta_query'] = array(
|
||||||
|
array(
|
||||||
|
'key' => '_hvac_template_category',
|
||||||
|
'value' => $category,
|
||||||
|
'compare' => '='
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$templates = get_posts( $args );
|
||||||
|
$formatted_templates = array();
|
||||||
|
|
||||||
|
foreach ( $templates as $template ) {
|
||||||
|
$formatted_templates[] = array(
|
||||||
|
'id' => $template->ID,
|
||||||
|
'title' => $template->post_title,
|
||||||
|
'content' => $template->post_content,
|
||||||
|
'category' => get_post_meta( $template->ID, '_hvac_template_category', true ),
|
||||||
|
'description' => get_post_meta( $template->ID, '_hvac_template_description', true ),
|
||||||
|
'created' => $template->post_date,
|
||||||
|
'modified' => $template->post_modified,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $formatted_templates;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save a template
|
||||||
|
*
|
||||||
|
* @param array $template_data Template data
|
||||||
|
* @return int|WP_Error Template ID on success, WP_Error on failure
|
||||||
|
*/
|
||||||
|
public function save_template( $template_data ) {
|
||||||
|
// Validate required fields
|
||||||
|
if ( empty( $template_data['title'] ) || empty( $template_data['content'] ) ) {
|
||||||
|
return new WP_Error( 'missing_data', __( 'Template title and content are required.', 'hvac-community-events' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$post_data = array(
|
||||||
|
'post_type' => self::POST_TYPE,
|
||||||
|
'post_title' => sanitize_text_field( $template_data['title'] ),
|
||||||
|
'post_content' => wp_kses_post( $template_data['content'] ),
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'post_author' => get_current_user_id(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update existing template if ID provided
|
||||||
|
if ( ! empty( $template_data['id'] ) ) {
|
||||||
|
$post_data['ID'] = intval( $template_data['id'] );
|
||||||
|
|
||||||
|
// Verify ownership
|
||||||
|
$existing_template = get_post( $post_data['ID'] );
|
||||||
|
if ( ! $existing_template || $existing_template->post_author != get_current_user_id() ) {
|
||||||
|
return new WP_Error( 'permission_denied', __( 'You can only edit your own templates.', 'hvac-community-events' ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$template_id = wp_insert_post( $post_data );
|
||||||
|
|
||||||
|
if ( is_wp_error( $template_id ) ) {
|
||||||
|
return $template_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save metadata
|
||||||
|
if ( ! empty( $template_data['category'] ) ) {
|
||||||
|
update_post_meta( $template_id, '_hvac_template_category', sanitize_text_field( $template_data['category'] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! empty( $template_data['description'] ) ) {
|
||||||
|
update_post_meta( $template_id, '_hvac_template_description', sanitize_text_field( $template_data['description'] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $template_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a template
|
||||||
|
*
|
||||||
|
* @param int $template_id Template ID
|
||||||
|
* @return bool Success status
|
||||||
|
*/
|
||||||
|
public function delete_template( $template_id ) {
|
||||||
|
$template = get_post( $template_id );
|
||||||
|
|
||||||
|
if ( ! $template || $template->post_type !== self::POST_TYPE ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify ownership
|
||||||
|
if ( $template->post_author != get_current_user_id() && ! current_user_can( 'delete_others_posts' ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wp_delete_post( $template_id, true ) !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process placeholders in template content
|
||||||
|
*
|
||||||
|
* @param string $content Template content
|
||||||
|
* @param array $context Context data for placeholders
|
||||||
|
* @return string Processed content
|
||||||
|
*/
|
||||||
|
public function process_placeholders( $content, $context = array() ) {
|
||||||
|
$current_user = wp_get_current_user();
|
||||||
|
|
||||||
|
// Default context values
|
||||||
|
$defaults = array(
|
||||||
|
'attendee_name' => '',
|
||||||
|
'event_title' => '',
|
||||||
|
'event_date' => '',
|
||||||
|
'event_time' => '',
|
||||||
|
'event_location' => '',
|
||||||
|
'trainer_name' => $current_user->display_name,
|
||||||
|
'business_name' => get_user_meta( $current_user->ID, 'business_name', true ),
|
||||||
|
'trainer_email' => $current_user->user_email,
|
||||||
|
'trainer_phone' => get_user_meta( $current_user->ID, 'phone_number', true ),
|
||||||
|
'current_date' => date( 'F j, Y' ),
|
||||||
|
'website_name' => get_bloginfo( 'name' ),
|
||||||
|
'website_url' => home_url(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get trainer contact email if available
|
||||||
|
if ( in_array( 'hvac_trainer', $current_user->roles ) ) {
|
||||||
|
$contact_email = get_user_meta( $current_user->ID, 'contact_email', true );
|
||||||
|
if ( ! empty( $contact_email ) && is_email( $contact_email ) ) {
|
||||||
|
$defaults['trainer_email'] = $contact_email;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$context = wp_parse_args( $context, $defaults );
|
||||||
|
|
||||||
|
// Replace placeholders
|
||||||
|
foreach ( self::PLACEHOLDERS as $placeholder => $description ) {
|
||||||
|
$key = str_replace( array( '{', '}' ), '', $placeholder );
|
||||||
|
if ( isset( $context[ $key ] ) ) {
|
||||||
|
$content = str_replace( $placeholder, $context[ $key ], $content );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get default templates
|
||||||
|
*
|
||||||
|
* @return array Default templates
|
||||||
|
*/
|
||||||
|
public function get_default_templates() {
|
||||||
|
return array(
|
||||||
|
array(
|
||||||
|
'title' => __( 'Event Reminder - 24 Hours', 'hvac-community-events' ),
|
||||||
|
'category' => 'event_reminder',
|
||||||
|
'description' => __( 'Reminder sent 24 hours before the event', 'hvac-community-events' ),
|
||||||
|
'content' => "Hello {attendee_name},\n\nThis is a friendly reminder that you're registered for {event_title} tomorrow at {event_time}.\n\nEvent Details:\n- Date: {event_date}\n- Time: {event_time}\n- Location: {event_location}\n\nPlease bring a valid ID and any materials mentioned in your registration confirmation.\n\nIf you have any questions, please don't hesitate to contact me.\n\nBest regards,\n{trainer_name}\n{business_name}\n{trainer_email}\n{trainer_phone}"
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => __( 'Welcome & Pre-Event Information', 'hvac-community-events' ),
|
||||||
|
'category' => 'pre_event',
|
||||||
|
'description' => __( 'Welcome message with event preparation information', 'hvac-community-events' ),
|
||||||
|
'content' => "Welcome {attendee_name}!\n\nThank you for registering for {event_title}. I'm excited to have you join us on {event_date} at {event_time}.\n\nTo help you prepare for the training:\n\n1. Please arrive 15 minutes early for check-in\n2. Bring a valid photo ID\n3. Dress comfortably and wear closed-toe shoes\n4. Bring a notebook and pen for taking notes\n5. Lunch will be provided\n\nIf you have any questions before the event, please feel free to reach out.\n\nLooking forward to seeing you there!\n\n{trainer_name}\n{business_name}\n{trainer_email}\n{trainer_phone}"
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => __( 'Thank You & Certificate Information', 'hvac-community-events' ),
|
||||||
|
'category' => 'post_event',
|
||||||
|
'description' => __( 'Post-event thank you with certificate details', 'hvac-community-events' ),
|
||||||
|
'content' => "Dear {attendee_name},\n\nThank you for attending {event_title} on {event_date}. It was great having you participate in the training.\n\nYour certificate of completion will be available within 3-5 business days. You can download it from your attendee profile on our website.\n\nIf you have any questions about the training content or need additional resources, please don't hesitate to contact me.\n\nThank you again for your participation, and I look forward to seeing you at future training events.\n\nBest regards,\n{trainer_name}\n{business_name}\n{trainer_email}\n{trainer_phone}"
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => __( 'Certificate Ready for Download', 'hvac-community-events' ),
|
||||||
|
'category' => 'certificate',
|
||||||
|
'description' => __( 'Notification when certificate is ready', 'hvac-community-events' ),
|
||||||
|
'content' => "Hello {attendee_name},\n\nGreat news! Your certificate of completion for {event_title} is now ready for download.\n\nTo access your certificate:\n1. Visit {website_url}\n2. Log into your attendee profile\n3. Navigate to the 'My Certificates' section\n4. Download your certificate for {event_title}\n\nYour certificate includes:\n- Official completion verification\n- Training date and hours\n- Digital security features\n- Suitable for continuing education records\n\nIf you have any trouble accessing your certificate, please contact me directly.\n\nCongratulations on completing the training!\n\n{trainer_name}\n{business_name}\n{trainer_email}\n{trainer_phone}"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install default templates for a user
|
||||||
|
*
|
||||||
|
* @param int $user_id User ID
|
||||||
|
*/
|
||||||
|
public function install_default_templates( $user_id ) {
|
||||||
|
$defaults = $this->get_default_templates();
|
||||||
|
|
||||||
|
foreach ( $defaults as $template ) {
|
||||||
|
$template_data = array(
|
||||||
|
'title' => $template['title'],
|
||||||
|
'content' => $template['content'],
|
||||||
|
'category' => $template['category'],
|
||||||
|
'description' => $template['description'],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Temporarily switch to the target user
|
||||||
|
$current_user_id = get_current_user_id();
|
||||||
|
wp_set_current_user( $user_id );
|
||||||
|
|
||||||
|
$this->save_template( $template_data );
|
||||||
|
|
||||||
|
// Switch back to original user
|
||||||
|
wp_set_current_user( $current_user_id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AJAX handler for saving templates
|
||||||
|
*/
|
||||||
|
public function ajax_save_template() {
|
||||||
|
check_ajax_referer( 'hvac_templates_nonce', 'nonce' );
|
||||||
|
|
||||||
|
if ( ! is_user_logged_in() ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'You must be logged in to save templates.', 'hvac-community-events' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$template_data = array(
|
||||||
|
'id' => isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : 0,
|
||||||
|
'title' => isset( $_POST['title'] ) ? sanitize_text_field( $_POST['title'] ) : '',
|
||||||
|
'content' => isset( $_POST['content'] ) ? wp_kses_post( $_POST['content'] ) : '',
|
||||||
|
'category' => isset( $_POST['category'] ) ? sanitize_text_field( $_POST['category'] ) : '',
|
||||||
|
'description' => isset( $_POST['description'] ) ? sanitize_text_field( $_POST['description'] ) : '',
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $this->save_template( $template_data );
|
||||||
|
|
||||||
|
if ( is_wp_error( $result ) ) {
|
||||||
|
wp_send_json_error( array( 'message' => $result->get_error_message() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json_success( array(
|
||||||
|
'template_id' => $result,
|
||||||
|
'message' => __( 'Template saved successfully.', 'hvac-community-events' )
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AJAX handler for loading templates
|
||||||
|
*/
|
||||||
|
public function ajax_load_template() {
|
||||||
|
check_ajax_referer( 'hvac_templates_nonce', 'nonce' );
|
||||||
|
|
||||||
|
if ( ! is_user_logged_in() ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'You must be logged in to load templates.', 'hvac-community-events' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : 0;
|
||||||
|
|
||||||
|
if ( empty( $template_id ) ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'Invalid template ID.', 'hvac-community-events' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$template = get_post( $template_id );
|
||||||
|
|
||||||
|
if ( ! $template || $template->post_type !== self::POST_TYPE ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'Template not found.', 'hvac-community-events' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify ownership or admin access
|
||||||
|
if ( $template->post_author != get_current_user_id() && ! current_user_can( 'edit_others_posts' ) ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'You can only load your own templates.', 'hvac-community-events' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json_success( array(
|
||||||
|
'id' => $template->ID,
|
||||||
|
'title' => $template->post_title,
|
||||||
|
'content' => $template->post_content,
|
||||||
|
'category' => get_post_meta( $template->ID, '_hvac_template_category', true ),
|
||||||
|
'description' => get_post_meta( $template->ID, '_hvac_template_description', true ),
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AJAX handler for deleting templates
|
||||||
|
*/
|
||||||
|
public function ajax_delete_template() {
|
||||||
|
check_ajax_referer( 'hvac_templates_nonce', 'nonce' );
|
||||||
|
|
||||||
|
if ( ! is_user_logged_in() ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'You must be logged in to delete templates.', 'hvac-community-events' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$template_id = isset( $_POST['template_id'] ) ? intval( $_POST['template_id'] ) : 0;
|
||||||
|
|
||||||
|
if ( empty( $template_id ) ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'Invalid template ID.', 'hvac-community-events' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->delete_template( $template_id );
|
||||||
|
|
||||||
|
if ( ! $result ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'Failed to delete template.', 'hvac-community-events' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json_success( array( 'message' => __( 'Template deleted successfully.', 'hvac-community-events' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AJAX handler for getting templates list
|
||||||
|
*/
|
||||||
|
public function ajax_get_templates() {
|
||||||
|
check_ajax_referer( 'hvac_templates_nonce', 'nonce' );
|
||||||
|
|
||||||
|
if ( ! is_user_logged_in() ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'You must be logged in to view templates.', 'hvac-community-events' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$category = isset( $_POST['category'] ) ? sanitize_text_field( $_POST['category'] ) : '';
|
||||||
|
$templates = $this->get_user_templates( get_current_user_id(), $category );
|
||||||
|
|
||||||
|
wp_send_json_success( array( 'templates' => $templates ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the class
|
||||||
|
new HVAC_Communication_Templates();
|
||||||
|
|
@ -0,0 +1,584 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* HVAC Community Events - Communication Templates Template
|
||||||
|
*
|
||||||
|
* Template for managing email templates.
|
||||||
|
*
|
||||||
|
* @package HVAC_Community_Events
|
||||||
|
* @subpackage Templates
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Exit if accessed directly
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user is logged in
|
||||||
|
if ( ! is_user_logged_in() ) {
|
||||||
|
wp_redirect( site_url( '/community-login/' ) );
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the templates class
|
||||||
|
require_once HVAC_CE_PLUGIN_DIR . 'includes/communication/class-communication-templates.php';
|
||||||
|
$templates_manager = new HVAC_Communication_Templates();
|
||||||
|
|
||||||
|
// Get current user templates
|
||||||
|
$user_templates = $templates_manager->get_user_templates();
|
||||||
|
$categories = HVAC_Communication_Templates::DEFAULT_CATEGORIES;
|
||||||
|
|
||||||
|
// Handle first-time user setup
|
||||||
|
$current_user = wp_get_current_user();
|
||||||
|
$has_templates = !empty($user_templates);
|
||||||
|
|
||||||
|
// Install default templates if this is a new trainer
|
||||||
|
if (!$has_templates && in_array('hvac_trainer', $current_user->roles)) {
|
||||||
|
$install_defaults = isset($_GET['install_defaults']) ? $_GET['install_defaults'] === 'true' : false;
|
||||||
|
|
||||||
|
if ($install_defaults) {
|
||||||
|
$templates_manager->install_default_templates(get_current_user_id());
|
||||||
|
wp_redirect(remove_query_arg('install_defaults'));
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the site title for the page title
|
||||||
|
$site_title = get_bloginfo( 'name' );
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html <?php language_attributes(); ?>>
|
||||||
|
<head>
|
||||||
|
<meta charset="<?php bloginfo( 'charset' ); ?>">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title><?php echo esc_html( $site_title ); ?> - <?php _e( 'Communication Templates', 'hvac-community-events' ); ?></title>
|
||||||
|
<?php wp_head(); ?>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.hvac-templates-wrapper {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-templates-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-templates-title h1 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
color: var(--hvac-theme-text-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-templates-navigation {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-templates-stats {
|
||||||
|
background: var(--hvac-background-subtle);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: var(--hvac-radius-lg);
|
||||||
|
margin-bottom: 30px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-stat-item {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-stat-number {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--hvac-primary);
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-stat-label {
|
||||||
|
color: var(--hvac-theme-text-light);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-getting-started {
|
||||||
|
background: var(--hvac-info-light);
|
||||||
|
border: 1px solid var(--hvac-accent);
|
||||||
|
border-radius: var(--hvac-radius-lg);
|
||||||
|
padding: 30px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-getting-started h2 {
|
||||||
|
color: var(--hvac-accent);
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-templates-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-card {
|
||||||
|
background: var(--hvac-background-white);
|
||||||
|
border: 1px solid var(--hvac-border);
|
||||||
|
border-radius: var(--hvac-radius-lg);
|
||||||
|
padding: 20px;
|
||||||
|
transition: all var(--hvac-transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: var(--hvac-shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-card-title {
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--hvac-theme-text-dark);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-card-category {
|
||||||
|
background: var(--hvac-primary);
|
||||||
|
color: white;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: var(--hvac-radius-sm);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-card-description {
|
||||||
|
color: var(--hvac-theme-text-light);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-card-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-card-actions button {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--hvac-radius-sm);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all var(--hvac-transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-category-tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-category-tab {
|
||||||
|
padding: 10px 15px;
|
||||||
|
background: var(--hvac-background-subtle);
|
||||||
|
border: 1px solid var(--hvac-border);
|
||||||
|
border-radius: var(--hvac-radius-md);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all var(--hvac-transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-category-tab.active {
|
||||||
|
background: var(--hvac-primary);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--hvac-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 1000;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hvac-template-form-modal {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background: var(--hvac-background-white);
|
||||||
|
border-radius: var(--hvac-radius-lg);
|
||||||
|
padding: 30px;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 600px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body <?php body_class(); ?>>
|
||||||
|
<?php wp_body_open(); ?>
|
||||||
|
|
||||||
|
<div class="hvac-templates-wrapper">
|
||||||
|
<div class="hvac-templates-header">
|
||||||
|
<div class="hvac-templates-title">
|
||||||
|
<h1><?php _e( 'Communication Templates', 'hvac-community-events' ); ?></h1>
|
||||||
|
<p><?php _e( 'Manage your email templates for communicating with event attendees.', 'hvac-community-events' ); ?></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hvac-templates-navigation">
|
||||||
|
<a href="<?php echo esc_url( site_url( '/hvac-dashboard/' ) ); ?>" class="ast-button ast-button-secondary">
|
||||||
|
<?php _e( 'Return to Dashboard', 'hvac-community-events' ); ?>
|
||||||
|
</a>
|
||||||
|
<button type="button" class="ast-button ast-button-primary" onclick="HVACTemplates.createNewTemplate()">
|
||||||
|
<?php _e( 'Create New Template', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if (!$has_templates && in_array('hvac_trainer', $current_user->roles)) : ?>
|
||||||
|
<div class="hvac-getting-started">
|
||||||
|
<h2><?php _e( 'Welcome to Communication Templates!', 'hvac-community-events' ); ?></h2>
|
||||||
|
<p><?php _e( 'Save time by creating reusable email templates for your events. You can create your own templates or start with our professionally crafted defaults.', 'hvac-community-events' ); ?></p>
|
||||||
|
|
||||||
|
<div style="margin: 20px 0;">
|
||||||
|
<a href="<?php echo esc_url( add_query_arg( 'install_defaults', 'true' ) ); ?>" class="ast-button ast-button-primary" style="margin-right: 10px;">
|
||||||
|
<?php _e( 'Install Default Templates', 'hvac-community-events' ); ?>
|
||||||
|
</a>
|
||||||
|
<button type="button" class="ast-button ast-button-secondary" onclick="HVACTemplates.createNewTemplate()">
|
||||||
|
<?php _e( 'Create From Scratch', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<small><?php _e( 'Default templates include: Event reminders, welcome messages, post-event follow-ups, and certificate notifications.', 'hvac-community-events' ); ?></small>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if ($has_templates) : ?>
|
||||||
|
<!-- Template Statistics -->
|
||||||
|
<div class="hvac-templates-stats">
|
||||||
|
<div class="hvac-stat-item">
|
||||||
|
<div class="hvac-stat-number"><?php echo count($user_templates); ?></div>
|
||||||
|
<div class="hvac-stat-label"><?php _e( 'Total Templates', 'hvac-community-events' ); ?></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$category_counts = array();
|
||||||
|
foreach ($user_templates as $template) {
|
||||||
|
$category = $template['category'] ?: 'general';
|
||||||
|
$category_counts[$category] = ($category_counts[$category] ?? 0) + 1;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="hvac-stat-item">
|
||||||
|
<div class="hvac-stat-number"><?php echo count($category_counts); ?></div>
|
||||||
|
<div class="hvac-stat-label"><?php _e( 'Categories Used', 'hvac-community-events' ); ?></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hvac-stat-item">
|
||||||
|
<div class="hvac-stat-number"><?php echo date('M Y', strtotime(max(array_column($user_templates, 'modified')))); ?></div>
|
||||||
|
<div class="hvac-stat-label"><?php _e( 'Last Updated', 'hvac-community-events' ); ?></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Category Tabs -->
|
||||||
|
<div class="hvac-category-tabs">
|
||||||
|
<div class="hvac-category-tab active" data-category="">
|
||||||
|
<?php _e( 'All Templates', 'hvac-community-events' ); ?>
|
||||||
|
<span class="hvac-count-badge"><?php echo count($user_templates); ?></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php foreach ($categories as $key => $label) : ?>
|
||||||
|
<?php $count = $category_counts[$key] ?? 0; ?>
|
||||||
|
<?php if ($count > 0) : ?>
|
||||||
|
<div class="hvac-category-tab" data-category="<?php echo esc_attr($key); ?>">
|
||||||
|
<?php echo esc_html($label); ?>
|
||||||
|
<span class="hvac-count-badge"><?php echo $count; ?></span>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Templates Grid -->
|
||||||
|
<div class="hvac-templates-grid" id="templates-grid">
|
||||||
|
<?php foreach ($user_templates as $template) : ?>
|
||||||
|
<div class="hvac-template-card" data-category="<?php echo esc_attr($template['category']); ?>">
|
||||||
|
<div class="hvac-template-card-header">
|
||||||
|
<h3 class="hvac-template-card-title"><?php echo esc_html($template['title']); ?></h3>
|
||||||
|
<?php if (!empty($template['category'])) : ?>
|
||||||
|
<span class="hvac-template-card-category">
|
||||||
|
<?php echo esc_html($categories[$template['category']] ?? $template['category']); ?>
|
||||||
|
</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if (!empty($template['description'])) : ?>
|
||||||
|
<p class="hvac-template-card-description"><?php echo esc_html($template['description']); ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="hvac-template-card-actions">
|
||||||
|
<button type="button" class="hvac-btn-edit ast-button ast-button-secondary" data-template-id="<?php echo $template['id']; ?>">
|
||||||
|
<?php _e( 'Edit', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="hvac-btn-preview ast-button ast-button-outline" data-template-id="<?php echo $template['id']; ?>">
|
||||||
|
<?php _e( 'Preview', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="hvac-btn-delete ast-button ast-button-danger" data-template-id="<?php echo $template['id']; ?>">
|
||||||
|
<?php _e( 'Delete', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- Template Form Modal -->
|
||||||
|
<div class="hvac-template-form-overlay" id="template-form-overlay">
|
||||||
|
<div class="hvac-template-form-modal">
|
||||||
|
<h2 id="template-form-title"><?php _e( 'Create New Template', 'hvac-community-events' ); ?></h2>
|
||||||
|
|
||||||
|
<form id="template-form">
|
||||||
|
<div class="hvac-template-form-row">
|
||||||
|
<label for="hvac_template_title"><?php _e( 'Template Name:', 'hvac-community-events' ); ?> <span class="hvac-required">*</span></label>
|
||||||
|
<input type="text" id="hvac_template_title" name="title" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hvac-template-form-row">
|
||||||
|
<label for="hvac_template_category"><?php _e( 'Category:', 'hvac-community-events' ); ?></label>
|
||||||
|
<select id="hvac_template_category" name="category">
|
||||||
|
<option value=""><?php _e( 'Select category...', 'hvac-community-events' ); ?></option>
|
||||||
|
<?php foreach ($categories as $key => $label) : ?>
|
||||||
|
<option value="<?php echo esc_attr($key); ?>"><?php echo esc_html($label); ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hvac-template-form-row">
|
||||||
|
<label for="hvac_template_description"><?php _e( 'Description:', 'hvac-community-events' ); ?></label>
|
||||||
|
<input type="text" id="hvac_template_description" name="description" placeholder="<?php _e( 'Brief description of when to use this template', 'hvac-community-events' ); ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hvac-template-form-row">
|
||||||
|
<label for="hvac_template_content"><?php _e( 'Content:', 'hvac-community-events' ); ?> <span class="hvac-required">*</span></label>
|
||||||
|
<textarea id="hvac_template_content" name="content" rows="12" required placeholder="<?php _e( 'Enter your email template content here. Use placeholders like {attendee_name} and {event_title} for dynamic content.', 'hvac-community-events' ); ?>"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Placeholder Helper -->
|
||||||
|
<div class="hvac-placeholder-helper">
|
||||||
|
<h4><?php _e( 'Available Placeholders', 'hvac-community-events' ); ?></h4>
|
||||||
|
<p><?php _e( 'Click any placeholder below to insert it into your template:', 'hvac-community-events' ); ?></p>
|
||||||
|
<div class="hvac-placeholder-grid"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hvac-template-form-actions">
|
||||||
|
<button type="button" class="hvac-btn-secondary hvac-template-form-cancel">
|
||||||
|
<?php _e( 'Cancel', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
<button type="submit" class="hvac-btn-primary hvac-template-form-save">
|
||||||
|
<span class="hvac-spinner" style="display: none;"></span>
|
||||||
|
<?php _e( 'Save Template', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Category filtering
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const tabs = document.querySelectorAll('.hvac-category-tab');
|
||||||
|
const cards = document.querySelectorAll('.hvac-template-card');
|
||||||
|
|
||||||
|
tabs.forEach(tab => {
|
||||||
|
tab.addEventListener('click', function() {
|
||||||
|
const category = this.dataset.category;
|
||||||
|
|
||||||
|
// Update active tab
|
||||||
|
tabs.forEach(t => t.classList.remove('active'));
|
||||||
|
this.classList.add('active');
|
||||||
|
|
||||||
|
// Filter cards
|
||||||
|
cards.forEach(card => {
|
||||||
|
if (!category || card.dataset.category === category) {
|
||||||
|
card.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
card.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Template actions
|
||||||
|
document.addEventListener('click', function(e) {
|
||||||
|
if (e.target.classList.contains('hvac-btn-edit')) {
|
||||||
|
const templateId = e.target.dataset.templateId;
|
||||||
|
HVACTemplates.editTemplate(templateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.target.classList.contains('hvac-btn-delete')) {
|
||||||
|
const templateId = e.target.dataset.templateId;
|
||||||
|
if (confirm('<?php echo esc_js(__('Are you sure you want to delete this template?', 'hvac-community-events')); ?>')) {
|
||||||
|
HVACTemplates.deleteTemplate(templateId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Modal handling
|
||||||
|
const overlay = document.getElementById('template-form-overlay');
|
||||||
|
const cancelBtn = document.querySelector('.hvac-template-form-cancel');
|
||||||
|
|
||||||
|
cancelBtn.addEventListener('click', function() {
|
||||||
|
overlay.style.display = 'none';
|
||||||
|
HVACTemplates.cancelTemplateForm();
|
||||||
|
});
|
||||||
|
|
||||||
|
overlay.addEventListener('click', function(e) {
|
||||||
|
if (e.target === overlay) {
|
||||||
|
overlay.style.display = 'none';
|
||||||
|
HVACTemplates.cancelTemplateForm();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Form submission
|
||||||
|
document.getElementById('template-form').addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
HVACTemplates.saveTemplate();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Override HVACTemplates methods for modal
|
||||||
|
if (typeof HVACTemplates !== 'undefined') {
|
||||||
|
HVACTemplates.createNewTemplate = function() {
|
||||||
|
this.currentTemplateId = null;
|
||||||
|
this.isEditing = true;
|
||||||
|
|
||||||
|
// Clear form
|
||||||
|
document.getElementById('hvac_template_title').value = '';
|
||||||
|
document.getElementById('hvac_template_content').value = '';
|
||||||
|
document.getElementById('hvac_template_category').value = '';
|
||||||
|
document.getElementById('hvac_template_description').value = '';
|
||||||
|
|
||||||
|
// Show modal
|
||||||
|
document.getElementById('template-form-overlay').style.display = 'block';
|
||||||
|
document.getElementById('template-form-title').textContent = '<?php echo esc_js(__('Create New Template', 'hvac-community-events')); ?>';
|
||||||
|
|
||||||
|
// Focus on title field
|
||||||
|
document.getElementById('hvac_template_title').focus();
|
||||||
|
};
|
||||||
|
|
||||||
|
HVACTemplates.editTemplate = function(templateId) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: this.config.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'hvac_load_template',
|
||||||
|
nonce: this.config.nonce,
|
||||||
|
template_id: templateId
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
const template = response.data;
|
||||||
|
self.currentTemplateId = template.id;
|
||||||
|
self.isEditing = true;
|
||||||
|
|
||||||
|
// Populate form
|
||||||
|
document.getElementById('hvac_template_title').value = template.title;
|
||||||
|
document.getElementById('hvac_template_content').value = template.content;
|
||||||
|
document.getElementById('hvac_template_category').value = template.category;
|
||||||
|
document.getElementById('hvac_template_description').value = template.description;
|
||||||
|
|
||||||
|
// Show modal
|
||||||
|
document.getElementById('template-form-overlay').style.display = 'block';
|
||||||
|
document.getElementById('template-form-title').textContent = '<?php echo esc_js(__('Edit Template', 'hvac-community-events')); ?>';
|
||||||
|
|
||||||
|
} else {
|
||||||
|
alert(response.data.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
HVACTemplates.saveTemplate = function() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
const templateData = {
|
||||||
|
action: 'hvac_save_template',
|
||||||
|
nonce: this.config.nonce,
|
||||||
|
template_id: this.currentTemplateId || 0,
|
||||||
|
title: document.getElementById('hvac_template_title').value,
|
||||||
|
content: document.getElementById('hvac_template_content').value,
|
||||||
|
category: document.getElementById('hvac_template_category').value,
|
||||||
|
description: document.getElementById('hvac_template_description').value
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!templateData.title || !templateData.content) {
|
||||||
|
alert('<?php echo esc_js(__('Template title and content are required', 'hvac-community-events')); ?>');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: this.config.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: templateData,
|
||||||
|
beforeSend: function() {
|
||||||
|
document.querySelector('.hvac-template-form-save .hvac-spinner').style.display = 'inline-block';
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
alert(response.data.message);
|
||||||
|
document.getElementById('template-form-overlay').style.display = 'none';
|
||||||
|
location.reload(); // Refresh page to show updated templates
|
||||||
|
} else {
|
||||||
|
alert(response.data.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
document.querySelector('.hvac-template-form-save .hvac-spinner').style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
HVACTemplates.deleteTemplate = function(templateId) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: this.config.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'hvac_delete_template',
|
||||||
|
nonce: this.config.nonce,
|
||||||
|
template_id: templateId
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
if (response.success) {
|
||||||
|
alert(response.data.message);
|
||||||
|
location.reload(); // Refresh page
|
||||||
|
} else {
|
||||||
|
alert(response.data.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<?php wp_footer(); ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,180 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* HVAC Community Events - Template Manager Widget
|
||||||
|
*
|
||||||
|
* Widget for managing templates within email forms.
|
||||||
|
*
|
||||||
|
* @package HVAC_Community_Events
|
||||||
|
* @subpackage Templates
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Exit if accessed directly
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the templates class if not already loaded
|
||||||
|
if (!class_exists('HVAC_Communication_Templates')) {
|
||||||
|
require_once HVAC_CE_PLUGIN_DIR . 'includes/communication/class-communication-templates.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
$templates_manager = new HVAC_Communication_Templates();
|
||||||
|
$user_templates = $templates_manager->get_user_templates();
|
||||||
|
$categories = HVAC_Communication_Templates::DEFAULT_CATEGORIES;
|
||||||
|
|
||||||
|
// Check if this is the first time user setup
|
||||||
|
$current_user = wp_get_current_user();
|
||||||
|
$has_templates = !empty($user_templates);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="hvac-template-manager" style="display: none;">
|
||||||
|
<h3><?php _e( 'Email Templates', 'hvac-community-events' ); ?></h3>
|
||||||
|
|
||||||
|
<?php if (!$has_templates && in_array('hvac_trainer', $current_user->roles)) : ?>
|
||||||
|
<div class="hvac-template-empty">
|
||||||
|
<div class="hvac-template-empty-icon">📝</div>
|
||||||
|
<h4><?php _e( 'No Templates Yet', 'hvac-community-events' ); ?></h4>
|
||||||
|
<p><?php _e( 'Create reusable email templates to save time when communicating with attendees.', 'hvac-community-events' ); ?></p>
|
||||||
|
|
||||||
|
<div class="hvac-template-actions">
|
||||||
|
<a href="<?php echo esc_url( add_query_arg( 'install_defaults', 'true', site_url( '/communication-templates/' ) ) ); ?>" class="hvac-btn-primary">
|
||||||
|
<?php _e( 'Install Default Templates', 'hvac-community-events' ); ?>
|
||||||
|
</a>
|
||||||
|
<button type="button" class="hvac-btn-secondary" onclick="HVACTemplates.createNewTemplate()">
|
||||||
|
<?php _e( 'Create Custom Template', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php else : ?>
|
||||||
|
<!-- Template Selector -->
|
||||||
|
<div class="hvac-template-selector">
|
||||||
|
<select class="hvac-template-category-filter">
|
||||||
|
<option value=""><?php _e( 'All Categories', 'hvac-community-events' ); ?></option>
|
||||||
|
<?php foreach ($categories as $key => $label) : ?>
|
||||||
|
<option value="<?php echo esc_attr($key); ?>"><?php echo esc_html($label); ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select class="hvac-template-dropdown">
|
||||||
|
<option value=""><?php _e( 'Select a template...', 'hvac-community-events' ); ?></option>
|
||||||
|
<?php foreach ($user_templates as $template) : ?>
|
||||||
|
<option value="<?php echo $template['id']; ?>" data-category="<?php echo esc_attr($template['category']); ?>">
|
||||||
|
<?php echo esc_html($template['title']); ?>
|
||||||
|
<?php if (!empty($template['category'])) : ?>
|
||||||
|
(<?php echo esc_html($categories[$template['category']] ?? $template['category']); ?>)
|
||||||
|
<?php endif; ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<div class="hvac-template-actions-buttons">
|
||||||
|
<button type="button" class="hvac-btn-load" title="<?php _e( 'Load selected template into email form', 'hvac-community-events' ); ?>">
|
||||||
|
📝 <?php _e( 'Use', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="hvac-btn-edit" title="<?php _e( 'Edit selected template', 'hvac-community-events' ); ?>">
|
||||||
|
✏️ <?php _e( 'Edit', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="hvac-btn-delete" title="<?php _e( 'Delete selected template', 'hvac-community-events' ); ?>">
|
||||||
|
🗑️ <?php _e( 'Delete', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Quick Actions -->
|
||||||
|
<div class="hvac-template-actions" style="margin-top: 15px;">
|
||||||
|
<button type="button" class="hvac-template-toggle hvac-btn-save" onclick="HVACTemplates.saveCurrentEmailAsTemplate()">
|
||||||
|
💾 <?php _e( 'Save Current as Template', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
<a href="<?php echo esc_url( site_url( '/communication-templates/' ) ); ?>" class="hvac-btn-secondary" target="_blank">
|
||||||
|
⚙️ <?php _e( 'Manage All Templates', 'hvac-community-events' ); ?>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- Template Form (for creating/editing) -->
|
||||||
|
<div class="hvac-template-form">
|
||||||
|
<h4 id="hvac-template-form-title"><?php _e( 'Save as Template', 'hvac-community-events' ); ?></h4>
|
||||||
|
|
||||||
|
<div class="hvac-template-form-row">
|
||||||
|
<label for="hvac_template_title"><?php _e( 'Template Name:', 'hvac-community-events' ); ?> <span class="hvac-required">*</span></label>
|
||||||
|
<input type="text" id="hvac_template_title" placeholder="<?php _e( 'e.g., Event Reminder - 24 Hours', 'hvac-community-events' ); ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hvac-template-form-row">
|
||||||
|
<label for="hvac_template_category"><?php _e( 'Category:', 'hvac-community-events' ); ?></label>
|
||||||
|
<select id="hvac_template_category">
|
||||||
|
<option value=""><?php _e( 'Select category...', 'hvac-community-events' ); ?></option>
|
||||||
|
<?php foreach ($categories as $key => $label) : ?>
|
||||||
|
<option value="<?php echo esc_attr($key); ?>"><?php echo esc_html($label); ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hvac-template-form-row">
|
||||||
|
<label for="hvac_template_description"><?php _e( 'Description:', 'hvac-community-events' ); ?></label>
|
||||||
|
<input type="text" id="hvac_template_description" placeholder="<?php _e( 'Brief description of when to use this template', 'hvac-community-events' ); ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hvac-template-form-row">
|
||||||
|
<label for="hvac_template_content"><?php _e( 'Content:', 'hvac-community-events' ); ?> <span class="hvac-required">*</span></label>
|
||||||
|
<textarea id="hvac_template_content" rows="8" placeholder="<?php _e( 'Email content will be copied from the form above...', 'hvac-community-events' ); ?>"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Placeholder Helper -->
|
||||||
|
<div class="hvac-placeholder-helper">
|
||||||
|
<h4><?php _e( 'Available Placeholders', 'hvac-community-events' ); ?></h4>
|
||||||
|
<p><?php _e( 'Click any placeholder to insert it into your template:', 'hvac-community-events' ); ?></p>
|
||||||
|
<div class="hvac-placeholder-grid">
|
||||||
|
<!-- Populated by JavaScript -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hvac-template-form-actions">
|
||||||
|
<button type="button" class="hvac-btn-secondary hvac-template-form-cancel">
|
||||||
|
<?php _e( 'Cancel', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="hvac-btn-primary hvac-template-form-save">
|
||||||
|
<span class="hvac-spinner" style="display: none;"></span>
|
||||||
|
<?php _e( 'Save Template', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Add template toggle button -->
|
||||||
|
<div class="hvac-template-actions" style="margin-bottom: 20px;">
|
||||||
|
<button type="button" class="hvac-template-toggle">
|
||||||
|
📝 <?php _e( 'Use Email Template', 'hvac-community-events' ); ?>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Auto-populate template content when saving current email
|
||||||
|
if (typeof HVACTemplates !== 'undefined') {
|
||||||
|
const originalSaveCurrentEmail = HVACTemplates.saveCurrentEmailAsTemplate;
|
||||||
|
|
||||||
|
HVACTemplates.saveCurrentEmailAsTemplate = function() {
|
||||||
|
const content = this.getCurrentEmailContent();
|
||||||
|
const subject = this.getCurrentEmailSubject();
|
||||||
|
|
||||||
|
if (!content && !subject) {
|
||||||
|
this.showMessage('<?php echo esc_js(__('No email content to save as template', 'hvac-community-events')); ?>', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-fill form with current email content
|
||||||
|
$('#hvac_template_title').val(subject || '<?php echo esc_js(__('New Template', 'hvac-community-events')); ?>');
|
||||||
|
$('#hvac_template_content').val(content);
|
||||||
|
|
||||||
|
// Show the form
|
||||||
|
$('.hvac-template-form').addClass('active');
|
||||||
|
$('#hvac-template-form-title').text('<?php echo esc_js(__('Save Current Email as Template', 'hvac-community-events')); ?>');
|
||||||
|
|
||||||
|
// Scroll to form
|
||||||
|
$('.hvac-template-form')[0].scrollIntoView({ behavior: 'smooth' });
|
||||||
|
|
||||||
|
this.isEditing = true;
|
||||||
|
this.currentTemplateId = null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -245,6 +245,9 @@ $site_title = get_bloginfo( 'name' );
|
||||||
<?php _e( 'This event has no attendees registered yet.', 'hvac-community-events' ); ?>
|
<?php _e( 'This event has no attendees registered yet.', 'hvac-community-events' ); ?>
|
||||||
</div>
|
</div>
|
||||||
<?php else : ?>
|
<?php else : ?>
|
||||||
|
<!-- Include Template Manager Widget -->
|
||||||
|
<?php include HVAC_CE_PLUGIN_DIR . 'templates/communication/template-manager-widget.php'; ?>
|
||||||
|
|
||||||
<form method="post" class="hvac-email-form">
|
<form method="post" class="hvac-email-form">
|
||||||
<?php wp_nonce_field( 'hvac_email_attendees_' . $event_id ); ?>
|
<?php wp_nonce_field( 'hvac_email_attendees_' . $event_id ); ?>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue