fix: fire part_selected after hydration to get real part name

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 06:57:13 -04:00
parent 3a345b6c26
commit f12e2ffee7
+17 -3
View File
@@ -356,6 +356,8 @@ function GunbuilderPageContent() {
// Parts data state
// -----------------------------
const [parts, setParts] = useState<Part[]>([]);
const previousPartIdsRef = useRef<Set<string>>(new Set());
const isFirstPartsHydrationRef = useRef(true);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
@@ -668,6 +670,20 @@ function GunbuilderPageContent() {
setParts(hydrated);
// Track newly selected parts (fires after API returns with real names).
// Skip the first hydration — that's restoring a saved build, not a new selection.
if (isFirstPartsHydrationRef.current) {
isFirstPartsHydrationRef.current = false;
} else {
const prevIds = previousPartIdsRef.current;
for (const p of hydrated) {
if (!prevIds.has(String(p.id))) {
trackPartSelected(p.categoryId as BuilderSlotKey, p.name, String(p.id));
}
}
}
previousPartIdsRef.current = new Set(hydrated.map((p) => String(p.id)));
// ✅ Mark key as hydrated ONLY after success
lastHydrateKeyRef.current = key;
} catch (err: any) {
@@ -904,10 +920,8 @@ function GunbuilderPageContent() {
}
return next;
});
const partName = parts.find((p) => String(p.id) === String(partId))?.name ?? String(partId);
trackPartSelected(categoryId, partName, String(partId));
},
[build, parts]
[build]
);
// Handle URL query parameters (?select, ?remove) and keep platform synced + canonical
useEffect(() => {