summaryrefslogtreecommitdiffhomepage
path: root/frontend/src/utilities/routers.ts
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/utilities/routers.ts')
-rw-r--r--frontend/src/utilities/routers.ts40
1 files changed, 40 insertions, 0 deletions
diff --git a/frontend/src/utilities/routers.ts b/frontend/src/utilities/routers.ts
new file mode 100644
index 000000000..b3c91c541
--- /dev/null
+++ b/frontend/src/utilities/routers.ts
@@ -0,0 +1,40 @@
+// A workaround of built-in hooks in React-Router v6
+// https://gist.github.com/rmorse/426ffcc579922a82749934826fa9f743
+
+import type { Blocker, History, Transition } from "history";
+import { useContext, useEffect } from "react";
+import { UNSAFE_NavigationContext } from "react-router-dom";
+
+export function useBlocker(blocker: Blocker, when = true) {
+ const navigator = useContext(UNSAFE_NavigationContext).navigator as History;
+
+ useEffect(() => {
+ if (!when) return;
+
+ const unblock = navigator.block((tx: Transition) => {
+ const autoUnblockingTx = {
+ ...tx,
+ retry() {
+ // Automatically unblock the transition so it can play all the way
+ // through before retrying it. TODO: Figure out how to re-enable
+ // this block if the transition is cancelled for some reason.
+ unblock();
+ tx.retry();
+ },
+ };
+
+ blocker(autoUnblockingTx);
+ });
+
+ return unblock;
+ }, [navigator, blocker, when]);
+}
+
+// TODO: Replace with Mantine's confirmation modal
+export function usePrompt(when: boolean, message: string) {
+ useBlocker((tx) => {
+ if (window.confirm(message)) {
+ tx.retry();
+ }
+ }, when);
+}