upgraded to next 15 and react 19.
CI / test (push) Successful in 5s

This commit is contained in:
2026-01-30 22:22:41 -05:00
parent 4267c34399
commit 4989bf6de4
73 changed files with 2353 additions and 463 deletions
+1
View File
@@ -17,6 +17,7 @@ export default function AdminUsersPage() {
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
async function fetchUsers() { async function fetchUsers() {
console.log("in the users fetch");
try { try {
setLoading(true); setLoading(true);
setError(null); setError(null);
+3 -1
View File
@@ -6,7 +6,9 @@ const API_BASE_URL =
// POST /api/admin/beta-invites?dryRun=true&limit=10&tokenMinutes=30 // POST /api/admin/beta-invites?dryRun=true&limit=10&tokenMinutes=30
export async function POST(req: Request) { export async function POST(req: Request) {
const token = cookies().get("session_token")?.value; const cookieStore = await cookies();
const token = cookieStore.get("session_token")?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: "Missing admin token" }, { status: 401 }); return NextResponse.json({ error: "Missing admin token" }, { 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.NEXT_PUBLIC_API_BASE_URL ?? "";
// POST /api/admin/beta-invites?dryRun=true&limit=10&tokenMinutes=30
export async function POST(req: Request) {
const token = cookies().get("session_token")?.value;
if (!token) {
return NextResponse.json({ error: "Missing admin token" }, { status: 401 });
}
const url = new URL(req.url);
const dryRun = url.searchParams.get("dryRun") ?? "true";
const limit = url.searchParams.get("limit") ?? "0";
const tokenMinutes = url.searchParams.get("tokenMinutes") ?? "30";
const upstream = `${API_BASE_URL}/api/v1/admin/beta/invites/send?dryRun=${dryRun}&limit=${limit}&tokenMinutes=${tokenMinutes}`;
const res = await fetch(upstream, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
},
cache: "no-store",
});
const text = await res.text();
return new NextResponse(text, {
status: res.status,
headers: { "Content-Type": res.headers.get("content-type") ?? "application/json" },
});
}
@@ -5,19 +5,21 @@ const API_BASE_URL =
process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get("session_token")?.value; const cookieStore = await cookies();
const token = cookieStore.get("session_token")?.value;
if (!token) throw new Error("Unauthorized"); if (!token) throw new Error("Unauthorized");
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
export async function POST( export async function POST(
_req: Request, _req: Request,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/admin/beta/requests/${params.id}/invite`, `${API_BASE_URL}/api/v1/admin/beta/requests/${resolvedParams.id}/invite`,
{ {
method: "POST", method: "POST",
headers, headers,
@@ -0,0 +1,39 @@
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 POST(
_req: Request,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/beta/requests/${params.id}/invite`,
{
method: "POST",
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: "Unauthorized" }, { status: 401 });
}
}
+2 -1
View File
@@ -5,7 +5,8 @@ const API_BASE_URL =
process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get("session_token")?.value; const cookieStore = await cookies();
const token = cookieStore.get("session_token")?.value;
if (!token) throw new Error("Unauthorized"); if (!token) throw new Error("Unauthorized");
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
+39
View File
@@ -0,0 +1,39 @@
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(req: Request) {
try {
const headers = await getAuthHeader();
const url = new URL(req.url);
const search = url.searchParams.toString();
const upstream = `${API_BASE_URL}/api/v1/admin/beta/requests${
search ? `?${search}` : ""
}`;
const res = await fetch(upstream, {
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: "Unauthorized" }, { status: 401 });
}
}
+3 -1
View File
@@ -5,7 +5,9 @@ const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BAS
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
try { try {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); return NextResponse.json({ error: '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;
export async function GET(request: NextRequest) {
try {
const token = cookies().get('session_token')?.value;
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const searchParams = request.nextUrl.searchParams;
const queryString = searchParams.toString();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/calibers${queryString ? `?${queryString}` : ''}`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/json',
},
}
);
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 || 'Internal server error' },
{ status: 500 }
);
}
}
+2 -1
View File
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
@@ -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 }
);
}
}
+8 -5
View File
@@ -5,20 +5,22 @@ const API_BASE_URL =
process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get("session_token")?.value; const cookieStore = await cookies();
const token = cookieStore.get("session_token")?.value;
if (!token) throw new Error("Unauthorized"); if (!token) throw new Error("Unauthorized");
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
export async function PUT( export async function PUT(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const body = await request.json(); const body = await request.json();
const res = await fetch(`${API_BASE_URL}/api/email/${params.id}`, { const res = await fetch(`${API_BASE_URL}/api/email/${resolvedParams.id}`, {
method: "PUT", method: "PUT",
headers: { ...headers, "Content-Type": "application/json" }, headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify(body), body: JSON.stringify(body),
@@ -39,12 +41,13 @@ export async function PUT(
export async function DELETE( export async function DELETE(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const res = await fetch(`${API_BASE_URL}/api/email/${params.id}`, { const res = await fetch(`${API_BASE_URL}/api/email/${resolvedParams.id}`, {
method: "DELETE", method: "DELETE",
headers, headers,
}); });
+63
View File
@@ -0,0 +1,63 @@
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 PUT(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const body = await request.json();
const res = await fetch(`${API_BASE_URL}/api/email/${params.id}`, {
method: "PUT",
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: "Unauthorized" }, { status: 401 });
}
}
export async function DELETE(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const res = await fetch(`${API_BASE_URL}/api/email/${params.id}`, {
method: "DELETE",
headers,
});
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json({ ok: true });
} catch (err: any) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
}
+2 -1
View File
@@ -5,7 +5,8 @@ const API_BASE_URL =
process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get("session_token")?.value; const cookieStore = await cookies();
const token = cookieStore.get("session_token")?.value;
if (!token) throw new Error("Unauthorized"); if (!token) throw new Error("Unauthorized");
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
+56
View File
@@ -0,0 +1,56 @@
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() {
try {
const headers = await getAuthHeader();
const res = await fetch(`${API_BASE_URL}/api/email`, {
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: "Unauthorized" }, { status: 401 });
}
}
export async function POST(request: NextRequest) {
try {
const headers = await getAuthHeader();
const body = await request.json();
const res = await fetch(`${API_BASE_URL}/api/email`, {
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: "Unauthorized" }, { status: 401 });
}
}
@@ -5,15 +5,19 @@ const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BAS
export async function POST( export async function POST(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string; action: string } } { params }: { params: Promise<{ id: string; action: string }> }
) { ) {
try { try {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
} }
const { id, action } = params; const resolvedParams = await params;
const { id, action } = resolvedParams;
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/admin/enrichment/${id}/${action}`, `${API_BASE_URL}/api/admin/enrichment/${id}/${action}`,
@@ -0,0 +1,48 @@
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;
export async function POST(
request: NextRequest,
{ params }: { params: { id: string; action: string } }
) {
try {
const token = cookies().get('session_token')?.value;
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const { id, action } = params;
const res = await fetch(
`${API_BASE_URL}/api/admin/enrichment/${id}/${action}`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
}
);
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
const contentType = res.headers.get('content-type');
if (contentType?.includes('application/json')) {
return NextResponse.json(await res.json());
}
return NextResponse.json({ success: true });
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Internal server error' },
{ status: 500 }
);
}
}
+3 -1
View File
@@ -5,7 +5,9 @@ const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BAS
export async function POST(request: NextRequest) { export async function POST(request: NextRequest) {
try { try {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
} }
@@ -0,0 +1,46 @@
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;
export async function POST(request: NextRequest) {
try {
const token = cookies().get('session_token')?.value;
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const searchParams = request.nextUrl.searchParams;
const queryString = searchParams.toString();
const res = await fetch(
`${API_BASE_URL}/api/admin/enrichment/ai/run${queryString ? `?${queryString}` : ''}`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
}
);
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
const contentType = res.headers.get('content-type');
if (contentType?.includes('application/json')) {
return NextResponse.json(await res.json());
}
return NextResponse.json({ success: true });
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Internal server error' },
{ status: 500 }
);
}
}
+3 -1
View File
@@ -6,7 +6,9 @@ const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BAS
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
try { try {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
} }
@@ -0,0 +1,44 @@
import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
import { fixImageUrls } from '@/lib/server/image-utils';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
export async function GET(request: NextRequest) {
try {
const token = cookies().get('session_token')?.value;
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const searchParams = request.nextUrl.searchParams;
const queryString = searchParams.toString();
const res = await fetch(
`${API_BASE_URL}/api/admin/enrichment/queue2${queryString ? `?${queryString}` : ''}`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/json',
},
}
);
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
const data = await res.json();
// Fix mixed content warnings: upgrade HTTP image URLs to HTTPS
return NextResponse.json(fixImageUrls(data));
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Internal server error' },
{ status: 500 }
);
}
}
+3 -1
View File
@@ -5,7 +5,9 @@ const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BAS
export async function POST(request: NextRequest) { export async function POST(request: NextRequest) {
try { try {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
} }
+46
View File
@@ -0,0 +1,46 @@
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;
export async function POST(request: NextRequest) {
try {
const token = cookies().get('session_token')?.value;
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const searchParams = request.nextUrl.searchParams;
const queryString = searchParams.toString();
const res = await fetch(
`${API_BASE_URL}/api/admin/enrichment/run${queryString ? `?${queryString}` : ''}`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
}
);
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
const contentType = res.headers.get('content-type');
if (contentType?.includes('application/json')) {
return NextResponse.json(await res.json());
}
return NextResponse.json({ success: true });
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Internal server error' },
{ status: 500 }
);
}
}
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
@@ -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 }
);
}
}
+2 -1
View File
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
@@ -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 }
);
}
}
+2 -1
View File
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
+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 }
);
}
}
+2 -1
View File
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
@@ -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 }
);
}
}
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
@@ -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 }
);
}
}
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
@@ -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 }
);
}
}
+2 -1
View File
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
+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 }
);
}
}
+5 -3
View File
@@ -4,20 +4,22 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
export async function POST( export async function POST(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/admin/merchants/${params.id}/import`, `${API_BASE_URL}/api/v1/admin/merchants/${resolvedParams.id}/import`,
{ method: 'POST', headers } { method: 'POST', headers }
); );
@@ -0,0 +1,35 @@
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,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/merchants/${params.id}/import`,
{ method: 'POST', headers }
);
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: 'Unauthorized' }, { status: 401 });
}
}
@@ -4,20 +4,22 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
export async function POST( export async function POST(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/admin/merchants/${params.id}/offer-sync`, `${API_BASE_URL}/api/v1/admin/merchants/${resolvedParams.id}/offer-sync`,
{ method: 'POST', headers } { method: 'POST', headers }
); );
@@ -0,0 +1,35 @@
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,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/merchants/${params.id}/offer-sync`,
{ method: 'POST', headers }
);
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: 'Unauthorized' }, { status: 401 });
}
}
+11 -7
View File
@@ -4,20 +4,22 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
export async function GET( export async function GET(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/admin/merchants/${params.id}`, `${API_BASE_URL}/api/v1/admin/merchants/${resolvedParams.id}`,
{ headers } { headers }
); );
@@ -36,14 +38,15 @@ export async function GET(
export async function PUT( export async function PUT(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const body = await request.json(); const body = await request.json();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/admin/merchants/${params.id}`, `${API_BASE_URL}/api/v1/admin/merchants/${resolvedParams.id}`,
{ {
method: 'PUT', method: 'PUT',
headers: { ...headers, 'Content-Type': 'application/json' }, headers: { ...headers, 'Content-Type': 'application/json' },
@@ -66,13 +69,14 @@ export async function PUT(
export async function DELETE( export async function DELETE(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/admin/merchants/${params.id}`, `${API_BASE_URL}/api/v1/admin/merchants/${resolvedParams.id}`,
{ method: 'DELETE', headers } { method: 'DELETE', headers }
); );
+90
View File
@@ -0,0 +1,90 @@
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,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/merchants/${params.id}`,
{ headers }
);
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: 'Unauthorized' }, { status: 401 });
}
}
export async function PUT(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const body = await request.json();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/merchants/${params.id}`,
{
method: 'PUT',
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: 'Unauthorized' }, { status: 401 });
}
}
export async function DELETE(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/merchants/${params.id}`,
{ method: 'DELETE', headers }
);
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: 'Unauthorized' }, { status: 401 });
}
}
+2 -1
View File
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
+54
View File
@@ -0,0 +1,54 @@
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() {
try {
const headers = await getAuthHeader();
const res = await fetch(`${API_BASE_URL}/api/v1/admin/merchants`, {
headers,
});
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: 'Unauthorized' }, { status: 401 });
}
}
export async function POST(request: NextRequest) {
try {
const headers = await getAuthHeader();
const body = await request.json();
const res = await fetch(`${API_BASE_URL}/api/v1/admin/merchants`, {
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: 'Unauthorized' }, { status: 401 });
}
}
+8 -5
View File
@@ -4,21 +4,23 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
export async function PATCH( export async function PATCH(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const body = await request.json(); const body = await request.json();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/admin/platforms/${params.id}`, `${API_BASE_URL}/api/v1/admin/platforms/${resolvedParams.id}`,
{ {
method: 'PATCH', method: 'PATCH',
headers: { headers: {
@@ -44,13 +46,14 @@ export async function PATCH(
export async function DELETE( export async function DELETE(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/admin/platforms/${params.id}`, `${API_BASE_URL}/api/v1/admin/platforms/${resolvedParams.id}`,
{ method: 'DELETE', headers } { method: 'DELETE', headers }
); );
+68
View File
@@ -0,0 +1,68 @@
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 PATCH(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const body = await request.json();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/platforms/${params.id}`,
{
method: 'PATCH',
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: 'Unauthorized' }, { status: 401 });
}
}
export async function DELETE(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/platforms/${params.id}`,
{ method: 'DELETE', headers }
);
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json({ ok: true });
} catch (err: any) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
}
+2 -1
View File
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
+72
View File
@@ -0,0 +1,72 @@
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 = request.nextUrl.searchParams;
const queryString = searchParams.toString();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/platforms${queryString ? `?${queryString}` : ''}`,
{
headers: {
...headers,
Accept: 'application/json',
},
}
);
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 }
);
}
}
export async function POST(request: NextRequest) {
try {
const headers = await getAuthHeader();
const body = await request.json();
const res = await fetch(`${API_BASE_URL}/api/v1/admin/platforms`, {
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 }
);
}
}
+3 -1
View File
@@ -5,7 +5,9 @@ const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BAS
export async function PATCH(request: NextRequest) { export async function PATCH(request: NextRequest) {
try { try {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
} }
+41
View File
@@ -0,0 +1,41 @@
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;
export async function PATCH(request: NextRequest) {
try {
const token = cookies().get('session_token')?.value;
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const body = await request.json();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/products/bulk`,
{
method: 'PATCH',
headers: {
Authorization: `Bearer ${token}`,
'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 || 'Internal server error' },
{ status: 500 }
);
}
}
+3 -1
View File
@@ -5,7 +5,9 @@ const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BAS
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
try { try {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
} }
@@ -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;
export async function GET(request: NextRequest) {
try {
const token = cookies().get('session_token')?.value;
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const searchParams = request.nextUrl.searchParams;
const queryString = searchParams.toString();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/products/calibers${queryString ? `?${queryString}` : ''}`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/json',
},
}
);
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 || 'Internal server error' },
{ status: 500 }
);
}
}
+3 -1
View File
@@ -5,7 +5,9 @@ const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BAS
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
try { try {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); return NextResponse.json({ error: '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;
export async function GET(request: NextRequest) {
try {
const token = cookies().get('session_token')?.value;
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const searchParams = request.nextUrl.searchParams;
const queryString = searchParams.toString();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/products/roles${queryString ? `?${queryString}` : ''}`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/json',
},
}
);
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 || 'Internal server error' },
{ status: 500 }
);
}
}
+3 -1
View File
@@ -6,7 +6,9 @@ const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BAS
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
try { try {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
} }
+42
View File
@@ -0,0 +1,42 @@
import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers';
import { fixImageUrls } from '@/lib/server/image-utils';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
export async function GET(request: NextRequest) {
try {
const token = cookies().get('session_token')?.value;
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const searchParams = request.nextUrl.searchParams;
const queryString = searchParams.toString();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/products${queryString ? `?${queryString}` : ''}`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/json',
},
}
);
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
const data = await res.json();
return NextResponse.json(fixImageUrls(data));
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Internal server error' },
{ status: 500 }
);
}
}
+8 -5
View File
@@ -4,21 +4,23 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
export async function PATCH( export async function PATCH(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const body = await request.json(); const body = await request.json();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/admin/platforms/${params.id}`, `${API_BASE_URL}/api/v1/admin/platforms/${resolvedParams.id}`,
{ {
method: 'PATCH', method: 'PATCH',
headers: { headers: {
@@ -44,13 +46,14 @@ export async function PATCH(
export async function DELETE( export async function DELETE(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const resolvedParams = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/admin/platforms/${params.id}`, `${API_BASE_URL}/api/v1/admin/platforms/${resolvedParams.id}`,
{ method: 'DELETE', headers } { method: 'DELETE', headers }
); );
+68
View File
@@ -0,0 +1,68 @@
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 PATCH(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const body = await request.json();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/platforms/${params.id}`,
{
method: 'PATCH',
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: 'Unauthorized' }, { status: 401 });
}
}
export async function DELETE(
request: NextRequest,
{ params }: { params: { id: string } }
) {
try {
const headers = await getAuthHeader();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/platforms/${params.id}`,
{ method: 'DELETE', headers }
);
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
return NextResponse.json({ ok: true });
} catch (err: any) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
}
+2 -1
View File
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
+72
View File
@@ -0,0 +1,72 @@
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 = request.nextUrl.searchParams;
const queryString = searchParams.toString();
const res = await fetch(
`${API_BASE_URL}/api/v1/admin/users${queryString ? `?${queryString}` : ''}`,
{
headers: {
...headers,
Accept: 'application/json',
},
}
);
if (!res.ok) {
return NextResponse.json(
{ error: await res.text() },
{ status: res.status }
);
}
const data = await res.json();
return NextResponse.json(data);
} catch (err: any) {
return NextResponse.json(
{ error: err?.message || 'Unauthorized' },
{ status: 401 }
);
}
}
export async function POST(request: NextRequest) {
try {
const headers = await getAuthHeader();
const body = await request.json();
const res = await fetch(`${API_BASE_URL}/api/v1/admin/users`, {
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 }
);
}
}
+2 -1
View File
@@ -25,7 +25,8 @@ export async function POST(request: NextRequest) {
const data = await res.json(); const data = await res.json();
// Set HTTP-only cookie instead of returning token // Set HTTP-only cookie instead of returning token
cookies().set('session_token', data.token, { const cookieStore = await cookies();
cookieStore.set('session_token', data.token, {
httpOnly: true, httpOnly: true,
secure: process.env.NODE_ENV === 'production', secure: process.env.NODE_ENV === 'production',
sameSite: 'lax', sameSite: 'lax',
+2 -1
View File
@@ -2,6 +2,7 @@ import { NextResponse } from 'next/server';
import { cookies } from 'next/headers'; import { cookies } from 'next/headers';
export async function POST() { export async function POST() {
cookies().delete('session_token'); const cookieStore = await cookies();
cookieStore.delete('session_token');
return NextResponse.json({ success: true }); return NextResponse.json({ success: true });
} }
+3 -2
View File
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) { if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
@@ -16,7 +17,7 @@ export async function GET(request: NextRequest) {
}); });
if (!res.ok) { if (!res.ok) {
cookies().delete('session_token'); cookieStore.delete('session_token');
return NextResponse.json({ error: 'Session expired' }, { status: 401 }); return NextResponse.json({ error: 'Session expired' }, { status: 401 });
} }
+2 -1
View File
@@ -26,7 +26,8 @@ export async function POST(request: NextRequest) {
// Set HTTP-only cookie on successful registration // Set HTTP-only cookie on successful registration
if (data.token) { if (data.token) {
cookies().set('session_token', data.token, { const cookieStore = await cookies();
cookieStore.set('session_token', data.token, {
httpOnly: true, httpOnly: true,
secure: process.env.NODE_ENV === 'production', secure: process.env.NODE_ENV === 'production',
sameSite: 'lax', sameSite: 'lax',
+11 -7
View File
@@ -4,20 +4,22 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
export async function GET( export async function GET(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const { id } = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/gunbuilder/builds/${params.id}`, `${API_BASE_URL}/api/v1/gunbuilder/builds/${id}`,
{ headers } { headers }
); );
@@ -36,14 +38,15 @@ export async function GET(
export async function PUT( export async function PUT(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const { id } = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const body = await request.json(); const body = await request.json();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/gunbuilder/builds/${params.id}`, `${API_BASE_URL}/api/v1/gunbuilder/builds/${id}`,
{ {
method: 'PUT', method: 'PUT',
headers: { ...headers, 'Content-Type': 'application/json' }, headers: { ...headers, 'Content-Type': 'application/json' },
@@ -66,13 +69,14 @@ export async function PUT(
export async function DELETE( export async function DELETE(
request: NextRequest, request: NextRequest,
{ params }: { params: { id: string } } { params }: { params: Promise<{ id: string }> }
) { ) {
try { try {
const { id } = await params;
const headers = await getAuthHeader(); const headers = await getAuthHeader();
const res = await fetch( const res = await fetch(
`${API_BASE_URL}/api/v1/gunbuilder/builds/${params.id}`, `${API_BASE_URL}/api/v1/gunbuilder/builds/${id}`,
{ method: 'DELETE', headers } { method: 'DELETE', headers }
); );
+2 -1
View File
@@ -4,7 +4,8 @@ import { cookies } from 'next/headers';
const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL; const API_BASE_URL = process.env.API_BASE_URL || process.env.NEXT_PUBLIC_API_BASE_URL;
async function getAuthHeader() { async function getAuthHeader() {
const token = cookies().get('session_token')?.value; const cookieStore = await cookies();
const token = cookieStore.get('session_token')?.value;
if (!token) throw new Error('Unauthorized'); if (!token) throw new Error('Unauthorized');
return { Authorization: `Bearer ${token}` }; return { Authorization: `Bearer ${token}` };
} }
+5 -3
View File
@@ -29,11 +29,13 @@ function timeAgo(iso?: string | null) {
export default async function BuildBreakdownPage({ export default async function BuildBreakdownPage({
params, params,
}: { }: {
params: { buildId: string }; params: Promise<{ buildId: string }>;
}) { }) {
const { buildId } = await params;
// Public detail endpoint - use Next.js API route // Public detail endpoint - use Next.js API route
const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'; const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000';
const res = await fetch(`${baseUrl}/api/builds/public/${params.buildId}`, { const res = await fetch(`${baseUrl}/api/builds/public/${buildId}`, {
cache: "no-store", cache: "no-store",
}); });
@@ -359,7 +361,7 @@ export default async function BuildBreakdownPage({
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<span className="text-zinc-500">Build ID</span> <span className="text-zinc-500">Build ID</span>
<span className="text-zinc-300"> <span className="text-zinc-300">
{(build.uuid ?? params.buildId).slice(0, 8)} {(build.uuid ?? buildId).slice(0, 8)}
</span> </span>
</div> </div>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
+10 -10
View File
@@ -3,17 +3,17 @@ import { useMemo } from "react";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import type React from "react"; import type React from "react";
import "react-quill/dist/quill.snow.css"; // import "react-quill/dist/quill.snow.css";
const ReactQuill = dynamic(() => import("react-quill-new"), { ssr: false });
type RichTextEditorProps = {
value: string;
onChange: (html: string) => void;
placeholder?: string;
className?: string;
};
const ReactQuill = dynamic(() => import("react-quill"), { ssr: false });
type RichTextEditorProps = {
value: string;
onChange: (html: string) => void;
placeholder?: string;
className?: string;
};
export default function RichTextEditor({ export default function RichTextEditor({
value, value,
onChange, onChange,
+2 -1
View File
@@ -1,5 +1,6 @@
/// <reference types="next" /> /// <reference types="next" />
/// <reference types="next/image-types/global" /> /// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />
// NOTE: This file should not be edited // NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information. // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
-3
View File
@@ -1,8 +1,5 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
experimental: {
appDir: true,
},
typescript: { typescript: {
ignoreBuildErrors: true, ignoreBuildErrors: true,
}, },
+791 -371
View File
File diff suppressed because it is too large Load Diff
+5 -6
View File
@@ -19,7 +19,7 @@
], ],
"license": "UNLICENSED", "license": "UNLICENSED",
"scripts": { "scripts": {
"dev": "next dev --turbopack", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint" "lint": "next lint"
@@ -29,12 +29,11 @@
"@heroicons/react": "^2.2.0", "@heroicons/react": "^2.2.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"lucide-react": "^0.555.0", "lucide-react": "^0.555.0",
"next": "14.2.3", "next": "15.5.11",
"quill": "^2.0.3",
"quill-image-resize-module": "^3.0.0", "quill-image-resize-module": "^3.0.0",
"react": "18.3.1", "react": "^19.2.4",
"react-dom": "18.3.1", "react-dom": "^19.2.4",
"react-quill": "^2.0.0" "react-quill-new": "^3.7.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "20.12.7", "@types/node": "20.12.7",