refactor: migrate Ant Design notifications to use App.useApp() context via a new global provider.

1.
notifications_manager.tsx
 - Hybrid notification approach:

Added notificationInstance variable to store the context-based instance
Added
setNotificationInstance()
 function to inject the instance from context
Created
getNotification()
 helper that prefers context instance, falls back to static
Added COMMON_NOTIFICATION_PROPS (exported) with showProgress: true and pauseOnHover: true
All notification methods (
error
,
warning
,
info
,
success
,
fromBackend
) now spread COMMON_NOTIFICATION_PROPS
2.
AntdGlobalProvider.tsx
 - New context provider:

Wraps app with Antd's <App> component
Uses App.useApp() hook to get the context-based notification instance
Injects it into NotificationManager via
setNotificationInstance()
This commit is contained in:
Swayambhu 2026-02-06 09:44:02 +05:30
parent 95f8cbe5ca
commit 08a6fe2bfa
3 changed files with 54 additions and 15 deletions

View file

@ -2,6 +2,8 @@ import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import AntdGlobalProvider from "@/contexts/AntdGlobalProvider";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
@ -17,7 +19,9 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
<body className={inter.className}>
<AntdGlobalProvider>{children}</AntdGlobalProvider>
</body>
</html>
);
}

View file

@ -1,8 +1,18 @@
import React from "react";
import { notification } from "antd";
import { notification as staticNotification } from "antd";
import type { NotificationInstance } from "antd/es/notification/interface";
import { parseErrorMessage } from "../shared/errorUtils";
import { ArgsProps } from "antd/es/notification";
let notificationInstance: NotificationInstance | null = null;
export const setNotificationInstance = (instance: NotificationInstance) => {
notificationInstance = instance;
};
// Helper to get the best available notification instance
const getNotification = () => notificationInstance || staticNotification;
type Placement = "top" | "topLeft" | "topRight" | "bottom" | "bottomLeft" | "bottomRight";
type NotificationConfig = {
@ -251,7 +261,7 @@ function looksErrorPayload(input: any, status?: number): boolean {
const NotificationManager = {
error(input: string | NotificationConfig) {
const cfg = normalize(input, "Error");
notification.error({
getNotification().error({
...COMMON_NOTIFICATION_PROPS,
...cfg,
placement: cfg.placement ?? defaultPlacement(),
@ -261,7 +271,7 @@ const NotificationManager = {
warning(input: string | NotificationConfig) {
const cfg = normalize(input, "Warning");
notification.warning({
getNotification().warning({
...COMMON_NOTIFICATION_PROPS,
...cfg,
placement: cfg.placement ?? defaultPlacement(),
@ -271,7 +281,7 @@ const NotificationManager = {
info(input: string | NotificationConfig) {
const cfg = normalize(input, "Info");
notification.info({
getNotification().info({
...COMMON_NOTIFICATION_PROPS,
...cfg,
placement: cfg.placement ?? defaultPlacement(),
@ -281,7 +291,7 @@ const NotificationManager = {
success(input: string | React.ReactNode | NotificationConfig) {
if (React.isValidElement(input)) {
notification.success({
getNotification().success({
...COMMON_NOTIFICATION_PROPS,
message: "Success",
description: input,
@ -291,7 +301,7 @@ const NotificationManager = {
return;
}
const cfg = normalize(input as string | NotificationConfig, "Success");
notification.success({
getNotification().success({
...COMMON_NOTIFICATION_PROPS,
...cfg,
placement: cfg.placement ?? defaultPlacement(),
@ -316,11 +326,11 @@ const NotificationManager = {
title === "Content Blocked" ||
title === "Integration Error"
) {
notification.warning({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 7 });
getNotification().warning({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 7 });
return;
}
if (title === "Server Error") {
notification.error({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 8 });
getNotification().error({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 8 });
return;
}
if (
@ -331,10 +341,10 @@ const NotificationManager = {
title === "Error" ||
title === "Already Exists"
) {
notification.error({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 6 });
getNotification().error({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 6 });
return;
}
notification.info({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 4 });
getNotification().info({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 4 });
return;
}
@ -343,18 +353,18 @@ const NotificationManager = {
const payload = { ...base, message: cls?.title ?? "Info" };
if (cls?.kind === "success") {
notification.success({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 3.5 });
getNotification().success({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 3.5 });
return;
}
if (cls?.kind === "warning") {
notification.warning({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 6 });
getNotification().warning({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 6 });
return;
}
notification.info({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 4 });
getNotification().info({ ...COMMON_NOTIFICATION_PROPS, ...payload, duration: extra?.duration ?? 4 });
},
clear() {
notification.destroy();
getNotification().destroy();
},
};

View file

@ -0,0 +1,25 @@
"use client";
import React, { useEffect } from "react";
import { App } from "antd";
import { setNotificationInstance } from "@/components/molecules/notifications_manager";
// Inner component to use the hook
const AntdAppInit = () => {
const { notification } = App.useApp();
useEffect(() => {
setNotificationInstance(notification);
}, [notification]);
return null;
};
export default function AntdGlobalProvider({ children }: { children: React.ReactNode }) {
return (
<App>
<AntdAppInit />
{children}
</App>
);
}