fixing vault. allow users to delete their builds or update
This commit is contained in:
@@ -12,16 +12,25 @@
|
||||
* Notes for devs:
|
||||
* - We intentionally keep ONE save-to-vault handler: handleSaveAs()
|
||||
* - Toast is used for clear user feedback (save success/fail)
|
||||
*
|
||||
* Auth note:
|
||||
* - /api/v1/builds/me/* requires JWT.
|
||||
* - The builder can render before AuthContext hydrates from localStorage, so we
|
||||
* guard “load build” calls until auth is ready to avoid a 401.
|
||||
*/
|
||||
|
||||
import { useMemo, useState, useEffect, useCallback, useRef } from "react";
|
||||
import Link from "next/link";
|
||||
import { useSearchParams, useRouter } from "next/navigation";
|
||||
import { X, Link2, Square, CheckSquare } from "lucide-react";
|
||||
|
||||
import { useApi } from "@/lib/api";
|
||||
import { useAuth } from "@/context/AuthContext";
|
||||
|
||||
import { CATEGORIES } from "@/data/gunbuilderParts";
|
||||
import { BUILDER_SLOTS, isSlotSatisfied } from "@/data/builderSlots";
|
||||
import type { CategoryId, Part } from "@/types/gunbuilder";
|
||||
import { PART_ROLE_TO_CATEGORY } from "@/lib/catalogMappings";
|
||||
import { X, Link2, Square, CheckSquare } from "lucide-react";
|
||||
|
||||
// ✅ Centralized overlap rules + helpers
|
||||
import OverlapChip from "@/components/builder/OverlapChip";
|
||||
@@ -132,6 +141,11 @@ export default function GunbuilderPage() {
|
||||
const searchParams = useSearchParams();
|
||||
const router = useRouter();
|
||||
|
||||
const api = useApi();
|
||||
|
||||
// ✅ Auth: we need the token ready before calling /builds/me/*
|
||||
const { token, loading: authLoading, getAuthHeaders } = useAuth();
|
||||
|
||||
// -----------------------------
|
||||
// Save As… modal state (Vault variants)
|
||||
// -----------------------------
|
||||
@@ -509,13 +523,30 @@ export default function GunbuilderPage() {
|
||||
|
||||
if (!uuidToLoad) return;
|
||||
|
||||
// ✅ Wait for AuthProvider hydration before calling /me endpoints.
|
||||
if (authLoading) return;
|
||||
|
||||
// ✅ If not logged in, don't spam the backend; show a helpful message instead.
|
||||
if (!token) {
|
||||
setShareStatus("Please log in to load builds from your Vault.");
|
||||
window.setTimeout(() => setShareStatus(null), 4500);
|
||||
return;
|
||||
}
|
||||
|
||||
const run = async () => {
|
||||
try {
|
||||
setShareStatus("Loading build…");
|
||||
|
||||
// NOTE: using fetch here avoids any “stale api instance” issues and lets us
|
||||
// explicitly attach JWT headers.
|
||||
const res = await fetch(
|
||||
`${API_BASE_URL}/api/v1/builds/me/${encodeURIComponent(uuidToLoad)}`,
|
||||
{ credentials: "include" }
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...getAuthHeaders(),
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!res.ok) {
|
||||
@@ -551,8 +582,14 @@ export default function GunbuilderPage() {
|
||||
};
|
||||
|
||||
run();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [searchParams, router]);
|
||||
}, [
|
||||
searchParams,
|
||||
router,
|
||||
authLoading,
|
||||
token,
|
||||
getAuthHeaders,
|
||||
// API_BASE_URL is a module constant; no need to include
|
||||
]);
|
||||
|
||||
// -----------------------------
|
||||
// SAVE AS… (single source of truth for saving to Vault)
|
||||
@@ -584,16 +621,11 @@ export default function GunbuilderPage() {
|
||||
setSaveAsSaving(true);
|
||||
showToast({ type: "info", message: "Saving build…" });
|
||||
|
||||
const res = await fetch(`${API_BASE_URL}/api/v1/builds/me`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
credentials: "include",
|
||||
body: JSON.stringify({
|
||||
title,
|
||||
description: saveAsDesc?.trim() || null,
|
||||
isPublic: false,
|
||||
items,
|
||||
}),
|
||||
const res = await api.post("/api/v1/builds/me", {
|
||||
title,
|
||||
description: saveAsDesc?.trim() || null,
|
||||
isPublic: false,
|
||||
items,
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
|
||||
Reference in New Issue
Block a user