init
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, RefObject } from 'react';
|
||||
|
||||
export function useClickOutside(
|
||||
ref: RefObject<HTMLDivElement | null>,
|
||||
callback: () => void
|
||||
) {
|
||||
useEffect(() => {
|
||||
const handleClick = (event: MouseEvent) => {
|
||||
if (!ref) {
|
||||
return;
|
||||
}
|
||||
if (ref.current && !ref.current.contains(event.target as Node)) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('mousedown', handleClick);
|
||||
return () => {
|
||||
document.removeEventListener('mousedown', handleClick);
|
||||
};
|
||||
}, [ref, callback]);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
|
||||
interface UseNavigationBlockerProps {
|
||||
shouldBlock: boolean;
|
||||
message?: string;
|
||||
onConfirm?: () => void;
|
||||
onCancel?: () => void;
|
||||
}
|
||||
|
||||
export const useNavigationBlocker = ({
|
||||
shouldBlock,
|
||||
message,
|
||||
onConfirm,
|
||||
onCancel
|
||||
}: UseNavigationBlockerProps) => {
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
if (!shouldBlock) return;
|
||||
|
||||
const handleBeforeUnload = (e: BeforeUnloadEvent) => {
|
||||
e.preventDefault();
|
||||
e.returnValue = message;
|
||||
return message;
|
||||
};
|
||||
|
||||
const handleClick = (e: MouseEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
const link = target.closest('a');
|
||||
|
||||
if (link && link.href) {
|
||||
const currentUrl = window.location.href;
|
||||
if (link.href !== currentUrl && !link.href.startsWith('#')) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const confirmed = window.confirm(message);
|
||||
if (confirmed) {
|
||||
onConfirm?.();
|
||||
window.location.href = link.href;
|
||||
} else {
|
||||
onCancel?.();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('beforeunload', handleBeforeUnload);
|
||||
document.addEventListener('click', handleClick, true);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('beforeunload', handleBeforeUnload);
|
||||
document.removeEventListener('click', handleClick, true);
|
||||
};
|
||||
}, [shouldBlock, message, onConfirm, onCancel]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!shouldBlock) return;
|
||||
|
||||
const originalPush = router.push;
|
||||
|
||||
router.push = async (...args) => {
|
||||
const confirmed = window.confirm(message);
|
||||
if (confirmed) {
|
||||
onConfirm?.();
|
||||
return originalPush.apply(router, args);
|
||||
} else {
|
||||
onCancel?.();
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
};
|
||||
|
||||
return () => {
|
||||
router.push = originalPush;
|
||||
};
|
||||
}, [shouldBlock, message, router, onConfirm, onCancel]);
|
||||
};
|
||||
Reference in New Issue
Block a user