1(function($) { 2 'use strict'; 3 4 const USERSPN_ProfileProgress = { 5 init: function() { 6 this.calculateProgress(); 7 this.bindEvents(); 8 }, 9 10 bindEvents: function() { 11 // Recalculate progress when profile is updated 12 $(document).on('userspn_profile_updated', () => { 13 this.calculateProgress(); 14 }); 15 }, 16 17 calculateProgress: function() { 18 const user_id = $('.userspn-profile-wrapper').data('user-id'); 19 if (!user_id) return; 20 21 $.ajax({ 22 url: userspn_ajax.ajax_url, 23 type: 'POST', 24 data: { 25 action: 'userspn_ajax', 26 userspn_ajax_nonce: userspn_ajax.userspn_ajax_nonce, 27 userspn_ajax_type: 'userspn_profile_progress', 28 user_id: user_id 29 }, 30 success: (response) => { 31 if (response.success) { 32 this.updateProgressBar(response.data); 33 } 34 } 35 }); 36 }, 37 38 updateProgressBar: function(data) { 39 const { percentage, fields } = data; 40 41 // Update progress bar 42 $('#userspn-profile-progress-bar').css('width', percentage + '%'); 43 $('#userspn-profile-progress-percentage').text(percentage + '%'); 44 45 // Update fields list 46 const fieldsContainer = $('#userspn-profile-progress-fields'); 47 fieldsContainer.empty(); 48 49 fields.forEach(field => { 50 const fieldHtml = ` 51 <div class="field-item ${field.completed ? 'completed' : ''}"> 52 <span class="field-icon material-icons-outlined"> 53 ${field.completed ? 'check' : 'radio_button_unchecked'} 54 </span> 55 <span class="field-name">${field.name}</span> 56 <span class="field-status"> 57 ${field.completed ? userspn_i18n.completed : userspn_i18n.pending} 58 </span> 59 </div> 60 `; 61 fieldsContainer.append(fieldHtml); 62 }); 63 } 64 }; 65 66 $(document).ready(function() { 67 USERSPN_ProfileProgress.init(); 68 }); 69 70})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.