Replace all inline CSS with Tailwind utility classes

Convert style attributes to Tailwind: width:fit-content → w-fit,
background:#fafafa → bg-[#fafafa], display:none → hidden attr,
display:inline → inline class, max-height → max-h-[360px],
padding/border-radius/font-size → px-5 py-3 rounded-lg text-sm.
Update JS to use .hidden property instead of .style.display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
shuki
2026-03-04 05:03:22 +02:00
parent a59c44e5ab
commit 1efde7487b
7 changed files with 28 additions and 28 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +1,2 @@
<!-- Tailwind/DaisyUI class safelist for gniza WHM plugin --> <!-- Tailwind/DaisyUI class safelist for gniza WHM plugin -->
<div class="alert alert-error alert-info alert-success alert-warning badge badge-error badge-sm badge-success badge-warning bg-base-100 bg-base-200 bg-neutral bg-primary/10 border border-base-300 border-base-content/5 breadcrumbs btn btn-error btn-ghost btn-primary btn-secondary btn-sm btn-xs card card-body card-title checkbox checkbox-sm cursor-pointer flex flex-1 flex-col flex-wrap font-bold font-medium font-mono font-semibold gap-1 gap-2 gap-3 hidden inline input input-bordered input-sm items-center items-start mx-auto join join-item link list-disc loading loading-spinner loading-xs max-h-48 max-w-2xl max-w-xs mb-1 mb-2.5 mb-3 mb-4 mb-5 mb-6 ml-2 modal modal-action modal-backdrop modal-box mt-2 mt-3 mt-4 mt-5 my-2 my-4 overflow-x-auto overflow-y-auto p-3 p-4 pt-1 pt-2 pl-5 px-4 py-1 py-3 py-4 radio radio-sm rounded-box rounded-lg select select-bordered select-sm shadow-sm steps tab tab-content table hover tabs tabs-box tabs-lg tab-active text-center text-error text-lg textarea textarea-bordered textarea-sm text-base-content/60 text-neutral-content text-sm text-xl text-xs toggle toggle-sm toggle-success w-11/12 w-44 w-full whitespace-pre-wrap font-sans text-[1.7rem] text-warning badge-info badge-neutral btn-active leading-relaxed inline-flex items-stretch"></div> <div class="alert alert-error alert-info alert-success alert-warning badge badge-error badge-sm badge-success badge-warning bg-base-100 bg-base-200 bg-neutral bg-primary/10 border border-base-300 border-base-content/5 breadcrumbs btn btn-error btn-ghost btn-primary btn-secondary btn-sm btn-xs card card-body card-title checkbox checkbox-sm cursor-pointer flex flex-1 flex-col flex-wrap font-bold font-medium font-mono font-semibold gap-1 gap-2 gap-3 hidden inline input input-bordered input-sm items-center items-start mx-auto join join-item link list-disc loading loading-spinner loading-xs max-h-48 max-w-2xl max-w-xs mb-1 mb-2.5 mb-3 mb-4 mb-5 mb-6 ml-2 modal modal-action modal-backdrop modal-box mt-2 mt-3 mt-4 mt-5 my-2 my-4 overflow-x-auto overflow-y-auto p-3 p-4 pt-1 pt-2 pl-5 px-4 py-1 py-3 py-4 radio radio-sm rounded-box rounded-lg select select-bordered select-sm shadow-sm steps tab tab-content table hover tabs tabs-box tabs-lg tab-active text-center text-error text-lg textarea textarea-bordered textarea-sm text-base-content/60 text-neutral-content text-sm text-xl text-xs toggle toggle-sm toggle-success w-11/12 w-44 w-full whitespace-pre-wrap font-sans text-[1.7rem] text-warning badge-info badge-neutral btn-active leading-relaxed inline-flex items-stretch w-fit bg-[#fafafa] px-5 max-h-[360px]"></div>

View File

