Merge pull request 'fix: add null checks for document and firebase messaging to prevent SSR errors' (#49) from table-filter into develop

Reviewed-on: https://repo.ravanertebat.com/TM/tm_panel/pulls/49
Reviewed-by: Sina Nakhostin <s.nakhostin@ravanertebat.com>
This commit is contained in:
Sina Nakhostin
2025-11-15 12:32:34 +03:30
6 changed files with 50 additions and 17 deletions
+2 -1
View File
@@ -130,8 +130,9 @@ function MultiSelect<T extends FieldValues>({
return; return;
setShow(false); setShow(false);
}; };
document?.addEventListener("click", clickHandler); document?.addEventListener("click", clickHandler);
return () => document.removeEventListener("click", clickHandler); return () => document?.removeEventListener("click", clickHandler);
}, [show]); }, [show]);
return ( return (
+4 -1
View File
@@ -8,12 +8,15 @@ import { toast } from "react-toastify";
const Notification = ({ children }: PropsWithChildren) => { const Notification = ({ children }: PropsWithChildren) => {
useEffect(() => { useEffect(() => {
onMessage(messaging, (payload) => { const messagingInstance = messaging();
if (messagingInstance) {
onMessage(messagingInstance, (payload) => {
console.log("Message received. ", payload); console.log("Message received. ", payload);
if (payload.notification) { if (payload.notification) {
toast.success(payload.notification.title ?? "New Notification"); toast.success(payload.notification.title ?? "New Notification");
} }
}); });
}
}, []); }, []);
return <>{children}</>; return <>{children}</>;
+3 -3
View File
@@ -54,12 +54,12 @@ const ConfirmationModal: React.FC<ConfirmationModalProps> = (props) => {
if (isOpen) { if (isOpen) {
document?.addEventListener("keydown", handleEscape); document?.addEventListener("keydown", handleEscape);
document.body.style.overflow = "hidden"; if (document) document.body.style.overflow = "hidden";
} }
return () => { return () => {
document.removeEventListener("keydown", handleEscape); document?.removeEventListener("keydown", handleEscape);
document.body.style.overflow = "unset"; if (document) document.body.style.overflow = "unset";
}; };
}, [isOpen, onCancel]); }, [isOpen, onCancel]);
+2 -2
View File
@@ -46,9 +46,9 @@ export function Dropdown({ children, isOpen, setIsOpen }: DropdownProps) {
if (isOpen) { if (isOpen) {
triggerRef.current = document.activeElement as HTMLElement; triggerRef.current = document.activeElement as HTMLElement;
document.body.style.pointerEvents = "none"; if (document) document.body.style.pointerEvents = "none";
} else { } else {
document.body.style.removeProperty("pointer-events"); if (document) document.body.style.removeProperty("pointer-events");
setTimeout(() => { setTimeout(() => {
triggerRef.current?.focus(); triggerRef.current?.focus();
+3 -3
View File
@@ -33,13 +33,13 @@ const Modal: React.FC<ModalProps> = ({
useEffect(() => { useEffect(() => {
if (isOpen) { if (isOpen) {
document.body.style.overflow = "hidden"; if (document) document.body.style.overflow = "hidden";
} else { } else {
document.body.style.overflow = "unset"; if (document) document.body.style.overflow = "unset";
} }
return () => { return () => {
document.body.style.overflow = "unset"; if (document) document.body.style.overflow = "unset";
}; };
}, [isOpen]); }, [isOpen]);
+31 -2
View File
@@ -2,6 +2,7 @@ import { COOKIE_KEYS } from "@/lib/shared/cookies";
import { initializeApp } from "firebase/app"; import { initializeApp } from "firebase/app";
import { getMessaging, getToken } from "firebase/messaging"; import { getMessaging, getToken } from "firebase/messaging";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
const firebaseConfig = { const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
@@ -11,11 +12,35 @@ const firebaseConfig = {
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
}; };
// Initialize Firebase app
const app = initializeApp(firebaseConfig); const app = initializeApp(firebaseConfig);
export const messaging = getMessaging(app);
// Lazy initialization of messaging to avoid SSR issues
let messaging: any = null;
const getMessagingInstance = () => {
if (typeof window !== 'undefined' && !messaging) {
try {
messaging = getMessaging(app);
} catch (error) {
console.warn('Failed to initialize Firebase Messaging:', error);
}
}
return messaging;
};
export const requestForToken = () => { export const requestForToken = () => {
return getToken(messaging) // Only run on client side
if (typeof window === 'undefined') {
return Promise.resolve(null);
}
const messagingInstance = getMessagingInstance();
if (!messagingInstance) {
return Promise.resolve(null);
}
return getToken(messagingInstance)
.then((currentToken) => { .then((currentToken) => {
if (currentToken) { if (currentToken) {
console.log("current token for client: ", currentToken); console.log("current token for client: ", currentToken);
@@ -27,9 +52,13 @@ export const requestForToken = () => {
); );
// ... // ...
} }
return currentToken;
}) })
.catch((err) => { .catch((err) => {
console.log("An error occurred while retrieving token. ", err); console.log("An error occurred while retrieving token. ", err);
// ... // ...
return null;
}); });
}; };
export { getMessagingInstance as messaging };