Check Notification Test Status

This commit is contained in:
headlesdev 2025-05-25 21:43:42 +02:00
parent 78f1d54fc3
commit fb13c2bfce
4 changed files with 101 additions and 8 deletions

View File

@ -0,0 +1,33 @@
import { NextRequest, NextResponse } from "next/server";
import prisma from "@/app/prisma";
import { z } from "zod/v4";
const schema = z.object({
notificationTestId: z.string()
})
export async function GET(request: NextRequest) {
try {
const searchParams = request.nextUrl.searchParams;
const notificationTestId = schema.parse({ notificationTestId: searchParams.get('notificationTestId') });
if(!notificationTestId) {
return NextResponse.json({ error: "Notification test ID is required" }, { status: 400 });
}
const notificationTest = await prisma.notificationTest.findUnique({
where: { id: parseInt(notificationTestId.notificationTestId) }
})
if(!notificationTest) {
return NextResponse.json({ error: "Notification test not found" }, { status: 404 });
}
return NextResponse.json({ notificationTest }, { status: 200 });
} 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 });
}
}

View File

@ -11,11 +11,13 @@ import Loading from '@/components/Loading';
export const NotificationSettings = ({ onError, onSuccess }: { onError: (message: string) => void, onSuccess: (message: string) => void }) => {
const { loadNotifications, notifications, loading, testNotification } = useNotifications();
const [deleteNotificationId, setDeleteNotificationId] = useState<number | null>(null);
const [notificationTestId, setNotificationTestId] = useState<number | null>(null);
const testNotificationHandler = async (notificationProviderId: number) => {
(document.getElementById('test_notification') as HTMLDialogElement)?.showModal();
await testNotification(notificationProviderId);
const notificationTest = await testNotification(notificationProviderId);
setNotificationTestId(notificationTest.id);
}
return (
@ -79,7 +81,9 @@ export const NotificationSettings = ({ onError, onSuccess }: { onError: (message
{deleteNotificationId && (
<DeleteNotification notificationId={deleteNotificationId} onNotificationDeleted={loadNotifications} onError={onError} onSuccess={onSuccess} />
)}
<TestNotification />
{notificationTestId && (
<TestNotification notificationTestId={notificationTestId} />
)}
</div>
</div>
);

View File

@ -1,6 +1,22 @@
import { Bell, CheckCircle2, Clock } from "lucide-react"
import { Bell, CheckCircle2, Clock, X } from "lucide-react"
import useNotifications from "@/hooks/useNotifications";
import { useState } from "react";
import { useEffect } from "react";
interface TestNotificationProps {
notificationTestId: number;
}
export default function TestNotification({ notificationTestId }: TestNotificationProps) {
const { getNotificationTest, notificationTest } = useNotifications();
const checkNotificationTest = async () => {
console.log(notificationTestId);
await getNotificationTest(notificationTestId);
}
export default function TestNotification() {
return (
<div>
<dialog id="test_notification" className="modal">
@ -25,21 +41,40 @@ export default function TestNotification() {
</p>
<div className="flex items-center gap-3 mt-6">
<button className="btn btn-success gap-2">
<button className="btn btn-success gap-2" onClick={checkNotificationTest}>
<Clock className="h-4 w-4" />
Check Status
</button>
<div className="flex items-center gap-2 px-4 py-2 bg-base-300 rounded-lg">
<span className="text-sm font-medium">Status:</span>
{!notificationTest?.sent && !notificationTest?.success && (
<div className="flex items-center gap-1.5 text-warning">
<Clock className="h-4 w-4" />
<span className="text-sm">Pending</span>
</div>
<span className="text-sm">Pending</span>
</div>
)}
{notificationTest?.sent && !notificationTest?.success && (
<div className="flex items-center gap-1.5 text-error">
<X className="h-4 w-4" />
<span className="text-sm">Failed</span>
</div>
)}
{notificationTest?.sent && notificationTest?.success && (
<div className="flex items-center gap-1.5 text-success">
<CheckCircle2 className="h-4 w-4" />
<span className="text-sm">Success</span>
</div>
)}
</div>
</div>
</div>
</div>
<div className="modal-action">
<form method="dialog" className="flex gap-3 w-full justify-end">
<button className="btn btn-outline">Close</button>
</form>
</div>
</div>
</dialog>
</div>

View File

@ -1,9 +1,17 @@
import { useState, useEffect, useCallback } from "react";
import axios from "axios";
interface NotificationTest {
id: number;
notificationProviderId: number;
sent: boolean;
success: boolean;
}
const useNotifications = () => {
const [notifications, setNotifications] = useState([]);
const [loading, setLoading] = useState(false);
const [notificationTest, setNotificationTest] = useState<NotificationTest | null>(null);
const loadNotifications = useCallback(() => {
setLoading(true);
@ -51,13 +59,26 @@ const useNotifications = () => {
});
}
const getNotificationTest = (notificationTestId: number): Promise<string> | string => {
return axios.get('/api/notifications/test/get', { params: { notificationTestId } })
.then((response) => {
setNotificationTest(response.data.notificationTest);
return response.data.notificationTest;
})
.catch(err => {
throw err.response?.data?.error || 'An error occurred';
});
}
return {
notifications,
loading,
addNotification,
deleteNotification,
loadNotifications,
testNotification
testNotification,
getNotificationTest,
notificationTest
};
}