Update plugin browser to match standard WordPress interface

This commit is contained in:
Marcus Quinn
2025-03-16 04:19:56 +00:00
parent abf39b1131
commit e23129602c
3 changed files with 602 additions and 279 deletions

View File

@ -1,75 +1,70 @@
/* Plugin Browser Styles */
.wp-allstars-plugin-browser {
margin: 0 -16px;
}
/* Plugin List Container */ /* Plugin List Container */
.wp-list-table-container { #wpa-plugin-list {
margin-top: 20px; display: flex;
position: relative; flex-wrap: wrap;
min-height: 400px; margin: 0;
} }
/* Plugin Cards */ /* Plugin Cards */
.plugin-card { .plugin-card {
float: left;
margin: 0 8px 16px;
width: calc(50% - 16px); width: calc(50% - 16px);
margin: 8px;
background-color: #fff;
border: 1px solid #dcdcde; border: 1px solid #dcdcde;
box-sizing: border-box; box-sizing: border-box;
background-color: #fff; position: relative;
box-shadow: 0 1px 1px rgba(0,0,0,.04); display: flex;
padding: 0; flex-direction: column;
border-radius: 3px;
}
.plugin-card:hover {
border-color: #999;
} }
.plugin-card-top { .plugin-card-top {
padding: 20px 20px 10px;
position: relative; position: relative;
padding: 20px 20px 10px;
min-height: 135px; min-height: 135px;
} }
.plugin-card .name, .plugin-icon {
.plugin-card .desc { position: absolute;
margin-right: 120px; top: 20px;
left: 20px;
width: 128px;
height: 128px;
margin: 0 20px 20px 0;
} }
.plugin-card .name h3 { .plugin-icon img {
font-size: 15px; width: 100%;
line-height: 1.3; height: 100%;
max-width: 128px;
max-height: 128px;
}
.name.column-name {
margin-right: 200px;
margin-left: 148px;
}
.name.column-name h3 {
font-size: 1.3em;
line-height: 1.4;
margin: 0 0 12px; margin: 0 0 12px;
} }
.plugin-card .desc { .action-links {
color: #646970;
font-size: 13px;
line-height: 1.5;
margin: 0 0 10px;
}
.plugin-card .plugin-card-bottom {
clear: both;
padding: 12px 20px;
background-color: #f6f7f7;
border-top: 1px solid #dcdcde;
overflow: hidden;
}
.plugin-card .column-rating {
line-height: 23px;
}
.plugin-card .column-updated,
.plugin-card .column-downloaded {
text-align: right;
color: #646970;
font-size: 13px;
}
.plugin-card .plugin-icon {
position: absolute; position: absolute;
top: 20px; top: 20px;
right: 20px; right: 20px;
width: 100px; width: 200px;
height: 100px;
}
.plugin-card .action-links {
position: relative;
} }
.plugin-action-buttons { .plugin-action-buttons {
@ -80,43 +75,194 @@
text-align: right; text-align: right;
} }
.plugin-action-buttons .button { .plugin-action-buttons li {
margin-right: 5px; margin-bottom: 10px;
} }
.plugin-card-bottom .star-rating { .plugin-card-bottom {
clear: both;
padding: 12px 20px;
background-color: #f6f7f7;
overflow: hidden;
border-top: 1px solid #dcdcde;
display: flex;
flex-wrap: wrap;
}
.plugin-card-bottom > div {
margin-bottom: 0;
flex: 1 0 auto;
padding-bottom: 0;
}
.column-rating {
line-height: 23px;
}
.column-downloaded,
.column-updated,
.column-compatibility {
text-align: right;
color: #50575e;
font-size: 13px;
}
.column-compatibility span {
font-style: italic;
}
.compatibility-compatible {
color: #00a32a;
}
.compatibility-incompatible {
color: #d63638;
}
.compatibility-untested {
color: #dba617;
}
.desc.column-description {
margin-left: 148px;
margin-right: 120px;
}
.desc.column-description p {
font-size: 13px;
line-height: 1.5;
margin: 0 0 10px;
}
.desc.column-description p.authors {
color: #50575e;
font-size: 13px;
margin-top: 0;
}
.star-rating {
display: inline-block; display: inline-block;
vertical-align: middle; position: relative;
height: 20px;
width: 100px;
font-size: 20px;
}
.star-rating .star {
width: 20px;
height: 20px;
display: inline-block;
background-image: url(../images/stars.png);
background-repeat: no-repeat;
}
.star-rating .star-full {
background-position: 0 0;
}
.star-rating .star-half {
background-position: -20px 0;
}
.star-rating .star-empty {
background-position: -40px 0;
}
.num-ratings {
font-size: 13px;
color: #50575e;
} }
/* Plugin Filters */ /* Plugin Filters */
.wpa-plugin-filters { .wp-filter {
margin: 20px 0;
padding: 12px 15px;
background: #fff;
border: 1px solid #c3c4c7;
border-radius: 4px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 8px; margin: 12px 0 25px;
padding: 0 10px;
background: #fff;
border: 1px solid #dcdcde;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
position: relative;
box-sizing: border-box;
width: 100%;
border-radius: 3px;
} }
.wpa-plugin-filters a { .filter-links {
display: flex;
flex-wrap: wrap;
margin: 0; margin: 0;
} }
.filter-links li {
margin: 0;
padding: 0;
display: inline-block;
}
.filter-links li > a {
display: inline-block;
margin: 0;
padding: 15px 10px;
cursor: pointer;
color: #646970;
text-decoration: none;
border-bottom: 4px solid transparent;
box-sizing: border-box;
}
.filter-links li > a:hover,
.filter-links li > a:focus {
color: #2271b1;
}
.filter-links .current {
box-shadow: none;
border-bottom: 4px solid #2271b1;
color: #1d2327;
}
.filter-count {
display: inline-block;
vertical-align: middle;
min-width: 10px;
padding: 2px 5px;
font-size: 10px;
font-weight: 600;
line-height: 1;
color: #fff;
background-color: #d63638;
border-radius: 10px;
z-index: 26;
margin-left: 5px;
}
/* Loading Overlay */ /* Loading Overlay */
.wpa-loading-overlay { .wp-allstars-loading-overlay {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background: rgba(255, 255, 255, 0.8); background-color: rgba(255, 255, 255, 0.7);
z-index: 10;
display: flex; display: flex;
align-items: center;
justify-content: center; justify-content: center;
align-items: center;
z-index: 100;
}
.wp-allstars-loading-spinner {
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
} }
/* Theme Browser */ /* Theme Browser */
@ -127,53 +273,66 @@
position: relative; position: relative;
width: 30.6%; width: 30.6%;
border: 1px solid #dcdcde; border: 1px solid #dcdcde;
box-shadow: 0 1px 1px rgba(0,0,0,.04); box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.1);
box-sizing: border-box; box-sizing: border-box;
} }
.theme-browser .theme:nth-child(3n) {
margin-right: 0;
}
.theme-browser .theme .theme-screenshot { .theme-browser .theme .theme-screenshot {
display: block; display: block;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
background: #fff; transition: opacity 0.2s ease-in-out;
}
.theme-browser .theme .theme-screenshot:after {
content: "";
display: block;
padding-top: 66.66666%;
} }
.theme-browser .theme .theme-screenshot img { .theme-browser .theme .theme-screenshot img {
display: block;
width: 100%;
height: auto; height: auto;
position: absolute;
left: 0;
top: 0;
width: 100%;
transition: opacity 0.2s ease-in-out;
} }
.theme-browser .theme .theme-name { .theme-browser .theme .theme-name {
font-size: 15px; font-size: 15px;
font-weight: 600; font-weight: 600;
height: 48px; height: 18px;
margin: 0; margin: 0;
padding: 15px; padding: 15px;
box-shadow: inset 0 1px 0 rgba(0,0,0,.1); box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1);
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
background: #f6f7f7; background: #fff;
position: relative; background: rgba(255, 255, 255, 0.65);
} }
.theme-browser .theme .theme-actions { .theme-browser .theme .theme-actions {
position: absolute; position: absolute;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
left: 0;
right: 0; right: 0;
bottom: auto; padding: 10px 15px;
height: auto; box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1);
background: rgba(244, 244, 244, 0.7);
border-left: 1px solid rgba(0, 0, 0, 0.05);
height: 100%;
box-sizing: border-box;
display: flex; display: flex;
align-items: center; flex-direction: column;
justify-content: center; justify-content: center;
gap: 5px;
background: rgba(255, 255, 255, 0.9);
padding: 20px 0;
opacity: 0; opacity: 0;
transition: opacity .1s ease-in-out; transition: opacity 0.1s ease-in-out;
} }
.theme-browser .theme:hover .theme-actions { .theme-browser .theme:hover .theme-actions {
@ -181,23 +340,99 @@
} }
.theme-browser .theme .theme-actions .button { .theme-browser .theme .theme-actions .button {
margin: 0; margin-top: 5px;
}
.theme-browser .theme .theme-actions .button:first-child {
margin-top: 0;
} }
/* Responsive Adjustments */ /* Responsive Adjustments */
@media screen and (max-width: 1100px) { @media only screen and (max-width: 1120px) {
.plugin-card { .plugin-card {
width: calc(100% - 16px); width: 100%;
} }
.theme-browser .theme { .theme-browser .theme {
width: 47%; width: 47%;
margin-right: 6%;
}
.theme-browser .theme:nth-child(3n) {
margin-right: 6%;
}
.theme-browser .theme:nth-child(2n) {
margin-right: 0;
} }
} }
@media screen and (max-width: 782px) { @media only screen and (max-width: 782px) {
.plugin-card-top {
min-height: 155px;
}
.name.column-name {
margin-right: 0;
}
.action-links {
position: static;
margin-left: 148px;
width: auto;
}
.plugin-action-buttons {
float: none;
margin: 1em 0 0;
text-align: left;
}
.plugin-action-buttons li {
display: inline-block;
margin-right: 10px;
}
.plugin-card-bottom {
flex-direction: column;
}
.plugin-card-bottom > div {
padding-top: 10px;
padding-bottom: 10px;
border-top: 1px solid #dcdcde;
}
.plugin-card-bottom > div:first-child {
border-top: none;
}
.column-downloaded,
.column-updated,
.column-compatibility {
text-align: left;
}
}
@media only screen and (max-width: 480px) {
.theme-browser .theme { .theme-browser .theme {
width: 100%; width: 100%;
margin-right: 0; margin-right: 0;
} }
.plugin-card-top {
padding-top: 146px;
}
.plugin-icon {
top: 20px;
left: 50%;
transform: translateX(-50%);
}
.name.column-name,
.desc.column-description,
.action-links {
margin-left: 0;
}
} }

