Safety backup before Path A fixes - fixing function mismatches and missing functions

This commit is contained in:
2026-03-11 11:01:43 -04:00
parent 0a5042e130
commit 083f152b35
62 changed files with 202 additions and 261 deletions
+1 -1
View File
@@ -396,7 +396,7 @@ export {
triggerQuickScan,
};
Alpine.global("admin", {
Alpine.store("admin", {
hideScanProgress,
loadSystemStats,
loadWatchStatus,
+5
View File
@@ -1,4 +1,5 @@
import { showToast } from "./toast";
import { Alpine } from "./alpine";
async function loadAnalytics(): Promise<void> {
const token = localStorage.getItem("token");
@@ -124,3 +125,7 @@ function renderPopularBooks(popular: PopularBooksResponse): void {
document.addEventListener("DOMContentLoaded", loadAnalytics);
export { loadAnalytics };
Alpine.store("analytics", {
loadAnalytics,
});
+1 -1
View File
@@ -132,7 +132,7 @@ export {
tryDocEndpoint,
};
Alpine.global("apiExplorerDoc", {
Alpine.store("apiExplorerDoc", {
copyDocRequest,
copyDocResponse,
generateDocCURL,
+1 -1
View File
@@ -99,7 +99,7 @@ export {
handleError,
};
Alpine.global("api", {
Alpine.store("api", {
get: apiGet,
post: apiPost,
put: apiPut,
+1 -1
View File
@@ -196,7 +196,7 @@ export {
viewBook,
};
Alpine.global("bookshelf", {
Alpine.store("bookshelf", {
changePage,
initBookshelf,
loadBookshelf,
+1 -1
View File
@@ -408,7 +408,7 @@ export {
toggleRule,
};
Alpine.global("collectionRules", {
Alpine.store("collectionRules", {
backToCollection,
clearForm,
deleteRule,
+1 -1
View File
@@ -914,7 +914,7 @@ export {
updateSelectedCount,
};
Alpine.global("collections", {
Alpine.store("collections", {
addbooksToAdd,
backToCollections,
closeCollectionModal,
+1 -1
View File
@@ -216,7 +216,7 @@ export {
showResolveModal,
};
Alpine.global("conflicts", {
Alpine.store("conflicts", {
bulkDismiss,
bulkResolve,
dismissAllResolved,
+1 -1
View File
@@ -556,7 +556,7 @@ export {
showShelfMappings,
};
Alpine.global("devices", {
Alpine.store("devices", {
approveDevice,
clearSyncQueue,
copyToClipboard,
+2 -2
View File
@@ -93,14 +93,14 @@ document.addEventListener("DOMContentLoaded", () => {
initializeDocsSearch();
});
Alpine.global("docs", {
Alpine.store("docs", {
toggleSidebar,
initializeSearch: initializeDocsSearch,
});
export { toggleSidebar, initializeDocsSearch };
Alpine.global("docs", {
Alpine.store("docs", {
toggleSidebar,
initializeSearch: initializeDocsSearch,
});
+2 -29
View File
@@ -1,28 +1,6 @@
// Header functionality
import { Alpine } from "./alpine";
import { applyTheme } from "./theme";
import { updateThemeIndicators } from "./themeDropdown";
const changeTheme = (theme: string): void => {
// Apply the theme using the consolidated function from theme.ts
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));
}
// Alpine closes dropdown automatically via template state
};
const logout = (): void => {
localStorage.removeItem("token");
@@ -30,13 +8,8 @@ const logout = (): void => {
window.location.href = "/";
};
export { changeTheme, logout };
export { logout };
Alpine.global("header", {
Alpine.store("header", {
logout,
changeThemeTo: (theme: string) => {
console.log("changeThemeTo called with:", theme);
changeTheme(theme);
updateThemeIndicators();
},
});
+1 -1
View File
@@ -43,7 +43,7 @@ async function checkAuthRedirect(): Promise<void> {
export { changeTheme, checkAuthRedirect, initIndexTheme };
Alpine.global("index", {
Alpine.store("index", {
changeTheme,
checkAuthRedirect,
initIndexTheme,
+1 -1
View File
@@ -680,7 +680,7 @@ export {
confirmDeleteLibrary,
};
Alpine.global("library", {
Alpine.store("library", {
deleteLibrary,
showLibraryFolders,
addLibraryFolder,
+1 -1
View File
@@ -201,7 +201,7 @@ export {
showSuggestionsModal,
};
Alpine.global("linking", {
Alpine.store("linking", {
autoLinkBooks,
getSuggestions,
hideMatchModal,
+1 -1
View File
@@ -22,7 +22,7 @@ function changeTheme(): void {
export { changeTheme, initLoginTheme };
Alpine.global("login", {
Alpine.store("login", {
changeTheme,
initLoginTheme,
});
+1 -1
View File
@@ -189,6 +189,6 @@ function initPasswordValidation(): void {
// Export for use in template
export { initPasswordValidation };
Alpine.global("validation", {
Alpine.store("validation", {
initPasswordValidation,
});
+1 -1
View File
@@ -26,7 +26,7 @@ function setupProfileModal(): void {
export { closeProfileModal, setupProfileModal };
Alpine.global("profileModal", {
Alpine.store("profileModal", {
closeProfileModal,
setupProfileModal,
});
+1 -1
View File
@@ -41,6 +41,6 @@ async function confirmDeleteAccount(): Promise<void> {
export { confirmDeleteAccount };
Alpine.global("profile", {
Alpine.store("profile", {
confirmDeleteAccount,
});
+1 -1
View File
@@ -164,7 +164,7 @@ export {
retryQueueItem,
};
Alpine.global("queue", {
Alpine.store("queue", {
clearAllItems,
clearFailedItems,
deleteQueueItem,
+1 -1
View File
@@ -11,6 +11,6 @@ function initRegisterTheme(): void {
export { initRegisterTheme };
Alpine.global("register", {
Alpine.store("register", {
initRegisterTheme,
});
+1 -1
View File
@@ -307,6 +307,6 @@ document.addEventListener("DOMContentLoaded", initializeSearch);
export { selectLibraryAndBook };
Alpine.global("search", {
Alpine.store("search", {
selectLibraryAndBook,
});
+104 -10
View File
@@ -1,3 +1,4 @@
import { Alpine } from "./alpine";
// Theme management functionality
type ThemeType =
@@ -37,14 +38,8 @@ const loadTheme = (): void => {
applyTheme(theme);
};
// Handle theme change from user selection
const changeTheme = async (): Promise<void> => {
const themeSelect = document.getElementById(
"theme-select",
) as HTMLSelectElement;
if (!themeSelect) return;
const theme = themeSelect.value as ThemeType;
// Change: Remove DOM element lookup, accept theme as parameter
const changeTheme = async (theme: string): Promise<void> => {
applyTheme(theme);
// Save to server if logged in
@@ -128,14 +123,113 @@ const setupSmoothScroll = (): void => {
});
};
// Wood paneling management functionality
type WoodPanelingType = "none" | "wood-light" | "wood-dark" | "wood-mahogany";
const WOOD_STORAGE_KEY = "wood-paneling";
// Apply wood paneling to collections container
const applyWoodPaneling = (paneling: WoodPanelingType): void => {
const container = document.getElementById("collections-container");
const body = document.body;
if (!container || !body) return;
// Remove all wood background classes from container
container.classList.remove(
"bg-wood-light",
"bg-wood-dark",
"bg-wood-mahogany",
);
container.removeAttribute("data-wood");
// Remove from body
body.classList.remove("bg-wood-light", "bg-wood-dark", "bg-wood-mahogany");
if (paneling !== "none") {
// Add selected wood background class to both container and body
const woodClass = `bg-${paneling}`;
container.classList.add(woodClass);
container.setAttribute("data-wood", paneling);
// Add to body for overscroll area
body.classList.add(woodClass);
}
// Save to localStorage
localStorage.setItem(WOOD_STORAGE_KEY, paneling);
};
// Load wood paneling from localStorage on page load
const loadWoodPaneling = (): void => {
const stored = localStorage.getItem(
WOOD_STORAGE_KEY,
) as WoodPanelingType | null;
if (stored) {
applyWoodPaneling(stored);
} else {
// Default to none
applyWoodPaneling("none");
}
};
// Change wood paneling (called from theme dropdown)
const changeWoodPaneling = (paneling: WoodPanelingType): void => {
applyWoodPaneling(paneling);
// Update active indicators
updateWoodPanelingIndicators();
// Alpine closes dropdown automatically via template state
};
// Update visual indicators for wood paneling buttons
const updateWoodPanelingIndicators = (): void => {
const currentWood = localStorage.getItem(WOOD_STORAGE_KEY) || "none";
// Update wood paneling buttons
document.querySelectorAll(".wood-paneling-btn").forEach((btn) => {
const wood = btn.getAttribute("data-wood");
if (wood === currentWood) {
// Active state - use CSS class instead of inline style
btn.classList.add("bg-wood-active");
btn.classList.remove("bg-wood-inactive");
} else {
// Inactive state
btn.classList.remove("bg-wood-active");
btn.classList.add("bg-wood-inactive");
}
});
};
// Auto-initialize when DOM is ready
if (typeof document !== "undefined") {
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initializeTheme);
document.addEventListener("DOMContentLoaded", () => {
initializeTheme();
loadWoodPaneling();
updateWoodPanelingIndicators();
});
} else {
initializeTheme();
loadWoodPaneling();
updateWoodPanelingIndicators();
}
}
export { applyTheme, changeTheme, initializeTheme, loadTheme, loadUserTheme };
Alpine.store("theme", {
changeTheme,
changeWoodPaneling,
});
export {
applyTheme,
changeTheme,
changeWoodPaneling,
initializeTheme,
loadTheme,
loadUserTheme,
loadWoodPaneling,
updateWoodPanelingIndicators,
};
export type { ThemeType };
-28
View File
@@ -1,28 +0,0 @@
// Theme dropdown active indicator management
import { Alpine } from "./alpine";
import { updateWoodPanelingIndicators } from "./woodPaneling";
// Update visual indicators for theme buttons
// Note: With Alpine.js, most theme state is handled reactively in the template
// This function primarily ensures wood paneling indicators are updated
const updateThemeIndicators = (): void => {
updateWoodPanelingIndicators();
};
// Auto-initialize when DOM is ready
if (typeof document !== "undefined") {
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => {
updateThemeIndicators();
});
} else {
updateThemeIndicators();
}
}
Alpine.global("themeDropdown", {
updateIndicators: updateThemeIndicators,
});
export { updateThemeIndicators };
+1 -1
View File
@@ -30,6 +30,6 @@ function showErrorToast(message: string): void {
export { showErrorToast };
Alpine.global("toastError", {
Alpine.store("toastError", {
showErrorToast,
});
+1 -1
View File
@@ -226,7 +226,7 @@ if (typeof document !== "undefined") {
}
// Export toast API for manual use
Alpine.global("showToast", {
Alpine.store("showToast", {
error: (message: string, duration?: number) =>
showToast(message, "error", duration),
success: (message: string, duration?: number) =>
+1 -1
View File
@@ -427,7 +427,7 @@ export {
toggleAllUnlinked,
};
Alpine.global("unlinkedBooks", {
Alpine.store("unlinkedBooks", {
bulkAutoLink,
bulkGetSuggestions,
confirmManualLink,
-100
View File
@@ -1,100 +0,0 @@
// Wood paneling management functionality
import { Alpine } from "./alpine";
type WoodPanelingType = "none" | "wood-light" | "wood-dark" | "wood-mahogany";
const WOOD_STORAGE_KEY = "wood-paneling";
// Apply wood paneling to collections container
const applyWoodPaneling = (paneling: WoodPanelingType): void => {
const container = document.getElementById("collections-container");
const body = document.body;
if (!container || !body) return;
// Remove all wood background classes from container
container.classList.remove(
"bg-wood-light",
"bg-wood-dark",
"bg-wood-mahogany",
);
container.removeAttribute("data-wood");
// Remove from body
body.classList.remove("bg-wood-light", "bg-wood-dark", "bg-wood-mahogany");
if (paneling !== "none") {
// Add selected wood background class to both container and body
const woodClass = `bg-${paneling}`;
container.classList.add(woodClass);
container.setAttribute("data-wood", paneling);
// Add to body for overscroll area
body.classList.add(woodClass);
}
// Save to localStorage
localStorage.setItem(WOOD_STORAGE_KEY, paneling);
};
// Load wood paneling from localStorage on page load
const loadWoodPaneling = (): void => {
const stored = localStorage.getItem(
WOOD_STORAGE_KEY,
) as WoodPanelingType | null;
if (stored) {
applyWoodPaneling(stored);
} else {
// Default to none
applyWoodPaneling("none");
}
};
// Change wood paneling (called from theme dropdown)
const changeWoodPaneling = (paneling: WoodPanelingType): void => {
applyWoodPaneling(paneling);
// Update active indicators
updateWoodPanelingIndicators();
// Alpine closes dropdown automatically via template state
};
// Update visual indicators for wood paneling buttons
const updateWoodPanelingIndicators = (): void => {
const currentWood = localStorage.getItem(WOOD_STORAGE_KEY) || "none";
// Update wood paneling buttons
document.querySelectorAll(".wood-paneling-btn").forEach((btn) => {
const wood = btn.getAttribute("data-wood");
if (wood === currentWood) {
// Active state - use CSS class instead of inline style
btn.classList.add("bg-wood-active");
btn.classList.remove("bg-wood-inactive");
} else {
// Inactive state
btn.classList.remove("bg-wood-active");
btn.classList.add("bg-wood-inactive");
}
});
};
export { changeWoodPaneling, loadWoodPaneling, updateWoodPanelingIndicators };
// Register with Alpine for template access
Alpine.global("woodPaneling", {
change: changeWoodPaneling,
});
// Auto-initialize when DOM is ready
if (typeof document !== "undefined") {
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", () => {
loadWoodPaneling();
updateWoodPanelingIndicators();
});
} else {
loadWoodPaneling();
updateWoodPanelingIndicators();
}
}