admin-menu.js
3 months ago
documentation.js
3 months ago
import.js
3 months ago
settings.js
3 months ago
support.js
3 months ago
support.js
257 lines
| 1 | jQuery( document ).ready( function( $ ) { |
| 2 | |
| 3 | /** |
| 4 | * Show/hide conditional fields |
| 5 | */ |
| 6 | function updateConditionalFields() { |
| 7 | $( '.helpdocs-field[data-condition-field]' ).each( function() { |
| 8 | var $field = $( this ); |
| 9 | var targetId = $field.data( 'condition-field' ); |
| 10 | var expectedValue = $field.data( 'condition-value' ); |
| 11 | var $target = $( '#' + targetId ); |
| 12 | |
| 13 | if ( $target.length ) { |
| 14 | var isVisible = false; |
| 15 | |
| 16 | if ( $target.is( ':checkbox' ) ) { |
| 17 | var isChecked = $target.is( ':checked' ) ? '1' : '0'; |
| 18 | isVisible = ( isChecked == expectedValue ); |
| 19 | } else { |
| 20 | isVisible = ( $target.val() == expectedValue ); |
| 21 | } |
| 22 | |
| 23 | if ( isVisible ) { |
| 24 | $field.removeClass( 'condition-hide' ); |
| 25 | } else { |
| 26 | $field.addClass( 'condition-hide' ); |
| 27 | } |
| 28 | } |
| 29 | } ); |
| 30 | } |
| 31 | |
| 32 | // Listen for changes on any field that has a condition tied to it |
| 33 | $( document ).on( 'change', '.has-condition, .has-condition input, .has-condition select', function() { |
| 34 | updateConditionalFields(); |
| 35 | } ); |
| 36 | |
| 37 | |
| 38 | /** |
| 39 | * Submit Support Form via AJAX |
| 40 | */ |
| 41 | $( '#helpdocs-support-form' ).on( 'submit', function( e ) { |
| 42 | e.preventDefault(); |
| 43 | |
| 44 | var $form = $( this ); |
| 45 | var $response = $( '#helpdocs-support-response' ); |
| 46 | var $button = $( '#helpdocs-submit-support' ); |
| 47 | var $spinner = $form.find( '.spinner' ); |
| 48 | |
| 49 | var isError = false; |
| 50 | var errorMsg = helpdocs_support.required_fields; |
| 51 | $form.find( '[required]:visible' ).each( function() { |
| 52 | var $el = $( this ); |
| 53 | if ( ! $el.val() || ( $el.is( ':checkbox' ) && ! $el.is( ':checked' ) ) ) { |
| 54 | isError = true; |
| 55 | $el.addClass( 'field-error' ); |
| 56 | } else { |
| 57 | $el.removeClass( 'field-error' ); |
| 58 | } |
| 59 | } ); |
| 60 | |
| 61 | var totalSize = 0; |
| 62 | var maxSizeBytes = helpdocs_support.max_attachment_mb * 1024 * 1024; // 10MB default |
| 63 | var $fileInput = $form.find( 'input[type="file"]' ); |
| 64 | |
| 65 | if ( $fileInput.length && $fileInput[0].files.length > 0 ) { |
| 66 | $.each( $fileInput[0].files, function( i, file ) { |
| 67 | totalSize += file.size; |
| 68 | } ); |
| 69 | } |
| 70 | |
| 71 | if ( totalSize > maxSizeBytes ) { |
| 72 | isError = true; |
| 73 | errorMsg = helpdocs_support.files_too_large; |
| 74 | } |
| 75 | |
| 76 | if ( isError ) { |
| 77 | $response.addClass( 'error' ).html( '<p>' + errorMsg + '</p>' ).fadeIn(); |
| 78 | return; |
| 79 | } |
| 80 | |
| 81 | var formData = new FormData( this ); |
| 82 | formData.append( 'action', 'helpdocs_send_support_email' ); |
| 83 | |
| 84 | $response.hide().removeClass( 'success error' ); |
| 85 | $button.prop( 'disabled', true ); |
| 86 | $spinner.addClass( 'is-active' ); |
| 87 | |
| 88 | $.ajax( { |
| 89 | url: ajaxurl, |
| 90 | type: 'POST', |
| 91 | data: formData, |
| 92 | processData: false, |
| 93 | contentType: false, |
| 94 | success: function( res ) { |
| 95 | $spinner.removeClass( 'is-active' ); |
| 96 | $button.prop( 'disabled', false ); |
| 97 | |
| 98 | if ( res.success ) { |
| 99 | $response.addClass( 'success' ).html( '<p>' + res.data.message + '</p>' ).fadeIn(); |
| 100 | |
| 101 | var now = new Date(); |
| 102 | var dateStr = formatCurrentDate( helpdocs_support.log_date_format ); |
| 103 | |
| 104 | // Fix: Use correct IDs (prepended with helpdocs_) |
| 105 | var subject = $( '#subject' ).val() || 'No Subject'; |
| 106 | var reason = $( '#contact_reason' ).val(); |
| 107 | var message = $( '#message_body' ).val(); |
| 108 | |
| 109 | // Build Attachment HTML |
| 110 | var attachmentHtml = ''; |
| 111 | if ( res.data.attachments && res.data.attachments.length > 0 ) { |
| 112 | attachmentHtml = '<div class="log-attachments-container">' + |
| 113 | '<strong>Attachments:</strong> ' + res.data.attachments.join( ', ' ) + |
| 114 | '</div>'; |
| 115 | } |
| 116 | |
| 117 | var newRows = '<tr>' + |
| 118 | '<td class="log-date">' + dateStr + '</td>' + |
| 119 | '<td class="log-subject"><strong>' + subject + '</strong><br><a href="#" class="helpdocs-toggle-message">View Message</a></td>' + |
| 120 | '<td class="log-reason"><span class="log-badge">' + reason + '</span></td>' + |
| 121 | '<td class="log-user">You</td>' + |
| 122 | '</tr>' + |
| 123 | '<tr class="log-message-row" style="display: none;">' + |
| 124 | '<td colspan="4">' + |
| 125 | '<div class="log-message">' + message + '</div>' + |
| 126 | attachmentHtml + |
| 127 | '</td>' + |
| 128 | '</tr>'; |
| 129 | |
| 130 | $( '#helpdocs-logs-tbody' ).prepend( newRows ); |
| 131 | $( '#helpdocs-support-logs' ).show(); |
| 132 | $form[0].reset(); |
| 133 | updateConditionalFields(); |
| 134 | } |
| 135 | } |
| 136 | } ); |
| 137 | } ); |
| 138 | |
| 139 | |
| 140 | // Helper function to format current date in PHP-like format |
| 141 | function formatCurrentDate(phpFormat) { |
| 142 | const now = new Date(); |
| 143 | |
| 144 | const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; |
| 145 | const days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]; |
| 146 | |
| 147 | const hours = now.getHours(); |
| 148 | const minutes = now.getMinutes(); |
| 149 | const day = now.getDate(); |
| 150 | const month = now.getMonth(); |
| 151 | const year = now.getFullYear(); |
| 152 | |
| 153 | const map = { |
| 154 | // Day |
| 155 | 'd': (day < 10 ? '0' : '') + day, // Day, 2 digits with leading zeros (01-31) |
| 156 | 'j': day, // Day, no leading zeros (1-31) |
| 157 | 'S': (day % 10 == 1 && day != 11 ? 'st' : (day % 10 == 2 && day != 12 ? 'nd' : (day % 10 == 3 && day != 13 ? 'rd' : 'th'))), |
| 158 | 'l': days[now.getDay()], // Full textual representation of day (Sunday) |
| 159 | 'D': days[now.getDay()].substring(0, 3), // Short textual representation of day (Sun) |
| 160 | |
| 161 | // Month |
| 162 | 'm': (month + 1 < 10 ? '0' : '') + (month + 1), // Month, 2 digits with leading zeros (01-12) |
| 163 | 'M': months[month].substring(0, 3), // Short month (Jan) |
| 164 | 'F': months[month], // Full month (January) |
| 165 | 'n': month + 1, // Month, no leading zeros (1-12) |
| 166 | |
| 167 | // Year |
| 168 | 'Y': year, // Full year (2026) |
| 169 | 'y': year.toString().substring(2), // 2-digit year (26) |
| 170 | |
| 171 | // Time |
| 172 | 'g': (hours % 12 || 12), // 12-hour format, no leading zeros (1-12) |
| 173 | 'G': hours, // 24-hour format, no leading zeros (0-23) |
| 174 | 'h': ((hours % 12 || 12) < 10 ? '0' : '') + (hours % 12 || 12), // 12-hour, leading zeros |
| 175 | 'H': (hours < 10 ? '0' : '') + hours, // 24-hour, leading zeros |
| 176 | 'i': (minutes < 10 ? '0' : '') + minutes, // Minutes, leading zeros (00-59) |
| 177 | 's': (now.getSeconds() < 10 ? '0' : '') + now.getSeconds(), // Seconds |
| 178 | 'a': hours >= 12 ? 'pm' : 'am', // Lowercase am/pm |
| 179 | 'A': hours >= 12 ? 'PM' : 'AM' // Uppercase AM/PM |
| 180 | }; |
| 181 | |
| 182 | // Regex to find all characters in the map |
| 183 | const regex = new RegExp(Object.keys(map).join('|'), 'g'); |
| 184 | |
| 185 | return phpFormat.replace(regex, function(matched) { |
| 186 | return map[matched]; |
| 187 | }); |
| 188 | } |
| 189 | |
| 190 | |
| 191 | /** |
| 192 | * Toggle Log Message Visibility |
| 193 | */ |
| 194 | $( document ).on( 'click', '.helpdocs-toggle-message', function( e ) { |
| 195 | e.preventDefault(); |
| 196 | var $link = $( this ); |
| 197 | var $messageRow = $link.closest( 'tr' ).next( '.log-message-row' ); |
| 198 | |
| 199 | $messageRow.toggle(); |
| 200 | var label = $messageRow.is( ':visible' ) ? 'Hide Message' : 'View Message'; |
| 201 | $link.text( label ); |
| 202 | } ); |
| 203 | |
| 204 | |
| 205 | /** |
| 206 | * Clear Support Logs |
| 207 | */ |
| 208 | $( '#helpdocs-clear-logs' ).on( 'click', function( e ) { |
| 209 | e.preventDefault(); |
| 210 | |
| 211 | var $btn = $( this ); |
| 212 | var $response = $( '#helpdocs-support-response' ); |
| 213 | |
| 214 | if ( ! confirm( helpdocs_support.clear_logs_confirm ) ) { |
| 215 | return; |
| 216 | } |
| 217 | |
| 218 | // Clear previous responses and dim button |
| 219 | $response.hide().removeClass( 'success error' ); |
| 220 | $btn.prop( 'disabled', true ).css( 'opacity', '0.5' ); |
| 221 | |
| 222 | $.post( ajaxurl, { |
| 223 | action: 'helpdocs_clear_support_logs', |
| 224 | nonce: helpdocs_support.nonce, |
| 225 | }, function( res ) { |
| 226 | // Restore button state |
| 227 | $btn.prop( 'disabled', false ).css( 'opacity', '1' ); |
| 228 | |
| 229 | if ( res.success ) { |
| 230 | // UI Cleanup: Clear the table and show the "No Logs" state |
| 231 | $( '#helpdocs-logs-tbody' ).empty(); |
| 232 | $( '.helpdocs-logs-table' ).addClass( 'condition-hide' ); |
| 233 | $( '.helpdocs-no-logs' ).removeClass( 'condition-hide' ); |
| 234 | |
| 235 | // Display Success Message |
| 236 | $response.addClass( 'success' ) |
| 237 | .html( '<p>' + res.data + '</p>' ) |
| 238 | .fadeIn(); |
| 239 | |
| 240 | // Optional: Hide success message after 3 seconds |
| 241 | setTimeout( function() { $response.fadeOut(); }, 3000 ); |
| 242 | } else { |
| 243 | // Display Error Message |
| 244 | var errorMsg = res.data || 'Failed to clear support logs.'; |
| 245 | $response.addClass( 'error' ) |
| 246 | .html( '<p>' + errorMsg + '</p>' ) |
| 247 | .fadeIn(); |
| 248 | } |
| 249 | } ).fail( function() { |
| 250 | // Handle server/network errors |
| 251 | $btn.prop( 'disabled', false ).css( 'opacity', '1' ); |
| 252 | $response.addClass( 'error' ) |
| 253 | .html( '<p>' + 'A server error occurred while clearing logs.' + '</p>' ) |
| 254 | .fadeIn(); |
| 255 | } ); |
| 256 | } ); |
| 257 | } ); |