Skip to content

Commit 1f6dd86

Browse files
authored
feat: create useNotifications hook (#220)
1 parent faf9f8c commit 1f6dd86

5 files changed

Lines changed: 130 additions & 1 deletion

File tree

app/providers.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
import { SessionProvider } from 'next-auth/react';
44
import { ReactNode } from 'react';
55
import { AuthProvider } from '@/components/providers/auth-provider';
6+
import { NotificationProvider } from 'react-notification-core';
7+
import {
8+
mockFetchNotifications,
9+
mockMarkAsRead,
10+
mockMarkAllAsRead,
11+
mockDeleteNotification,
12+
} from '@/lib/mock';
613

714
interface ProvidersProps {
815
children: ReactNode;
@@ -11,7 +18,21 @@ interface ProvidersProps {
1118
export function Providers({ children }: ProvidersProps) {
1219
return (
1320
<SessionProvider>
14-
<AuthProvider>{children}</AuthProvider>
21+
<AuthProvider>
22+
<NotificationProvider
23+
fetchNotifications={mockFetchNotifications}
24+
onMarkAsRead={mockMarkAsRead}
25+
onMarkAllAsRead={mockMarkAllAsRead}
26+
onDeleteNotification={mockDeleteNotification}
27+
fetchOptions={{
28+
retryCount: 2,
29+
retryDelay: 1000,
30+
timeout: 5000,
31+
}}
32+
>
33+
{children}
34+
</NotificationProvider>
35+
</AuthProvider>
1536
</SessionProvider>
1637
);
1738
}

hooks/use-notifications.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { useNotifications as useCoreNotifications } from 'react-notification-core';
2+
3+
export function useNotifications() {
4+
const {
5+
notifications,
6+
unreadCount,
7+
markAsRead,
8+
markAllAsRead,
9+
deleteNotification,
10+
refreshNotifications,
11+
isLoading,
12+
error,
13+
} = useCoreNotifications();
14+
15+
return {
16+
notifications,
17+
unreadCount,
18+
markAsRead,
19+
markAllAsRead,
20+
deleteNotification,
21+
refreshNotifications,
22+
isLoading,
23+
error,
24+
};
25+
}

lib/mock.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { Project } from '@/types/project';
2+
import type { Notification } from "react-notification-core"
3+
24

35
export const mockProjects: Project[] = [
46
{
@@ -108,3 +110,72 @@ export const mockCampaignDetails = {
108110
],
109111
status: 'validated',
110112
};
113+
114+
115+
116+
const mockNotifications: Notification[] = [
117+
118+
{
119+
id: "1",
120+
title: "New feature available",
121+
message: "Check out our new dashboard features.",
122+
timestamp: new Date(Date.now() - 60 * 60 * 1000),
123+
read: true,
124+
type: "info",
125+
},
126+
{
127+
id: "2",
128+
title: "Action required",
129+
message: "Please verify your email address.",
130+
timestamp: new Date(Date.now() - 2 * 60 * 60 * 1000),
131+
read: false,
132+
type: "warning",
133+
},
134+
{
135+
id: "3",
136+
title: "Payment successful",
137+
message: "Your subscription has been renewed.",
138+
timestamp: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000),
139+
read: true,
140+
type: "success",
141+
},
142+
{
143+
id: "4",
144+
title: "Login attempt",
145+
message: "A new login was detected from an unknown device.",
146+
timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000),
147+
read: false,
148+
type: "error",
149+
},
150+
]
151+
152+
let notifications = [...mockNotifications]
153+
154+
// Mock API functions
155+
export async function mockFetchNotifications(): Promise<Notification[]> {
156+
await new Promise((resolve) => setTimeout(resolve, 500))
157+
158+
// Simulate occasional errors (1 in 10 chance)
159+
if (Math.random() < 0.1) {
160+
throw new Error("Failed to fetch notifications")
161+
}
162+
163+
return [...notifications]
164+
}
165+
166+
export async function mockMarkAsRead(id: string): Promise<void> {
167+
await new Promise((resolve) => setTimeout(resolve, 300))
168+
notifications = notifications.map((notification) =>
169+
notification.id === id ? { ...notification, read: true } : notification,
170+
)
171+
}
172+
173+
export async function mockMarkAllAsRead(): Promise<void> {
174+
await new Promise((resolve) => setTimeout(resolve, 300))
175+
notifications = notifications.map((notification) => ({ ...notification, read: true }))
176+
}
177+
178+
export async function mockDeleteNotification(id: string): Promise<void> {
179+
await new Promise((resolve) => setTimeout(resolve, 300))
180+
notifications = notifications.filter((notification) => notification.id !== id)
181+
}

package-lock.json

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
"react-day-picker": "^9.8.0",
7777
"react-dom": "19.1.0",
7878
"react-hook-form": "^7.62.0",
79+
"react-notification-core": "^1.0.5",
7980
"react-resizable-panels": "^3.0.3",
8081
"recharts": "^2.15.4",
8182
"sonner": "^2.0.6",

0 commit comments

Comments
 (0)