From 3a409461f760a96f10d3f17e7e3cba8007bd6a87 Mon Sep 17 00:00:00 2001 From: Biswajeet Das Date: Thu, 5 Sep 2024 22:24:40 +0530 Subject: [PATCH] feat: doc (#687) * feat: doc * feat: add old code examples * feat: add inbox * feat: remove export * feat: add compoents code for old implementation --- inbox/react/migration-guide.mdx | 878 ++++++++++++++++++++++++++++++++ mint.json | 3 +- 2 files changed, 880 insertions(+), 1 deletion(-) create mode 100644 inbox/react/migration-guide.mdx diff --git a/inbox/react/migration-guide.mdx b/inbox/react/migration-guide.mdx new file mode 100644 index 00000000..1b09447e --- /dev/null +++ b/inbox/react/migration-guide.mdx @@ -0,0 +1,878 @@ +--- +title: "Migration Guide" +sidebarTitle: "Migration Guide" +description: "This guide outlines the key differences between the `@novu/notification-center` package and the new `@novu/react` package. Follow the steps below to migrate your application to the latest version." +--- + +The `@novu/react` package introduces a more flexible and customizable way to display notifications in your application. This guide outlines the key differences between the `@novu/notification-center` package and the new `@novu/react` package. Follow the steps below to migrate your application to the latest Inbox version. + +## Why you should upgrade to @novu/react + +- **Customization**: The `@novu/react` package provides more customization options for the appearance and behavior of the notification components. +- **Flexibility**: The new package offers more flexibility in handling notifications and integrating with third-party libraries. +- **Performance**: It is optimized for performance and provides a smoother user experience. +- **Bundle Size**: The new package has a smaller bundle size and improved tree-shaking capabilities. +- **Compatibility with the `@novu/framework`**: The `@novu/react` package is designed to work seamlessly with the `@novu/framework` package for creating and managing notifications. + +## Breaking Changes + +The `@novu/react` package introduces several breaking changes compared to the `@novu/notification-center` package. Here are the key differences: + +### Components + +- The `PopoverNotificationCenter` component has been replaced with the `Inbox` component. +- The `NotificationCenter` component has been replaced with the `Notifications` component. +- The `NotificationBell` component has been replaced with the `Bell` component. + +### Styling + +- The `styles` props is replaced by an enchanced and easy to use `appearance` prop to customize the appearance of the notification components. For more information on `appearance` customization visit [here](customization#appearance-prop). + +### Notification + +- Removal of `seen` , `lastSeenDate`, `content`, `templateIdentifier`, `payload`, `cta` properties from the Notification object. +- We have introduced `archive` functionality to the Notification object. + +```diff +type Notification = { +- _id: string; ++ id: string; + +- content: string; ++ body: string; + +- cta: IMessageCTA; ++ redirect?: Redirect; ++ primaryAction?: Action; ++ secondaryAction?: Action; + +- channel: ChannelTypeEnum; ++ channelType: ChannelType; + +- payload: Record; ++ data?: Record; + +- subscriber: Subscriber; ++ to: Subscriber; + +- seen: boolean; +- lastSeenDate: string; +- templateIdentifier: string; + ++ subject?: string; ++ isRead: boolean; ++ isArchived: boolean; ++ readAt?: string | null; ++ archivedAt?: string | null; ++ avatar?: string; ++ tags?: string[]; + +createdAt: string; +}; + + +type Subscriber = { + id: string; + firstName?: string; + lastName?: string; + avatar?: string; + subscriberId: string; +}; + +type Redirect = { + url: string; + target?: '_self' | '_blank' | '_parent' | '_top' | '_unfencedTop'; +}; + +type Action = { + label: string; + isCompleted: boolean; + redirect?: Redirect; +}; +``` + +## Getting Started + +To begin migrating to `@novu/react`, install the package via npm: + +```bash +npm install @novu/react +``` + +## Basic Usage + +- Old Implementation + +```tsx +import { + NovuProvider, + PopoverNotificationCenter, + NotificationBell, +} from "@novu/notification-center"; + +function Novu() { + return ( + + + {({ unseenCount }) => } + + + ); +} +export default Novu; +``` + +- New Implementation with @novu/react + +```tsx +import { Inbox } from "@novu/react"; + +function Novu() { + return ( + + ); +} + +export default Novu; +``` + +## Notification Center without Bell Icon + +The @novu/react package introduces a flexible way to display notifications as a list without the default bell icon. Utilize the `Inbox` and `Notifications` components to achieve this functionality. + +- Old Implementation + +```tsx +import { NovuProvider, NotificationCenter } from "@novu/notification-center"; + +function Novu() { + return ( + + + + ); +} + +export default Novu; +``` + +- New Implementation with @novu/react + +```tsx +import { Inbox, Notifications } from "@novu/react"; + +function Novu() { + return ( + + + + ); +} + +export default Novu; +``` + +## Custom Bell Icon + +Customize the bell icon that triggers the notifications popover using the `renderBell` prop. + +- Old Implementation + +```tsx +import { + NovuProvider, + PopoverNotificationCenter, +} from "@novu/notification-center"; +import CustomBell from "./CustomBell"; // Your custom bell icon component + +function Novu() { + return ( + + + {({ unseenCount }) => ( + + )} + + + ); +} + +export default Novu; +``` + +- New Implementation with @novu/react + +```tsx +import { Inbox } from "@novu/react"; +import CustomBell from "./CustomBell"; // Your custom bell icon component + +function Novu() { + return ( + } + /> + ); +} + +export default Novu; +``` + +## Notification Actions + +Handle user interactions with notifications effectively using the action handlers provided by `@novu/react`. + +### onNotificationClick + +Trigger a callback function when a user clicks on a notification item. + +- Old Implementation + +```tsx +import { + NovuProvider, + PopoverNotificationCenter, + NotificationBell, + IMessage, +} from "@novu/notification-center"; + +function Novu() { + function handleOnNotificationClick(message: IMessage) { + // your logic to handle the notification click + if (message?.cta?.data?.url) { + window.location.href = message.cta.data.url; + } + } + + return ( + + + {({ unseenCount }) => } + + + ); +} + +export default Novu; +``` + +- New Implementation with @novu/react + +```tsx +import { Inbox } from "@novu/react"; + +function Novu() { + const handleNotificationClick = (notification) => { + // Your custom logic here + console.log("Notification clicked:", notification); + }; + + return ( + + ); +} + +export default Novu; +``` + +### onPrimaryActionClick and onSecondaryActionClick + +Handle primary and secondary actions within a notification explicitly. + +- Old Implementation + +```tsx +import { + NovuProvider, + PopoverNotificationCenter, + IMessage, + MessageActionStatusEnum, + useUpdateAction, + ButtonTypeEnum, + NotificationBell, +} from "@novu/notification-center"; + +function Novu() { + const CustomNotificationCenter = () => { + const { updateAction } = useUpdateAction(); + + const handleOnActionClick = async ( + templateIdentifier: string, + btnType: ButtonTypeEnum, + notification: IMessage + ) => { + if (templateIdentifier === "friend-request") { + if (btnType === "primary") { + /** Call your API to accept the friend request here **/ + + /** And then update Novu that this action has been taken, so the user won't see the button again **/ + updateAction({ + messageId: notification._id, + actionButtonType: btnType, + status: MessageActionStatusEnum.DONE, + }); + } + } + }; + + return ( + + {({ unseenCount }) => } + + ); + }; + + return ( + + + + ); +} + +export default Novu; +``` + +- New Implementation with @novu/react + +```tsx +import { Inbox } from "@novu/react"; + +function Novu() { + const handlePrimaryActionClick = (notification) => { + // Handle primary action + console.log("Primary action clicked:", notification); + }; + + const handleSecondaryActionClick = (notification) => { + // Handle secondary action + console.log("Secondary action clicked:", notification); + }; + + return ( + + ); +} + +export default Novu; +``` + +## Avatar Icons + +Customize the avatar displayed alongside notifications by specifying an avatar `URL` at the workflow definition level using `@novu/framework`. + +```ts +import { workflow } from "@novu/framework"; + +workflow("welcome-notification", async (step) => { + await step.inApp("inbox", async () => ({ + subject: "Welcome to Our Service!", + body: "We are thrilled to have you onboard.", + avatar: "https://example.com/path-to-your-avatar-image.png", + })); +}); +``` + +## Popover Positioning + +For advanced positioning and styling of the notifications popover, integrate third-party popover libraries such as Radix UI. + +- Old Implementation + +```tsx +import { + PopoverNotificationCenter, + NotificationBell, + NovuProvider, +} from "@novu/notification-center"; + +function Novu() { + return ( + + + {({ unseenCount }) => } + + + ); +} + +export default Novu; +``` + +- New Implementation with @novu/react and Radix UI as an example + +```tsx +import React from "react"; +import * as RadixPopover from "@radix-ui/react-popover"; +import { Inbox, Bell, Notifications } from "@novu/react"; + +function Novu() { + return ( + + + + + + + + + + + + + + ); +} + +export default Novu; +``` + +## Custom Notification Item + +Customize the appearance and structure of individual notification items using the `renderNotification` prop. + +- Old Implementation + +```tsx +import { + NovuProvider, + PopoverNotificationCenter, + NotificationBell, +} from "@novu/notification-center"; + +function Novu() { + return ( + + { + return ( + { + e.preventDefault(); + handleNotificationClick(); + }} + > + {notification.content} + + ); + }} + > + {({ unseenCount }) => { + return ; + }} + + + ); +} + +export default Novu; +``` + +- New Implementation with @novu/react + +```tsx +import { Inbox } from "@novu/react"; + +function Novu() { + const renderCustomNotificationItem = (notification) => ( +
notification.read()} + > + Avatar +
+

