diff --git a/admin/css/wp-allstars-plugins.css b/admin/css/wp-allstars-plugins.css index 66f0f61..4376160 100644 --- a/admin/css/wp-allstars-plugins.css +++ b/admin/css/wp-allstars-plugins.css @@ -1,75 +1,70 @@ +/* Plugin Browser Styles */ +.wp-allstars-plugin-browser { + margin: 0 -16px; +} + /* Plugin List Container */ -.wp-list-table-container { - margin-top: 20px; - position: relative; - min-height: 400px; +#wpa-plugin-list { + display: flex; + flex-wrap: wrap; + margin: 0; } /* Plugin Cards */ .plugin-card { - float: left; - margin: 0 8px 16px; width: calc(50% - 16px); + margin: 8px; + background-color: #fff; border: 1px solid #dcdcde; box-sizing: border-box; - background-color: #fff; - box-shadow: 0 1px 1px rgba(0,0,0,.04); - padding: 0; + position: relative; + display: flex; + flex-direction: column; + border-radius: 3px; +} + +.plugin-card:hover { + border-color: #999; } .plugin-card-top { - padding: 20px 20px 10px; position: relative; + padding: 20px 20px 10px; min-height: 135px; } -.plugin-card .name, -.plugin-card .desc { - margin-right: 120px; +.plugin-icon { + position: absolute; + top: 20px; + left: 20px; + width: 128px; + height: 128px; + margin: 0 20px 20px 0; } -.plugin-card .name h3 { - font-size: 15px; - line-height: 1.3; +.plugin-icon img { + width: 100%; + 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; } -.plugin-card .desc { - 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 { +.action-links { position: absolute; top: 20px; right: 20px; - width: 100px; - height: 100px; -} - -.plugin-card .action-links { - position: relative; + width: 200px; } .plugin-action-buttons { @@ -80,43 +75,194 @@ text-align: right; } -.plugin-action-buttons .button { - margin-right: 5px; +.plugin-action-buttons li { + 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; - 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 */ -.wpa-plugin-filters { - margin: 20px 0; - padding: 12px 15px; - background: #fff; - border: 1px solid #c3c4c7; - border-radius: 4px; +.wp-filter { display: flex; 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; } +.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 */ -.wpa-loading-overlay { +.wp-allstars-loading-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; - background: rgba(255, 255, 255, 0.8); - z-index: 10; + background-color: rgba(255, 255, 255, 0.7); display: flex; - align-items: 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 */ @@ -127,53 +273,66 @@ position: relative; width: 30.6%; 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; } +.theme-browser .theme:nth-child(3n) { + margin-right: 0; +} + .theme-browser .theme .theme-screenshot { display: block; overflow: hidden; 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 { - display: block; - width: 100%; height: auto; + position: absolute; + left: 0; + top: 0; + width: 100%; + transition: opacity 0.2s ease-in-out; } .theme-browser .theme .theme-name { font-size: 15px; font-weight: 600; - height: 48px; + height: 18px; margin: 0; 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; white-space: nowrap; text-overflow: ellipsis; - background: #f6f7f7; - position: relative; + background: #fff; + background: rgba(255, 255, 255, 0.65); } .theme-browser .theme .theme-actions { position: absolute; top: 50%; transform: translateY(-50%); - left: 0; right: 0; - bottom: auto; - height: auto; + padding: 10px 15px; + 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; - align-items: center; + flex-direction: column; justify-content: center; - gap: 5px; - background: rgba(255, 255, 255, 0.9); - padding: 20px 0; opacity: 0; - transition: opacity .1s ease-in-out; + transition: opacity 0.1s ease-in-out; } .theme-browser .theme:hover .theme-actions { @@ -181,23 +340,99 @@ } .theme-browser .theme .theme-actions .button { - margin: 0; + margin-top: 5px; +} + +.theme-browser .theme .theme-actions .button:first-child { + margin-top: 0; } /* Responsive Adjustments */ -@media screen and (max-width: 1100px) { +@media only screen and (max-width: 1120px) { .plugin-card { - width: calc(100% - 16px); + width: 100%; } .theme-browser .theme { 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 { width: 100%; 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; + } } \ No newline at end of file diff --git a/admin/js/wp-allstars-admin.js b/admin/js/wp-allstars-admin.js index 7ca3167..bb341dc 100644 --- a/admin/js/wp-allstars-admin.js +++ b/admin/js/wp-allstars-admin.js @@ -42,237 +42,312 @@ jQuery(document).ready(function($) { }); } - // Initialize all toggle switches - function initToggleSwitches() { - // Handle toggle switch clicks - $('.wp-toggle-switch').on('click', function(e) { - e.stopPropagation(); - var $checkbox = $(this).find('input[type="checkbox"]'); - var isChecked = $checkbox.is(':checked'); - $checkbox.prop('checked', !isChecked).trigger('change'); - }); - - // Prevent label clicks from triggering the toggle - $('.wp-setting-label, .wp-allstars-toggle label').on('click', function(e) { - e.stopPropagation(); - return false; - }); - - // Handle checkbox changes - $('.wp-toggle-switch input[type="checkbox"]').on('change', 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'); + // Toggle settings panel + $('.wp-allstars-toggle-switch').on('click', function(e) { + e.stopPropagation(); + $(this).closest('.wp-allstars-toggle-main').find('.wp-allstars-toggle-settings').slideToggle(200); + $(this).closest('.wp-allstars-toggle-main').toggleClass('expanded'); }); - // 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 click on the main toggle area (but not on the switch itself) + $('.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(); + }); + + // Initialize tabs + $('.nav-tab-wrapper .nav-tab').on('click', function(e) { + e.preventDefault(); + var target = $(this).data('tab'); - // Handle category filter clicks - $('.wpa-plugin-filters a').on('click', function(e) { + // Update active tab + $('.nav-tab-wrapper .nav-tab').removeClass('nav-tab-active'); + $(this).addClass('nav-tab-active'); + + // Show target tab content + $('.tab-content').hide(); + $('#' + 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 = new URLSearchParams($(this).attr('href').split('?')[1]).get('category'); + 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); - - // Update URL without page reload - var newUrl = $(this).attr('href'); - history.pushState({}, '', newUrl); - - // Update active state - $('.wpa-plugin-filters a').removeClass('button-primary'); - $(this).addClass('button-primary'); }); - } - - // Function to load plugins - function loadPlugins(category) { - // Show loading overlay - $('.wpa-loading-overlay').fadeIn(); - // Log the nonce for debugging - console.log('Using nonce:', wpAllstars.nonce); - - $.ajax({ - url: ajaxurl, - type: 'GET', - data: { - action: 'wp_allstars_get_plugins', - category: category || 'minimal', - _wpnonce: wpAllstars.nonce - }, - success: function(response) { - if (response.success) { - $('#wpa-plugin-list').html(response.data); - } else { - console.error('Server returned error:', response); - $('#wpa-plugin-list').html('
Failed to load plugins: ' + (response.data || 'Unknown error') + '
Failed to load plugins. Please try again. Error: ' + error + '
Failed to load theme: ' + (response.data || 'Unknown error') + '
' + response.data + '
Failed to load theme. Please try again. Error: ' + error + '
Failed to load plugins. Please try again. Error: ' + error + '
' + response.data + '
Failed to load themes. Please try again. Error: ' + error + '
short_description); ?>
-short_description); ?>
+ +