28632e8970
- Add admin authentication and dashboard - Create event management pages (list, create, edit, archive) - Implement gallery enhancements (search, sorting, bulk download) - Add email configuration and archive management pages - Integrate Umami analytics with tracking throughout the app - Add comprehensive error boundaries and loading states - Implement accessibility features (WCAG 2.1 AA compliance) - Create theme system with preset themes and customization - Add branding settings and company information management - Fix backend database initialization and health check - Configure proper API URLs and environment variables 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
24 lines
725 B
TypeScript
24 lines
725 B
TypeScript
import { useEffect, type RefObject } from 'react';
|
|
|
|
export function useOnClickOutside<T extends HTMLElement = HTMLElement>(
|
|
ref: RefObject<T | null>,
|
|
handler: () => void
|
|
) {
|
|
useEffect(() => {
|
|
const listener = (event: MouseEvent | TouchEvent) => {
|
|
// Do nothing if clicking ref's element or descendent elements
|
|
if (!ref.current || ref.current.contains(event.target as Node)) {
|
|
return;
|
|
}
|
|
handler();
|
|
};
|
|
|
|
document.addEventListener('mousedown', listener);
|
|
document.addEventListener('touchstart', listener);
|
|
|
|
return () => {
|
|
document.removeEventListener('mousedown', listener);
|
|
document.removeEventListener('touchstart', listener);
|
|
};
|
|
}, [ref, handler]);
|
|
} |