From a3e94f3f3ddfbc4b47bacc71e061792190bdd83d Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Sat, 21 Mar 2026 21:06:49 -0700 Subject: [PATCH] fix(admin-web): correct 12 broken API calls across 5 pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pages fixed: - waitlist: GET /waitlist/list → GET /waitlist (root) - delivery: GET /delivery/log → GET /delivery/logs; disable retry button (no backend endpoint) - reviews: GET /reviews/list → GET /reviews; approve/reject → POST /:id/decision with body; disable flag (no endpoint) - jobs: GET /jobs/list → GET /jobs; GET /runs/list → GET /runs; trigger → POST /jobs/trigger with {jobId} - gdpr-export: GET /exports/list → GET /exports; POST /exports/create → POST /exports TODO Q1: delivery retry endpoint not implemented in backend TODO Q2: reviews flag endpoint not implemented in backend --- .../src/app/(dashboard)/delivery/page.tsx | 27 ++++++----------- .../src/app/(dashboard)/gdpr-export/page.tsx | 4 +-- .../src/app/(dashboard)/jobs/page.tsx | 4 +-- .../src/app/(dashboard)/reviews/page.tsx | 29 ++++++++++--------- .../src/app/(dashboard)/waitlist/page.tsx | 2 +- 5 files changed, 30 insertions(+), 36 deletions(-) diff --git a/dashboards/admin-web/src/app/(dashboard)/delivery/page.tsx b/dashboards/admin-web/src/app/(dashboard)/delivery/page.tsx index cbb71d9d..a2463658 100644 --- a/dashboards/admin-web/src/app/(dashboard)/delivery/page.tsx +++ b/dashboards/admin-web/src/app/(dashboard)/delivery/page.tsx @@ -3,10 +3,9 @@ import { createProxyFetch } from '@/lib/proxy-fetch'; import { useState, useEffect, useCallback } from 'react'; -import { Mail, RotateCcw } from 'lucide-react'; +import { Mail } from 'lucide-react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; -import { Button } from '@/components/ui/button'; import { Table, TableBody, @@ -63,7 +62,7 @@ export default function DeliveryPage() { const params = new URLSearchParams(); if (statusFilter !== 'all') params.set('status', statusFilter); const qs = params.toString() ? `?${params.toString()}` : ''; - const data = await apiFetch(`log${qs}`); + const data = await apiFetch(`logs${qs}`); setEntries(Array.isArray(data?.entries) ? data.entries : Array.isArray(data) ? data : []); setLoading(false); }, [statusFilter]); @@ -72,10 +71,12 @@ export default function DeliveryPage() { void loadData(); }, [loadData]); - async function handleRetry(id: string) { - await apiFetch(`log/${id}/retry`, { method: 'POST' }); - loadData(); - } + // TODO Q1: Backend has no retry endpoint for delivery log entries. + // When /delivery/logs/:id/retry is implemented, uncomment this. + // async function handleRetry(id: string) { + // await apiFetch(`logs/${id}/retry`, { method: 'POST' }); + // loadData(); + // } const deliveredCount = entries.filter(e => e.status === 'delivered').length; const failedCount = entries.filter(e => e.status === 'failed').length; @@ -190,17 +191,7 @@ export default function DeliveryPage() { {formatDate(e.createdAt)} - {e.status === 'failed' && ( - - )} + {/* TODO Q1: Retry button disabled — backend has no retry endpoint yet */} ); diff --git a/dashboards/admin-web/src/app/(dashboard)/gdpr-export/page.tsx b/dashboards/admin-web/src/app/(dashboard)/gdpr-export/page.tsx index bfe9a3f0..9c9ee91e 100644 --- a/dashboards/admin-web/src/app/(dashboard)/gdpr-export/page.tsx +++ b/dashboards/admin-web/src/app/(dashboard)/gdpr-export/page.tsx @@ -39,7 +39,7 @@ export default function GdprExportPage() { if (!userId.trim()) return; setLoading(true); try { - const res = await fetch(`/api/exports/list?userId=${encodeURIComponent(userId)}`, { + const res = await fetch(`/api/exports?userId=${encodeURIComponent(userId)}`, { headers: { 'Content-Type': 'application/json' }, }); const data = await res.json(); @@ -55,7 +55,7 @@ export default function GdprExportPage() { setExporting(true); setExportResult(null); try { - const res = await fetch('/api/exports/create', { + const res = await fetch('/api/exports', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: userId.trim(), entityTypes: ['all'], format: 'json' }), diff --git a/dashboards/admin-web/src/app/(dashboard)/jobs/page.tsx b/dashboards/admin-web/src/app/(dashboard)/jobs/page.tsx index 44e35027..9278d31c 100644 --- a/dashboards/admin-web/src/app/(dashboard)/jobs/page.tsx +++ b/dashboards/admin-web/src/app/(dashboard)/jobs/page.tsx @@ -70,7 +70,7 @@ export default function JobsPage() { const loadData = useCallback(async () => { setLoading(true); - const [jData, rData] = await Promise.all([jobsFetch('list'), runsFetch('list?limit=50')]); + const [jData, rData] = await Promise.all([jobsFetch(''), runsFetch('?limit=50')]); setJobs(Array.isArray(jData?.jobs) ? jData.jobs : Array.isArray(jData) ? jData : []); setRuns(Array.isArray(rData?.runs) ? rData.runs : Array.isArray(rData) ? rData : []); setLoading(false); @@ -81,7 +81,7 @@ export default function JobsPage() { }, [loadData]); async function handleTrigger(id: string) { - await jobsFetch(`${id}/trigger`, { method: 'POST' }); + await jobsFetch('trigger', { method: 'POST', body: JSON.stringify({ jobId: id }) }); loadData(); } diff --git a/dashboards/admin-web/src/app/(dashboard)/reviews/page.tsx b/dashboards/admin-web/src/app/(dashboard)/reviews/page.tsx index b468244b..28483646 100644 --- a/dashboards/admin-web/src/app/(dashboard)/reviews/page.tsx +++ b/dashboards/admin-web/src/app/(dashboard)/reviews/page.tsx @@ -62,7 +62,7 @@ export default function ReviewsPage() { const params = new URLSearchParams(); if (statusFilter !== 'all') params.set('status', statusFilter); const qs = params.toString() ? `?${params.toString()}` : ''; - const data = await apiFetch(`list${qs}`); + const data = await apiFetch(`${qs}`); setReviews(Array.isArray(data?.reviews) ? data.reviews : Array.isArray(data) ? data : []); setTotal(data?.total ?? (Array.isArray(data?.reviews) ? data.reviews.length : 0)); setLoading(false); @@ -73,19 +73,27 @@ export default function ReviewsPage() { }, [loadData]); async function handleApprove(id: string) { - await apiFetch(`${id}/approve`, { method: 'POST' }); + await apiFetch(`${id}/decision`, { + method: 'POST', + body: JSON.stringify({ decision: 'approved' }), + }); loadData(); } async function handleReject(id: string) { - await apiFetch(`${id}/reject`, { method: 'POST' }); + await apiFetch(`${id}/decision`, { + method: 'POST', + body: JSON.stringify({ decision: 'rejected' }), + }); loadData(); } - async function handleFlag(id: string) { - await apiFetch(`${id}/flag`, { method: 'POST' }); - loadData(); - } + // TODO Q2: Backend has no /reviews/:id/flag endpoint. + // When flagging is implemented, uncomment this. + // async function handleFlag(id: string) { + // await apiFetch(`${id}/flag`, { method: 'POST' }); + // loadData(); + // } const pendingCount = reviews.filter(r => r.status === 'pending').length; const flaggedCount = reviews.filter(r => r.flagged).length; @@ -245,12 +253,7 @@ export default function ReviewsPage() { Reject )} - {!r.flagged && ( - handleFlag(r.id)}> - - Flag - - )} + {/* TODO Q2: Flag button disabled — no backend endpoint yet */} diff --git a/dashboards/admin-web/src/app/(dashboard)/waitlist/page.tsx b/dashboards/admin-web/src/app/(dashboard)/waitlist/page.tsx index 5a831a7c..75b7e004 100644 --- a/dashboards/admin-web/src/app/(dashboard)/waitlist/page.tsx +++ b/dashboards/admin-web/src/app/(dashboard)/waitlist/page.tsx @@ -85,7 +85,7 @@ export default function WaitlistPage() { if (statusFilter !== 'all') params.set('status', statusFilter); if (search) params.set('search', search); const qs = params.toString() ? `?${params.toString()}` : ''; - const data = await apiFetch(`list${qs}`); + const data = await apiFetch(`${qs}`); if (data?.entries) { setEntries(data.entries); setTotal(data.total ?? data.entries.length);