v0.7.37 - Enhanced admin interface with sliding sidebar navigation, moved dark mode and logout to sidebar footer, improved button styling consistency
This commit is contained in:
@@ -1171,24 +1171,56 @@ body.dark-mode .sql-results-table tbody tr:nth-child(even) {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: none;
|
border: 2px solid var(--secondary-color);
|
||||||
background: none;
|
background: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item:hover {
|
.nav-item:hover {
|
||||||
background: rgba(0, 0, 0, 0.05);
|
border: 2px solid var(--secondary-color);
|
||||||
border-left: 4px solid var(--accent-color);
|
background:var(--muted-color);
|
||||||
padding-left: 16px;
|
color: var(--accent-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item.active {
|
.nav-item.active {
|
||||||
background: rgba(255, 0, 0, 0.1);
|
text-decoration: underline;
|
||||||
border-left: 4px solid var(--accent-color);
|
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-footer-btn {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 20px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: var(--font-family);
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-footer-btn:hover {
|
||||||
|
background:var(--muted-color);
|
||||||
|
border-color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-footer-btn:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.header-title.clickable {
|
.header-title.clickable {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
|||||||
@@ -19,6 +19,10 @@
|
|||||||
<li><button class="nav-item" data-page="dm">DM</button></li>
|
<li><button class="nav-item" data-page="dm">DM</button></li>
|
||||||
<li><button class="nav-item" data-page="database">Database Query</button></li>
|
<li><button class="nav-item" data-page="database">Database Query</button></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<div class="nav-footer">
|
||||||
|
<button class="nav-footer-btn" id="nav-dark-mode-btn">DARK MODE</button>
|
||||||
|
<button class="nav-footer-btn" id="nav-logout-btn">LOGOUT</button>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- Side Navigation Overlay -->
|
<!-- Side Navigation Overlay -->
|
||||||
@@ -49,10 +53,7 @@
|
|||||||
<span id="header-user-name" class="header-user-name">Loading...</span>
|
<span id="header-user-name" class="header-user-name">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- Logout dropdown -->
|
<!-- Logout dropdown -->
|
||||||
<div class="logout-dropdown" id="logout-dropdown" style="display: none;">
|
<!-- Dropdown menu removed - buttons moved to sidebar -->
|
||||||
<button type="button" id="dark-mode-btn" class="logout-btn">🌙 DARK MODE</button>
|
|
||||||
<button type="button" id="logout-btn" class="logout-btn">LOGOUT</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
95
api/index.js
95
api/index.js
@@ -52,8 +52,6 @@ const loginModalContainer = document.getElementById('login-modal-container');
|
|||||||
const profileArea = document.getElementById('profile-area');
|
const profileArea = document.getElementById('profile-area');
|
||||||
const headerUserImage = document.getElementById('header-user-image');
|
const headerUserImage = document.getElementById('header-user-image');
|
||||||
const headerUserName = document.getElementById('header-user-name');
|
const headerUserName = document.getElementById('header-user-name');
|
||||||
const logoutDropdown = document.getElementById('logout-dropdown');
|
|
||||||
const logoutBtn = document.getElementById('logout-btn');
|
|
||||||
|
|
||||||
// Legacy elements (kept for backward compatibility)
|
// Legacy elements (kept for backward compatibility)
|
||||||
const persistentUserName = document.getElementById('persistent-user-name');
|
const persistentUserName = document.getElementById('persistent-user-name');
|
||||||
@@ -579,10 +577,6 @@ function hideProfileFromHeader() {
|
|||||||
if (profileArea) {
|
if (profileArea) {
|
||||||
profileArea.style.display = 'none';
|
profileArea.style.display = 'none';
|
||||||
}
|
}
|
||||||
// Also hide logout dropdown if visible
|
|
||||||
if (logoutDropdown) {
|
|
||||||
logoutDropdown.style.display = 'none';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update login/logout UI visibility (legacy function - kept for backward compatibility)
|
// Update login/logout UI visibility (legacy function - kept for backward compatibility)
|
||||||
@@ -2102,45 +2096,8 @@ async function sendConfigUpdateCommand(configObjects) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Profile area click handler for logout dropdown
|
// Profile area click handler removed - dropdown moved to sidebar
|
||||||
function toggleLogoutDropdown(event) {
|
// Logout and dark mode buttons are now in the sidebar footer
|
||||||
if (!logoutDropdown) return;
|
|
||||||
|
|
||||||
// Only toggle if clicking on the image, not the text or container
|
|
||||||
if (event.target === headerUserImage) {
|
|
||||||
const isVisible = logoutDropdown.style.display === 'block';
|
|
||||||
logoutDropdown.style.display = isVisible ? 'none' : 'block';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close logout dropdown when clicking outside
|
|
||||||
document.addEventListener('click', function(event) {
|
|
||||||
if (profileArea && logoutDropdown && !profileArea.contains(event.target)) {
|
|
||||||
logoutDropdown.style.display = 'none';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Initialize profile area click handler
|
|
||||||
if (profileArea) {
|
|
||||||
profileArea.addEventListener('click', toggleLogoutDropdown);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize logout button handler
|
|
||||||
if (logoutBtn) {
|
|
||||||
logoutBtn.addEventListener('click', function(e) {
|
|
||||||
e.stopPropagation(); // Prevent profile area click
|
|
||||||
logout();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize dark mode button handler
|
|
||||||
const darkModeBtn = document.getElementById('dark-mode-btn');
|
|
||||||
if (darkModeBtn) {
|
|
||||||
darkModeBtn.addEventListener('click', function(e) {
|
|
||||||
e.stopPropagation(); // Prevent profile area click
|
|
||||||
toggleDarkMode();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize relay pubkey container click handler for clipboard copy
|
// Initialize relay pubkey container click handler for clipboard copy
|
||||||
const relayPubkeyContainer = document.getElementById('relay-pubkey-container');
|
const relayPubkeyContainer = document.getElementById('relay-pubkey-container');
|
||||||
@@ -4563,9 +4520,9 @@ function toggleDarkMode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateDarkModeButton(isDarkMode) {
|
function updateDarkModeButton(isDarkMode) {
|
||||||
const darkModeBtn = document.getElementById('dark-mode-btn');
|
const navDarkModeBtn = document.getElementById('nav-dark-mode-btn');
|
||||||
if (darkModeBtn) {
|
if (navDarkModeBtn) {
|
||||||
darkModeBtn.textContent = isDarkMode ? 'LIGHT MODE' : 'DARK MODE';
|
navDarkModeBtn.textContent = isDarkMode ? 'LIGHT MODE' : 'DARK MODE';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4655,6 +4612,18 @@ function switchPage(pageName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Special handling for configuration page - ensure config-display is visible and refresh data
|
||||||
|
if (pageName === 'configuration') {
|
||||||
|
const configDisplay = document.getElementById('config-display');
|
||||||
|
if (configDisplay) {
|
||||||
|
configDisplay.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
// Always refresh configuration data when navigating to config page
|
||||||
|
fetchConfiguration().catch(error => {
|
||||||
|
console.log('Failed to refresh configuration on page switch: ' + error.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Close side navigation
|
// Close side navigation
|
||||||
closeSideNav();
|
closeSideNav();
|
||||||
|
|
||||||
@@ -4668,6 +4637,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
// Initialize dark mode
|
// Initialize dark mode
|
||||||
initializeDarkMode();
|
initializeDarkMode();
|
||||||
|
|
||||||
|
// Initialize sidebar button text
|
||||||
|
const navDarkModeBtn = document.getElementById('nav-dark-mode-btn');
|
||||||
|
if (navDarkModeBtn) {
|
||||||
|
navDarkModeBtn.textContent = document.body.classList.contains('dark-mode') ? 'LIGHT MODE' : 'DARK MODE';
|
||||||
|
}
|
||||||
|
|
||||||
// Start RELAY letter animation
|
// Start RELAY letter animation
|
||||||
startRelayAnimation();
|
startRelayAnimation();
|
||||||
|
|
||||||
@@ -4714,6 +4689,30 @@ function initializeSideNavigation() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Footer button handlers
|
||||||
|
const navDarkModeBtn = document.getElementById('nav-dark-mode-btn');
|
||||||
|
const navLogoutBtn = document.getElementById('nav-logout-btn');
|
||||||
|
|
||||||
|
if (navDarkModeBtn) {
|
||||||
|
navDarkModeBtn.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
toggleDarkMode();
|
||||||
|
// Update button text after toggle
|
||||||
|
setTimeout(() => {
|
||||||
|
navDarkModeBtn.textContent = document.body.classList.contains('dark-mode') ? 'LIGHT MODE' : 'DARK MODE';
|
||||||
|
}, 10);
|
||||||
|
closeSideNav();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navLogoutBtn) {
|
||||||
|
navLogoutBtn.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
logout();
|
||||||
|
closeSideNav();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Set initial page
|
// Set initial page
|
||||||
switchPage(currentPage);
|
switchPage(currentPage);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -10,10 +10,10 @@
|
|||||||
#define MAIN_H
|
#define MAIN_H
|
||||||
|
|
||||||
// Version information (auto-updated by build system)
|
// Version information (auto-updated by build system)
|
||||||
#define VERSION "v0.7.36"
|
#define VERSION "v0.7.37"
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 7
|
#define VERSION_MINOR 7
|
||||||
#define VERSION_PATCH 36
|
#define VERSION_PATCH 37
|
||||||
|
|
||||||
// Relay metadata (authoritative source for NIP-11 information)
|
// Relay metadata (authoritative source for NIP-11 information)
|
||||||
#define RELAY_NAME "C-Relay"
|
#define RELAY_NAME "C-Relay"
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ int validate_timestamp_range(long since, long until, char* error_message, size_t
|
|||||||
int validate_numeric_limits(int limit, char* error_message, size_t error_size);
|
int validate_numeric_limits(int limit, char* error_message, size_t error_size);
|
||||||
int validate_search_term(const char* search_term, char* error_message, size_t error_size);
|
int validate_search_term(const char* search_term, char* error_message, size_t error_size);
|
||||||
|
|
||||||
|
// Forward declaration for monitoring function
|
||||||
|
void monitoring_on_subscription_change(void);
|
||||||
|
|
||||||
// Global database variable
|
// Global database variable
|
||||||
extern sqlite3* g_db;
|
extern sqlite3* g_db;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user