{notification.subject}

+

{notification.body}

+
+
+ ); + + return ( + + ); +} + +export default Novu; +``` + +## Styling with appearance Prop + +Customize the overall look and feel of the notification components using the appearance prop, which supports both CSS objects and class names (including Tailwind CSS classes). + +- Old Implementation + +```tsx +import { + NovuProvider, + PopoverNotificationCenter, + NotificationBell, +} from "@novu/notification-center"; + +function Novu() { + return ( + + + {({ unseenCount }) => } + + + ); +} + +export default Novu; +``` + +- New Implementation with @novu/react + +```tsx +import { Inbox } from "@novu/react"; + +function Novu() { + return ( + + ); +} + +export default Novu; +``` + +For more information on `appearance` customization visit [here](customization#appearance-prop). + +## Multiple Tabs Support + +Organize notifications into different categories using tabs by leveraging the tags property in workflow definitions and the tabs prop in the Inbox component. + +### Create Multiple Tabs + +- Old Implementation + +- After defining the feeds on the Workflow UI, you were able to filter notifications based on the feedIdentifier. + +```tsx +import { + NovuProvider, + PopoverNotificationCenter, + NotificationBell, +} from "@novu/notification-center"; + +function Novu() { + return ( + + + {({ unseenCount }) => { + return ( + + ); + }} + + + ); +} + +export default Novu; +``` + +- New Implementation with @novu/react + +1. Define multiple workflows with relevant tags. + +```ts +import { workflow } from "@novu/framework"; + +workflow( + "security-alerts", + async (step) => { + await step.inApp("inbox", async () => ({ + subject: "Security Alert", + body: "A new login attempt was detected.", + })); + }, + { tags: ["security"] } +); + +workflow( + "promotional-offers", + async (step) => { + await step.inApp("inbox", async () => ({ + subject: "Exclusive Offer!", + body: "Get 50% off on your next purchase.", + })); + }, + { tags: ["promotions"] } +); +``` + +2. Assign relevant tags to each workflow to categorize notifications appropriately. + +```tsx +import { Inbox } from "@novu/react"; + +const tabs = [ + { label: "All Notifications", value: [] }, + { label: "Security", value: ["security"] }, + { label: "Promotions", value: ["promotions"] }, +]; + +function Novu() { + return ( + + ); +} + +export default Novu; +``` + +## Localization + +Customize the language and text content of the notification components using the localization prop. + +```tsx +import { Inbox } from "@novu/react"; + +function Novu() { + return ( + + ); +} + +export default Novu; +``` + +## HMAC Encryption + +The process remains the same as before. See the detailed guide [here](advanced-configuration#hmac-encryption). + +## Handling Notifications + +Handle notifications using the methods provided by the notification object. + +### Marking Notifications as Read + +Mark notifications as read using the `read` method provided by the notification object. + +```tsx +import { Inbox } from "@novu/react"; + +function Novu() { + const handleNotificationClick = (notification) => { + notification.read(); + }; + + return ( + + ); +} + +export default Novu; +``` + +### Marking Notifications as Unread + +Mark notifications as unread using the `unread` method provided by the notification object. + +```tsx +import { Inbox } from "@novu/react"; + +function Novu() { + const handleNotificationClick = (notification) => { + notification.unread(); + }; + + return ( + + ); +} + +export default Novu; +``` + +### Marking Notifications as Archive + +Mark notifications as archive using the `archive` method provided by the notification object. + +```tsx +import { Inbox } from "@novu/react"; + +function Novu() { + const handleNotificationClick = (notification) => { + notification.archive(); + }; + + return ( + + ); +} + +export default Novu; +``` + +### Marking Notifications as Unarchive + +Mark notifications as unarchive using the `unarchive` method provided by the notification object. + +```tsx +import { Inbox } from "@novu/react"; + +function Novu() { + const handleNotificationClick = (notification) => { + notification.unarchive(); + }; + + return ( + + ); +} + +export default Novu; +``` diff --git a/mint.json b/mint.json index c4e7b2e1..a60cd11c 100644 --- a/mint.json +++ b/mint.json @@ -125,7 +125,8 @@ "inbox/react/components", "inbox/react/preference", "inbox/react/multiple-tabs", - "inbox/react/advanced-configuration" + "inbox/react/advanced-configuration", + "inbox/react/migration-guide" ] }, {