diff --git a/app/api/notifications/test/route.ts b/app/api/notifications/test/route.ts new file mode 100644 index 0000000..f89ec61 --- /dev/null +++ b/app/api/notifications/test/route.ts @@ -0,0 +1,33 @@ +import { NextRequest, NextResponse } from "next/server"; +import prisma from "@/app/prisma"; +import { z } from "zod/v4"; + +const schema = z.object({ + notificationProviderId: z.number() +}) + +export async function POST(request: NextRequest) { + try { + const body = await request.json(); + const { notificationProviderId } = schema.parse(body); + + const notificationProvider = await prisma.notificationProvider.findUnique({ + where: { id: notificationProviderId } + }) + + if(!notificationProvider) { + return NextResponse.json({ error: "Notification provider not found" }, { status: 404 }); + } + + const notificationTest = await prisma.notificationTest.create({ + data: { notificationProviderId: notificationProviderId } + }) + + return NextResponse.json({ notificationTest }, { status: 201 }); + } catch (error) { + if(error instanceof z.ZodError) { + return NextResponse.json({ error: error.issues[0].message }, { status: 400 }); + } + return NextResponse.json({ error: "Internal server error" }, { status: 500 }); + } +} \ No newline at end of file diff --git a/components/cards/settings/NotificationSettings.tsx b/components/cards/settings/NotificationSettings.tsx index 500f016..954d574 100644 --- a/components/cards/settings/NotificationSettings.tsx +++ b/components/cards/settings/NotificationSettings.tsx @@ -3,14 +3,21 @@ import { useState } from 'react'; import AddNotification from '@/components/dialogues/AddNotification'; import DeleteNotification from '@/components/dialogues/DeleteNotification'; +import TestNotification from '@/components/dialogues/TestNotification'; import useNotifications from '@/hooks/useNotifications'; import { Plus, Trash2, Play, Bell } from 'lucide-react'; import Loading from '@/components/Loading'; export const NotificationSettings = ({ onError, onSuccess }: { onError: (message: string) => void, onSuccess: (message: string) => void }) => { - const { loadNotifications, notifications, loading } = useNotifications(); + const { loadNotifications, notifications, loading, testNotification } = useNotifications(); const [deleteNotificationId, setDeleteNotificationId] = useState(null); + + const testNotificationHandler = async (notificationProviderId: number) => { + (document.getElementById('test_notification') as HTMLDialogElement)?.showModal(); + await testNotification(notificationProviderId); + } + return (
@@ -48,7 +55,7 @@ export const NotificationSettings = ({ onError, onSuccess }: { onError: (message {notification.type}
- +
@@ -72,6 +79,7 @@ export const NotificationSettings = ({ onError, onSuccess }: { onError: (message {deleteNotificationId && ( )} +
); diff --git a/components/dialogues/TestNotification.tsx b/components/dialogues/TestNotification.tsx new file mode 100644 index 0000000..7901cd4 --- /dev/null +++ b/components/dialogues/TestNotification.tsx @@ -0,0 +1,24 @@ +import { Bell } from "lucide-react" + +export default function TestNotification() { + return ( +
+ +
+
+
+ +
+

Test Notification

+
+ +
+

+ This will send a test notification to the selected notification provider. +

+
+
+
+
+ ) +} \ No newline at end of file diff --git a/hooks/useNotifications.ts b/hooks/useNotifications.ts index f1eafa0..012fad0 100644 --- a/hooks/useNotifications.ts +++ b/hooks/useNotifications.ts @@ -41,12 +41,23 @@ const useNotifications = () => { }); } + const testNotification = (notificationProviderId: number): Promise | string => { + return axios.post('/api/notifications/test', { notificationProviderId }) + .then((response) => { + return response.data.notificationTest; + }) + .catch(err => { + throw err.response?.data?.error || 'An error occurred'; + }); + } + return { notifications, loading, addNotification, deleteNotification, - loadNotifications + loadNotifications, + testNotification }; }