fixing admin pages
CI / test (push) Successful in 6s

This commit is contained in:
2026-01-25 14:22:58 -05:00
parent e49dc96522
commit 3aee0e6755
11 changed files with 311 additions and 10 deletions
+4 -3
View File
@@ -46,8 +46,8 @@ export default function ImportStatusPage() {
setError(null); setError(null);
const [summaryRes, byMerchantRes] = await Promise.all([ const [summaryRes, byMerchantRes] = await Promise.all([
fetch(`${API_BASE_URL}/api/admin/import-status/summary`), fetch('/api/admin/import-status/summary', { credentials: 'include' }),
fetch(`${API_BASE_URL}/api/admin/import-status/by-merchant`), fetch('/api/admin/import-status/by-merchant', { credentials: 'include' }),
]); ]);
if (!summaryRes.ok || !byMerchantRes.ok) { if (!summaryRes.ok || !byMerchantRes.ok) {
@@ -108,9 +108,10 @@ export default function ImportStatusPage() {
try { try {
setImportingId(merchantId); setImportingId(merchantId);
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/admin/merchants/${merchantId}/import`, `/api/admin/merchants/${merchantId}/import`,
{ {
method: "POST", method: "POST",
credentials: 'include',
} }
); );
+10 -6
View File
@@ -198,8 +198,9 @@ export default function MappingAdminPage() {
// EXPECTED backend endpoint (new): // EXPECTED backend endpoint (new):
// GET { merchants: [{id,name}], canonicalCategories: [{id,name,slug}] } // GET { merchants: [{id,name}], canonicalCategories: [{id,name,slug}] }
const res = await fetch(`${API_BASE_URL}/api/admin/mapping/options`, { const res = await fetch('/api/admin/mapping/options', {
headers: { Accept: "application/json" }, headers: { Accept: "application/json" },
credentials: 'include',
cache: "no-store", cache: "no-store",
}); });
@@ -243,8 +244,9 @@ export default function MappingAdminPage() {
if (tab === "roles") { if (tab === "roles") {
// Existing endpoint you already have: // Existing endpoint you already have:
// GET /api/admin/mapping/pending-buckets // GET /api/admin/mapping/pending-buckets
const res = await fetch(`${API_BASE_URL}/api/admin/mapping/pending-buckets`, { const res = await fetch('/api/admin/mapping/pending-buckets', {
headers: { Accept: "application/json" }, headers: { Accept: "application/json" },
credentials: 'include',
cache: "no-store", cache: "no-store",
}); });
@@ -277,8 +279,8 @@ export default function MappingAdminPage() {
if (q?.trim()) params.set("q", q.trim()); if (q?.trim()) params.set("q", q.trim());
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/admin/mapping/raw-categories?${params.toString()}`, `/api/admin/mapping/raw-categories?${params.toString()}`,
{ headers: { Accept: "application/json" }, cache: "no-store" } { headers: { Accept: "application/json" }, credentials: 'include', cache: "no-store" }
); );
if (!res.ok) { if (!res.ok) {
@@ -336,9 +338,10 @@ export default function MappingAdminPage() {
// Existing endpoint you already have: // Existing endpoint you already have:
// POST /api/admin/mapping/apply // POST /api/admin/mapping/apply
const res = await fetch(`${API_BASE_URL}/api/admin/mapping/apply`, { const res = await fetch('/api/admin/mapping/apply', {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
credentials: 'include',
body: JSON.stringify({ body: JSON.stringify({
merchantId: row.merchantId, merchantId: row.merchantId,
rawCategoryKey: row.rawCategoryKey, rawCategoryKey: row.rawCategoryKey,
@@ -390,9 +393,10 @@ export default function MappingAdminPage() {
// EXPECTED new endpoint: // EXPECTED new endpoint:
// POST /api/admin/mapping/upsert // POST /api/admin/mapping/upsert
const res = await fetch(`${API_BASE_URL}/api/admin/mapping/upsert`, { const res = await fetch('/api/admin/mapping/upsert', {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
credentials: 'include',
body: JSON.stringify({ body: JSON.stringify({
merchantId: row.merchantId, merchantId: row.merchantId,
platform: row.platform ?? platform ?? null, platform: row.platform ?? platform ?? null,
+3 -1
View File
@@ -24,7 +24,9 @@ export default function AdminLandingPage() {
try { try {
setLoading(true); setLoading(true);
setError(null); setError(null);
const res = await fetch(`${API_BASE_URL}/api/admin/dashboard/overview`); const res = await fetch('/api/admin/dashboard/overview', {
credentials: 'include',
});
if (!res.ok) { if (!res.ok) {
throw new Error(`Failed to load dashboard (${res.status})`); throw new Error(`Failed to load dashboard (${res.status})`);
} }
+35
View File
@@ -0,0 +1,35 @@
import { NextResponse } from 'next/server';
import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() {
const token = cookies().get('session_token')?.value;
if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` };
}
export async function GET() {
try {
const headers = await getAuthHeader();
const res = await fetch(`${API_BASE_URL}/api/admin/dashboard/overview`, {
headers,
cache: 'no-store',
});
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json(await res.json());
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Unauthorized' },
{ status: 401 }
);
}
}
@@ -0,0 +1,35 @@
import { NextResponse } from 'next/server';
import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() {
const token = cookies().get('session_token')?.value;
if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` };
}
export async function GET() {
try {
const headers = await getAuthHeader();
const res = await fetch(`${API_BASE_URL}/api/admin/import-status/by-merchant`, {
headers,
cache: 'no-store',
});
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json(await res.json());
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Unauthorized' },
{ status: 401 }
);
}
}
@@ -0,0 +1,35 @@
import { NextResponse } from 'next/server';
import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() {
const token = cookies().get('session_token')?.value;
if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` };
}
export async function GET() {
try {
const headers = await getAuthHeader();
const res = await fetch(`${API_BASE_URL}/api/admin/import-status/summary`, {
headers,
cache: 'no-store',
});
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json(await res.json());
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Unauthorized' },
{ status: 401 }
);
}
}
+40
View File
@@ -0,0 +1,40 @@
import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() {
const token = cookies().get('session_token')?.value;
if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` };
}
export async function POST(request: NextRequest) {
try {
const headers = await getAuthHeader();
const body = await request.json();
const res = await fetch(`${API_BASE_URL}/api/admin/mapping/apply`, {
method: 'POST',
headers: {
...headers,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json(await res.json());
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Unauthorized' },
{ status: 401 }
);
}
}
+35
View File
@@ -0,0 +1,35 @@
import { NextResponse } from 'next/server';
import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() {
const token = cookies().get('session_token')?.value;
if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` };
}
export async function GET() {
try {
const headers = await getAuthHeader();
const res = await fetch(`${API_BASE_URL}/api/admin/mapping/options`, {
headers,
cache: 'no-store',
});
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json(await res.json());
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Unauthorized' },
{ status: 401 }
);
}
}
@@ -0,0 +1,35 @@
import { NextResponse } from 'next/server';
import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() {
const token = cookies().get('session_token')?.value;
if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` };
}
export async function GET() {
try {
const headers = await getAuthHeader();
const res = await fetch(`${API_BASE_URL}/api/admin/mapping/pending-buckets`, {
headers,
cache: 'no-store',
});
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json(await res.json());
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Unauthorized' },
{ status: 401 }
);
}
}
@@ -0,0 +1,39 @@
import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() {
const token = cookies().get('session_token')?.value;
if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` };
}
export async function GET(request: NextRequest) {
try {
const headers = await getAuthHeader();
const { searchParams } = new URL(request.url);
const res = await fetch(
`${API_BASE_URL}/api/admin/mapping/raw-categories?${searchParams.toString()}`,
{
headers,
cache: 'no-store',
}
);
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json(await res.json());
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Unauthorized' },
{ status: 401 }
);
}
}
+40
View File
@@ -0,0 +1,40 @@
import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() {
const token = cookies().get('session_token')?.value;
if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` };
}
export async function POST(request: NextRequest) {
try {
const headers = await getAuthHeader();
const body = await request.json();
const res = await fetch(`${API_BASE_URL}/api/admin/mapping/upsert`, {
method: 'POST',
headers: {
...headers,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json(await res.json());
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Unauthorized' },
{ status: 401 }
);
}
}