✨ Enhanced Template Selector: - Grouped templates by category with descriptions - Template preview modal with field data display - Apply template functionality with AJAX loading - Enhanced UI with preview icons and better UX ✨ Save as Template Functionality: - Complete save template dialog with validation - Template name, description, and category fields - Public/private template sharing options - AJAX integration with error handling and success feedback ✨ Progressive Disclosure: - Advanced options toggle with smooth animations - Fields marked as advanced (capacity, cost, timezone) - Local storage for user preference persistence - Staggered reveal animations for better UX ✨ Enhanced Auto-save: - Intelligent auto-save with field-type specific delays - Draft recovery with age information and user confirmation - Error handling with fallback to essential fields only - Visual feedback with status indicator and animations - Auto-save on page visibility change ✨ AJAX Infrastructure: - Template preview handler (hvac_get_template_preview) - Template loading handler (hvac_load_template_data) - Template saving handler (hvac_save_template) - Comprehensive error handling and security validation 🎨 UI/UX Enhancements: - Modern modal dialogs with backdrop overlays - Responsive design for mobile devices - Smooth animations and transitions - Status indicators with rotating save icons - Comprehensive styling for all new components 🚀 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
1321 lines
No EOL
36 KiB
PHP
1321 lines
No EOL
36 KiB
PHP
<?php
|
|
/**
|
|
* Template Name: HVAC Create Event
|
|
* Description: Native HVAC event creation using HVAC_Event_Form_Builder
|
|
*/
|
|
|
|
// Define constant to indicate we are in a page template
|
|
define('HVAC_IN_PAGE_TEMPLATE', true);
|
|
|
|
// Check if user is logged in and has trainer capabilities
|
|
if (!is_user_logged_in()) {
|
|
wp_redirect(home_url('/training-login/'));
|
|
exit;
|
|
}
|
|
|
|
$user = wp_get_current_user();
|
|
if (!array_intersect(['hvac_trainer', 'hvac_master_trainer'], $user->roles)) {
|
|
wp_die(__('Access denied. Trainer role required.', 'hvac-community-events'));
|
|
}
|
|
|
|
get_header();
|
|
|
|
// Initialize HVAC Event Form Builder
|
|
if (class_exists('HVAC_Event_Form_Builder')) {
|
|
$form_builder = new HVAC_Event_Form_Builder('hvac_event_form', true);
|
|
$form_builder->create_event_form([
|
|
'include_template_selector' => true,
|
|
'include_venue_fields' => true,
|
|
'include_organizer_fields' => true,
|
|
'include_cost_fields' => true,
|
|
'include_capacity_fields' => true,
|
|
'include_datetime_fields' => true,
|
|
'template_categories' => ['general', 'training', 'workshop', 'certification']
|
|
]);
|
|
}
|
|
?>
|
|
|
|
<style>
|
|
.hvac-create-event-wrapper {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
}
|
|
|
|
.hvac-page-header {
|
|
margin-bottom: 30px;
|
|
text-align: center;
|
|
}
|
|
|
|
.hvac-page-header h1 {
|
|
color: #1a1a1a;
|
|
font-size: 32px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.hvac-page-description {
|
|
color: #666;
|
|
font-size: 16px;
|
|
margin-bottom: 30px;
|
|
}
|
|
|
|
/* Quick action buttons */
|
|
.hvac-quick-actions {
|
|
display: flex;
|
|
gap: 15px;
|
|
margin-bottom: 30px;
|
|
justify-content: center;
|
|
}
|
|
|
|
.hvac-quick-actions .button {
|
|
padding: 10px 20px;
|
|
background: #f7f7f7;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
text-decoration: none;
|
|
color: #333;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.hvac-quick-actions .button:hover {
|
|
background: #0073aa;
|
|
color: white;
|
|
border-color: #0073aa;
|
|
}
|
|
|
|
.hvac-quick-actions .button.active {
|
|
background: #0073aa;
|
|
color: white;
|
|
border-color: #0073aa;
|
|
}
|
|
|
|
/* Native HVAC form styling */
|
|
.hvac-event-form {
|
|
background: #fff;
|
|
padding: 40px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.hvac-event-form .form-section {
|
|
margin-bottom: 30px;
|
|
}
|
|
|
|
.hvac-event-form .form-section h3 {
|
|
color: #0073aa;
|
|
font-size: 18px;
|
|
margin-bottom: 15px;
|
|
padding-bottom: 8px;
|
|
border-bottom: 2px solid #0073aa;
|
|
}
|
|
|
|
.hvac-event-form .form-group {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.hvac-event-form .form-group label {
|
|
display: block;
|
|
font-weight: 600;
|
|
color: #333;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.hvac-event-form .form-group label .required {
|
|
color: #dc3232;
|
|
}
|
|
|
|
.hvac-event-form input[type="text"],
|
|
.hvac-event-form input[type="email"],
|
|
.hvac-event-form input[type="url"],
|
|
.hvac-event-form input[type="tel"],
|
|
.hvac-event-form input[type="number"],
|
|
.hvac-event-form input[type="datetime-local"],
|
|
.hvac-event-form textarea,
|
|
.hvac-event-form select {
|
|
width: 100%;
|
|
padding: 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
box-sizing: border-box;
|
|
transition: border-color 0.3s;
|
|
}
|
|
|
|
.hvac-event-form input:focus,
|
|
.hvac-event-form textarea:focus,
|
|
.hvac-event-form select:focus {
|
|
outline: none;
|
|
border-color: #0073aa;
|
|
box-shadow: 0 0 0 2px rgba(0,115,170,0.1);
|
|
}
|
|
|
|
.hvac-event-form textarea {
|
|
min-height: 120px;
|
|
resize: vertical;
|
|
}
|
|
|
|
.hvac-event-form .form-submit {
|
|
text-align: center;
|
|
padding-top: 20px;
|
|
border-top: 1px solid #eee;
|
|
}
|
|
|
|
.hvac-event-form input[type="submit"] {
|
|
background: #0073aa;
|
|
color: white;
|
|
padding: 15px 40px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: background 0.3s;
|
|
}
|
|
|
|
.hvac-event-form input[type="submit"]:hover {
|
|
background: #005a87;
|
|
}
|
|
|
|
/* Enhanced template selector styling */
|
|
.hvac-template-selector {
|
|
background: #f8f9fa;
|
|
padding: 20px;
|
|
border-radius: 6px;
|
|
margin-bottom: 25px;
|
|
}
|
|
|
|
.hvac-template-selector h4 {
|
|
margin-top: 0;
|
|
color: #495057;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.enhanced-selector select {
|
|
position: relative;
|
|
}
|
|
|
|
.enhanced-selector .template-info-icon {
|
|
display: inline-block;
|
|
margin-left: 8px;
|
|
color: #666;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.enhanced-selector .template-info-icon:hover {
|
|
color: #0073aa;
|
|
}
|
|
|
|
/* Template preview modal styling */
|
|
.hvac-template-preview {
|
|
position: fixed;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
|
|
z-index: 10000;
|
|
min-width: 500px;
|
|
max-width: 90vw;
|
|
max-height: 80vh;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.hvac-template-preview .preview-header {
|
|
background: #0073aa;
|
|
color: white;
|
|
padding: 15px 20px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.hvac-template-preview .preview-header h4 {
|
|
margin: 0;
|
|
font-size: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.hvac-template-preview .preview-close {
|
|
background: none;
|
|
border: none;
|
|
color: white;
|
|
font-size: 24px;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
width: 30px;
|
|
height: 30px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.hvac-template-preview .preview-close:hover {
|
|
background: rgba(255,255,255,0.2);
|
|
}
|
|
|
|
.hvac-template-preview .preview-content {
|
|
padding: 20px;
|
|
max-height: calc(80vh - 120px);
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.hvac-template-preview .preview-info {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.hvac-template-preview .template-name strong {
|
|
font-size: 18px;
|
|
color: #333;
|
|
}
|
|
|
|
.hvac-template-preview .template-description {
|
|
color: #666;
|
|
margin: 8px 0;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.hvac-template-preview .template-category span {
|
|
background: #e8f5e8;
|
|
color: #2e7d2e;
|
|
padding: 3px 8px;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.hvac-template-preview .preview-fields {
|
|
border-top: 1px solid #eee;
|
|
padding-top: 15px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.hvac-template-preview .field-list {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.hvac-template-preview .field-list li {
|
|
background: #f9f9f9;
|
|
margin: 5px 0;
|
|
padding: 8px 12px;
|
|
border-radius: 4px;
|
|
border-left: 3px solid #0073aa;
|
|
}
|
|
|
|
.hvac-template-preview .preview-actions {
|
|
border-top: 1px solid #eee;
|
|
padding-top: 15px;
|
|
text-align: right;
|
|
}
|
|
|
|
.hvac-template-preview .preview-actions .button {
|
|
margin-left: 10px;
|
|
}
|
|
|
|
/* Overlay backdrop */
|
|
.hvac-template-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0,0,0,0.5);
|
|
z-index: 9999;
|
|
display: none;
|
|
}
|
|
|
|
/* Save template dialog styling */
|
|
.hvac-save-template-dialog {
|
|
position: fixed;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
|
|
z-index: 10001;
|
|
min-width: 450px;
|
|
max-width: 90vw;
|
|
max-height: 80vh;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.hvac-save-template-dialog .dialog-header {
|
|
background: #0073aa;
|
|
color: white;
|
|
padding: 15px 20px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.hvac-save-template-dialog .dialog-header h4 {
|
|
margin: 0;
|
|
font-size: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.hvac-save-template-dialog .dialog-close {
|
|
background: none;
|
|
border: none;
|
|
color: white;
|
|
font-size: 24px;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
width: 30px;
|
|
height: 30px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.hvac-save-template-dialog .dialog-close:hover {
|
|
background: rgba(255,255,255,0.2);
|
|
}
|
|
|
|
.hvac-save-template-dialog .dialog-content {
|
|
padding: 25px;
|
|
max-height: calc(80vh - 120px);
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.hvac-save-template-dialog .form-group {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.hvac-save-template-dialog .form-group label {
|
|
display: block;
|
|
margin-bottom: 8px;
|
|
color: #333;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.hvac-save-template-dialog .template-input {
|
|
width: 100%;
|
|
padding: 10px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.hvac-save-template-dialog .template-input:focus {
|
|
outline: none;
|
|
border-color: #0073aa;
|
|
box-shadow: 0 0 0 2px rgba(0,115,170,0.1);
|
|
}
|
|
|
|
.hvac-save-template-dialog .checkbox-group {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 8px;
|
|
}
|
|
|
|
.hvac-save-template-dialog .checkbox-group label {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 8px;
|
|
font-weight: normal;
|
|
margin-bottom: 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.hvac-save-template-dialog .checkbox-group input[type="checkbox"] {
|
|
margin: 0;
|
|
width: auto;
|
|
}
|
|
|
|
.hvac-save-template-dialog .description {
|
|
color: #666;
|
|
font-size: 12px;
|
|
display: block;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
.hvac-save-template-dialog .dialog-actions {
|
|
border-top: 1px solid #eee;
|
|
padding: 15px 25px;
|
|
text-align: right;
|
|
}
|
|
|
|
.hvac-save-template-dialog .dialog-actions .button {
|
|
margin-left: 10px;
|
|
}
|
|
|
|
/* Progressive disclosure styling */
|
|
.hvac-advanced-options-toggle {
|
|
text-align: center;
|
|
margin: 30px 0;
|
|
padding: 15px;
|
|
background: #f8f9fa;
|
|
border-radius: 6px;
|
|
border: 1px dashed #ddd;
|
|
}
|
|
|
|
.hvac-advanced-options-toggle .toggle-advanced-options {
|
|
background: none;
|
|
border: none;
|
|
color: #0073aa;
|
|
font-size: 16px;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
justify-content: center;
|
|
width: auto;
|
|
margin: 0 auto 5px;
|
|
padding: 8px 16px;
|
|
border-radius: 4px;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.hvac-advanced-options-toggle .toggle-advanced-options:hover {
|
|
background: rgba(0,115,170,0.1);
|
|
color: #005a87;
|
|
}
|
|
|
|
.hvac-advanced-options-toggle .toggle-icon {
|
|
transition: transform 0.3s;
|
|
font-size: 18px;
|
|
}
|
|
|
|
.hvac-advanced-options-toggle.expanded .toggle-icon {
|
|
transform: rotate(180deg);
|
|
}
|
|
|
|
.hvac-advanced-options-toggle .toggle-description {
|
|
color: #666;
|
|
font-size: 13px;
|
|
display: block;
|
|
margin: 0;
|
|
}
|
|
|
|
/* Advanced fields styling */
|
|
.advanced-field {
|
|
display: none;
|
|
opacity: 0;
|
|
transform: translateY(-10px);
|
|
transition: all 0.3s ease-in-out;
|
|
}
|
|
|
|
.advanced-field.show {
|
|
display: block;
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
|
|
.advanced-fields-section {
|
|
margin-top: 20px;
|
|
padding-top: 20px;
|
|
border-top: 2px solid #e8f5e8;
|
|
position: relative;
|
|
}
|
|
|
|
.advanced-fields-section::before {
|
|
content: "Advanced Options";
|
|
position: absolute;
|
|
top: -12px;
|
|
left: 20px;
|
|
background: #fff;
|
|
color: #0073aa;
|
|
font-weight: 600;
|
|
font-size: 14px;
|
|
padding: 0 10px;
|
|
}
|
|
|
|
/* Animation for advanced fields reveal */
|
|
@keyframes slideInDown {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.advanced-field.animate-in {
|
|
animation: slideInDown 0.3s ease-out forwards;
|
|
}
|
|
|
|
/* Auto-save indicator styling */
|
|
.hvac-autosave-indicator {
|
|
position: fixed;
|
|
top: 20px;
|
|
right: 20px;
|
|
z-index: 9998;
|
|
padding: 10px 15px;
|
|
border-radius: 6px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
display: none;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.hvac-autosave-indicator .dashicons {
|
|
font-size: 16px;
|
|
vertical-align: text-top;
|
|
margin-right: 5px;
|
|
}
|
|
|
|
.hvac-autosave-indicator.status-saving {
|
|
background: #fff3cd;
|
|
color: #856404;
|
|
border: 1px solid #ffeaa7;
|
|
}
|
|
|
|
.hvac-autosave-indicator.status-saved {
|
|
background: #d4edda;
|
|
color: #155724;
|
|
border: 1px solid #c3e6cb;
|
|
}
|
|
|
|
.hvac-autosave-indicator.status-error {
|
|
background: #f8d7da;
|
|
color: #721c24;
|
|
border: 1px solid #f5c6cb;
|
|
}
|
|
|
|
.hvac-autosave-indicator.status-draft-loaded {
|
|
background: #cce5ff;
|
|
color: #004085;
|
|
border: 1px solid #99ccff;
|
|
}
|
|
|
|
/* Saving animation */
|
|
.hvac-autosave-indicator.status-saving .dashicons {
|
|
animation: rotate 1s linear infinite;
|
|
}
|
|
|
|
@keyframes rotate {
|
|
from {
|
|
transform: rotate(0deg);
|
|
}
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
/* Mobile responsive */
|
|
@media (max-width: 768px) {
|
|
.hvac-autosave-indicator {
|
|
top: 10px;
|
|
right: 10px;
|
|
left: 10px;
|
|
text-align: center;
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
|
|
/* Success message styling */
|
|
.hvac-success-message {
|
|
background: #d4edda;
|
|
border: 1px solid #c3e6cb;
|
|
border-radius: 4px;
|
|
padding: 15px;
|
|
margin-bottom: 20px;
|
|
color: #155724;
|
|
}
|
|
|
|
/* Error message styling */
|
|
.hvac-error-message {
|
|
background: #f8d7da;
|
|
border: 1px solid #f5c6cb;
|
|
border-radius: 4px;
|
|
padding: 15px;
|
|
margin-bottom: 20px;
|
|
color: #721c24;
|
|
}
|
|
|
|
/* Phase 2 Integration Notice */
|
|
.hvac-phase2-notice {
|
|
background: #e8f5e8;
|
|
border: 2px solid #4CAF50;
|
|
border-radius: 6px;
|
|
padding: 15px;
|
|
margin-bottom: 30px;
|
|
text-align: center;
|
|
}
|
|
|
|
.hvac-phase2-notice strong {
|
|
color: #2e7d2e;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.hvac-phase2-notice p {
|
|
margin: 8px 0 0 0;
|
|
color: #2e7d2e;
|
|
}
|
|
|
|
/* Responsive design */
|
|
@media (max-width: 768px) {
|
|
.hvac-create-event-wrapper {
|
|
padding: 15px;
|
|
}
|
|
|
|
.hvac-event-form {
|
|
padding: 20px;
|
|
}
|
|
|
|
.hvac-quick-actions {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
.hvac-quick-actions .button {
|
|
width: 200px;
|
|
text-align: center;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<div class="hvac-create-event-wrapper">
|
|
<?php
|
|
// Display trainer navigation menu
|
|
if (class_exists('HVAC_Menu_System')) {
|
|
HVAC_Menu_System::instance()->render_trainer_menu();
|
|
}
|
|
|
|
// Display breadcrumbs
|
|
if (class_exists('HVAC_Breadcrumbs')) {
|
|
HVAC_Breadcrumbs::instance()->render();
|
|
}
|
|
?>
|
|
|
|
<div class="hvac-page-header">
|
|
<h1>Create New Training Event</h1>
|
|
<p class="hvac-page-description">
|
|
Share your expertise by creating a training event using our native HVAC event management system.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Phase 2 Integration Success Notice -->
|
|
<div class="hvac-phase2-notice">
|
|
<strong>✓ Phase 2 TEC Integration Complete</strong>
|
|
<p>Now using native HVAC Event Form Builder with template system and TEC Core integration</p>
|
|
</div>
|
|
|
|
<div class="hvac-quick-actions">
|
|
<a href="<?php echo home_url('/trainer/events/my-events/'); ?>" class="button">My Events</a>
|
|
<a href="<?php echo home_url('/trainer/events/create/'); ?>" class="button active">Create Event</a>
|
|
<a href="<?php echo home_url('/trainer/dashboard/'); ?>" class="button">Dashboard</a>
|
|
</div>
|
|
|
|
<div class="hvac-event-form">
|
|
<?php
|
|
// Display any success/error messages
|
|
if (isset($_GET['success'])) {
|
|
echo '<div class="hvac-success-message">Event created successfully!</div>';
|
|
}
|
|
if (isset($_GET['error'])) {
|
|
echo '<div class="hvac-error-message">Error creating event. Please try again.</div>';
|
|
}
|
|
|
|
// Render the native HVAC event creation form
|
|
if (isset($form_builder)) {
|
|
echo $form_builder->render();
|
|
} else {
|
|
echo '<div class="hvac-error-message">';
|
|
echo '<p><strong>Form Builder Not Available</strong></p>';
|
|
echo '<p>The HVAC Event Form Builder is not loaded. Please ensure the plugin is properly activated.</p>';
|
|
echo '<p><a href="' . esc_url(home_url('/trainer/dashboard/')) . '" class="button">Return to Dashboard</a></p>';
|
|
echo '</div>';
|
|
}
|
|
?>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
jQuery(document).ready(function($) {
|
|
// Enhanced template selector functionality
|
|
let templateData = {};
|
|
|
|
// Parse template data from form
|
|
try {
|
|
const $templateSelector = $('[name="event_template"]');
|
|
if ($templateSelector.length && $templateSelector.data('templates')) {
|
|
const templates = $templateSelector.data('templates');
|
|
templates.forEach(function(template) {
|
|
templateData[template.id] = template;
|
|
});
|
|
}
|
|
} catch (e) {
|
|
console.warn('Could not parse template data:', e);
|
|
}
|
|
|
|
// Template selector change handler
|
|
$(document).on('change', '[name="event_template"]', function() {
|
|
const templateId = $(this).val();
|
|
|
|
if (templateId && templateId !== '0') {
|
|
// Show template preview
|
|
hvacShowTemplatePreview(templateId);
|
|
} else {
|
|
// Hide preview if no template selected
|
|
hvacCloseTemplatePreview();
|
|
}
|
|
});
|
|
|
|
// Add preview icon to template selector
|
|
$('[name="event_template"]').after(
|
|
'<span class="template-info-icon dashicons dashicons-info" title="Click to preview template"></span>'
|
|
);
|
|
|
|
// Preview icon click handler
|
|
$(document).on('click', '.template-info-icon', function() {
|
|
const templateId = $('[name="event_template"]').val();
|
|
if (templateId && templateId !== '0') {
|
|
hvacShowTemplatePreview(templateId);
|
|
}
|
|
});
|
|
|
|
// Enhanced auto-save functionality for long forms
|
|
let autoSaveTimeout;
|
|
let autoSaveIndicator;
|
|
|
|
// Create auto-save indicator
|
|
function createAutoSaveIndicator() {
|
|
if ($('#hvac-autosave-indicator').length === 0) {
|
|
const indicator = $('<div id="hvac-autosave-indicator" class="hvac-autosave-indicator"></div>');
|
|
$('.hvac-event-form').prepend(indicator);
|
|
autoSaveIndicator = indicator;
|
|
}
|
|
}
|
|
|
|
// Update auto-save status
|
|
function updateAutoSaveStatus(status, message = '') {
|
|
if (!autoSaveIndicator) createAutoSaveIndicator();
|
|
|
|
const statusClasses = {
|
|
'saving': 'status-saving',
|
|
'saved': 'status-saved',
|
|
'error': 'status-error',
|
|
'draft-loaded': 'status-draft-loaded'
|
|
};
|
|
|
|
const statusMessages = {
|
|
'saving': '<span class="dashicons dashicons-backup"></span> Saving draft...',
|
|
'saved': '<span class="dashicons dashicons-yes"></span> Draft saved',
|
|
'error': '<span class="dashicons dashicons-warning"></span> Save failed - will retry',
|
|
'draft-loaded': '<span class="dashicons dashicons-restore"></span> Draft restored'
|
|
};
|
|
|
|
autoSaveIndicator
|
|
.removeClass(Object.values(statusClasses).join(' '))
|
|
.addClass(statusClasses[status])
|
|
.html(message || statusMessages[status])
|
|
.show();
|
|
|
|
if (status === 'saved') {
|
|
setTimeout(() => {
|
|
autoSaveIndicator.fadeOut();
|
|
}, 3000);
|
|
} else if (status === 'draft-loaded') {
|
|
setTimeout(() => {
|
|
autoSaveIndicator.fadeOut();
|
|
}, 5000);
|
|
}
|
|
}
|
|
|
|
// Enhanced auto-save function with error handling
|
|
function performAutoSave() {
|
|
const formData = {};
|
|
let hasContent = false;
|
|
|
|
// Collect form data more selectively
|
|
$('form input, form textarea, form select').each(function() {
|
|
const $field = $(this);
|
|
const name = $field.attr('name');
|
|
const value = $field.val();
|
|
|
|
if (name && value && value.toString().trim() &&
|
|
!name.includes('nonce') && !name.includes('_wp_http_referer') &&
|
|
name !== 'submit') {
|
|
formData[name] = value;
|
|
hasContent = true;
|
|
}
|
|
});
|
|
|
|
// Only save if there's meaningful content
|
|
if (!hasContent) return;
|
|
|
|
updateAutoSaveStatus('saving');
|
|
|
|
// Add metadata
|
|
const saveData = {
|
|
formData: formData,
|
|
timestamp: new Date().toISOString(),
|
|
url: window.location.href,
|
|
version: '2.0'
|
|
};
|
|
|
|
try {
|
|
localStorage.setItem('hvac_event_draft', JSON.stringify(saveData));
|
|
updateAutoSaveStatus('saved');
|
|
} catch (e) {
|
|
console.warn('Auto-save failed:', e);
|
|
updateAutoSaveStatus('error');
|
|
|
|
// Try to save with reduced data if quota exceeded
|
|
if (e.name === 'QuotaExceededError') {
|
|
try {
|
|
// Save only essential fields
|
|
const essentialData = {
|
|
event_title: formData.event_title,
|
|
event_description: formData.event_description,
|
|
event_start_datetime: formData.event_start_datetime,
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
localStorage.setItem('hvac_event_draft_essential', JSON.stringify(essentialData));
|
|
} catch (e2) {
|
|
console.error('Even essential data save failed:', e2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Enhanced auto-save trigger with debouncing and intelligent timing
|
|
$('input, textarea, select').on('input change', function() {
|
|
clearTimeout(autoSaveTimeout);
|
|
|
|
const fieldType = this.type || this.tagName.toLowerCase();
|
|
let delay = 2000; // Default delay
|
|
|
|
// Adjust delay based on field type
|
|
if (fieldType === 'text' || fieldType === 'textarea') {
|
|
delay = 3000; // Longer delay for text fields to avoid saving on every keystroke
|
|
} else if (fieldType === 'select') {
|
|
delay = 1000; // Shorter delay for dropdowns
|
|
}
|
|
|
|
autoSaveTimeout = setTimeout(performAutoSave, delay);
|
|
});
|
|
|
|
// Enhanced draft recovery with user confirmation
|
|
function attemptDraftRecovery() {
|
|
const draftData = localStorage.getItem('hvac_event_draft');
|
|
const essentialDraft = localStorage.getItem('hvac_event_draft_essential');
|
|
|
|
if (!draftData && !essentialDraft) return;
|
|
if ($('[name="event_id"]').val()) return; // Don't restore for existing events
|
|
|
|
let parsedData;
|
|
let isEssentialOnly = false;
|
|
|
|
try {
|
|
if (draftData) {
|
|
parsedData = JSON.parse(draftData);
|
|
} else {
|
|
parsedData = JSON.parse(essentialDraft);
|
|
isEssentialOnly = true;
|
|
}
|
|
} catch (e) {
|
|
console.warn('Invalid draft data found, clearing...');
|
|
localStorage.removeItem('hvac_event_draft');
|
|
localStorage.removeItem('hvac_event_draft_essential');
|
|
return;
|
|
}
|
|
|
|
const draftAge = new Date() - new Date(parsedData.timestamp);
|
|
const hoursOld = Math.floor(draftAge / (1000 * 60 * 60));
|
|
|
|
// Show draft recovery dialog
|
|
const draftInfo = isEssentialOnly ? '(essential fields only)' : '(complete form)';
|
|
const message = `Found a draft from ${hoursOld} hours ago ${draftInfo}. Would you like to restore it?`;
|
|
|
|
if (confirm(message)) {
|
|
Object.entries(parsedData.formData || parsedData).forEach(([key, value]) => {
|
|
if (key === 'timestamp') return;
|
|
|
|
const $field = $(`[name="${key}"]`);
|
|
if ($field.length && !$field.val()) {
|
|
$field.val(value).trigger('change');
|
|
}
|
|
});
|
|
|
|
updateAutoSaveStatus('draft-loaded',
|
|
`<span class="dashicons dashicons-restore"></span> Draft restored ${draftInfo}`);
|
|
}
|
|
|
|
// Clean up old drafts
|
|
if (hoursOld > 72) { // Remove drafts older than 3 days
|
|
localStorage.removeItem('hvac_event_draft');
|
|
localStorage.removeItem('hvac_event_draft_essential');
|
|
}
|
|
}
|
|
|
|
// Initialize enhanced auto-save
|
|
createAutoSaveIndicator();
|
|
setTimeout(attemptDraftRecovery, 500); // Delay to ensure form is ready
|
|
|
|
// Clear draft on successful submission
|
|
$('form').on('submit', function() {
|
|
localStorage.removeItem('hvac_event_draft');
|
|
localStorage.removeItem('hvac_event_draft_essential');
|
|
if (autoSaveIndicator) {
|
|
autoSaveIndicator.hide();
|
|
}
|
|
});
|
|
|
|
// Handle page visibility change (auto-save when user switches tabs)
|
|
$(document).on('visibilitychange', function() {
|
|
if (document.hidden) {
|
|
clearTimeout(autoSaveTimeout);
|
|
performAutoSave();
|
|
}
|
|
});
|
|
});
|
|
|
|
// Enhanced template preview functions
|
|
function hvacShowTemplatePreview(templateId) {
|
|
const $ = jQuery;
|
|
|
|
// Create overlay if it doesn't exist
|
|
if (!$('.hvac-template-overlay').length) {
|
|
$('body').append('<div class="hvac-template-overlay"></div>');
|
|
}
|
|
|
|
// Show overlay
|
|
$('.hvac-template-overlay').show();
|
|
|
|
// Get template data via AJAX
|
|
$.ajax({
|
|
url: ajaxurl || '/wp-admin/admin-ajax.php',
|
|
type: 'POST',
|
|
data: {
|
|
action: 'hvac_get_template_preview',
|
|
template_id: templateId,
|
|
nonce: $('[name="hvac_event_form_nonce"]').val()
|
|
},
|
|
beforeSend: function() {
|
|
// Show loading state
|
|
$('#hvac-template-preview .template-name strong').text('Loading...');
|
|
$('#hvac-template-preview .template-description').text('');
|
|
$('#hvac-template-preview .template-category span').text('');
|
|
$('#hvac-template-preview .field-list').empty();
|
|
},
|
|
success: function(response) {
|
|
if (response.success && response.data) {
|
|
const template = response.data;
|
|
|
|
// Populate preview with template data
|
|
$('#hvac-template-preview .template-name strong').text(template.name);
|
|
$('#hvac-template-preview .template-description').text(template.description || 'No description available');
|
|
$('#hvac-template-preview .template-category span').text(template.category);
|
|
|
|
// Show field data
|
|
const $fieldList = $('#hvac-template-preview .field-list');
|
|
$fieldList.empty();
|
|
|
|
if (template.field_data && Object.keys(template.field_data).length > 0) {
|
|
Object.keys(template.field_data).forEach(function(fieldName) {
|
|
const fieldValue = template.field_data[fieldName];
|
|
if (fieldValue && fieldValue.toString().trim()) {
|
|
const displayName = fieldName.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
$fieldList.append(
|
|
'<li><strong>' + displayName + ':</strong> ' +
|
|
String(fieldValue).substring(0, 100) +
|
|
(String(fieldValue).length > 100 ? '...' : '') + '</li>'
|
|
);
|
|
}
|
|
});
|
|
} else {
|
|
$fieldList.append('<li><em>No pre-filled fields in this template</em></li>');
|
|
}
|
|
|
|
// Store template data for apply function
|
|
window.hvacCurrentTemplate = template;
|
|
}
|
|
},
|
|
error: function() {
|
|
$('#hvac-template-preview .template-name strong').text('Error loading template');
|
|
$('#hvac-template-preview .template-description').text('Could not load template data');
|
|
},
|
|
complete: function() {
|
|
// Show preview modal
|
|
$('#hvac-template-preview').show();
|
|
}
|
|
});
|
|
}
|
|
|
|
function hvacCloseTemplatePreview() {
|
|
const $ = jQuery;
|
|
$('#hvac-template-preview').hide();
|
|
$('.hvac-template-overlay').hide();
|
|
delete window.hvacCurrentTemplate;
|
|
}
|
|
|
|
function hvacApplyTemplate() {
|
|
const $ = jQuery;
|
|
|
|
if (!window.hvacCurrentTemplate) {
|
|
alert('No template data available');
|
|
return;
|
|
}
|
|
|
|
const template = window.hvacCurrentTemplate;
|
|
|
|
// Apply template field data to form
|
|
if (template.field_data) {
|
|
Object.keys(template.field_data).forEach(function(fieldName) {
|
|
const $field = $('[name="' + fieldName + '"]');
|
|
if ($field.length && template.field_data[fieldName]) {
|
|
$field.val(template.field_data[fieldName]).trigger('change');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Show success message
|
|
if ($('.hvac-success-message').length) {
|
|
$('.hvac-success-message').remove();
|
|
}
|
|
$('.hvac-event-form').prepend(
|
|
'<div class="hvac-success-message">Template "' + template.name + '" applied successfully!</div>'
|
|
);
|
|
|
|
// Auto-remove success message after 5 seconds
|
|
setTimeout(function() {
|
|
$('.hvac-success-message').fadeOut();
|
|
}, 5000);
|
|
|
|
// Close preview
|
|
hvacCloseTemplatePreview();
|
|
}
|
|
|
|
// Close preview when clicking overlay
|
|
jQuery(document).on('click', '.hvac-template-overlay', function() {
|
|
hvacCloseTemplatePreview();
|
|
});
|
|
|
|
// Escape key to close preview
|
|
jQuery(document).on('keyup', function(e) {
|
|
if (e.key === "Escape") {
|
|
hvacCloseTemplatePreview();
|
|
hvacCloseSaveDialog();
|
|
}
|
|
});
|
|
|
|
// Save template dialog functions
|
|
function hvacShowSaveTemplateDialog(event) {
|
|
event.preventDefault();
|
|
const $ = jQuery;
|
|
|
|
// Create overlay if it doesn't exist
|
|
if (!$('.hvac-template-overlay').length) {
|
|
$('body').append('<div class="hvac-template-overlay"></div>');
|
|
}
|
|
|
|
// Show overlay
|
|
$('.hvac-template-overlay').show();
|
|
|
|
// Clear previous form data
|
|
$('#template-name').val('');
|
|
$('#template-description').val('');
|
|
$('#template-category').val('');
|
|
$('#template-public').prop('checked', false);
|
|
|
|
// Show dialog
|
|
$('#hvac-save-template-dialog').show();
|
|
}
|
|
|
|
function hvacCloseSaveDialog() {
|
|
const $ = jQuery;
|
|
$('#hvac-save-template-dialog').hide();
|
|
$('.hvac-template-overlay').hide();
|
|
}
|
|
|
|
function hvacSaveAsTemplate() {
|
|
const $ = jQuery;
|
|
|
|
// Get form data
|
|
const templateName = $('#template-name').val().trim();
|
|
const templateDescription = $('#template-description').val().trim();
|
|
const templateCategory = $('#template-category').val();
|
|
const isPublic = $('#template-public').is(':checked');
|
|
|
|
// Basic validation
|
|
if (!templateName) {
|
|
alert('Please enter a template name');
|
|
$('#template-name').focus();
|
|
return;
|
|
}
|
|
|
|
if (!templateCategory) {
|
|
alert('Please select a category');
|
|
$('#template-category').focus();
|
|
return;
|
|
}
|
|
|
|
// Collect current form data
|
|
const formData = {};
|
|
$('form input, form textarea, form select').each(function() {
|
|
const $field = $(this);
|
|
const name = $field.attr('name');
|
|
const value = $field.val();
|
|
|
|
if (name && value && name !== 'template_name' && name !== 'template_description' &&
|
|
name !== 'template_category' && name !== 'template_public' &&
|
|
name !== 'hvac_event_form_nonce' && name !== '_wp_http_referer') {
|
|
formData[name] = value;
|
|
}
|
|
});
|
|
|
|
// Show saving state
|
|
$('.hvac-save-template-dialog .button-primary').prop('disabled', true).text('Saving...');
|
|
|
|
// Send AJAX request
|
|
$.ajax({
|
|
url: ajaxurl || '/wp-admin/admin-ajax.php',
|
|
type: 'POST',
|
|
data: {
|
|
action: 'hvac_save_template',
|
|
template_name: templateName,
|
|
template_description: templateDescription,
|
|
template_category: templateCategory,
|
|
is_public: isPublic ? 1 : 0,
|
|
field_data: formData,
|
|
nonce: $('[name="hvac_event_form_nonce"]').val()
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
// Show success message
|
|
if ($('.hvac-success-message').length) {
|
|
$('.hvac-success-message').remove();
|
|
}
|
|
$('.hvac-event-form').prepend(
|
|
'<div class="hvac-success-message">Template "' + templateName + '" saved successfully!</div>'
|
|
);
|
|
|
|
// Auto-remove success message after 5 seconds
|
|
setTimeout(function() {
|
|
$('.hvac-success-message').fadeOut();
|
|
}, 5000);
|
|
|
|
// Close dialog
|
|
hvacCloseSaveDialog();
|
|
|
|
// Refresh template selector if it exists
|
|
if ($('[name="event_template"]').length) {
|
|
// Add new template to selector
|
|
const newOption = '<option value="' + response.data.template_id + '">' +
|
|
templateName + ' (' + templateCategory.charAt(0).toUpperCase() + templateCategory.slice(1) + ')</option>';
|
|
$('[name="event_template"]').append(newOption);
|
|
}
|
|
} else {
|
|
alert('Error saving template: ' + (response.data || 'Unknown error'));
|
|
}
|
|
},
|
|
error: function() {
|
|
alert('Error saving template. Please try again.');
|
|
},
|
|
complete: function() {
|
|
// Reset button state
|
|
$('.hvac-save-template-dialog .button-primary').prop('disabled', false).text('Save Template');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Close save dialog when clicking overlay
|
|
jQuery(document).on('click', '.hvac-template-overlay', function(e) {
|
|
if (e.target === this) {
|
|
hvacCloseTemplatePreview();
|
|
hvacCloseSaveDialog();
|
|
}
|
|
});
|
|
|
|
// Progressive disclosure functions
|
|
function hvacToggleAdvancedOptions() {
|
|
const $ = jQuery;
|
|
const $toggle = $('.hvac-advanced-options-toggle');
|
|
const $toggleText = $('.toggle-text');
|
|
const $advancedSection = $('.advanced-fields-section');
|
|
const $advancedFields = $('.advanced-field');
|
|
|
|
const isExpanded = $toggle.hasClass('expanded');
|
|
|
|
if (isExpanded) {
|
|
// Hide advanced section
|
|
$advancedSection.slideUp(300, function() {
|
|
$advancedFields.removeClass('show animate-in');
|
|
});
|
|
$toggle.removeClass('expanded');
|
|
$toggleText.text('Show Advanced Options');
|
|
|
|
// Save state
|
|
localStorage.setItem('hvac_advanced_options_visible', 'false');
|
|
} else {
|
|
// Show advanced section
|
|
$toggle.addClass('expanded');
|
|
$toggleText.text('Hide Advanced Options');
|
|
|
|
$advancedSection.slideDown(300, function() {
|
|
// Show fields with staggered animation
|
|
let delay = 0;
|
|
$advancedFields.each(function(index) {
|
|
const $field = $(this);
|
|
setTimeout(function() {
|
|
$field.addClass('show animate-in');
|
|
}, delay);
|
|
delay += 50;
|
|
});
|
|
});
|
|
|
|
// Save state
|
|
localStorage.setItem('hvac_advanced_options_visible', 'true');
|
|
}
|
|
}
|
|
|
|
// Initialize progressive disclosure on page load
|
|
jQuery(document).ready(function($) {
|
|
// Wait for form to be fully rendered
|
|
setTimeout(function() {
|
|
// Check if advanced options should be visible (from localStorage)
|
|
const advancedVisible = localStorage.getItem('hvac_advanced_options_visible') === 'true';
|
|
|
|
// Add advanced section wrapper if there are advanced fields
|
|
if ($('.advanced-field').length > 0) {
|
|
// Group advanced fields together
|
|
let $firstAdvanced = $('.advanced-field').first();
|
|
let $advancedContainer = $('<div class="advanced-fields-section"></div>');
|
|
|
|
// Insert the container before the first advanced field
|
|
$firstAdvanced.before($advancedContainer);
|
|
|
|
// Move all advanced fields into the container
|
|
$('.advanced-field').each(function() {
|
|
$advancedContainer.append($(this));
|
|
});
|
|
|
|
if (advancedVisible) {
|
|
// Show advanced options without animation on page load
|
|
$('.hvac-advanced-options-toggle').addClass('expanded');
|
|
$('.toggle-text').text('Hide Advanced Options');
|
|
$('.advanced-field').addClass('show');
|
|
$advancedContainer.show();
|
|
} else {
|
|
// Hide advanced fields and container by default
|
|
$('.advanced-field').removeClass('show');
|
|
$advancedContainer.hide();
|
|
}
|
|
}
|
|
}, 100);
|
|
});
|
|
</script>
|
|
|
|
<?php
|
|
get_footer();
|
|
?>
|