From efcf4dfb6cbc6e9512dc1758f7893a95c2f8b440 Mon Sep 17 00:00:00 2001 From: Ayomide Philip Date: Tue, 17 Mar 2026 12:59:07 +0100 Subject: [PATCH 01/10] style: format layout component for improved readability --- app/(admin)/layout.tsx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/app/(admin)/layout.tsx b/app/(admin)/layout.tsx index fbed809..355ef47 100644 --- a/app/(admin)/layout.tsx +++ b/app/(admin)/layout.tsx @@ -1,18 +1,26 @@ -import React from 'react' -import Link from 'next/link' +import React from "react"; +import Link from "next/link"; -export default function AdminLayout({ children }: { children: React.ReactNode }) { +export default function AdminLayout({ + children, +}: { + children: React.ReactNode; +}) { return (
- DRM Admin + + DRM Admin +
{children}
- ) + ); } From 51c7c9222c6f82b7648b66de5279e2046daa7b11 Mon Sep 17 00:00:00 2001 From: Ayomide Philip Date: Tue, 17 Mar 2026 14:43:03 +0100 Subject: [PATCH 02/10] style: adjust layout component for improved structure and readability; update import path in TypeScript definitions --- app/(admin)/layout.tsx | 6 +++--- next-env.d.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/(admin)/layout.tsx b/app/(admin)/layout.tsx index 355ef47..7a4e780 100644 --- a/app/(admin)/layout.tsx +++ b/app/(admin)/layout.tsx @@ -8,8 +8,8 @@ export default function AdminLayout({ }) { return (
-
-
+
+
DRM Admin @@ -20,7 +20,7 @@ export default function AdminLayout({
-
{children}
+
{children}
); } diff --git a/next-env.d.ts b/next-env.d.ts index 9edff1c..c4b7818 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/types/routes.d.ts"; +import "./.next/dev/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. From 34c8ecda9aa18e3f36cdc2fa02a8df439ffdd387 Mon Sep 17 00:00:00 2001 From: Ayomide Philip Date: Tue, 17 Mar 2026 14:56:54 +0100 Subject: [PATCH 03/10] feat: implement admin layout with sidebar and navbar components; add utility functions and navigation data --- app/(admin)/_components/AdminCard.tsx | 91 ++++++++++++++++++++++++ app/(admin)/_components/AdminNavbar.tsx | 66 +++++++++++++++++ app/(admin)/_components/AdminSidebar.tsx | 72 +++++++++++++++++++ app/(admin)/_components/AdminTable.tsx | 47 ++++++++++++ app/(admin)/_components/adminData.ts | 23 ++++++ app/(admin)/_components/utils.ts | 3 + app/(admin)/layout.tsx | 30 ++++---- 7 files changed, 318 insertions(+), 14 deletions(-) create mode 100644 app/(admin)/_components/AdminCard.tsx create mode 100644 app/(admin)/_components/AdminNavbar.tsx create mode 100644 app/(admin)/_components/AdminSidebar.tsx create mode 100644 app/(admin)/_components/AdminTable.tsx create mode 100644 app/(admin)/_components/adminData.ts create mode 100644 app/(admin)/_components/utils.ts diff --git a/app/(admin)/_components/AdminCard.tsx b/app/(admin)/_components/AdminCard.tsx new file mode 100644 index 0000000..0e139ab --- /dev/null +++ b/app/(admin)/_components/AdminCard.tsx @@ -0,0 +1,91 @@ +import React from 'react' +import { cn } from './utils' + +type CardProps = { + title?: string + subtitle?: string + className?: string + children: React.ReactNode +} + +export function Card({ title, subtitle, className, children }: CardProps) { + return ( +
+ {title ?

{title}

: null} + {subtitle ?

{subtitle}

: null} +
{children}
+
+ ) +} + +type StatCardProps = { + label: string + value: string + trend?: string +} + +export function StatCard({ label, value, trend }: StatCardProps) { + return ( + +

{label}

+

{value}

+ {trend ?

{trend}

: null} +
+ ) +} + +export function PageTitle({ title, description }: { title: string; description?: string }) { + return ( +
+

{title}

+ {description ?

{description}

: null} +
+ ) +} + +const statusStyles: Record<'success' | 'warning' | 'danger' | 'neutral', string> = { + success: 'border-emerald-200 bg-emerald-50 text-emerald-700', + warning: 'border-amber-200 bg-amber-50 text-amber-700', + danger: 'border-rose-200 bg-rose-50 text-rose-700', + neutral: 'border-slate-200 bg-slate-100 text-slate-700', +} + +export function StatusBadge({ + label, + tone, +}: { + label: string + tone: 'success' | 'warning' | 'danger' | 'neutral' +}) { + return ( + + {label} + + ) +} + +export function ActionButton({ + children, + variant = 'secondary', +}: { + children: React.ReactNode + variant?: 'primary' | 'secondary' | 'danger' +}) { + const variants: Record = { + primary: 'border-slate-900 bg-slate-900 text-white hover:bg-slate-800', + secondary: 'border-slate-200 bg-white text-slate-700 hover:bg-slate-50', + danger: 'border-rose-200 bg-rose-50 text-rose-700 hover:bg-rose-100', + } + + return ( + + ) +} diff --git a/app/(admin)/_components/AdminNavbar.tsx b/app/(admin)/_components/AdminNavbar.tsx new file mode 100644 index 0000000..754a2de --- /dev/null +++ b/app/(admin)/_components/AdminNavbar.tsx @@ -0,0 +1,66 @@ +'use client' + +import { Bell, Menu, Search } from 'lucide-react' +import { usePathname } from 'next/navigation' + +const titleMap: Record = { + '/admin': 'Dashboard', + '/admin/incident-reports': 'Incident Reports', + '/admin/agencies': 'Agencies', + '/admin/users': 'Users', + '/admin/notifications': 'Notifications', + '/admin/analytics': 'Analytics', + '/admin/data-export': 'Data Export', + '/admin/subscriptions': 'Subscriptions', + '/admin/settings': 'Settings', +} + +export default function AdminNavbar({ onMenuClick }: { onMenuClick: () => void }) { + const pathname = usePathname() + const title = titleMap[pathname] || 'Admin' + + return ( +
+
+ + +
+

{title}

+

Disaster response management

+
+ + + + + + +
+
+ ) +} diff --git a/app/(admin)/_components/AdminSidebar.tsx b/app/(admin)/_components/AdminSidebar.tsx new file mode 100644 index 0000000..fb81317 --- /dev/null +++ b/app/(admin)/_components/AdminSidebar.tsx @@ -0,0 +1,72 @@ +'use client' + +import Link from 'next/link' +import { usePathname } from 'next/navigation' +import { X } from 'lucide-react' +import { navItems } from './adminData' +import { cn } from './utils' + +type AdminSidebarProps = { + isOpen: boolean + onClose: () => void +} + +export default function AdminSidebar({ isOpen, onClose }: AdminSidebarProps) { + const pathname = usePathname() + + return ( + <> +
+ + + + ) +} diff --git a/app/(admin)/_components/AdminTable.tsx b/app/(admin)/_components/AdminTable.tsx new file mode 100644 index 0000000..b2d0d6f --- /dev/null +++ b/app/(admin)/_components/AdminTable.tsx @@ -0,0 +1,47 @@ +import React from 'react' + +type Column = { + key: string + title: string + className?: string + render: (row: T) => React.ReactNode +} + +export function AdminTable({ + columns, + rows, +}: { + columns: Column[] + rows: T[] +}) { + return ( +
+ + + + {columns.map((column) => ( + + ))} + + + + {rows.map((row, index) => ( + + {columns.map((column) => ( + + ))} + + ))} + +
+ {column.title} +
+ {column.render(row)} +
+
+ ) +} diff --git a/app/(admin)/_components/adminData.ts b/app/(admin)/_components/adminData.ts new file mode 100644 index 0000000..eb431ef --- /dev/null +++ b/app/(admin)/_components/adminData.ts @@ -0,0 +1,23 @@ +import { + Bell, + ChartSpline, + Database, + FileUp, + LayoutDashboard, + Settings, + ShieldAlert, + Users, + UserCog, +} from 'lucide-react' + +export const navItems = [ + { label: 'Dashboard', href: '/admin', icon: LayoutDashboard }, + { label: 'Incident Reports', href: '/admin/incident-reports', icon: ShieldAlert }, + { label: 'Agencies', href: '/admin/agencies', icon: UserCog }, + { label: 'Users', href: '/admin/users', icon: Users }, + { label: 'Notifications', href: '/admin/notifications', icon: Bell }, + { label: 'Analytics', href: '/admin/analytics', icon: ChartSpline }, + { label: 'Data Export', href: '/admin/data-export', icon: FileUp }, + { label: 'Subscriptions', href: '/admin/subscriptions', icon: Database }, + { label: 'Settings', href: '/admin/settings', icon: Settings }, +] diff --git a/app/(admin)/_components/utils.ts b/app/(admin)/_components/utils.ts new file mode 100644 index 0000000..b7aba69 --- /dev/null +++ b/app/(admin)/_components/utils.ts @@ -0,0 +1,3 @@ +export function cn(...classes: Array) { + return classes.filter(Boolean).join(' ') +} diff --git a/app/(admin)/layout.tsx b/app/(admin)/layout.tsx index 7a4e780..9107fae 100644 --- a/app/(admin)/layout.tsx +++ b/app/(admin)/layout.tsx @@ -1,26 +1,28 @@ +"use client"; + import React from "react"; -import Link from "next/link"; +import AdminSidebar from "./_components/AdminSidebar"; +import AdminNavbar from "./_components/AdminNavbar"; export default function AdminLayout({ children, }: { children: React.ReactNode; }) { + const [isSidebarOpen, setSidebarOpen] = React.useState(false); + return ( -
-
-
- - DRM Admin - - +
+
+ setSidebarOpen(false)} /> + +
+ setSidebarOpen(true)} /> +
+
{children}
+
-
-
{children}
+
); } From b382604fb9851e63b23de4d8ee8db132a157a810 Mon Sep 17 00:00:00 2001 From: Ayomide Philip Date: Tue, 17 Mar 2026 15:05:41 +0100 Subject: [PATCH 04/10] Refactor Admin components for improved readability and consistency - Updated AdminNavbar and AdminSidebar components to use consistent quotation marks and formatting. - Enhanced AdminTable component with improved type definitions and formatting. - Created new pages for Agencies, Analytics, Data Export, Incident Reports, Notifications, Settings, Subscriptions, and Users with structured layouts and data handling. - Added functionality to manage agency subscriptions and user accounts with appropriate actions. - Improved layout structure in Admin layout file for better sidebar and navbar integration. --- app/(admin)/_components/AdminCard.tsx | 113 ++++++++++++-------- app/(admin)/_components/AdminNavbar.tsx | 55 ++++++---- app/(admin)/_components/AdminSidebar.tsx | 48 +++++---- app/(admin)/_components/AdminTable.tsx | 30 +++--- app/(admin)/_components/adminData.ts | 26 +++-- app/(admin)/_components/utils.ts | 2 +- app/(admin)/admin/agencies/page.tsx | 49 +++++++++ app/(admin)/admin/analytics/page.tsx | 53 +++++++++ app/(admin)/admin/data-export/page.tsx | 33 ++++++ app/(admin)/admin/incident-reports/page.tsx | 72 +++++++++++++ app/(admin)/admin/notifications/page.tsx | 61 +++++++++++ app/(admin)/admin/page.tsx | 93 ++++++++++------ app/(admin)/admin/settings/page.tsx | 58 ++++++++++ app/(admin)/admin/subscriptions/page.tsx | 48 +++++++++ app/(admin)/admin/users/page.tsx | 48 +++++++++ app/(admin)/layout.tsx | 5 +- 16 files changed, 654 insertions(+), 140 deletions(-) create mode 100644 app/(admin)/admin/agencies/page.tsx create mode 100644 app/(admin)/admin/analytics/page.tsx create mode 100644 app/(admin)/admin/data-export/page.tsx create mode 100644 app/(admin)/admin/incident-reports/page.tsx create mode 100644 app/(admin)/admin/notifications/page.tsx create mode 100644 app/(admin)/admin/settings/page.tsx create mode 100644 app/(admin)/admin/subscriptions/page.tsx create mode 100644 app/(admin)/admin/users/page.tsx diff --git a/app/(admin)/_components/AdminCard.tsx b/app/(admin)/_components/AdminCard.tsx index 0e139ab..1b3318c 100644 --- a/app/(admin)/_components/AdminCard.tsx +++ b/app/(admin)/_components/AdminCard.tsx @@ -1,91 +1,120 @@ -import React from 'react' -import { cn } from './utils' +import React from "react"; +import { cn } from "./utils"; type CardProps = { - title?: string - subtitle?: string - className?: string - children: React.ReactNode -} + title?: string; + subtitle?: string; + className?: string; + children: React.ReactNode; +}; export function Card({ title, subtitle, className, children }: CardProps) { return ( -
- {title ?

{title}

: null} - {subtitle ?

{subtitle}

: null} -
{children}
+
+ {title ? ( +

{title}

+ ) : null} + {subtitle ? ( +

{subtitle}

+ ) : null} +
{children}
- ) + ); } type StatCardProps = { - label: string - value: string - trend?: string -} + label: string; + value: string; + trend?: string; +}; export function StatCard({ label, value, trend }: StatCardProps) { return ( -

{label}

+

+ {label} +

{value}

{trend ?

{trend}

: null}
- ) + ); } -export function PageTitle({ title, description }: { title: string; description?: string }) { +export function PageTitle({ + title, + description, +}: { + title: string; + description?: string; +}) { return (
-

{title}

- {description ?

{description}

: null} +

+ {title} +

+ {description ? ( +

{description}

+ ) : null}
- ) + ); } -const statusStyles: Record<'success' | 'warning' | 'danger' | 'neutral', string> = { - success: 'border-emerald-200 bg-emerald-50 text-emerald-700', - warning: 'border-amber-200 bg-amber-50 text-amber-700', - danger: 'border-rose-200 bg-rose-50 text-rose-700', - neutral: 'border-slate-200 bg-slate-100 text-slate-700', -} +const statusStyles: Record< + "success" | "warning" | "danger" | "neutral", + string +> = { + success: "border-emerald-200 bg-emerald-50 text-emerald-700", + warning: "border-amber-200 bg-amber-50 text-amber-700", + danger: "border-rose-200 bg-rose-50 text-rose-700", + neutral: "border-slate-200 bg-slate-100 text-slate-700", +}; export function StatusBadge({ label, tone, }: { - label: string - tone: 'success' | 'warning' | 'danger' | 'neutral' + label: string; + tone: "success" | "warning" | "danger" | "neutral"; }) { return ( - + {label} - ) + ); } export function ActionButton({ children, - variant = 'secondary', + variant = "secondary", }: { - children: React.ReactNode - variant?: 'primary' | 'secondary' | 'danger' + children: React.ReactNode; + variant?: "primary" | "secondary" | "danger"; }) { const variants: Record = { - primary: 'border-slate-900 bg-slate-900 text-white hover:bg-slate-800', - secondary: 'border-slate-200 bg-white text-slate-700 hover:bg-slate-50', - danger: 'border-rose-200 bg-rose-50 text-rose-700 hover:bg-rose-100', - } + primary: "border-slate-900 bg-slate-900 text-white hover:bg-slate-800", + secondary: "border-slate-200 bg-white text-slate-700 hover:bg-slate-50", + danger: "border-rose-200 bg-rose-50 text-rose-700 hover:bg-rose-100", + }; return ( - ) + ); } diff --git a/app/(admin)/_components/AdminNavbar.tsx b/app/(admin)/_components/AdminNavbar.tsx index 754a2de..d78793a 100644 --- a/app/(admin)/_components/AdminNavbar.tsx +++ b/app/(admin)/_components/AdminNavbar.tsx @@ -1,23 +1,27 @@ -'use client' +"use client"; -import { Bell, Menu, Search } from 'lucide-react' -import { usePathname } from 'next/navigation' +import { Bell, Menu, Search } from "lucide-react"; +import { usePathname } from "next/navigation"; const titleMap: Record = { - '/admin': 'Dashboard', - '/admin/incident-reports': 'Incident Reports', - '/admin/agencies': 'Agencies', - '/admin/users': 'Users', - '/admin/notifications': 'Notifications', - '/admin/analytics': 'Analytics', - '/admin/data-export': 'Data Export', - '/admin/subscriptions': 'Subscriptions', - '/admin/settings': 'Settings', -} + "/admin": "Dashboard", + "/admin/incident-reports": "Incident Reports", + "/admin/agencies": "Agencies", + "/admin/users": "Users", + "/admin/notifications": "Notifications", + "/admin/analytics": "Analytics", + "/admin/data-export": "Data Export", + "/admin/subscriptions": "Subscriptions", + "/admin/settings": "Settings", +}; -export default function AdminNavbar({ onMenuClick }: { onMenuClick: () => void }) { - const pathname = usePathname() - const title = titleMap[pathname] || 'Admin' +export default function AdminNavbar({ + onMenuClick, +}: { + onMenuClick: () => void; +}) { + const pathname = usePathname(); + const title = titleMap[pathname] || "Admin"; return (
@@ -32,8 +36,12 @@ export default function AdminNavbar({ onMenuClick }: { onMenuClick: () => void }
-

{title}

-

Disaster response management

+

+ {title} +

+

+ Disaster response management +

- ) + ); } diff --git a/app/(admin)/_components/AdminSidebar.tsx b/app/(admin)/_components/AdminSidebar.tsx index fb81317..5660d2b 100644 --- a/app/(admin)/_components/AdminSidebar.tsx +++ b/app/(admin)/_components/AdminSidebar.tsx @@ -1,39 +1,43 @@ -'use client' +"use client"; -import Link from 'next/link' -import { usePathname } from 'next/navigation' -import { X } from 'lucide-react' -import { navItems } from './adminData' -import { cn } from './utils' +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { X } from "lucide-react"; +import { navItems } from "./adminData"; +import { cn } from "./utils"; type AdminSidebarProps = { - isOpen: boolean - onClose: () => void -} + isOpen: boolean; + onClose: () => void; +}; export default function AdminSidebar({ isOpen, onClose }: AdminSidebarProps) { - const pathname = usePathname() + const pathname = usePathname(); return ( <>
- ) + ); } diff --git a/app/(admin)/_components/AdminTable.tsx b/app/(admin)/_components/AdminTable.tsx index b2d0d6f..45b2dd7 100644 --- a/app/(admin)/_components/AdminTable.tsx +++ b/app/(admin)/_components/AdminTable.tsx @@ -1,18 +1,18 @@ -import React from 'react' +import React from "react"; type Column = { - key: string - title: string - className?: string - render: (row: T) => React.ReactNode -} + key: string; + title: string; + className?: string; + render: (row: T) => React.ReactNode; +}; export function AdminTable({ columns, rows, }: { - columns: Column[] - rows: T[] + columns: Column[]; + rows: T[]; }) { return (
@@ -23,7 +23,7 @@ export function AdminTable({ {column.title} @@ -32,9 +32,15 @@ export function AdminTable({ {rows.map((row, index) => ( - + {columns.map((column) => ( - + {column.render(row)} ))} @@ -43,5 +49,5 @@ export function AdminTable({
- ) + ); } diff --git a/app/(admin)/_components/adminData.ts b/app/(admin)/_components/adminData.ts index eb431ef..267b158 100644 --- a/app/(admin)/_components/adminData.ts +++ b/app/(admin)/_components/adminData.ts @@ -8,16 +8,20 @@ import { ShieldAlert, Users, UserCog, -} from 'lucide-react' +} from "lucide-react"; export const navItems = [ - { label: 'Dashboard', href: '/admin', icon: LayoutDashboard }, - { label: 'Incident Reports', href: '/admin/incident-reports', icon: ShieldAlert }, - { label: 'Agencies', href: '/admin/agencies', icon: UserCog }, - { label: 'Users', href: '/admin/users', icon: Users }, - { label: 'Notifications', href: '/admin/notifications', icon: Bell }, - { label: 'Analytics', href: '/admin/analytics', icon: ChartSpline }, - { label: 'Data Export', href: '/admin/data-export', icon: FileUp }, - { label: 'Subscriptions', href: '/admin/subscriptions', icon: Database }, - { label: 'Settings', href: '/admin/settings', icon: Settings }, -] + { label: "Dashboard", href: "/admin", icon: LayoutDashboard }, + { + label: "Incident Reports", + href: "/admin/incident-reports", + icon: ShieldAlert, + }, + { label: "Agencies", href: "/admin/agencies", icon: UserCog }, + { label: "Users", href: "/admin/users", icon: Users }, + { label: "Notifications", href: "/admin/notifications", icon: Bell }, + { label: "Analytics", href: "/admin/analytics", icon: ChartSpline }, + { label: "Data Export", href: "/admin/data-export", icon: FileUp }, + { label: "Subscriptions", href: "/admin/subscriptions", icon: Database }, + { label: "Settings", href: "/admin/settings", icon: Settings }, +]; diff --git a/app/(admin)/_components/utils.ts b/app/(admin)/_components/utils.ts index b7aba69..737ea7e 100644 --- a/app/(admin)/_components/utils.ts +++ b/app/(admin)/_components/utils.ts @@ -1,3 +1,3 @@ export function cn(...classes: Array) { - return classes.filter(Boolean).join(' ') + return classes.filter(Boolean).join(" "); } diff --git a/app/(admin)/admin/agencies/page.tsx b/app/(admin)/admin/agencies/page.tsx new file mode 100644 index 0000000..46bb863 --- /dev/null +++ b/app/(admin)/admin/agencies/page.tsx @@ -0,0 +1,49 @@ +import { ActionButton, Card, PageTitle, StatusBadge } from '../../_components/AdminCard' +import { AdminTable } from '../../_components/AdminTable' + +const agencies = [ + { name: 'Rapid Medical Unit', category: 'Medical', contact: 'rmu@agency.org', status: 'Active', activeIncidents: 13 }, + { name: 'Urban Fire Service', category: 'Fire', contact: 'ufs@agency.org', status: 'Trial', activeIncidents: 21 }, + { name: 'Flood Response Team', category: 'Flood', contact: 'frt@agency.org', status: 'Inactive', activeIncidents: 4 }, +] + +export default function AgenciesPage() { + return ( +
+ + + + {row.name} }, + { key: 'category', title: 'Category', render: (row) => row.category }, + { key: 'contact', title: 'Contact Info', render: (row) => row.contact }, + { + key: 'status', + title: 'Subscription Status', + render: (row) => ( + + ), + }, + { key: 'activeIncidents', title: 'Active Incident Count', render: (row) => row.activeIncidents }, + { + key: 'actions', + title: 'Actions', + render: () => ( +
+ View + Edit + Deactivate +
+ ), + }, + ]} + /> +
+
+ ) +} diff --git a/app/(admin)/admin/analytics/page.tsx b/app/(admin)/admin/analytics/page.tsx new file mode 100644 index 0000000..510aeb3 --- /dev/null +++ b/app/(admin)/admin/analytics/page.tsx @@ -0,0 +1,53 @@ +import { Card, PageTitle, StatCard } from '../../_components/AdminCard' + +export default function AnalyticsPage() { + return ( +
+ + +
+ +
+ {[42, 65, 28, 54, 36, 71].map((height, index) => ( +
+ ))} +
+ + + +
+
+ + + +
+
+
+
+ + +
+ {Array.from({ length: 48 }).map((_, i) => ( +
+ ))} +
+ + +
+ + + + +
+
+ ) +} diff --git a/app/(admin)/admin/data-export/page.tsx b/app/(admin)/admin/data-export/page.tsx new file mode 100644 index 0000000..b27b1eb --- /dev/null +++ b/app/(admin)/admin/data-export/page.tsx @@ -0,0 +1,33 @@ +import { Card, PageTitle } from '../../_components/AdminCard' + +export default function DataExportPage() { + return ( +
+ + + +
+ + + +
+
+ + +
+ + +
+
+
+ ) +} diff --git a/app/(admin)/admin/incident-reports/page.tsx b/app/(admin)/admin/incident-reports/page.tsx new file mode 100644 index 0000000..cca59c1 --- /dev/null +++ b/app/(admin)/admin/incident-reports/page.tsx @@ -0,0 +1,72 @@ +import { ActionButton, Card, PageTitle, StatusBadge } from '../../_components/AdminCard' +import { AdminTable } from '../../_components/AdminTable' + +const rows = [ + { id: 'IR-3021', title: 'Bridge Fire Alert', category: 'Fire', location: 'Lake Bridge', status: 'Active', timestamp: '2026-03-17 10:22' }, + { id: 'IR-3022', title: 'Flash Flood Warning', category: 'Flood', location: 'South Basin', status: 'Pending', timestamp: '2026-03-17 09:54' }, + { id: 'IR-3023', title: 'Power Grid Failure', category: 'Infrastructure', location: 'Central City', status: 'Resolved', timestamp: '2026-03-16 21:04' }, +] + +export default function IncidentReportsPage() { + return ( +
+ + + +
+ + + + + +
+
+ + + {row.id} }, + { key: 'title', title: 'Title', render: (row) => row.title }, + { key: 'category', title: 'Category', render: (row) => row.category }, + { key: 'location', title: 'Location', render: (row) => row.location }, + { + key: 'status', + title: 'Status', + render: (row) => ( + + ), + }, + { key: 'timestamp', title: 'Timestamp', render: (row) => row.timestamp }, + { + key: 'actions', + title: 'Actions', + render: () => ( +
+ View + Edit + Delete + Approve + Reject +
+ ), + }, + ]} + /> +
+
+ ) +} diff --git a/app/(admin)/admin/notifications/page.tsx b/app/(admin)/admin/notifications/page.tsx new file mode 100644 index 0000000..0efd8f3 --- /dev/null +++ b/app/(admin)/admin/notifications/page.tsx @@ -0,0 +1,61 @@ +import { Card, PageTitle, StatCard } from '../../_components/AdminCard' + +export default function NotificationsPage() { + return ( +
+ + + +
+
+
+ + +
+
+ +