@@ -46,7 +46,7 @@ my @NAV_ITEMS = (
sub render_nav { sub render_nav {
my ($current_page) = @_; my ($current_page) = @_;
my $html = qq{<div role="tablist" class="tabs tabs-box tabs-lg mb-5 mx-auto" style="width:fit-content">\n}; my $html = qq{<div role="tablist" class="tabs tabs-box tabs-lg mb-5 mx-auto w-fit">\n};
for my $item (@NAV_ITEMS) { for my $item (@NAV_ITEMS) {
my $active = ($item->{url} eq $current_page) ? ' tab-active' : ''; my $active = ($item->{url} eq $current_page) ? ' tab-active' : '';
my $label = esc($item->{label}); my $label = esc($item->{label});
@@ -630,7 +630,7 @@ sub page_header {
# (background, color, overflow, scrollbar) don't leak into WHM. # (background, color, overflow, scrollbar) don't leak into WHM.
$css = _scope_to_container($css); $css = _scope_to_container($css);
return qq{<style>$css</style>\n} return qq{<style>$css</style>\n}
. qq{<div data-theme="light" class="font-sans text-[1.7rem]" style="background:#fafafa">\n} . qq{<div data-theme="light" class="font-sans text-[1.7rem] bg-[#fafafa]">\n}
. qq{<h1 class="text-xl font-bold mb-4">$title</h1>\n}; . qq{<h1 class="text-xl font-bold mb-4">$title</h1>\n};
} }

View File

@@ -758,7 +758,7 @@ function gnizaToast(type, msg) {
area.innerHTML = ''; area.innerHTML = '';
var el = document.createElement('div'); var el = document.createElement('div');
el.className = 'alert alert-' + type; el.className = 'alert alert-' + type;
el.style.cssText = 'padding:12px 20px;border-radius:8px;font-size:14px'; el.className += ' px-5 py-3 rounded-lg text-sm';
el.textContent = msg; el.textContent = msg;
area.appendChild(el); area.appendChild(el);
setTimeout(function() { el.style.opacity = '0'; }, type === 'error' ? 6000 : 3000); setTimeout(function() { el.style.opacity = '0'; }, type === 'error' ? 6000 : 3000);

View File

@@ -262,7 +262,7 @@ sub handle_step2 {
['ssl', 'SSL'], ['ssl', 'SSL'],
); );
print qq{<div id="selective-panel" style="display:none">\n}; print qq{<div id="selective-panel" hidden>\n};
print qq{<div class="flex items-center gap-3 mb-2.5">\n}; print qq{<div class="flex items-center gap-3 mb-2.5">\n};
print qq{ <label class="w-44 font-medium text-sm">Restore Types</label>\n}; print qq{ <label class="w-44 font-medium text-sm">Restore Types</label>\n};
@@ -274,7 +274,7 @@ sub handle_step2 {
print qq{</div>\n}; print qq{</div>\n};
# Sub-field cards per type # Sub-field cards per type
print qq{<div id="field-path" style="display:none">\n}; print qq{<div id="field-path" hidden>\n};
print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n}; print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n};
print qq{<div class="card-body py-3 px-4">\n}; print qq{<div class="card-body py-3 px-4">\n};
print qq{ <h3 class="card-title text-sm">Files</h3>\n}; print qq{ <h3 class="card-title text-sm">Files</h3>\n};
@@ -290,7 +290,7 @@ sub handle_step2 {
print qq{</div>\n}; print qq{</div>\n};
print qq{</div>\n}; print qq{</div>\n};
print qq{<div id="field-dbname" style="display:none">\n}; print qq{<div id="field-dbname" hidden>\n};
print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n}; print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n};
print qq{<div class="card-body py-3 px-4">\n}; print qq{<div class="card-body py-3 px-4">\n};
print qq{ <h3 class="card-title text-sm">Databases</h3>\n}; print qq{ <h3 class="card-title text-sm">Databases</h3>\n};
@@ -302,7 +302,7 @@ sub handle_step2 {
print qq{</div>\n}; print qq{</div>\n};
print qq{</div>\n}; print qq{</div>\n};
print qq{<div id="field-email" style="display:none">\n}; print qq{<div id="field-email" hidden>\n};
print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n}; print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n};
print qq{<div class="card-body py-3 px-4">\n}; print qq{<div class="card-body py-3 px-4">\n};
print qq{ <h3 class="card-title text-sm">Mailboxes</h3>\n}; print qq{ <h3 class="card-title text-sm">Mailboxes</h3>\n};
@@ -314,7 +314,7 @@ sub handle_step2 {
print qq{</div>\n}; print qq{</div>\n};
print qq{</div>\n}; print qq{</div>\n};
print qq{<div id="field-dbusers" style="display:none">\n}; print qq{<div id="field-dbusers" hidden>\n};
print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n}; print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n};
print qq{<div class="card-body py-3 px-4">\n}; print qq{<div class="card-body py-3 px-4">\n};
print qq{ <h3 class="card-title text-sm">Database Users</h3>\n}; print qq{ <h3 class="card-title text-sm">Database Users</h3>\n};
@@ -326,7 +326,7 @@ sub handle_step2 {
print qq{</div>\n}; print qq{</div>\n};
print qq{</div>\n}; print qq{</div>\n};
print qq{<div id="field-cron" style="display:none">\n}; print qq{<div id="field-cron" hidden>\n};
print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n}; print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n};
print qq{<div class="card-body py-3 px-4">\n}; print qq{<div class="card-body py-3 px-4">\n};
print qq{ <h3 class="card-title text-sm">Cron Jobs</h3>\n}; print qq{ <h3 class="card-title text-sm">Cron Jobs</h3>\n};
@@ -337,7 +337,7 @@ sub handle_step2 {
print qq{</div>\n}; print qq{</div>\n};
print qq{</div>\n}; print qq{</div>\n};
print qq{<div id="field-domains" style="display:none">\n}; print qq{<div id="field-domains" hidden>\n};
print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n}; print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n};
print qq{<div class="card-body py-3 px-4">\n}; print qq{<div class="card-body py-3 px-4">\n};
print qq{ <h3 class="card-title text-sm">Domains</h3>\n}; print qq{ <h3 class="card-title text-sm">Domains</h3>\n};
@@ -349,7 +349,7 @@ sub handle_step2 {
print qq{</div>\n}; print qq{</div>\n};
print qq{</div>\n}; print qq{</div>\n};
print qq{<div id="field-ssl" style="display:none">\n}; print qq{<div id="field-ssl" hidden>\n};
print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n}; print qq{<div class="card bg-base-100 shadow-sm border border-base-300 mb-3">\n};
print qq{<div class="card-body py-3 px-4">\n}; print qq{<div class="card-body py-3 px-4">\n};
print qq{ <h3 class="card-title text-sm">SSL Certificates</h3>\n}; print qq{ <h3 class="card-title text-sm">SSL Certificates</h3>\n};
@@ -368,9 +368,9 @@ sub handle_step2 {
print qq{<div class="modal-box w-11/12 max-w-2xl">\n}; print qq{<div class="modal-box w-11/12 max-w-2xl">\n};
print qq{ <h3 class="text-lg font-bold mb-3">Browse Files</h3>\n}; print qq{ <h3 class="text-lg font-bold mb-3">Browse Files</h3>\n};
print qq{ <div id="fb-breadcrumbs" class="breadcrumbs text-sm mb-3"><ul><li>homedir</li></ul></div>\n}; print qq{ <div id="fb-breadcrumbs" class="breadcrumbs text-sm mb-3"><ul><li>homedir</li></ul></div>\n};
print qq{ <div id="fb-loading" class="text-center py-4" style="display:none"><span class="loading loading-spinner"></span> Loading...</div>\n}; print qq{ <div id="fb-loading" class="text-center py-4" hidden><span class="loading loading-spinner"></span> Loading...</div>\n};
print qq{ <div id="fb-error" class="alert alert-error mb-3" style="display:none"></div>\n}; print qq{ <div id="fb-error" class="alert alert-error mb-3" hidden></div>\n};
print qq{ <div id="fb-list" class="overflow-y-auto" style="max-height:360px">\n}; print qq{ <div id="fb-list" class="overflow-y-auto" class="max-h-[360px]">\n};
print qq{ <table class="table table-zebra w-full"><tbody id="fb-tbody"></tbody></table>\n}; print qq{ <table class="table table-zebra w-full"><tbody id="fb-tbody"></tbody></table>\n};
print qq{ </div>\n}; print qq{ </div>\n};
print qq{ <div class="modal-action">\n}; print qq{ <div class="modal-action">\n};
@@ -413,14 +413,14 @@ function gnizaSnapshotChange() {
function gnizaModeChanged() { function gnizaModeChanged() {
var mode = document.querySelector('input[name="restore_mode"]:checked').value; var mode = document.querySelector('input[name="restore_mode"]:checked').value;
var selective = mode === 'selective'; var selective = mode === 'selective';
document.getElementById('selective-panel').style.display = selective ? '' : 'none'; document.getElementById('selective-panel').hidden = !selective;
document.getElementById('type_account_hidden').disabled = selective; document.getElementById('type_account_hidden').disabled = selective;
if (selective) { if (selective) {
gnizaTypesChanged(); gnizaTypesChanged();
} else { } else {
var panels = ['field-path','field-dbname','field-email','field-dbusers','field-cron','field-domains','field-ssl']; var panels = ['field-path','field-dbname','field-email','field-dbusers','field-cron','field-domains','field-ssl'];
for (var i = 0; i < panels.length; i++) { for (var i = 0; i < panels.length; i++) {
document.getElementById(panels[i]).style.display = 'none'; document.getElementById(panels[i]).hidden = true;
} }
} }
} }
@@ -437,7 +437,7 @@ function gnizaTypesChanged() {
}; };
for (var t in types) { for (var t in types) {
var el = document.querySelector('input[name="type_' + t + '"]'); var el = document.querySelector('input[name="type_' + t + '"]');
document.getElementById(types[t]).style.display = el && el.checked ? '' : 'none'; document.getElementById(types[t]).hidden = !(el && el.checked);
} }
if (document.querySelector('input[name="type_database"]').checked) { gnizaLoadOptions('database', 'dbname-list', 'dbnames'); } if (document.querySelector('input[name="type_database"]').checked) { gnizaLoadOptions('database', 'dbname-list', 'dbnames'); }
@@ -619,8 +619,8 @@ function gnizaLoadDir(path) {
return; return;
} }
document.getElementById('fb-loading').style.display = ''; document.getElementById('fb-loading').hidden = false;
document.getElementById('fb-error').style.display = 'none'; document.getElementById('fb-error').hidden = true;
document.getElementById('fb-tbody').innerHTML = ''; document.getElementById('fb-tbody').innerHTML = '';
var url = 'restore.cgi?restore_step=fetch_options' var url = 'restore.cgi?restore_step=fetch_options'
@@ -634,24 +634,24 @@ function gnizaLoadDir(path) {
xhr.open('GET', url, true); xhr.open('GET', url, true);
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return; if (xhr.readyState !== 4) return;
document.getElementById('fb-loading').style.display = 'none'; document.getElementById('fb-loading').hidden = true;
if (xhr.status === 200) { if (xhr.status === 200) {
try { try {
var data = JSON.parse(xhr.responseText); var data = JSON.parse(xhr.responseText);
if (data.error) { if (data.error) {
document.getElementById('fb-error').textContent = data.error; document.getElementById('fb-error').textContent = data.error;
document.getElementById('fb-error').style.display = ''; document.getElementById('fb-error').hidden = false;
} else { } else {
fbCache[cacheKey] = data.options; fbCache[cacheKey] = data.options;
gnizaRenderFileList(path, data.options); gnizaRenderFileList(path, data.options);
} }
} catch(e) { } catch(e) {
document.getElementById('fb-error').textContent = 'Failed to parse response'; document.getElementById('fb-error').textContent = 'Failed to parse response';
document.getElementById('fb-error').style.display = ''; document.getElementById('fb-error').hidden = false;
} }
} else { } else {
document.getElementById('fb-error').textContent = 'Request failed'; document.getElementById('fb-error').textContent = 'Request failed';
document.getElementById('fb-error').style.display = ''; document.getElementById('fb-error').hidden = false;
} }
}; };
xhr.send(); xhr.send();

