Files
bookhoard/web/src/index.ts
T
john-okeefe b78aacd320 feat: Add new Alpine.js component TypeScript files
Extracted inline JavaScript from templates into proper TypeScript modules:

- api-explorer-docs.ts: API explorer page functionality
- collection-rules.ts: Collection rules management page
- index.ts: Homepage theme and auth redirect
- login.ts: Login page theme initialization
- profile-modal.ts: Profile modal close and escape key
- profile.ts: Profile page delete account
- register.ts: Registration page theme init
- toast-error.ts: Error toast with retry button
- unlinked_books.ts: Unlinked books management page

Each file:
- Uses ES imports (showToast, getToken, etc.)
- Has proper TypeScript types
- Registers with Alpine.js via Alpine.global()
- Uses async/await for API calls
2026-03-08 21:35:47 -04:00

51 lines
1.2 KiB
TypeScript

import { Alpine } from "./alpine";
import { applyTheme } from "./theme";
import { getToken } from "./storage";
function initIndexTheme(): void {
// Progressive enhancement: check localStorage immediately
const savedTheme = localStorage.getItem("theme");
if (savedTheme && savedTheme !== "tokyo-night") {
applyTheme(savedTheme);
}
}
function changeTheme(): void {
const select = document.getElementById("theme-select") as HTMLSelectElement;
if (!select) return;
const newTheme = select.value;
applyTheme(newTheme);
// Save to localStorage
localStorage.setItem("theme", newTheme);
}
async function checkAuthRedirect(): Promise<void> {
const token = getToken();
if (!token) return;
try {
const response = await fetch("/api/auth/profile", {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (response.ok) {
// Token is valid, redirect to dashboard
window.location.href = "/dashboard";
}
} catch (error) {
console.error("Failed to check auth", error);
}
}
export { changeTheme, checkAuthRedirect, initIndexTheme };
Alpine.global("index", {
changeTheme,
checkAuthRedirect,
initIndexTheme,
});