fixing vault. allow users to delete their builds or update

This commit is contained in:
2025-12-21 07:20:22 -05:00
parent 47d5cf239d
commit 008936ff98
5 changed files with 391 additions and 607 deletions
+46 -14
View File
@@ -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) {