Add dashboard redesign, custom section builder, and enhanced search functionality
Features: - Complete dashboard redesign with improved UI components and layout - Implement custom section builder for personalized book organization - Add new events tracking system for user interactions - Enhance search functionality with better static search.js - Update TypeScript type definitions for API responses Backend: - Update Go dependencies in go.mod - Add new frontend routes in router Templates: - Update admin and dashboard templates with new components Frontend: - Refactor analytics, collections, conflicts, and queue modules - Add new documentation features in docs.ts - Implement linking between books and collections - Add toast notifications for user feedback - Include placeholder book SVG asset This commit consolidates multiple feature additions and improvements across the entire stack including backend, templates, and frontend.
This commit is contained in:
+110
-92
@@ -1,117 +1,135 @@
|
||||
function onDelegatedClick(selector: string, handler: (element: HTMLElement, event: MouseEvent) => void): void {
|
||||
document.addEventListener('click', (event: MouseEvent) => {
|
||||
const target = event.target as HTMLElement;
|
||||
const element = target.closest(selector) as HTMLElement | null;
|
||||
if (element) {
|
||||
handler(element, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onDelegatedSubmit(selector: string, handler: (form: HTMLFormElement, event: Event) => void): void {
|
||||
document.addEventListener('submit', (event: Event) => {
|
||||
const target = event.target as HTMLElement;
|
||||
const form = target.closest(selector) as HTMLFormElement | null;
|
||||
if (form) {
|
||||
handler(form, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onDelegatedChange(selector: string, handler: (element: HTMLElement, event: Event) => void): void {
|
||||
document.addEventListener('change', (event: Event) => {
|
||||
const target = event.target as HTMLElement;
|
||||
const element = target.closest(selector) as HTMLElement | null;
|
||||
if (element) {
|
||||
handler(element, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onDelegatedKeydown(selector: string, handler: (element: HTMLElement, event: KeyboardEvent) => void): void {
|
||||
document.addEventListener('keydown', (event: KeyboardEvent) => {
|
||||
const target = event.target as HTMLElement;
|
||||
const element = target.closest(selector) as HTMLElement | null;
|
||||
if (element) {
|
||||
handler(element, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getDataAttribute(element: HTMLElement, name: string): string | undefined {
|
||||
return element.dataset[name];
|
||||
}
|
||||
|
||||
function setDataAttribute(element: HTMLElement, name: string, value: string): void {
|
||||
element.dataset[name] = value;
|
||||
}
|
||||
|
||||
function onClick(element: HTMLElement | null, handler: (event: MouseEvent) => void): void {
|
||||
function onDelegatedClick(
|
||||
selector: string,
|
||||
handler: (element: HTMLElement, event: MouseEvent) => void,
|
||||
): void {
|
||||
document.addEventListener("click", (event: MouseEvent) => {
|
||||
const target = event.target as HTMLElement;
|
||||
const element = target.closest(selector) as HTMLElement | null;
|
||||
if (element) {
|
||||
element.addEventListener('click', handler);
|
||||
handler(element, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onSubmit(element: HTMLFormElement | null, handler: (event: Event) => void): void {
|
||||
if (element) {
|
||||
element.addEventListener('submit', handler);
|
||||
function onDelegatedSubmit(
|
||||
selector: string,
|
||||
handler: (form: HTMLFormElement, event: Event) => void,
|
||||
): void {
|
||||
document.addEventListener("submit", (event: Event) => {
|
||||
const target = event.target as HTMLElement;
|
||||
const form = target.closest(selector) as HTMLFormElement | null;
|
||||
if (form) {
|
||||
handler(form, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onChange(element: HTMLElement | null, handler: (event: Event) => void): void {
|
||||
function onDelegatedChange(
|
||||
selector: string,
|
||||
handler: (element: HTMLElement, event: Event) => void,
|
||||
): void {
|
||||
document.addEventListener("change", (event: Event) => {
|
||||
const target = event.target as HTMLElement;
|
||||
const element = target.closest(selector) as HTMLElement | null;
|
||||
if (element) {
|
||||
element.addEventListener('change', handler);
|
||||
handler(element, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onKeydown(element: HTMLElement | null, handler: (event: KeyboardEvent) => void): void {
|
||||
function onDelegatedKeydown(
|
||||
selector: string,
|
||||
handler: (element: HTMLElement, event: KeyboardEvent) => void,
|
||||
): void {
|
||||
document.addEventListener("keydown", (event: KeyboardEvent) => {
|
||||
const target = event.target as HTMLElement;
|
||||
const element = target.closest(selector) as HTMLElement | null;
|
||||
if (element) {
|
||||
element.addEventListener('keydown', handler);
|
||||
handler(element, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onInput(element: HTMLElement | null, handler: (event: Event) => void): void {
|
||||
if (element) {
|
||||
element.addEventListener('input', handler);
|
||||
}
|
||||
function getDataAttribute(
|
||||
element: HTMLElement,
|
||||
name: string,
|
||||
): string | undefined {
|
||||
return element.dataset[name];
|
||||
}
|
||||
|
||||
function setDataAttribute(
|
||||
element: HTMLElement,
|
||||
name: string,
|
||||
value: string,
|
||||
): void {
|
||||
element.dataset[name] = value;
|
||||
}
|
||||
|
||||
function onClick(
|
||||
element: HTMLElement | null,
|
||||
handler: (event: MouseEvent) => void,
|
||||
): void {
|
||||
if (element) {
|
||||
element.addEventListener("click", handler);
|
||||
}
|
||||
}
|
||||
|
||||
function onSubmit(
|
||||
element: HTMLFormElement | null,
|
||||
handler: (event: Event) => void,
|
||||
): void {
|
||||
if (element) {
|
||||
element.addEventListener("submit", handler);
|
||||
}
|
||||
}
|
||||
|
||||
function onChange(
|
||||
element: HTMLElement | null,
|
||||
handler: (event: Event) => void,
|
||||
): void {
|
||||
if (element) {
|
||||
element.addEventListener("change", handler);
|
||||
}
|
||||
}
|
||||
|
||||
function onKeydown(
|
||||
element: HTMLElement | null,
|
||||
handler: (event: KeyboardEvent) => void,
|
||||
): void {
|
||||
if (element) {
|
||||
element.addEventListener("keydown", handler);
|
||||
}
|
||||
}
|
||||
|
||||
function onInput(
|
||||
element: HTMLElement | null,
|
||||
handler: (event: Event) => void,
|
||||
): void {
|
||||
if (element) {
|
||||
element.addEventListener("input", handler);
|
||||
}
|
||||
}
|
||||
|
||||
function preventDefault(event: Event): void {
|
||||
event.preventDefault();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
function stopPropagation(event: Event): void {
|
||||
event.stopPropagation();
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
(window as any).events = {
|
||||
onDelegatedClick,
|
||||
onDelegatedSubmit,
|
||||
onDelegatedChange,
|
||||
onDelegatedKeydown,
|
||||
getDataAttribute,
|
||||
setDataAttribute,
|
||||
onClick,
|
||||
onSubmit,
|
||||
onChange,
|
||||
onKeydown,
|
||||
onInput,
|
||||
preventDefault,
|
||||
stopPropagation
|
||||
};
|
||||
|
||||
export {
|
||||
onDelegatedClick,
|
||||
onDelegatedSubmit,
|
||||
onDelegatedChange,
|
||||
onDelegatedKeydown,
|
||||
getDataAttribute,
|
||||
setDataAttribute,
|
||||
onClick,
|
||||
onSubmit,
|
||||
onChange,
|
||||
onKeydown,
|
||||
onInput,
|
||||
preventDefault,
|
||||
stopPropagation
|
||||
onDelegatedClick,
|
||||
onDelegatedSubmit,
|
||||
onDelegatedChange,
|
||||
onDelegatedKeydown,
|
||||
getDataAttribute,
|
||||
setDataAttribute,
|
||||
onClick,
|
||||
onSubmit,
|
||||
onChange,
|
||||
onKeydown,
|
||||
onInput,
|
||||
preventDefault,
|
||||
stopPropagation,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user