87 lines
2.1 KiB
TypeScript
87 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef } from "react";
|
|
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
|
|
import { toast } from "@/lib/toast";
|
|
|
|
const TOAST_PARAM_NAMES = ["success", "error"] as const;
|
|
const PENDING_TOAST_STORAGE_KEY = "mohfarawati-pending-toast";
|
|
|
|
export function QueryToastBridge() {
|
|
const pathname = usePathname();
|
|
const router = useRouter();
|
|
const searchParams = useSearchParams();
|
|
const handledKeyRef = useRef<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
const rawToast = window.sessionStorage.getItem(PENDING_TOAST_STORAGE_KEY);
|
|
|
|
if (!rawToast) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const pendingToast = JSON.parse(rawToast) as {
|
|
message?: string;
|
|
type?: "success" | "error";
|
|
};
|
|
const localizedMessage = pendingToast.message;
|
|
|
|
if (!localizedMessage) {
|
|
return;
|
|
}
|
|
|
|
if (pendingToast.type === "error") {
|
|
toast.error(localizedMessage);
|
|
} else if (pendingToast.type === "success") {
|
|
toast.success(localizedMessage);
|
|
} else {
|
|
toast(localizedMessage);
|
|
}
|
|
} finally {
|
|
window.sessionStorage.removeItem(PENDING_TOAST_STORAGE_KEY);
|
|
}
|
|
}, [pathname]);
|
|
|
|
useEffect(() => {
|
|
const successMessage = searchParams.get("success");
|
|
const errorMessage = searchParams.get("error");
|
|
|
|
if (!successMessage && !errorMessage) {
|
|
handledKeyRef.current = null;
|
|
return;
|
|
}
|
|
|
|
const handledKey = `${pathname}:${successMessage ?? ""}:${errorMessage ?? ""}`;
|
|
|
|
if (handledKeyRef.current === handledKey) {
|
|
return;
|
|
}
|
|
|
|
handledKeyRef.current = handledKey;
|
|
|
|
if (successMessage) {
|
|
toast.success(successMessage);
|
|
}
|
|
|
|
if (errorMessage) {
|
|
toast.error(errorMessage);
|
|
}
|
|
|
|
const nextParams = new URLSearchParams(searchParams.toString());
|
|
|
|
for (const name of TOAST_PARAM_NAMES) {
|
|
nextParams.delete(name);
|
|
}
|
|
|
|
const nextQuery = nextParams.toString();
|
|
|
|
router.replace(nextQuery ? `${pathname}?${nextQuery}` : pathname, {
|
|
scroll: false,
|
|
});
|
|
}, [pathname, router, searchParams]);
|
|
|
|
return null;
|
|
}
|