diff --git a/app/admin/applications/[id]/page.tsx b/app/admin/applications/[id]/page.tsx index db3b0cc..e286a7f 100644 --- a/app/admin/applications/[id]/page.tsx +++ b/app/admin/applications/[id]/page.tsx @@ -1,27 +1,49 @@ "use client"; import Link from "next/link"; -import { getApplicationById } from "@/services/mockApplications"; -import ApproveRejectButtons from "@/components/admin/ApproveRejectButtons"; +import { useEffect, useState } from "react"; -type Props = { - params: Promise<{ id: string }>; +const STATUS_STYLES: Record = { + pending: "bg-amber-50 text-amber-700 ring-1 ring-amber-200", + approved: "bg-emerald-50 text-emerald-700 ring-1 ring-emerald-200", + rejected: "bg-red-50 text-red-600 ring-1 ring-red-200", }; -export default async function ApplicationDetail({ params }: Props) { - const { id } = await params; - const app = getApplicationById(id); - - if (!app) { - return ( -
-

Application not found

-

No mock application matches id {id}.

- - Back to applications - -
- ); +interface Application { + id: string; + type: string; + status: string; + submitterName: string; + submitterEmail: string; + payload: Record; + createdAt: string; + updatedAt: string; +} + +export default function ApplicationDetail({ params }: { params: { id: string } }) { + const [app, setApp] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [actioning, setActioning] = useState<"approved" | "rejected" | null>(null); + const [actionError, setActionError] = useState(null); + + async function handleAction(status: "approved" | "rejected") { + setActioning(status); + setActionError(null); + try { + const res = await fetch(`/api/admin/applications/${params.id}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ status }), + }); + if (!res.ok) { const b = await res.json(); throw new Error(b.error ?? "Failed to update"); } + const { data } = await res.json(); + setApp(data); + } catch (err: any) { + setActionError(err.message); + } finally { + setActioning(null); + } } useEffect(() => { @@ -61,15 +83,14 @@ export default async function ApplicationDetail({ params }: Props) { if (!app) return null; return ( -
-
-

Application: {app.name}

-
- - - Back - + + {/* Header */} +
+
+

{app.submitterName}

+

{app.submitterEmail}

+
diff --git a/app/api/admin/applications/route.ts b/app/api/admin/applications/route.ts index 71fcaf9..2d74c2b 100644 --- a/app/api/admin/applications/route.ts +++ b/app/api/admin/applications/route.ts @@ -1,7 +1,7 @@ import { NextResponse } from "next/server"; import { prisma } from "@/lib/prisma"; -export async function GET() { +export async function GET(request: NextRequest) { try { const session = await auth(); if (!session?.user?.email) { @@ -43,6 +43,7 @@ export async function GET() { }); return NextResponse.json({ data: applications }, { status: 200 }); + } catch (err) { console.error(err); return NextResponse.json(