diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 758e0d8..ca3faa6 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -972,23 +972,6 @@ "node": ">= 6" } }, - "node_modules/@creit.tech/stellar-wallets-kit/node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "extraneous": true, - "license": "Apache-2.0", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/@creit.tech/xbull-wallet-connect": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@creit.tech/xbull-wallet-connect/-/xbull-wallet-connect-0.4.0.tgz", @@ -7987,24 +7970,6 @@ "ws": "^7.5.1" } }, - "node_modules/@walletconnect/jsonrpc-ws-connection/node_modules/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "extraneous": true, - "hasInstallScript": true, - "license": "MIT", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, "node_modules/@walletconnect/jsonrpc-ws-connection/node_modules/ws": { "version": "7.5.11", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", @@ -13130,24 +13095,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "license": "MIT" }, - "node_modules/jayson/node_modules/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "extraneous": true, - "hasInstallScript": true, - "license": "MIT", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, "node_modules/jayson/node_modules/ws": { "version": "7.5.11", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz", diff --git a/dashboard/src/App.tsx b/dashboard/src/App.tsx index 967b943..bed2c53 100644 --- a/dashboard/src/App.tsx +++ b/dashboard/src/App.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useState, useRef, useEffect } from 'react'; import { EventExplorerPage } from './pages/EventExplorerPage'; import { NotificationTimelineView } from './components/NotificationTimelineView'; import { ActivityFeed } from './components/ActivityFeed'; @@ -22,105 +22,96 @@ type Tab = | 'preferences' | 'templates'; +const TAB_ITEMS: { id: Tab; label: string }[] = [ + { id: 'explorer', label: 'Event Explorer' }, + { id: 'timeline', label: 'Delivery Timeline' }, + { id: 'activity', label: 'Activity Feed' }, + { id: 'webhooks', label: 'Webhook Performance' }, + { id: 'export-history', label: 'Export History' }, + { id: 'search', label: 'Notification Search' }, + { id: 'preferences', label: 'Preferences' }, + { id: 'templates', label: 'Templates' }, +]; + export function App() { const [tab, setTab] = useState('explorer'); + const [menuOpen, setMenuOpen] = useState(false); const { theme, toggleTheme } = useTheme(); const events = useEventStore((state) => state.events); + const menuRef = useRef(null); - return ( -
-
- -
- | 'preferences'; + useEffect(() => { + function handleClickOutside(event: MouseEvent) { + if (menuRef.current && !menuRef.current.contains(event.target as Node)) { + setMenuOpen(false); + } + } -export function App() { - const [tab, setTab] = useState('explorer'); + function handleEscape(event: KeyboardEvent) { + if (event.key === 'Escape') { + setMenuOpen(false); + } + } + + if (menuOpen) { + document.addEventListener('mousedown', handleClickOutside); + document.addEventListener('keydown', handleEscape); + } + + return () => { + document.removeEventListener('mousedown', handleClickOutside); + document.removeEventListener('keydown', handleEscape); + }; + }, [menuOpen]); + + const handleTabChange = (newTab: Tab) => { + setTab(newTab); + setMenuOpen(false); + }; return (
- +
+
+

NotifyChain

+

Dashboard

+
+
+ +
+ + +
+
+
{tab === 'explorer' && ( <> diff --git a/dashboard/src/components/ExportHistorySkeleton.tsx b/dashboard/src/components/ExportHistorySkeleton.tsx new file mode 100644 index 0000000..73933aa --- /dev/null +++ b/dashboard/src/components/ExportHistorySkeleton.tsx @@ -0,0 +1,65 @@ +cliinterface ExportHistorySkeletonProps { + rows?: number; +} + +function SkeletonCell({ width }: { width: string }) { + return ( +

- {totalCount.toLocaleString()} {totalCount === 1 ? 'record' : 'records'} + {isLoading ? '—' : `${totalCount.toLocaleString()} ${totalCount === 1 ? 'record' : 'records'}`}

+ {/* ── Skeleton (loading) ───────────────────────────────────── */} + {isLoading && } + {/* ── Table or empty state ─────────────────────────────────── */} - {displayedExports.length > 0 ? ( + {!isLoading && displayedExports.length > 0 && ( - ) : ( + )} + + {!isLoading && displayedExports.length === 0 && (
+ {!isLoading && ( + + )} ); } diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index 7122a38..c5bb65f 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -4,6 +4,7 @@ import "./globals.css"; export const metadata: Metadata = { title: "NotifyChain - Analytics Dashboard", description: "Actionable insights into notification performance", + viewport: "width=device-width, initial-scale=1", }; export default function RootLayout({ diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx index f08f8dc..6f880d9 100644 --- a/frontend/app/page.tsx +++ b/frontend/app/page.tsx @@ -2,13 +2,13 @@ import Link from "next/link"; export default function Home() { return ( -
-
-

NotifyChain

-

Your analytics dashboard is ready!

+
+
+

NotifyChain

+

Your analytics dashboard is ready!

View Analytics Dashboard diff --git a/index.html b/index.html new file mode 100644 index 0000000..6794378 --- /dev/null +++ b/index.html @@ -0,0 +1,531 @@ + + + + + +Kairos Elite — Dashboard + + + + + + + +
+
+ + + + + +
+
+ +

Dashboard

+
+ + +
+ + + +
+ + +
+
+

Welcome back

+

Here's what's happening across your projects today.

+
+ +
+
+

Active projects

+

18

+ ▲ 3 this month +
+
+

Models in production

+

7

+ ▲ 1 this week +
+
+

Uptime, 30 days

+

99.92%

+ ▼ 0.03% +
+
+

Open tickets

+

5

+ ▲ 2 today +
+
+ +
+
+

Recent activity

+
    +
  • +
    +

    Deployment succeeded — Atlas NLP v2.3

    Cloud DevOps · Production
    + 2m ago +
  • +
  • +
    +

    New training run started — Sahel vision model

    AI / ML pipeline
    + 41m ago +
  • +
  • +
    +

    Design review approved — Client portal UI

    UI / UX design
    + 3h ago +
  • +
  • +
    +

    Smart contract audit completed — Ledger Vault

    Blockchain
    + Yesterday +
  • +
+
+ +
+

System status

+
API gatewayOperational
+
Inference clusterOperational
+
Data pipeline (Lagos)Degraded
+
Notification serviceOperational
+
BillingIncident
+
+
+
+ + +
+
+

Notifications

+

Updates from your projects, deployments, and team.

+
+ +
+ + + + +
+ +
+

Today

+
    +
  • +
    +

    Billing incident detected

    Payment webhook failing for 3 client accounts. Investigating now.
    + 9:41 AM +
  • +
  • +
    +

    Atlas NLP v2.3 deployed to production

    Rollout completed across all regions with zero downtime.
    + 8:15 AM +
  • +
+
+ +
+

Yesterday

+
    +
  • +
    +

    Data pipeline latency above threshold

    Lagos region ingest is running 40% slower than baseline.
    + 6:02 PM +
  • +
  • +
    +

    New comment on Client portal UI

    Amara left feedback on the onboarding flow mockups.
    + 2:47 PM +
  • +
  • +
    +

    Ledger Vault audit report ready

    Smart contract audit finished with no critical findings.
    + 11:20 AM +
  • +
+
+
+ +
+
+
+ + + + \ No newline at end of file