View File

@ -42,237 +42,312 @@ jQuery(document).ready(function($) {
}); });
} }
// Initialize all toggle switches // Toggle settings panel
function initToggleSwitches() { $('.wp-allstars-toggle-switch').on('click', function(e) {
// Handle toggle switch clicks
$('.wp-toggle-switch').on('click', function(e) {
e.stopPropagation(); e.stopPropagation();
var $checkbox = $(this).find('input[type="checkbox"]'); $(this).closest('.wp-allstars-toggle-main').find('.wp-allstars-toggle-settings').slideToggle(200);
var isChecked = $checkbox.is(':checked'); $(this).closest('.wp-allstars-toggle-main').toggleClass('expanded');
$checkbox.prop('checked', !isChecked).trigger('change');
}); });
// Prevent label clicks from triggering the toggle // Handle click on the main toggle area (but not on the switch itself)
$('.wp-setting-label, .wp-allstars-toggle label').on('click', function(e) { $('.wp-allstars-toggle-main').on('click', function(e) {
if (!$(e.target).hasClass('wp-allstars-toggle-switch') &&
!$(e.target).closest('.wp-allstars-toggle-switch').length &&
!$(e.target).closest('.wp-allstars-toggle-label').length) {
$(this).find('.wp-allstars-toggle-settings').slideToggle(200);
$(this).toggleClass('expanded');
}
});
// Prevent toggle when clicking on the label
$('.wp-allstars-toggle-label').on('click', function(e) {
e.stopPropagation(); e.stopPropagation();
return false;
}); });
// Handle checkbox changes // Initialize tabs
$('.wp-toggle-switch input[type="checkbox"]').on('change', function(e) { $('.nav-tab-wrapper .nav-tab').on('click', function(e) {
e.stopPropagation();
var $input = $(this);
var option = $input.attr('name');
var value = $input.is(':checked') ? 1 : 0;
var $label = $input.closest('.wp-setting-left, .wp-allstars-toggle-left').find('label');
updateOption(option, value)
.then(function() {
showNotification('Saved', $label);
})
.catch(function() {
showNotification('Error saving settings', $label, true);
});
});
}
// Initialize expandable panels
function initExpandablePanels() {
// Handle panel toggle
$('.wp-allstars-toggle-header').on('click', function(e) {
if (!$(e.target).closest('.wp-toggle-switch').length) {
var $settings = $(this).closest('.wp-allstars-toggle').find('.wp-allstars-toggle-settings');
var isExpanded = $(this).attr('aria-expanded') === 'true';
$(this).attr('aria-expanded', !isExpanded);
$settings.slideToggle();
}
});
// Set initial panel states
$('.wp-allstars-toggle-header').each(function() {
var $settings = $(this).closest('.wp-allstars-toggle').find('.wp-allstars-toggle-settings');
var isExpanded = $(this).attr('aria-expanded') === 'true';
if (!isExpanded) {
$settings.hide();
}
});
}
// Initialize text inputs
function initTextInputs() {
$('.wp-allstars-setting-row input[type="text"], .wp-allstars-setting-row input[type="number"], .wp-allstars-setting-row textarea').on('change', function() {
var $input = $(this);
var option = $input.attr('name');
var value = $input.val();
var $label = $input.closest('.wp-allstars-setting-row').find('label').first();
updateOption(option, value)
.then(function() {
showNotification('Saved', $label);
})
.catch(function(error) {
console.error('Error:', error);
showNotification('Error saving setting', $label, true);
});
});
}
// Initialize all components
initToggleSwitches();
initExpandablePanels();
initTextInputs();
// Handle form submission
$('form').on('submit', function() {
showNotification('Saved');
});
// Load plugins on page load
if ($('#wpa-plugin-list').length) {
var urlParams = new URLSearchParams(window.location.search);
var currentCategory = urlParams.get('category') || 'minimal';
loadPlugins(currentCategory);
// Handle category filter clicks
$('.wpa-plugin-filters a').on('click', function(e) {
e.preventDefault(); e.preventDefault();
var category = new URLSearchParams($(this).attr('href').split('?')[1]).get('category'); var target = $(this).data('tab');
loadPlugins(category);
// Update URL without page reload // Update active tab
var newUrl = $(this).attr('href'); $('.nav-tab-wrapper .nav-tab').removeClass('nav-tab-active');
history.pushState({}, '', newUrl); $(this).addClass('nav-tab-active');
// Update active state // Show target tab content
$('.wpa-plugin-filters a').removeClass('button-primary'); $('.tab-content').hide();
$(this).addClass('button-primary'); $('#' + target).show();
// Update URL hash
window.location.hash = target;
// Load plugins if needed
if (target === 'recommended' && $('#wpa-plugin-list').length && $('#wpa-plugin-list').is(':empty')) {
loadPlugins('all');
}
// Load themes if needed
if (target === 'theme' && $('#wpa-theme-list').length && $('#wpa-theme-list').is(':empty')) {
loadTheme();
}
}); });
// Initialize based on hash
if (window.location.hash) {
var hash = window.location.hash.substring(1);
$('.nav-tab-wrapper .nav-tab[data-tab="' + hash + '"]').trigger('click');
} else {
$('.nav-tab-wrapper .nav-tab:first').trigger('click');
}
// Plugin category filters
if ($('#wpa-plugin-filters').length) {
$('#wpa-plugin-filters a').on('click', function(e) {
e.preventDefault();
var category = $(this).data('category');
// Update active filter
$('#wpa-plugin-filters a').removeClass('current');
$(this).addClass('current');
// Load plugins for the selected category
loadPlugins(category);
});
// Load initial plugins if we're on the recommended tab
if ($('#recommended').is(':visible') && $('#wpa-plugin-list').is(':empty')) {
loadPlugins('all');
}
}
// Load theme tab content if we're on the theme tab
if ($('#theme').is(':visible') && $('#wpa-theme-list').length && $('#wpa-theme-list').is(':empty')) {
loadTheme();
} }
// Function to load plugins // Function to load plugins
function loadPlugins(category) { function loadPlugins(category) {
var $container = $('#wpa-plugin-list');
var $loadingOverlay = $('<div class="wp-allstars-loading-overlay"><div class="wp-allstars-loading-spinner"></div></div>');
// Show loading overlay // Show loading overlay
$('.wpa-loading-overlay').fadeIn(); $container.css('position', 'relative').append($loadingOverlay);
// Log the nonce for debugging // Clear existing plugins
console.log('Using nonce:', wpAllstars.nonce); $container.empty().append($loadingOverlay);
// AJAX request to get plugins
$.ajax({ $.ajax({
url: ajaxurl, url: ajaxurl,
type: 'GET', type: 'POST',
data: { data: {
action: 'wp_allstars_get_plugins', action: 'wp_allstars_get_plugins',
category: category || 'minimal', category: category,
_wpnonce: wpAllstars.nonce _wpnonce: wpAllstars.nonce
}, },
success: function(response) { success: function(response) {
// Remove loading overlay
$loadingOverlay.remove();
if (response.success) { if (response.success) {
$('#wpa-plugin-list').html(response.data); // Append plugins HTML
$container.html(response.data);
// Initialize plugin action buttons
initPluginActions();
} else { } else {
console.error('Server returned error:', response); // Show error message
$('#wpa-plugin-list').html('<div class="notice notice-error"><p>Failed to load plugins: ' + (response.data || 'Unknown error') + '</p></div>'); $container.html('<div class="notice notice-error"><p>' + response.data + '</p></div>');
} }
$('.wpa-loading-overlay').fadeOut();
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
console.error('Failed to load plugins:', {xhr: xhr, status: status, error: error}); // Remove loading overlay
$('#wpa-plugin-list').html('<div class="notice notice-error"><p>Failed to load plugins. Please try again. Error: ' + error + '</p></div>'); $loadingOverlay.remove();
$('.wpa-loading-overlay').fadeOut();
// Show error message
$container.html('<div class="notice notice-error"><p>Failed to load plugins. Please try again. Error: ' + error + '</p></div>');
console.error('AJAX Error:', xhr.responseText);
} }
}); });
} }
// Load theme on page load // Function to load themes
if ($('#wpa-theme-list').length) {
loadTheme();
}
// Function to load theme
function loadTheme() { function loadTheme() {
// Show loading overlay var $container = $('#wpa-theme-list');
$('.wpa-loading-overlay').fadeIn(); var $loadingOverlay = $('<div class="wp-allstars-loading-overlay"><div class="wp-allstars-loading-spinner"></div></div>');
// Show loading overlay
$container.css('position', 'relative').append($loadingOverlay);
// Clear existing themes
$container.empty().append($loadingOverlay);
// AJAX request to get themes
$.ajax({ $.ajax({
url: ajaxurl, url: ajaxurl,
type: 'GET', type: 'POST',
data: { data: {
action: 'wp_allstars_get_theme', action: 'wp_allstars_get_themes',
_wpnonce: wpAllstars.nonce _wpnonce: wpAllstars.nonce
}, },
success: function(response) { success: function(response) {
// Remove loading overlay
$loadingOverlay.remove();
if (response.success) { if (response.success) {
$('#wpa-theme-list').html(response.data); // Append themes HTML
$container.html(response.data);
// Initialize theme action buttons
initThemeHandlers(); initThemeHandlers();
} else { } else {
console.error('Server returned error:', response); // Show error message
$('#wpa-theme-list').html('<div class="notice notice-error"><p>Failed to load theme: ' + (response.data || 'Unknown error') + '</p></div>'); $container.html('<div class="notice notice-error"><p>' + response.data + '</p></div>');
} }
$('.wpa-loading-overlay').fadeOut();
}, },
error: function(xhr, status, error) { error: function(xhr, status, error) {
console.error('Failed to load theme:', {xhr: xhr, status: status, error: error}); // Remove loading overlay
$('#wpa-theme-list').html('<div class="notice notice-error"><p>Failed to load theme. Please try again. Error: ' + error + '</p></div>'); $loadingOverlay.remove();
$('.wpa-loading-overlay').fadeOut();
// Show error message
$container.html('<div class="notice notice-error"><p>Failed to load themes. Please try again. Error: ' + error + '</p></div>');
console.error('AJAX Error:', xhr.responseText);
} }
}); });
} }
// Initialize plugin action buttons
function initPluginActions() {
// Install plugin
$('.plugin-card .install-now').on('click', function(e) {
e.preventDefault();
var $button = $(this);
var slug = $button.data('slug');
$button.addClass('updating-message').text('Installing...');
wp.updates.installPlugin({
slug: slug,
success: function(response) {
$button.removeClass('updating-message').addClass('updated-message').text('Installed!');
setTimeout(function() {
$button.removeClass('updated-message install-now')
.addClass('activate-now')
.text('Activate')
.attr('href', response.activateUrl);
}, 1000);
},
error: function(response) {
$button.removeClass('updating-message').text('Install Now');
alert(response.errorMessage);
}
});
});
// Update plugin
$('.plugin-card .update-now').on('click', function(e) {
e.preventDefault();
var $button = $(this);
var slug = $button.data('slug');
$button.addClass('updating-message').text('Updating...');
wp.updates.updatePlugin({
slug: slug,
success: function() {
$button.removeClass('updating-message').addClass('updated-message').text('Updated!');
setTimeout(function() {
$button.removeClass('update-now updated-message')
.addClass('button-disabled')
.text('Active');
}, 1000);
},
error: function(response) {
$button.removeClass('updating-message').text('Update Now');
alert(response.errorMessage);
}
});
});
// Activate plugin
$('.plugin-card .activate-now').on('click', function(e) {
e.preventDefault();
var $button = $(this);
var url = $button.attr('href');
$button.addClass('updating-message').text('Activating...');
$.ajax({
url: url,
dataType: 'html',
success: function() {
$button.removeClass('updating-message').addClass('updated-message').text('Activated!');
setTimeout(function() {
$button.removeClass('activate-now updated-message')
.addClass('button-disabled')
.text('Active');
}, 1000);
},
error: function() {
$button.removeClass('updating-message').text('Activate');
alert('Failed to activate plugin. Please try again or activate from the Plugins page.');
}
});
});
}
// Initialize theme handlers // Initialize theme handlers
function initThemeHandlers() { function initThemeHandlers() {
// Handle theme installation // Install theme
$('.install-theme').on('click', function() { $('.theme-browser .theme-actions .install-now').on('click', function(e) {
var slug = $(this).data('slug'); e.preventDefault();
var $button = $(this); var $button = $(this);
var slug = $button.data('slug');
var $themeCard = $button.closest('.theme');
$button.text('Installing...').prop('disabled', true); $button.addClass('updating-message').text('Installing...');
wp.updates.installTheme({ wp.updates.installTheme({
slug: slug, slug: slug,
success: function(response) { success: function(response) {
$button.text('Activate').removeClass('install-theme').addClass('activate-theme'); $button.removeClass('updating-message').addClass('updated-message').text('Installed!');
$button.prop('disabled', false); setTimeout(function() {
$button.removeClass('updated-message install-now')
.addClass('activate-now')
.text('Activate')
.attr('href', response.activateUrl);
}, 1000);
}, },
error: function(response) { error: function(response) {
$button.text('Error').prop('disabled', false); $button.removeClass('updating-message').text('Install Now');
console.error('Theme installation error:', response); alert(response.errorMessage);
} }
}); });
}); });
// Handle theme activation // Activate theme
$('.activate-theme').on('click', function() { $('.theme-browser .theme-actions .activate-now').on('click', function(e) {
var slug = $(this).data('slug'); e.preventDefault();
var $button = $(this); var $button = $(this);
var url = $button.attr('href');
$button.text('Activating...').prop('disabled', true); $button.addClass('updating-message').text('Activating...');
$.ajax({ $.ajax({
url: ajaxurl, url: url,
type: 'POST', dataType: 'html',
data: { success: function() {
action: 'wp_allstars_activate_theme', $button.removeClass('updating-message').addClass('updated-message').text('Activated!');
theme: slug,
_wpnonce: wpAllstars.nonce
},
success: function(response) {
if (response.success) {
$button.text('Activated').prop('disabled', true);
// Optionally redirect to customizer
if (response.data && response.data.customize_url) {
setTimeout(function() { setTimeout(function() {
window.location.href = response.data.customize_url; $('.theme-browser .theme').removeClass('active');
$button.closest('.theme').addClass('active');
$button.removeClass('activate-now updated-message')
.addClass('button-disabled')
.text('Active');
}, 1000); }, 1000);
}
} else {
$button.text('Error').prop('disabled', false);
console.error('Theme activation error:', response);
}
}, },
error: function(xhr, status, error) { error: function() {
$button.text('Error').prop('disabled', false); $button.removeClass('updating-message').text('Activate');
console.error('Theme activation AJAX error:', error); alert('Failed to activate theme. Please try again or activate from the Themes page.');
} }
}); });
}); });

View File

@ -318,9 +318,8 @@ function wp_allstars_generate_plugin_cards($plugins) {
<div class="plugin-card-top"> <div class="plugin-card-top">
<div class="name column-name"> <div class="name column-name">
<h3> <h3>
<a href="<?php echo esc_url($plugin->homepage); ?>" target="_blank">
<?php echo esc_html($plugin->name); ?> <?php echo esc_html($plugin->name); ?>
</a> <img src="<?php echo esc_url(admin_url('images/spinner.gif')); ?>" class="plugin-spinner spinner" alt="">
</h3> </h3>
</div> </div>
<div class="action-links"> <div class="action-links">
@ -355,14 +354,17 @@ function wp_allstars_generate_plugin_cards($plugins) {
?> ?>
</ul> </ul>
</div> </div>
<div class="desc column-description">
<p><?php echo esc_html($plugin->short_description); ?></p>
</div>
<?php if (!empty($plugin->icons) && !empty($plugin->icons['1x'])): ?> <?php if (!empty($plugin->icons) && !empty($plugin->icons['1x'])): ?>
<div class="plugin-icon"> <div class="plugin-icon">
<img src="<?php echo esc_url($plugin->icons['1x']); ?>" alt=""> <img src="<?php echo esc_url($plugin->icons['1x']); ?>" alt="">
</div> </div>
<?php endif; ?> <?php endif; ?>
<div class="desc column-description">
<p><?php echo esc_html($plugin->short_description); ?></p>
<p class="authors">
<cite><?php printf(__('By %s'), $plugin->author); ?></cite>
</p>
</div>
</div> </div>
<div class="plugin-card-bottom"> <div class="plugin-card-bottom">
<div class="vers column-rating"> <div class="vers column-rating">
@ -376,6 +378,17 @@ function wp_allstars_generate_plugin_cards($plugins) {
<div class="column-downloaded"> <div class="column-downloaded">
<?php echo sprintf(_n('%s download', '%s downloads', $plugin->downloaded), number_format_i18n($plugin->downloaded)); ?> <?php echo sprintf(_n('%s download', '%s downloads', $plugin->downloaded), number_format_i18n($plugin->downloaded)); ?>
</div> </div>
<div class="column-compatibility">
<?php
if (!empty($plugin->tested) && version_compare(substr($GLOBALS['wp_version'], 0, strlen($plugin->tested)), $plugin->tested, '>')) {
echo '<span class="compatibility-untested">' . __('Untested with your version of WordPress') . '</span>';
} elseif (!empty($plugin->requires) && version_compare($GLOBALS['wp_version'], $plugin->requires, '<')) {
echo '<span class="compatibility-incompatible">' . __('Incompatible with your version of WordPress') . '</span>';
} else {
echo '<span class="compatibility-compatible">' . __('Compatible with your version of WordPress') . '</span>';
}
?>
</div>
</div> </div>
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>