Replace 2FA buttons with toggle switch

This commit is contained in:
Nariman Jelveh
2026-04-30 15:01:06 -07:00
parent 867d967b37
commit d772b557a0
2 changed files with 91 additions and 39 deletions
+33 -39
View File
@@ -85,8 +85,10 @@ const TabSecurity = {
h += `<span class="user-otp-state">${i18n(user.otp ? 'two_factor_enabled' : 'two_factor_disabled')}</span>`;
h += '</div>';
h += '</div>';
h += `<button class="button enable-2fa" style="${user.otp ? 'display:none;' : ''}">${i18n('enable_2fa')}</button>`;
h += `<button class="button disable-2fa" style="${user.otp ? '' : 'display:none;'}">${i18n('disable_2fa')}</button>`;
h += '<label class="dashboard-switch toggle-2fa-label">';
h += `<input type="checkbox" class="toggle-2fa"${user.otp ? ' checked' : ''}>`;
h += '<span class="dashboard-switch-slider"></span>';
h += '</label>';
h += '</div>';
}
@@ -124,47 +126,39 @@ const TabSecurity = {
});
});
$el_window.find('.dashboard-section-security .enable-2fa').on('click', async function (e) {
const { promise } = await UIWindow2FASetup({
window_options: {
parent_uuid: $el_window.attr('data-element_uuid'),
backdrop: true,
close_on_backdrop_click: true,
stay_on_top: true,
has_head: false,
parent_center: true,
},
});
const tfa_was_enabled = await promise;
$el_window.find('.dashboard-section-security .toggle-2fa').on('change', async function (e) {
const $toggle = $(this);
const enabling = $toggle.is(':checked');
$toggle.prop('disabled', true);
if ( tfa_was_enabled ) {
$el_window.find('.dashboard-section-security .enable-2fa').hide();
$el_window.find('.dashboard-section-security .disable-2fa').show();
$el_window.find('.dashboard-section-security .user-otp-state').text(i18n('two_factor_enabled'));
$el_window.find('.dashboard-section-security .dashboard-settings-card-2fa').removeClass('dashboard-settings-card-warning');
$el_window.find('.dashboard-section-security .dashboard-settings-card-2fa').addClass('dashboard-settings-card-success');
const window_options = {
parent_uuid: $el_window.attr('data-element_uuid'),
backdrop: true,
close_on_backdrop_click: true,
parent_center: true,
stay_on_top: true,
has_head: false,
};
const { promise } = enabling
? await UIWindow2FASetup({ window_options })
: await UIWindowDisable2FA({ window_options });
const succeeded = await promise;
$toggle.prop('disabled', false);
if ( ! succeeded ) {
$toggle.prop('checked', ! enabling);
return;
}
});
$el_window.find('.dashboard-section-security .disable-2fa').on('click', async function (e) {
const { promise } = await UIWindowDisable2FA({
window_options: {
parent_uuid: $el_window.attr('data-element_uuid'),
backdrop: true,
close_on_backdrop_click: true,
parent_center: true,
stay_on_top: true,
has_head: false,
},
});
const tfa_was_disabled = await promise;
if ( tfa_was_disabled ) {
$el_window.find('.dashboard-section-security .enable-2fa').show();
$el_window.find('.dashboard-section-security .disable-2fa').hide();
const $card = $el_window.find('.dashboard-section-security .dashboard-settings-card-2fa');
if ( enabling ) {
$el_window.find('.dashboard-section-security .user-otp-state').text(i18n('two_factor_enabled'));
$card.removeClass('dashboard-settings-card-warning').addClass('dashboard-settings-card-success');
} else {
$el_window.find('.dashboard-section-security .user-otp-state').text(i18n('two_factor_disabled'));
$el_window.find('.dashboard-section-security .dashboard-settings-card-2fa').removeClass('dashboard-settings-card-success');
$el_window.find('.dashboard-section-security .dashboard-settings-card-2fa').addClass('dashboard-settings-card-warning');
$card.removeClass('dashboard-settings-card-success').addClass('dashboard-settings-card-warning');
}
});
},
+58
View File
@@ -3236,6 +3236,64 @@ body {
color: var(--dashboard-warning-text);
}
/* Toggle switch */
.dashboard-switch {
position: relative;
display: inline-block;
width: 44px;
height: 24px;
flex-shrink: 0;
margin: 0;
}
.dashboard-switch input {
position: absolute;
opacity: 0;
width: 0;
height: 0;
pointer-events: none;
}
.dashboard-switch-slider {
position: absolute;
inset: 0;
cursor: pointer;
background-color: var(--dashboard-border);
transition: background-color 0.2s ease;
border-radius: 24px;
}
.dashboard-switch-slider::before {
content: "";
position: absolute;
height: 18px;
width: 18px;
left: 3px;
top: 3px;
background-color: #fff;
border-radius: 50%;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
transition: transform 0.2s ease;
}
.dashboard-switch input:checked + .dashboard-switch-slider {
background-color: var(--dashboard-success-border);
}
.dashboard-switch input:checked + .dashboard-switch-slider::before {
transform: translateX(20px);
}
.dashboard-switch input:focus-visible + .dashboard-switch-slider {
outline: 2px solid var(--select-color);
outline-offset: 2px;
}
.dashboard-switch input:disabled + .dashboard-switch-slider {
opacity: 0.6;
cursor: not-allowed;
}
/* Danger zone */
.dashboard-danger-zone {
padding-top: 24px;