This commit updates the web frontend TypeScript modules: Core modules: - admin.ts: Admin panel functionality and user management - analytics.ts: Analytics dashboard and data visualization - api-explorer.ts: Interactive API documentation explorer - api.ts: Core API client with request/response handling - collections.ts: Book collection management UI - conflicts.ts: Sync conflict resolution interface - custom-section-builder.ts: Dynamic section builder for UI - docs.ts: Documentation viewer and navigation - dom.ts: DOM manipulation utilities and helpers - header.ts: Application header with navigation - library.ts: Library view and book grid management - linking.ts: Device-book linking interface - password_validation.ts: Client-side password strength validation - queue.ts: Device sync queue management UI - search.ts: Full-text search with Lunr integration - storage.ts: Local storage and cache management - theme.ts: Theme management and CSS variable updates - themeDropdown.ts: Theme selector dropdown component - toast.ts: Toast notification system - woodPaneling.ts: Visual theme effects - woodPanelingInit.ts: Visual effects initialization Type definitions: - api.d.ts: Updated TypeScript definitions for API responses These updates enhance the frontend with improved functionality for book management, device synchronization, and user experience.
93 lines
2.6 KiB
TypeScript
93 lines
2.6 KiB
TypeScript
// Header functionality
|
|
|
|
const toggleThemeDropdown = (): void => {
|
|
const dropdown = document.getElementById("theme-dropdown");
|
|
if (dropdown) {
|
|
dropdown.classList.toggle("hidden");
|
|
|
|
// Close user menu if open
|
|
const userMenu = document.getElementById("user-menu");
|
|
if (userMenu && !dropdown.classList.contains("hidden")) {
|
|
userMenu.classList.add("hidden");
|
|
}
|
|
}
|
|
};
|
|
|
|
const toggleUserMenu = (): void => {
|
|
const menu = document.getElementById("user-menu");
|
|
if (menu) {
|
|
menu.classList.toggle("hidden");
|
|
|
|
// Close theme dropdown if open
|
|
const themeDropdown = document.getElementById("theme-dropdown");
|
|
if (themeDropdown && !menu.classList.contains("hidden")) {
|
|
themeDropdown.classList.add("hidden");
|
|
}
|
|
}
|
|
};
|
|
|
|
const changeThemeTo = (theme: string): void => {
|
|
// Apply the theme using the consolidated function from theme.ts
|
|
if ((window as any).applyTheme) {
|
|
(window as any).applyTheme(theme);
|
|
}
|
|
|
|
// Save to server if logged in
|
|
const token = localStorage.getItem("token");
|
|
if (token) {
|
|
fetch("/api/auth/theme", {
|
|
method: "PUT",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${token}`,
|
|
},
|
|
body: JSON.stringify({ theme }),
|
|
}).catch((err) => console.log("Theme save failed", err));
|
|
}
|
|
|
|
// Close dropdown
|
|
const dropdown = document.getElementById("theme-dropdown");
|
|
if (dropdown) {
|
|
dropdown.classList.add("hidden");
|
|
}
|
|
};
|
|
|
|
const logout = (): void => {
|
|
localStorage.removeItem("token");
|
|
localStorage.removeItem("user");
|
|
window.location.href = "/";
|
|
};
|
|
|
|
// Close dropdowns when clicking outside
|
|
document.addEventListener("click", (e) => {
|
|
const target = e.target as HTMLElement;
|
|
const themeDropdown = document.getElementById("theme-dropdown");
|
|
const userMenu = document.getElementById("user-menu");
|
|
const themeButton = target?.closest(
|
|
'button[onclick="toggleThemeDropdown()"]',
|
|
);
|
|
const userButton = target?.closest('button[onclick="toggleUserMenu()"]');
|
|
|
|
if (
|
|
!themeButton &&
|
|
themeDropdown &&
|
|
!themeDropdown.classList.contains("hidden")
|
|
) {
|
|
if (!themeDropdown.contains(target)) {
|
|
themeDropdown.classList.add("hidden");
|
|
}
|
|
}
|
|
|
|
if (!userButton && userMenu && !userMenu.classList.contains("hidden")) {
|
|
if (!userMenu.contains(target)) {
|
|
userMenu.classList.add("hidden");
|
|
}
|
|
}
|
|
});
|
|
|
|
// Make functions available globally
|
|
(window as any).toggleThemeDropdown = toggleThemeDropdown;
|
|
(window as any).toggleUserMenu = toggleUserMenu;
|
|
(window as any).changeThemeTo = changeThemeTo;
|
|
(window as any).logout = logout;
|