diff --git a/.env.production b/.env.production index 9b1b816..3987ead 100644 --- a/.env.production +++ b/.env.production @@ -1,5 +1,5 @@ -NEXT_PUBLIC_API_BASE_URL=http://localhost:8080 +NEXT_PUBLIC_API_BASE_URL=http://battlbuilder-api:8080 # Middleware to limited site to only root page NEXT_PUBLIC_LAUNCH_ONLY_ROOT=false diff --git a/app/(app)/(builder)/builder/page.tsx b/app/(app)/(builder)/builder/page.tsx index 6139b72..bebb4f1 100644 --- a/app/(app)/(builder)/builder/page.tsx +++ b/app/(app)/(builder)/builder/page.tsx @@ -75,7 +75,7 @@ const isUuid = (v: string) => ); const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; const STORAGE_KEY = "gunbuilder-build-state"; diff --git a/app/(app)/(builder)/parts/p/[platform]/[partRole]/[productSlug]/page.tsx b/app/(app)/(builder)/parts/p/[platform]/[partRole]/[productSlug]/page.tsx index ac9102c..7e33915 100644 --- a/app/(app)/(builder)/parts/p/[platform]/[partRole]/[productSlug]/page.tsx +++ b/app/(app)/(builder)/parts/p/[platform]/[partRole]/[productSlug]/page.tsx @@ -49,7 +49,7 @@ type GunbuilderProductFromApi = { type BuildState = Partial>; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; const STORAGE_KEY = "gunbuilder-build-state"; diff --git a/app/(app)/vault/page.tsx b/app/(app)/vault/page.tsx index 4a63dab..cc3796e 100644 --- a/app/(app)/vault/page.tsx +++ b/app/(app)/vault/page.tsx @@ -19,7 +19,7 @@ type BuildDto = { }; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; // UUID validator (defensive) const isUuid = (v: string) => diff --git a/app/admin/beta-invites/page.tsx b/app/admin/beta-invites/page.tsx index 7175325..87c6f18 100644 --- a/app/admin/beta-invites/page.tsx +++ b/app/admin/beta-invites/page.tsx @@ -5,7 +5,7 @@ import { Button, Field, Input } from "@/components/ui/form"; import { useAuth } from "@/context/AuthContext"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; type AdminBetaRequestDto = { id: number; diff --git a/app/admin/classification/reconcile/page.tsx b/app/admin/classification/reconcile/page.tsx index 0d3f093..48bd2d8 100644 --- a/app/admin/classification/reconcile/page.tsx +++ b/app/admin/classification/reconcile/page.tsx @@ -38,7 +38,7 @@ const DEFAULT_PLATFORM = "AR-15"; // Update these if your admin mapping UI lives elsewhere. const MAPPING_UI_PATH = "/admin/mapping"; // <- change if needed -const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; +const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; const url = `${API_BASE}/admin/classification/reconcile?dryRun=true&limit=500&platform=AR-15&merchantId=4`; @@ -80,7 +80,7 @@ export default function AdminClassificationReconcilePage() { if (merchantId?.trim()) params.set("merchantId", merchantId.trim()); if (includeLocked) params.set("includeLocked", "true"); - const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; const url = `${API_BASE}/admin/classification/reconcile?${params.toString()}`; const res = await fetch(url, { diff --git a/app/admin/enrichment/EnrichmentQueueClient.tsx b/app/admin/enrichment/EnrichmentQueueClient.tsx index c75f8ba..a41460c 100644 --- a/app/admin/enrichment/EnrichmentQueueClient.tsx +++ b/app/admin/enrichment/EnrichmentQueueClient.tsx @@ -29,7 +29,7 @@ type QueueItem = { }; const API_BASE = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; function getAuthHeaders(): HeadersInit { if (typeof window === "undefined") return {}; diff --git a/app/admin/import-status/page.tsx b/app/admin/import-status/page.tsx index c3d44ed..00427ef 100644 --- a/app/admin/import-status/page.tsx +++ b/app/admin/import-status/page.tsx @@ -4,7 +4,7 @@ import { useEffect, useState } from "react"; import Link from "next/link"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; const formatCount = (value: number | null | undefined) => (typeof value === "number" ? value : 0).toLocaleString(); diff --git a/app/admin/mapping/page.tsx b/app/admin/mapping/page.tsx index b24f7dd..7117f40 100644 --- a/app/admin/mapping/page.tsx +++ b/app/admin/mapping/page.tsx @@ -4,7 +4,7 @@ import { useEffect, useMemo, useState } from "react"; import { useSearchParams, useRouter } from "next/navigation"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; /** * Tabs: diff --git a/app/admin/merchants/page.tsx b/app/admin/merchants/page.tsx index 24b2027..be58ef2 100644 --- a/app/admin/merchants/page.tsx +++ b/app/admin/merchants/page.tsx @@ -3,7 +3,7 @@ import { useEffect, useState } from "react"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; type MerchantAdminDto = { id: number; diff --git a/app/admin/page.tsx b/app/admin/page.tsx index 44441f2..b9ebe27 100644 --- a/app/admin/page.tsx +++ b/app/admin/page.tsx @@ -4,7 +4,7 @@ import { useEffect, useState } from "react"; import Link from "next/link"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; type AdminOverview = { totalProducts: number; diff --git a/app/admin/products/_lib/auth.ts b/app/admin/products/_lib/auth.ts index 19c9272..4fb95a9 100644 --- a/app/admin/products/_lib/auth.ts +++ b/app/admin/products/_lib/auth.ts @@ -1,5 +1,5 @@ export const API_BASE = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; export function getCookie(name: string): string | null { if (typeof document === "undefined") return null; diff --git a/app/admin/users/page.tsx b/app/admin/users/page.tsx index 11c3fc5..36404c1 100644 --- a/app/admin/users/page.tsx +++ b/app/admin/users/page.tsx @@ -7,7 +7,7 @@ import { Loader2 } from "lucide-react"; import type { AdminUser, UserRole } from "@/types/user"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; export default function AdminUsersPage() { const { getAuthHeaders } = useAuth(); diff --git a/app/api/admin/beta-invites/route.ts b/app/api/admin/beta-invites/route.ts index 596d2ce..54d4417 100644 --- a/app/api/admin/beta-invites/route.ts +++ b/app/api/admin/beta-invites/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; import { cookies } from "next/headers"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; // POST /api/admin/beta-invites?dryRun=true&limit=10&tokenMinutes=30 export async function POST(req: Request) { diff --git a/app/api/beta-signup/route.ts b/app/api/beta-signup/route.ts index 8ea4b29..ecc45d2 100644 --- a/app/api/beta-signup/route.ts +++ b/app/api/beta-signup/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; const TOS_VERSION = "2025-12-27"; diff --git a/app/api/users/me/password/route.ts b/app/api/users/me/password/route.ts index f7ac6ff..af03d79 100644 --- a/app/api/users/me/password/route.ts +++ b/app/api/users/me/password/route.ts @@ -1,7 +1,7 @@ import { NextResponse } from "next/server"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; export async function POST(req: Request) { const body = await req.text().catch(() => ""); diff --git a/app/api/users/me/route.ts b/app/api/users/me/route.ts index 58bae83..13530f5 100644 --- a/app/api/users/me/route.ts +++ b/app/api/users/me/route.ts @@ -1,7 +1,7 @@ import { NextResponse } from "next/server"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; function passthroughHeaders(req: Request) { const h = new Headers(); diff --git a/app/api/users/me/username-available/route.ts b/app/api/users/me/username-available/route.ts index 308cb4b..81f47e4 100644 --- a/app/api/users/me/username-available/route.ts +++ b/app/api/users/me/username-available/route.ts @@ -1,7 +1,7 @@ import { NextResponse } from "next/server"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; export async function GET(req: Request) { const url = new URL(req.url); diff --git a/app/api/v1/admin/merchants/[id]/route.ts b/app/api/v1/admin/merchants/[id]/route.ts new file mode 100644 index 0000000..eb76afd --- /dev/null +++ b/app/api/v1/admin/merchants/[id]/route.ts @@ -0,0 +1,18 @@ +import { springProxy } from "@/lib/springProxy"; +import type { + MerchantAdminResponse, + MerchantAdminUpdateRequest, +} from "@/types/merchant-admin"; + +export async function PUT( + req: Request, + { params }: { params: { id: string } } +) { + const body = (await req.json()) as MerchantAdminUpdateRequest; + + return springProxy( + req, + `/api/v1/admin/merchants/${params.id}`, + { method: "PUT", body } + ); +} diff --git a/app/api/v1/admin/merchants/route.ts b/app/api/v1/admin/merchants/route.ts new file mode 100644 index 0000000..a6b99d2 --- /dev/null +++ b/app/api/v1/admin/merchants/route.ts @@ -0,0 +1,19 @@ +import { springProxy } from "@/lib/springProxy"; +import type { + MerchantAdminCreateRequest, + MerchantAdminResponse, +} from "@/types/merchant-admin"; + +export async function GET(req: Request) { + return springProxy(req, "/api/v1/admin/merchants"); +} + +export async function POST(req: Request) { + const body = (await req.json()) as MerchantAdminCreateRequest; + + return springProxy( + req, + "/api/v1/admin/merchants", + { method: "POST", body } + ); +} diff --git a/app/beta/confirm/page.tsx b/app/beta/confirm/page.tsx index b1c2e59..15479f5 100644 --- a/app/beta/confirm/page.tsx +++ b/app/beta/confirm/page.tsx @@ -6,7 +6,7 @@ import { useRouter, useSearchParams } from "next/navigation"; import { useAuth } from "@/context/AuthContext"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; function BetaConfirmPageContent() { const params = useSearchParams(); diff --git a/app/beta/magic/page.tsx b/app/beta/magic/page.tsx index 21501c3..159fcfa 100644 --- a/app/beta/magic/page.tsx +++ b/app/beta/magic/page.tsx @@ -27,7 +27,7 @@ function BetaMagicPageContent() { (async () => { try { - const res = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"}/api/auth/magic/exchange`, { + const res = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://battlbuilder-api:8080"}/api/auth/magic/exchange`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ token }), diff --git a/app/builds/[buildId]/page.tsx b/app/builds/[buildId]/page.tsx index cfb9792..1dd06f9 100644 --- a/app/builds/[buildId]/page.tsx +++ b/app/builds/[buildId]/page.tsx @@ -3,7 +3,7 @@ import Link from "next/link"; import { notFound } from "next/navigation"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; function formatMoney(n?: number | null) { if (n == null) return "—"; diff --git a/app/builds/page.tsx b/app/builds/page.tsx index 9e66441..783407e 100644 --- a/app/builds/page.tsx +++ b/app/builds/page.tsx @@ -57,7 +57,7 @@ type BuildFeedCardDto = { }; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; // --- UI Filter Sets (keep; we’ll generate options from data too) --- const CLASS_FILTERS: (BuildClass | "all")[] = ["all", "Rifle", "Pistol", "NFA"]; diff --git a/app/login/page.tsx b/app/login/page.tsx index fd2e139..96819eb 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -8,7 +8,7 @@ import { useAuth } from "@/context/AuthContext"; import { Button, Field, Input } from "@/components/ui/form"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; function LoginPageContent() { const router = useRouter(); diff --git a/components/parts/PartsBrowseClient.tsx b/components/parts/PartsBrowseClient.tsx index 6bb31b4..9079326 100644 --- a/components/parts/PartsBrowseClient.tsx +++ b/components/parts/PartsBrowseClient.tsx @@ -59,7 +59,7 @@ type GunbuilderProductFromApi = { }; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; const PAGE_SIZE = 24; diff --git a/components/parts/PartsListPageClient.tsx b/components/parts/PartsListPageClient.tsx index 0df6d22..ddc6773 100644 --- a/components/parts/PartsListPageClient.tsx +++ b/components/parts/PartsListPageClient.tsx @@ -5,7 +5,7 @@ import Link from "next/link"; import PlatformSwitcher from "./PlatformSwitcher"; import Image from "next/image"; -const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; +const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; type ProductListDto = { id: string; // your API returns strings sometimes; keep it flexible diff --git a/components/parts/ProductDetailPageClient.tsx b/components/parts/ProductDetailPageClient.tsx index ee995b8..6b59a54 100644 --- a/components/parts/ProductDetailPageClient.tsx +++ b/components/parts/ProductDetailPageClient.tsx @@ -4,7 +4,7 @@ import { useEffect, useMemo, useState } from "react"; import Link from "next/link"; import PlatformSwitcher from "./PlatformSwitcher"; -const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; +const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; type ProductDetailDto = { id: string; diff --git a/context/AuthContext.tsx b/context/AuthContext.tsx index 7af7b33..2c6a1ae 100644 --- a/context/AuthContext.tsx +++ b/context/AuthContext.tsx @@ -10,7 +10,7 @@ import { } from "react"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; type AuthUser = { uuid: string; diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 3c5a341..9d7d1d5 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -8,11 +8,13 @@ WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . +ENV NODE_ENV=production +ENV NEXT_PUBLIC_API_BASE_URL=http://battlbuilder-api:8080 RUN npm run build FROM node:20-alpine AS runner WORKDIR /app -ENV NODE_ENV=production + COPY --from=deps /app/node_modules ./node_modules COPY --from=builder /app/.next ./.next COPY --from=builder /app/public ./public diff --git a/lib/api.ts b/lib/api.ts index 58fde0b..5550bd2 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -4,7 +4,7 @@ import { useMemo } from "react"; import { useAuth } from "@/context/AuthContext"; const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; type JsonValue = any; diff --git a/lib/api/adminCategoryMappings.ts b/lib/api/adminCategoryMappings.ts index 94cc020..e4c11b3 100644 --- a/lib/api/adminCategoryMappings.ts +++ b/lib/api/adminCategoryMappings.ts @@ -1,7 +1,7 @@ // lib/api/adminCategoryMappings.ts const API_BASE = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; export interface AdminCategory { id: number; diff --git a/lib/api/adminMerchantMappings.ts b/lib/api/adminMerchantMappings.ts index 0f687ee..b4a0e16 100644 --- a/lib/api/adminMerchantMappings.ts +++ b/lib/api/adminMerchantMappings.ts @@ -1,5 +1,5 @@ const API_BASE = - process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_URL ?? ""; export interface AdminMerchantCategoryMapping { id: number; diff --git a/lib/api/emailRequests.ts b/lib/api/emailRequests.ts index fe4db01..0958bcd 100644 --- a/lib/api/emailRequests.ts +++ b/lib/api/emailRequests.ts @@ -17,7 +17,7 @@ export interface UpdateEmailRequestDto { status?: string; } -const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8080'; +const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL || ''; export async function fetchEmailRequests(token: string): Promise { const response = await fetch(`${API_BASE}/api/email`, { diff --git a/lib/api/platforms.ts b/lib/api/platforms.ts index a3cd991..5ba935a 100644 --- a/lib/api/platforms.ts +++ b/lib/api/platforms.ts @@ -15,7 +15,7 @@ export type CreatePlatformDto = { export type UpdatePlatformDto = Partial; const API_BASE = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; function normalizePlatform(raw: any): Platform { const id = Number(raw?.id); diff --git a/lib/auth-client.ts b/lib/auth-client.ts index 16fbf8c..4d1043a 100644 --- a/lib/auth-client.ts +++ b/lib/auth-client.ts @@ -1,7 +1,7 @@ // lib/auth-client.ts const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; export type AuthUser = { id: number; diff --git a/lib/catalog.ts b/lib/catalog.ts index 1944101..4b0e451 100644 --- a/lib/catalog.ts +++ b/lib/catalog.ts @@ -1,6 +1,6 @@ // app/lib/catalog.ts export const API_BASE_URL = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; export type ProductListItem = { id: string; diff --git a/lib/constants.tsx b/lib/constants.tsx index 4967eaa..86a9173 100644 --- a/lib/constants.tsx +++ b/lib/constants.tsx @@ -1,7 +1,7 @@ // Central place for app-wide constant values. // Branding / product -export const APP_NAME = "Ballistic Builder"; +export const APP_NAME = "Battl Builder"; export const APP_TAGLINE = "A smarter way to explore and assemble builds."; // URLs diff --git a/lib/springProxy.ts b/lib/springProxy.ts new file mode 100644 index 0000000..5662894 --- /dev/null +++ b/lib/springProxy.ts @@ -0,0 +1,68 @@ +import { NextResponse } from "next/server"; + +const SPRING_BASE = + process.env.SPRING_BASE_URL ?? "http://battlbuilder-api:8080"; + +function forwardHeaders(req: Request) { + const headers = new Headers(); + const auth = req.headers.get("authorization"); + const cookie = req.headers.get("cookie"); + + if (auth) headers.set("authorization", auth); + if (cookie) headers.set("cookie", cookie); + + headers.set("accept", "application/json"); + return headers; +} + +type SpringProxyOptions = { + method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; + body?: TBody; + cache?: RequestCache; +}; + +export async function springProxy( + req: Request, + path: string, + options?: SpringProxyOptions +) { + const url = `${SPRING_BASE}${path}`; + const headers = forwardHeaders(req); + + const init: RequestInit = { + method: options?.method ?? "GET", + headers, + cache: options?.cache ?? "no-store", + }; + + if (options && "body" in options && options.body !== undefined) { + headers.set("content-type", "application/json"); + init.body = JSON.stringify(options.body); + } + + const res = await fetch(url, init); + + // If Spring returns 204 No Content, don't try to parse JSON + if (res.status === 204) { + return new NextResponse(null, { status: 204 }); + } + + const contentType = res.headers.get("content-type") ?? ""; + let payload: unknown; + + if (contentType.includes("application/json")) { + payload = await res.json().catch(() => null); + } else { + payload = await res.text().catch(() => null); + } + + // If Spring returned JSON, we respond JSON; otherwise text + if (typeof payload === "string") { + return new NextResponse(payload, { + status: res.status, + headers: { "content-type": contentType || "text/plain" }, + }); + } + + return NextResponse.json(payload as TResponse, { status: res.status }); +} diff --git a/lib/useApi.ts b/lib/useApi.ts index f68eeb7..33ffe3b 100644 --- a/lib/useApi.ts +++ b/lib/useApi.ts @@ -4,7 +4,7 @@ import { useAuth } from "@/context/AuthContext"; import { useCallback, useMemo } from "react"; const DEFAULT_API_BASE = - process.env.NEXT_PUBLIC_API_BASE_URL ?? "http://localhost:8080"; + process.env.NEXT_PUBLIC_API_BASE_URL ?? ""; export function useApi(baseUrl: string = DEFAULT_API_BASE) { const { token } = useAuth(); diff --git a/next.config.mjs b/next.config.mjs index 718eb11..a2a9b1a 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -10,14 +10,14 @@ const nextConfig = { ignoreDuringBuilds: true, }, - async rewrites() { +/* async rewrites() { return [ { source: "/api/:path*", - destination: "http://localhost:8080/api/:path*", + destination: "http://battlbuilder-api:8080/api/:path*", }, ]; - }, + },*/ }; export default nextConfig; \ No newline at end of file diff --git a/push-image.sh b/push-image.sh index 4b1844e..ee26030 100755 --- a/push-image.sh +++ b/push-image.sh @@ -10,7 +10,7 @@ TAG=$(git rev-parse --short HEAD) FULL_IMAGE="$REGISTRY/$OWNER/$IMAGE" echo "Building $FULL_IMAGE:$TAG" -docker build -f frontend/Dockerfile -t $FULL_IMAGE:$TAG . +docker build -f frontend/Dockerfile --no-cache -t $FULL_IMAGE:$TAG . echo "Tagging latest" docker tag $FULL_IMAGE:$TAG $FULL_IMAGE:latest diff --git a/types/merchant-admin.ts b/types/merchant-admin.ts new file mode 100644 index 0000000..16f70ab --- /dev/null +++ b/types/merchant-admin.ts @@ -0,0 +1,24 @@ +export type MerchantAdminResponse = { + id: number; + name: string; + avantlinkMid: string | null; + feedUrl: string | null; + offerFeedUrl: string | null; + isActive: boolean; + lastFullImportAt: string | null; + lastOfferSyncAt: string | null; +}; + +export type MerchantAdminCreateRequest = { + name: string; + avantlinkMid?: string | null; + feedUrl?: string | null; + offerFeedUrl?: string | null; + isActive?: boolean | null; +}; + +export type MerchantAdminUpdateRequest = { + feedUrl?: string | null; + offerFeedUrl?: string | null; + isActive?: boolean | null; +}; diff --git a/types/merchant.ts b/types/merchant.ts new file mode 100644 index 0000000..48ea5ec --- /dev/null +++ b/types/merchant.ts @@ -0,0 +1,10 @@ +export type MerchantAdminDto = { + id?: number; // Optional for create payloads + name: string; + avantlinkMid?: string | null; + feedUrl?: string | null; + offerFeedUrl?: string | null; + isActive?: boolean | null; + lastFullImportAt?: string | null; // Spring Instant/LocalDateTime serialized as string + lastOfferSyncAt?: string | null; +};