feat(admin): reorganize housekeeping and strengthen shared workflows
This commit is contained in:
1 parent
35f66d879f
commit
a070004e7b
35 files changed
+1667
-462
No files matched your search
@@ -0,0 +1,50 @@
|
||||
"use client";
|
||||
import { useEffect } from "react";
|
||||
/** Protect browser close/reload and same-tab link navigation while editing. */
|
||||
export function useUnsavedChanges(dirty: boolean, message: string) {
|
||||
useEffect(() => {
|
||||
if (!dirty) return;
|
||||
function beforeUnload(event: BeforeUnloadEvent) {
|
||||
event.preventDefault();
|
||||
event.returnValue = "";
|
||||
}
|
||||
function click(event: MouseEvent) {
|
||||
if (
|
||||
event.defaultPrevented ||
|
||||
event.button !== 0 ||
|
||||
event.ctrlKey ||
|
||||
event.metaKey ||
|
||||
event.shiftKey ||
|
||||
event.altKey
|
||||
)
|
||||
return;
|
||||
const link =
|
||||
event.target instanceof Element
|
||||
? event.target.closest("a[href]")
|
||||
: null;
|
||||
if (
|
||||
!(link instanceof HTMLAnchorElement) ||
|
||||
link.hasAttribute("download") ||
|
||||
(link.target && link.target !== "_self")
|
||||
)
|
||||
return;
|
||||
const target = new URL(link.href, location.href);
|
||||
if (
|
||||
target.origin === location.origin &&
|
||||
target.pathname === location.pathname &&
|
||||
target.search === location.search
|
||||
)
|
||||
return;
|
||||
if (!window.confirm(message)) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
window.addEventListener("beforeunload", beforeUnload);
|
||||
document.addEventListener("click", click, true);
|
||||
return () => {
|
||||
window.removeEventListener("beforeunload", beforeUnload);
|
||||
document.removeEventListener("click", click, true);
|
||||
};
|
||||
}, [dirty, message]);
|
||||
}
|
||||
Reference in new issue
Block a user