refactor: Improve access control settings UI and functionality - Fix double notification issue when toggling feature - Improve AJAX handling with better error handling - Create consistent component design for role checkboxes - Improve notification display and positioning - Enhance toggle component with better header/content styling - Add responsive design for all screen sizes - Ensure expansion/collapse works correctly

This commit is contained in:
Marcus Quinn
2025-03-25 17:29:08 +00:00
parent e794126197
commit bd3a19b04a
2 changed files with 174 additions and 48 deletions

View File

@ -747,38 +747,35 @@ input:checked + .wp-toggle-slider:before {
.wp-allstars-toggle-left label, .wp-allstars-toggle-left label,
.wp-allstars-setting-row label { .wp-allstars-setting-row label {
position: relative; position: relative;
padding-right: 80px; /* Increased padding to accommodate notification */ padding-right: 20px;
display: inline-block; display: inline-block;
min-width: 200px; /* Ensure minimum width for labels */
} }
/* Ensure toggle switches don't wrap with notifications */ .wp-setting-left label .wp-setting-notification,
.wp-allstars-toggle-left { .wp-allstars-toggle-left label .wp-setting-notification,
display: flex; .wp-allstars-setting-row label .wp-setting-notification {
align-items: center; position: absolute;
flex-wrap: nowrap; right: -60px;
gap: 10px; top: -5px;
transform: translateY(0);
line-height: 1.4;
} }
.wp-allstars-toggle-left label { /* Role Checkboxes - Consistent component design */
flex: 1;
margin: 0;
padding-right: 80px;
}
/* Role Checkboxes */
.wp-allstars-role-checkboxes { .wp-allstars-role-checkboxes {
display: grid; display: flex;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); flex-wrap: wrap;
gap: 10px; gap: 10px;
margin-top: 10px; margin-top: 10px;
} }
.wp-allstars-role-checkbox { .wp-allstars-role-checkbox {
flex: 0 0 calc(33.333% - 10px);
max-width: calc(33.333% - 10px);
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
padding: 8px; padding: 8px 10px;
background: #f8f9fa; background: #f8f9fa;
border: 1px solid #ddd; border: 1px solid #ddd;
border-radius: 4px; border-radius: 4px;
@ -800,15 +797,19 @@ input:checked + .wp-toggle-slider:before {
color: #50575e; color: #50575e;
} }
/* Responsive adjustments for role checkboxes */ /* Responsive adjustments */
@media screen and (max-width: 782px) { @media screen and (max-width: 992px) {
.wp-allstars-role-checkboxes { .wp-allstars-role-checkbox {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); flex: 0 0 calc(50% - 10px);
gap: 8px; max-width: calc(50% - 10px);
}
} }
@media screen and (max-width: 782px) {
.wp-allstars-role-checkbox { .wp-allstars-role-checkbox {
padding: 6px; flex: 0 0 calc(50% - 8px);
max-width: calc(50% - 8px);
padding: 6px 8px;
} }
.wp-allstars-role-checkbox span { .wp-allstars-role-checkbox span {
@ -816,6 +817,49 @@ input:checked + .wp-toggle-slider:before {
} }
} }
@media screen and (max-width: 480px) {
.wp-allstars-role-checkbox {
flex: 0 0 100%;
max-width: 100%;
}
}
/* Enhanced toggle component */
.wp-allstars-toggle {
position: relative;
overflow: hidden;
}
.wp-allstars-toggle-header[aria-expanded="true"] {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
/* Better settings panel styling */
.wp-allstars-toggle-settings {
padding: 20px;
background: #f8f9fa;
border-top: 1px solid #ddd;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
.wp-allstars-setting-row {
margin-bottom: 20px;
}
.wp-allstars-setting-row:last-child {
margin-bottom: 0;
}
.wp-allstars-setting-row label {
display: block;
margin-bottom: 8px;
font-size: 14px;
font-weight: 600;
color: #1d2327;
}
@keyframes fadeIn { @keyframes fadeIn {
from { opacity: 0; } from { opacity: 0; }
to { opacity: 1; } to { opacity: 1; }

View File

@ -62,6 +62,9 @@ class WP_Allstars_Access_Manager {
var setting = $this.attr("id"); var setting = $this.attr("id");
var value = $this.is(":checked"); var value = $this.is(":checked");
// Clear any existing notifications
$(".wp-setting-notification").remove();
$.ajax({ $.ajax({
url: ajaxurl, url: ajaxurl,
type: "POST", type: "POST",
@ -74,12 +77,42 @@ class WP_Allstars_Access_Manager {
success: function(response) { success: function(response) {
if (response.success) { if (response.success) {
showSavedNotification($this); showSavedNotification($this);
// Update UI based on toggle state
var $container = $this.closest(".wp-allstars-toggle");
var $settingsArea = $container.find(".wp-allstars-toggle-settings");
var $header = $container.find(".wp-allstars-toggle-header");
if (value) {
// Set default roles (subscriber, customer) as checked when enabled
$settingsArea.find("input[value=\'subscriber\'], input[value=\'customer\']").prop("checked", true);
// Expand the section if it was toggled on
if ($header.attr("aria-expanded") === "false") {
$header.attr("aria-expanded", "true");
$settingsArea.slideDown(200);
}
} else {
// Clear all role checkboxes when disabled
$settingsArea.find("input[type=checkbox]").prop("checked", false);
// Optionally collapse the section if it was toggled off
// Uncomment this if you want the section to collapse when disabled
/*
if ($header.attr("aria-expanded") === "true") {
$header.attr("aria-expanded", "false");
$settingsArea.slideUp(200);
}
*/
}
} else { } else {
showErrorNotification($this); showErrorNotification($this);
// Revert the toggle to its previous state
$this.prop("checked", !value);
} }
}, },
error: function() { error: function() {
showErrorNotification($this); showErrorNotification($this);
// Revert the toggle to its previous state
$this.prop("checked", !value);
} }
}); });
}); });
@ -91,6 +124,9 @@ class WP_Allstars_Access_Manager {
var setting = $container.find("input").first().attr("name"); var setting = $container.find("input").first().attr("name");
var selectedRoles = []; var selectedRoles = [];
// Clear any existing notifications
$(".wp-setting-notification").remove();
$container.find("input:checked").each(function() { $container.find("input:checked").each(function() {
selectedRoles.push($(this).val()); selectedRoles.push($(this).val());
}); });
@ -106,28 +142,43 @@ class WP_Allstars_Access_Manager {
}, },
success: function(response) { success: function(response) {
if (response.success) { if (response.success) {
showSavedNotification($this); // Find the main toggle for this section
var $mainToggle = $this.closest(".wp-allstars-toggle").find(".wp-toggle-switch input");
// Update the main toggle based on role selection
if (selectedRoles.length > 0) {
$mainToggle.prop("checked", true);
showSavedNotification($mainToggle);
} else {
$mainToggle.prop("checked", false);
showSavedNotification($mainToggle);
}
} else { } else {
showErrorNotification($this); showErrorNotification($this);
// Revert the checkbox to its previous state
$this.prop("checked", !$this.prop("checked"));
} }
}, },
error: function() { error: function() {
showErrorNotification($this); showErrorNotification($this);
// Revert the checkbox to its previous state
$this.prop("checked", !$this.prop("checked"));
} }
}); });
}); });
function showSavedNotification($element) { function showSavedNotification($element) {
var $label = $element.closest(".wp-allstars-toggle-left").find("label"); // Find the nearest toggle header for notification placement
var $notification = $label.find(".wp-setting-notification"); var $toggleHeader = $element.closest(".wp-allstars-toggle").find(".wp-allstars-toggle-header");
var $notification = $("<span>").addClass("wp-setting-notification success").text("Saved");
if ($notification.length === 0) { // Remove any existing notifications
$notification = $("<span>").addClass("wp-setting-notification"); $toggleHeader.find(".wp-setting-notification").remove();
$label.append($notification);
}
$notification.text("Saved").removeClass("error").addClass("success"); // Add the notification
$toggleHeader.find("label").append($notification);
// Remove notification after delay
setTimeout(function() { setTimeout(function() {
$notification.fadeOut(300, function() { $notification.fadeOut(300, function() {
$(this).remove(); $(this).remove();
@ -136,22 +187,36 @@ class WP_Allstars_Access_Manager {
} }
function showErrorNotification($element) { function showErrorNotification($element) {
var $label = $element.closest(".wp-allstars-toggle-left").find("label"); // Find the nearest toggle header for notification placement
var $notification = $label.find(".wp-setting-notification"); var $toggleHeader = $element.closest(".wp-allstars-toggle").find(".wp-allstars-toggle-header");
var $notification = $("<span>").addClass("wp-setting-notification error").text("Error Saving");
if ($notification.length === 0) { // Remove any existing notifications
$notification = $("<span>").addClass("wp-setting-notification"); $toggleHeader.find(".wp-setting-notification").remove();
$label.append($notification);
}
$notification.text("Error Saving").removeClass("success").addClass("error"); // Add the notification
$toggleHeader.find("label").append($notification);
// Remove notification after delay
setTimeout(function() { setTimeout(function() {
$notification.fadeOut(300, function() { $notification.fadeOut(300, function() {
$(this).remove(); $(this).remove();
}); });
}, 2000); }, 2000);
} }
// Toggle expandable settings panels
$(".wp-allstars-toggle-header").on("click", function() {
var $this = $(this);
var $settings = $this.closest(".wp-allstars-toggle").find(".wp-allstars-toggle-settings");
var isExpanded = $this.attr("aria-expanded") === "true";
// Toggle aria-expanded attribute
$this.attr("aria-expanded", !isExpanded);
// Toggle settings visibility
$settings.slideToggle(200);
});
}); });
'; ';
@ -165,11 +230,13 @@ class WP_Allstars_Access_Manager {
// Verify nonce // Verify nonce
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'wp-allstars-nonce')) { if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'wp-allstars-nonce')) {
wp_send_json_error('Invalid nonce'); wp_send_json_error('Invalid nonce');
return;
} }
// Check user capabilities // Check user capabilities
if (!current_user_can('manage_options')) { if (!current_user_can('manage_options')) {
wp_send_json_error('Insufficient permissions'); wp_send_json_error('Insufficient permissions');
return;
} }
// Get and validate setting // Get and validate setting
@ -178,34 +245,49 @@ class WP_Allstars_Access_Manager {
if (empty($setting)) { if (empty($setting)) {
wp_send_json_error('Invalid setting'); wp_send_json_error('Invalid setting');
return;
} }
// Handle different setting types // Handle different setting types
$result = false;
switch ($setting) { switch ($setting) {
case 'wp_allstars_hide_admin_bar': case 'wp_allstars_hide_admin_bar':
$result = update_option('wp_allstars_hide_admin_bar_roles', $value ? array('guest', 'subscriber', 'customer') : array()); // When the main toggle is changed, update the roles option
$default_roles = array('guest', 'subscriber', 'customer');
$result = update_option('wp_allstars_hide_admin_bar_roles', $value ? $default_roles : array());
break; break;
case 'wp_allstars_restrict_dashboard': case 'wp_allstars_restrict_dashboard':
$result = update_option('wp_allstars_restrict_dashboard_roles', $value ? array('guest', 'subscriber', 'customer') : array()); // When the main toggle is changed, update the roles option
$default_roles = array('guest', 'subscriber', 'customer');
$result = update_option('wp_allstars_restrict_dashboard_roles', $value ? $default_roles : array());
break; break;
case 'wp_allstars_hide_admin_bar_roles': case 'wp_allstars_hide_admin_bar_roles[]':
case 'wp_allstars_restrict_dashboard_roles': // For role checkboxes, update the complete array
if (is_array($value)) { if (is_array($value)) {
$value = array_map('sanitize_text_field', $value); $value = array_map('sanitize_text_field', $value);
$result = update_option($setting, $value); $result = update_option('wp_allstars_hide_admin_bar_roles', $value);
}
break;
case 'wp_allstars_restrict_dashboard_roles[]':
// For role checkboxes, update the complete array
if (is_array($value)) {
$value = array_map('sanitize_text_field', $value);
$result = update_option('wp_allstars_restrict_dashboard_roles', $value);
} }
break; break;
default: default:
wp_send_json_error('Invalid setting name'); wp_send_json_error('Invalid setting name');
return;
} }
if ($result) { if ($result) {
wp_send_json_success(); wp_send_json_success(array('message' => 'Setting updated successfully'));
} else { } else {
wp_send_json_error('Failed to save setting'); wp_send_json_error(array('message' => 'Failed to save setting'));
} }
} }