View File

@@ -69,14 +69,14 @@ sub handle_list {
print qq{</td>}; print qq{</td>};
print qq{<td>}; print qq{<td>};
print qq{<div class="flex items-center gap-2">}; print qq{<div class="flex items-center gap-2">};
print qq{<form method="POST" action="schedules.cgi" style="display:inline">}; print qq{<form method="POST" action="schedules.cgi" class="inline">};
print qq{<input type="hidden" name="action" value="run_now">}; print qq{<input type="hidden" name="action" value="run_now">};
print qq{<input type="hidden" name="name" value="$esc_name">}; print qq{<input type="hidden" name="name" value="$esc_name">};
print GnizaWHM::UI::csrf_hidden_field(); print GnizaWHM::UI::csrf_hidden_field();
print qq{<button type="submit" class="btn btn-secondary btn-sm" onclick="return confirm('Run backup for schedule $esc_name now?')">Run Now</button>}; print qq{<button type="submit" class="btn btn-secondary btn-sm" onclick="return confirm('Run backup for schedule $esc_name now?')">Run Now</button>};
print qq{</form>}; print qq{</form>};
print qq{<a href="schedules.cgi?action=edit&amp;name=$esc_name" class="btn btn-ghost btn-sm">Edit</a>}; print qq{<a href="schedules.cgi?action=edit&amp;name=$esc_name" class="btn btn-ghost btn-sm">Edit</a>};
print qq{<form method="POST" action="schedules.cgi" style="display:inline">}; print qq{<form method="POST" action="schedules.cgi" class="inline">};
print qq{<input type="hidden" name="action" value="delete">}; print qq{<input type="hidden" name="action" value="delete">};
print qq{<input type="hidden" name="name" value="$esc_name">}; print qq{<input type="hidden" name="name" value="$esc_name">};
print GnizaWHM::UI::csrf_hidden_field(); print GnizaWHM::UI::csrf_hidden_field();

View File

@@ -280,7 +280,7 @@ function gnizaSmtpToast(type, msg) {
area.innerHTML = ''; area.innerHTML = '';
var el = document.createElement('div'); var el = document.createElement('div');
el.className = 'alert alert-' + type; el.className = 'alert alert-' + type;
el.style.cssText = 'padding:12px 20px;border-radius:8px;font-size:14px'; el.className += ' px-5 py-3 rounded-lg text-sm';
el.textContent = msg; el.textContent = msg;
area.appendChild(el); area.appendChild(el);
setTimeout(function() { el.style.opacity = '0'; }, type === 'error' ? 6000 : 3000); setTimeout(function() { el.style.opacity = '0'; }, type === 'error' ? 6000 : 3000);