This commit is contained in:
@@ -74,8 +74,7 @@ const isUuid = (v: string) =>
|
||||
v
|
||||
);
|
||||
|
||||
const API_BASE_URL =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL ?? "";
|
||||
// API routes now handled by Next.js /api routes (server-side)
|
||||
|
||||
const STORAGE_KEY = "gunbuilder-build-state";
|
||||
|
||||
@@ -337,8 +336,8 @@ function GunbuilderPageContent() {
|
||||
|
||||
const api = useApi();
|
||||
|
||||
// ✅ Auth: we need the token ready before calling /builds/me/*
|
||||
const { token, loading: authLoading, getAuthHeaders } = useAuth();
|
||||
// ✅ Auth: check if user is logged in
|
||||
const { user, loading: authLoading } = useAuth();
|
||||
|
||||
const [platform, setPlatform] = useState<(typeof PLATFORMS)[number]>("AR15");
|
||||
|
||||
@@ -616,7 +615,7 @@ function GunbuilderPageContent() {
|
||||
|
||||
try {
|
||||
const res = await fetch(
|
||||
`${API_BASE_URL}/api/v1/catalog/products/by-ids`,
|
||||
`/api/catalog/products/by-ids`,
|
||||
{
|
||||
method: "POST",
|
||||
signal: controller.signal,
|
||||
@@ -728,7 +727,7 @@ function GunbuilderPageContent() {
|
||||
if (authLoading) return;
|
||||
|
||||
// If not logged in, don't spam the backend; show a helpful message instead.
|
||||
if (!token) {
|
||||
if (!user) {
|
||||
setShareStatus("Please log in to load builds from your Vault.");
|
||||
window.setTimeout(() => setShareStatus(null), 4500);
|
||||
return;
|
||||
@@ -738,14 +737,12 @@ function GunbuilderPageContent() {
|
||||
try {
|
||||
setShareStatus("Loading build…");
|
||||
|
||||
// NOTE: using fetch here avoids any “stale api instance” issues and lets us
|
||||
// explicitly attach JWT headers.
|
||||
// NOTE: using fetch here goes through our Next.js API routes with HTTP-only cookies
|
||||
const res = await fetch(
|
||||
`${API_BASE_URL}/api/v1/builds/me/${encodeURIComponent(uuidToLoad)}`,
|
||||
`/api/builds/${encodeURIComponent(uuidToLoad)}`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...getAuthHeaders(),
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -787,9 +784,7 @@ function GunbuilderPageContent() {
|
||||
searchParams,
|
||||
router,
|
||||
authLoading,
|
||||
token,
|
||||
getAuthHeaders,
|
||||
// API_BASE_URL is a module constant; no need to include
|
||||
user,
|
||||
]);
|
||||
|
||||
// -----------------------------
|
||||
|
||||
@@ -18,8 +18,7 @@ type BuildDto = {
|
||||
updatedAt?: string | null;
|
||||
};
|
||||
|
||||
const API_BASE_URL =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL ?? "";
|
||||
// API routes now handled by Next.js /api routes (server-side)
|
||||
|
||||
// UUID validator (defensive)
|
||||
const isUuid = (v: string) =>
|
||||
@@ -40,14 +39,14 @@ export default function VaultPage() {
|
||||
|
||||
// NOTE:
|
||||
// - `loading` here is AuthContext hydration, not network.
|
||||
// - `token` is the real gate for /me endpoints.
|
||||
const { user, token, loading: authLoading } = useAuth();
|
||||
// - Auth is handled by HTTP-only cookies automatically.
|
||||
const { user, loading: authLoading } = useAuth();
|
||||
|
||||
const [builds, setBuilds] = useState<BuildDto[]>([]);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [busy, setBusy] = useState(false);
|
||||
|
||||
const authed = !!user && !!token;
|
||||
const authed = !!user;
|
||||
|
||||
// Redirect if not logged in (after auth hydrates)
|
||||
useEffect(() => {
|
||||
@@ -56,12 +55,12 @@ export default function VaultPage() {
|
||||
}
|
||||
}, [authLoading, authed, router]);
|
||||
|
||||
// When auth identity changes, clear stale list to avoid “ghost builds”
|
||||
// When auth identity changes, clear stale list to avoid "ghost builds"
|
||||
useEffect(() => {
|
||||
if (authLoading) return;
|
||||
setBuilds([]);
|
||||
setError(null);
|
||||
}, [authLoading, user?.uuid, token]);
|
||||
}, [authLoading, user?.uuid]);
|
||||
|
||||
// Fetch user builds
|
||||
useEffect(() => {
|
||||
@@ -75,8 +74,8 @@ export default function VaultPage() {
|
||||
|
||||
try {
|
||||
// IMPORTANT:
|
||||
// Use api wrapper so Authorization: Bearer <token> is consistently applied.
|
||||
const res = await api.get("/api/v1/builds/me");
|
||||
// Use api wrapper which includes credentials (cookies) automatically.
|
||||
const res = await api.get("/api/builds");
|
||||
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => "");
|
||||
|
||||
Reference in New Issue
Block a user