From 8d1ff5d816e39d4f9279959caacf3f2cd6741efe Mon Sep 17 00:00:00 2001 From: coo1estguy <70365929+coolestcodeguy@users.noreply.github.com> Date: Mon, 14 Sep 2026 23:14:11 +0530 Subject: [PATCH] feat(dashboard): add login screen, auth provider, and server-client example --- dashboard/next.config.ts | 9 +- dashboard/src/app/analytics/page.tsx | 2 +- dashboard/src/app/dlq/page.tsx | 6 +- dashboard/src/app/globals.css | 2 +- dashboard/src/app/layout.tsx | 17 +- dashboard/src/app/login/page.tsx | 143 ++++++++++++++ dashboard/src/app/projects/page.tsx | 5 +- dashboard/src/app/scheduled/page.tsx | 4 +- dashboard/src/app/system/page.tsx | 2 +- dashboard/src/app/templates/page.tsx | 4 +- dashboard/src/app/users/page.tsx | 4 +- dashboard/src/app/workflows/page.tsx | 6 +- dashboard/src/components/DashboardHeader.tsx | 43 +++-- dashboard/src/components/LogsTable.tsx | 4 +- dashboard/src/components/RealTimeFeed.tsx | 4 +- dashboard/src/components/Sidebar.tsx | 50 ++++- dashboard/src/hooks/useAuth.tsx | 190 +++++++++++++++++++ dashboard/src/hooks/useProjectKey.tsx | 61 ++++-- examples/basic-usage/index.js | 77 ++++---- examples/custom-server/index.js | 26 ++- examples/load-test/index.js | 16 +- examples/scheduled-notifications/index.js | 36 ++-- examples/server-client/README.md | 50 +++++ examples/server-client/client.js | 108 +++++++++++ examples/server-client/package.json | 10 + examples/server-client/server.js | 58 ++++++ examples/workflows/index.js | 68 +++---- scripts/coverage-badge.mjs | 18 +- 28 files changed, 837 insertions(+), 186 deletions(-) create mode 100644 dashboard/src/app/login/page.tsx create mode 100644 dashboard/src/hooks/useAuth.tsx create mode 100644 examples/server-client/README.md create mode 100644 examples/server-client/client.js create mode 100644 examples/server-client/package.json create mode 100644 examples/server-client/server.js diff --git a/dashboard/next.config.ts b/dashboard/next.config.ts index 41a9c18..91749db 100644 --- a/dashboard/next.config.ts +++ b/dashboard/next.config.ts @@ -1,5 +1,12 @@ import type { NextConfig } from "next"; -const nextConfig: NextConfig = {/* config options here */}; +const nextConfig: NextConfig = { + basePath: "/admin", + output: "export", + trailingSlash: true, + images: { + unoptimized: true, + }, +}; export default nextConfig; diff --git a/dashboard/src/app/analytics/page.tsx b/dashboard/src/app/analytics/page.tsx index f2533fb..2aac24f 100644 --- a/dashboard/src/app/analytics/page.tsx +++ b/dashboard/src/app/analytics/page.tsx @@ -26,7 +26,7 @@ export default function AnalyticsPage() { const fetchMetrics = useCallback(async () => { setIsLoading(true); try { - const apiUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000"; + const apiUrl = process.env.NEXT_PUBLIC_API_URL || ""; const res = await fetch(`${apiUrl}/v1/system/metrics`, { headers: { Authorization: `Bearer ${projectApiKey}`, diff --git a/dashboard/src/app/dlq/page.tsx b/dashboard/src/app/dlq/page.tsx index 6581466..a54752c 100644 --- a/dashboard/src/app/dlq/page.tsx +++ b/dashboard/src/app/dlq/page.tsx @@ -34,7 +34,7 @@ export default function DeadLetterQueuePage() { const fetchDLQ = useCallback(async () => { setIsLoading(true); try { - const apiUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000"; + const apiUrl = process.env.NEXT_PUBLIC_API_URL || ""; const res = await fetch(`${apiUrl}/v1/dlq`, { headers: { Authorization: `Bearer ${projectApiKey}`, @@ -60,7 +60,7 @@ export default function DeadLetterQueuePage() { const handleReplay = async (id: string) => { try { - const apiUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000"; + const apiUrl = process.env.NEXT_PUBLIC_API_URL || ""; const res = await fetch(`${apiUrl}/v1/dlq/replay`, { method: "POST", headers: { @@ -80,7 +80,7 @@ export default function DeadLetterQueuePage() { const handleDelete = async (id: string) => { try { - const apiUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3000"; + const apiUrl = process.env.NEXT_PUBLIC_API_URL || ""; const res = await fetch(`${apiUrl}/v1/dlq/${id}`, { method: "DELETE", headers: { diff --git a/dashboard/src/app/globals.css b/dashboard/src/app/globals.css index c56032b..6a25b1b 100644 --- a/dashboard/src/app/globals.css +++ b/dashboard/src/app/globals.css @@ -127,4 +127,4 @@ html { @apply font-sans; } -} \ No newline at end of file +} diff --git a/dashboard/src/app/layout.tsx b/dashboard/src/app/layout.tsx index 8b3023a..bbce3d5 100644 --- a/dashboard/src/app/layout.tsx +++ b/dashboard/src/app/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import { Toaster } from "@/components/ui/sonner"; import Sidebar from "@/components/Sidebar"; +import { AuthProvider } from "@/hooks/useAuth"; import { ProjectProvider } from "@/hooks/useProjectKey"; import "./globals.css"; @@ -16,8 +17,8 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "Notifkit Observability", - description: "Real-time delivery observability dashboard for Notifkit", + title: "Notifkit Observability & Admin", + description: "Real-time delivery observability dashboard and admin console for Notifkit", }; export default function RootLayout({ children }: { children: React.ReactNode }) { @@ -27,11 +28,13 @@ export default function RootLayout({ children }: { children: React.ReactNode }) className={`${geistSans.variable} ${geistMono.variable} h-full antialiased dark`} >
-