From 22d51be29d53b953eb6f5dc665929e12679844c4 Mon Sep 17 00:00:00 2001 From: Brian Stephan Date: Tue, 7 Jul 2026 14:02:06 -0400 Subject: [PATCH] feat: store local-editor api keys in local storage --- .../src/local-editor/LocalEditorShell.tsx | 69 ++++++++++++++++--- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/packages/visual-editor/src/local-editor/LocalEditorShell.tsx b/packages/visual-editor/src/local-editor/LocalEditorShell.tsx index 97cda56b3..f59134219 100644 --- a/packages/visual-editor/src/local-editor/LocalEditorShell.tsx +++ b/packages/visual-editor/src/local-editor/LocalEditorShell.tsx @@ -14,6 +14,11 @@ import type { LocalEditorShellProps } from "./types.ts"; import { useLocalEditorDocument } from "./useLocalEditorDocument.ts"; import { useLocalEditorManifest } from "./useLocalEditorManifest.ts"; +const LOCAL_EDITOR_MAPBOX_KEY_STORAGE_KEY = + "visual-editor.local-editor.mapbox-key"; +const LOCAL_EDITOR_NEARBY_LOCATIONS_KEY_STORAGE_KEY = + "visual-editor.local-editor.nearby-locations-key"; + const TEST_REVIEWS_AGG = [ { publisher: "FIRSTPARTY", @@ -62,8 +67,14 @@ export const LocalEditorShell = ({ const [locationSearch, setLocationSearch] = React.useState(() => { return typeof window === "undefined" ? "" : window.location.search; }); - const [mapboxKey, setMapboxKey] = React.useState(); - const [nearbyLocationsKey, setNearbyLocationsKey] = React.useState(); + const [mapboxKey, setMapboxKey] = React.useState(() => { + return readLocalStorageValue(LOCAL_EDITOR_MAPBOX_KEY_STORAGE_KEY); + }); + const [nearbyLocationsKey, setNearbyLocationsKey] = React.useState< + string | undefined + >(() => { + return readLocalStorageValue(LOCAL_EDITOR_NEARBY_LOCATIONS_KEY_STORAGE_KEY); + }); const { isManifestLoading, manifest, manifestError } = useLocalEditorManifest(apiBasePath); @@ -252,6 +263,32 @@ export const LocalEditorShell = ({ showReviewsData, ]); + const handleApiKeyUpdate = React.useCallback( + ( + promptText: string, + currentValue: string | undefined, + storageKey: string, + setApiKey: React.Dispatch + ) => { + const nextValue = window.prompt(promptText, currentValue); + + if (nextValue === null) { + return; + } + + const trimmedValue = nextValue.trim(); + if (!trimmedValue) { + window.localStorage.removeItem(storageKey); + setApiKey(undefined); + return; + } + + window.localStorage.setItem(storageKey, trimmedValue); + setApiKey(trimmedValue); + }, + [mapboxKey, nearbyLocationsKey] + ); + return (
{ - const promptResult = window.prompt("Enter Mapbox key", mapboxKey); - if (typeof promptResult === "string") { - setMapboxKey(promptResult); - } + handleApiKeyUpdate( + "Enter Mapbox key", + mapboxKey, + LOCAL_EDITOR_MAPBOX_KEY_STORAGE_KEY, + setMapboxKey + ); }} > {mapboxKey ? "Update Mapbox Key" : "Add Mapbox Key"} { - const promptResult = window.prompt( + handleApiKeyUpdate( "Yext API Key", - nearbyLocationsKey + nearbyLocationsKey, + LOCAL_EDITOR_NEARBY_LOCATIONS_KEY_STORAGE_KEY, + setNearbyLocationsKey ); - if (typeof promptResult === "string") { - setNearbyLocationsKey(promptResult); - } }} > {nearbyLocationsKey @@ -447,6 +485,15 @@ export const LocalEditorShell = ({ ); }; +const readLocalStorageValue = (storageKey: string): string | undefined => { + if (typeof window === "undefined") { + return undefined; + } + + const storedValue = window.localStorage.getItem(storageKey); + return storedValue?.trim() ? storedValue : undefined; +}; + const EditorShellButton = (props: { children: React.ReactNode; onClick: () => void;