mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-23 03:33:53 +00:00
Refactor: Improve header layout and theme toggle
This commit is contained in:
+13
-13
@@ -33,7 +33,7 @@
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Guard clauses to ensure essential elements exist before proceeding
|
||||
const themeToggle = document.getElementById('theme-toggle');
|
||||
const themeToggleButton = document.getElementById('theme-toggle-button');
|
||||
const connectionStatus = document.getElementById('connection-status');
|
||||
const mainTableBody = document.querySelector('#main-table tbody');
|
||||
const tooltipElement = document.getElementById('custom-tooltip');
|
||||
@@ -59,30 +59,30 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
|
||||
// Function to apply the theme (no longer needs to set checkbox state)
|
||||
function applyTheme(theme) {
|
||||
if (!themeToggle) return; // Guard against missing toggle
|
||||
if (theme === 'dark') {
|
||||
htmlElement.classList.add('dark');
|
||||
themeToggle.checked = true;
|
||||
localStorage.setItem('theme', 'dark');
|
||||
} else {
|
||||
htmlElement.classList.remove('dark');
|
||||
themeToggle.checked = false;
|
||||
localStorage.setItem('theme', 'light');
|
||||
}
|
||||
}
|
||||
|
||||
// Apply initial theme only if toggle exists
|
||||
if (themeToggle) {
|
||||
applyTheme(savedTheme || (prefersDarkScheme.matches ? 'dark' : 'light'));
|
||||
// Determine initial theme
|
||||
const initialTheme = savedTheme || (prefersDarkScheme.matches ? 'dark' : 'light');
|
||||
applyTheme(initialTheme);
|
||||
|
||||
themeToggle.addEventListener('change', function() {
|
||||
applyTheme(this.checked ? 'dark' : 'light');
|
||||
});
|
||||
// Add event listener to the button
|
||||
if (themeToggleButton) {
|
||||
themeToggleButton.addEventListener('click', function() {
|
||||
// Toggle theme based on current state
|
||||
const currentIsDark = htmlElement.classList.contains('dark');
|
||||
applyTheme(currentIsDark ? 'light' : 'dark');
|
||||
});
|
||||
} else {
|
||||
console.warn('Element #theme-toggle not found - theme switching disabled.');
|
||||
// Apply system preference without saving/using toggle state
|
||||
applyTheme(prefersDarkScheme.matches ? 'dark' : 'light');
|
||||
console.warn('Element #theme-toggle-button not found - theme switching disabled.');
|
||||
}
|
||||
|
||||
// --- Tab Functionality ---
|
||||
|
||||
+26
-24
@@ -55,13 +55,12 @@
|
||||
.dark .pulse-logo-inner { fill: #dbeafe; } /* blue-100 */
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-200 p-2 font-sans transition-colors duration-300">
|
||||
<body class="bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-200 p-2 font-sans">
|
||||
<div class="container max-w-[95%] mx-auto">
|
||||
<div class="header flex justify-between items-center mb-2 relative">
|
||||
<!-- Invisible Placeholder for spacing -->
|
||||
<div class="w-44"></div> <!-- Adjust width as needed based on controls size -->
|
||||
<!-- Logo and Title Container -->
|
||||
<div class="flex items-center gap-1 absolute left-1/2 -translate-x-1/2">
|
||||
<!-- Header with bottom border and padding -->
|
||||
<div class="header flex justify-between items-center pb-2 border-b border-gray-300 dark:border-gray-700 mb-2">
|
||||
<!-- Logo and Title Container (Aligned Left) -->
|
||||
<div class="flex items-center gap-1">
|
||||
<!-- Pulse Logo SVG -->
|
||||
<svg width="20" height="20" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" class="pulse-logo">
|
||||
<title>Pulse Logo</title>
|
||||
@@ -70,23 +69,26 @@
|
||||
</svg>
|
||||
<span class="text-lg font-medium text-gray-800 dark:text-gray-200">Pulse</span>
|
||||
</div>
|
||||
<!-- Header Controls (Aligned Right) -->
|
||||
<div class="header-controls flex items-center gap-4">
|
||||
<div class="flex items-center">
|
||||
<span class="theme-label text-sm mr-2">Dark Mode</span>
|
||||
<label class="theme-switch relative inline-block w-[48px] h-[20px]">
|
||||
<input type="checkbox" id="theme-toggle" class="peer opacity-0 w-0 h-0">
|
||||
<!-- Use Tailwind classes for the slider -->
|
||||
<span class="slider absolute cursor-pointer top-0 left-0 right-0 bottom-0 bg-gray-300 dark:bg-gray-600 peer-checked:bg-blue-600 dark:peer-checked:bg-blue-700 transition duration-400 rounded-full"></span>
|
||||
<span class="slider-knob absolute content-[''] h-[16px] w-[16px] left-[2px] bottom-[2px] bg-white transition duration-400 rounded-full peer-checked:translate-x-[28px]"></span>
|
||||
</label>
|
||||
</div>
|
||||
<!-- Replaced toggle switch with icon button - removed focus ring -->
|
||||
<button id="theme-toggle-button" type="button" class="p-1 rounded-md text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none" aria-label="Toggle theme">
|
||||
<!-- Sun icon (visible in light mode) -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 block dark:hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
|
||||
</svg>
|
||||
<!-- Moon icon (visible in dark mode) -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 hidden dark:block" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
|
||||
</svg>
|
||||
</button>
|
||||
<div id="connection-status" class="status disconnected text-xs px-2 py-1 rounded-full bg-gray-200 dark:bg-gray-700 text-gray-600 dark:text-gray-400">Disconnected</div>
|
||||
<!-- JS will need to toggle classes like 'bg-red-100 dark:bg-red-800/30 text-red-700 dark:text-red-300' for disconnected -->
|
||||
<!-- and 'bg-green-100 dark:bg-green-800/30 text-green-700 dark:text-green-300' for connected -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tabs flex mb-2 border-b border-gray-300 dark:border-gray-700">
|
||||
<div class="tabs flex mt-2 mb-2 border-b border-gray-300 dark:border-gray-700">
|
||||
<!-- Add Tailwind classes, JS will toggle active classes -->
|
||||
<div class="tab active px-3 py-1.5 cursor-pointer bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 border-b-0 rounded-t text-sm -mb-px" data-tab="main">Main</div>
|
||||
<div class="tab px-3 py-1.5 cursor-pointer bg-gray-100 dark:bg-gray-700/50 border-transparent text-sm text-gray-600 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-t" data-tab="nodes">Nodes</div>
|
||||
@@ -131,31 +133,31 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="segmented-control inline-flex border border-gray-300 dark:border-gray-600 rounded overflow-hidden">
|
||||
<input type="radio" id="group-grouped" name="group-filter" value="grouped" class="hidden peer/grouped" checked>
|
||||
<label for="group-grouped" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 peer-checked/grouped:bg-blue-100 dark:peer-checked/grouped:bg-blue-800/50 peer-checked/grouped:text-blue-700 dark:peer-checked/grouped:text-blue-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors select-none">Grouped</label>
|
||||
<label for="group-grouped" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 peer-checked/grouped:bg-blue-100 dark:peer-checked/grouped:bg-blue-800/50 peer-checked/grouped:text-blue-700 dark:peer-checked/grouped:text-blue-300 hover:bg-gray-50 dark:hover:bg-gray-700 select-none">Grouped</label>
|
||||
<input type="radio" id="group-list" name="group-filter" value="list" class="hidden peer/list">
|
||||
<label for="group-list" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 border-l border-gray-300 dark:border-gray-600 peer-checked/list:bg-blue-100 dark:peer-checked/list:bg-blue-800/50 peer-checked/list:text-blue-700 dark:peer-checked/list:text-blue-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors select-none">List</label>
|
||||
<label for="group-list" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 border-l border-gray-300 dark:border-gray-600 peer-checked/list:bg-blue-100 dark:peer-checked/list:bg-blue-800/50 peer-checked/list:text-blue-700 dark:peer-checked/list:text-blue-300 hover:bg-gray-50 dark:hover:bg-gray-700 select-none">List</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Show Toggle -->
|
||||
<div class="flex items-center gap-2 pl-2">
|
||||
<div class="segmented-control inline-flex border border-gray-300 dark:border-gray-600 rounded overflow-hidden">
|
||||
<input type="radio" id="filter-all" name="type-filter" value="all" class="hidden peer/all" checked>
|
||||
<label for="filter-all" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 peer-checked/all:bg-green-100 dark:peer-checked/all:bg-green-800/50 peer-checked/all:text-green-700 dark:peer-checked/all:text-green-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors select-none">All</label>
|
||||
<label for="filter-all" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 peer-checked/all:bg-green-100 dark:peer-checked/all:bg-green-800/50 peer-checked/all:text-green-700 dark:peer-checked/all:text-green-300 hover:bg-gray-50 dark:hover:bg-gray-700 select-none">All</label>
|
||||
<input type="radio" id="filter-vm" name="type-filter" value="vm" class="hidden peer/vm">
|
||||
<label for="filter-vm" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 border-l border-gray-300 dark:border-gray-600 peer-checked/vm:bg-green-100 dark:peer-checked/vm:bg-green-800/50 peer-checked/vm:text-green-700 dark:peer-checked/vm:text-green-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors select-none">VMs</label>
|
||||
<label for="filter-vm" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 border-l border-gray-300 dark:border-gray-600 peer-checked/vm:bg-green-100 dark:peer-checked/vm:bg-green-800/50 peer-checked/vm:text-green-700 dark:peer-checked/vm:text-green-300 hover:bg-gray-50 dark:hover:bg-gray-700 select-none">VMs</label>
|
||||
<input type="radio" id="filter-lxc" name="type-filter" value="ct" class="hidden peer/lxc">
|
||||
<label for="filter-lxc" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 border-l border-gray-300 dark:border-gray-600 peer-checked/lxc:bg-green-100 dark:peer-checked/lxc:bg-green-800/50 peer-checked/lxc:text-green-700 dark:peer-checked/lxc:text-green-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors select-none">LXCs</label>
|
||||
<label for="filter-lxc" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 border-l border-gray-300 dark:border-gray-600 peer-checked/lxc:bg-green-100 dark:peer-checked/lxc:bg-green-800/50 peer-checked/lxc:text-green-700 dark:peer-checked/lxc:text-green-300 hover:bg-gray-50 dark:hover:bg-gray-700 select-none">LXCs</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Status Toggle -->
|
||||
<div class="flex items-center gap-2 pl-2">
|
||||
<div class="segmented-control inline-flex border border-gray-300 dark:border-gray-600 rounded overflow-hidden">
|
||||
<input type="radio" id="filter-status-all" name="status-filter" value="all" class="hidden peer/status-all" checked>
|
||||
<label for="filter-status-all" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 peer-checked/status-all:bg-blue-100 dark:peer-checked/status-all:bg-blue-800/50 peer-checked/status-all:text-blue-700 dark:peer-checked/status-all:text-blue-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors select-none">All</label>
|
||||
<label for="filter-status-all" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 peer-checked/status-all:bg-blue-100 dark:peer-checked/status-all:bg-blue-800/50 peer-checked/status-all:text-blue-700 dark:peer-checked/status-all:text-blue-300 hover:bg-gray-50 dark:hover:bg-gray-700 select-none">All</label>
|
||||
<input type="radio" id="filter-status-running" name="status-filter" value="running" class="hidden peer/status-running">
|
||||
<label for="filter-status-running" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 border-l border-gray-300 dark:border-gray-600 peer-checked/status-running:bg-blue-100 dark:peer-checked/status-running:bg-blue-800/50 peer-checked/status-running:text-blue-700 dark:peer-checked/status-running:text-blue-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors select-none">Running</label>
|
||||
<label for="filter-status-running" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 border-l border-gray-300 dark:border-gray-600 peer-checked/status-running:bg-blue-100 dark:peer-checked/status-running:bg-blue-800/50 peer-checked/status-running:text-blue-700 dark:peer-checked/status-running:text-blue-300 hover:bg-gray-50 dark:hover:bg-gray-700 select-none">Running</label>
|
||||
<input type="radio" id="filter-status-stopped" name="status-filter" value="stopped" class="hidden peer/status-stopped">
|
||||
<label for="filter-status-stopped" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 border-l border-gray-300 dark:border-gray-600 peer-checked/status-stopped:bg-blue-100 dark:peer-checked/status-stopped:bg-blue-800/50 peer-checked/status-stopped:text-blue-700 dark:peer-checked/status-stopped:text-blue-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors select-none">Stopped</label>
|
||||
<label for="filter-status-stopped" class="px-2 py-0.5 text-xs cursor-pointer bg-white dark:bg-gray-800 border-l border-gray-300 dark:border-gray-600 peer-checked/status-stopped:bg-blue-100 dark:peer-checked/status-stopped:bg-blue-800/50 peer-checked/status-stopped:text-blue-700 dark:peer-checked/status-stopped:text-blue-300 hover:bg-gray-50 dark:hover:bg-gray-700 select-none">Stopped</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user