From 5fc24b7a42a45e89bc9e335dbf582f0fcb44044b Mon Sep 17 00:00:00 2001 From: Cory Hawkvelt Date: Mon, 20 Apr 2026 16:58:03 +0930 Subject: [PATCH] feat(org): persist selected organization to localStorage Add localStorage persistence for the currently selected organization. This ensures the user's organization selection is remembered across browser sessions, improving user experience by maintaining context after page reloads or revisiting the application. --- src/contexts/OrgContext.tsx | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/contexts/OrgContext.tsx b/src/contexts/OrgContext.tsx index 3dd3479..289beda 100644 --- a/src/contexts/OrgContext.tsx +++ b/src/contexts/OrgContext.tsx @@ -5,11 +5,13 @@ import { useEffect, useCallback, ReactNode, -} from "react"; -import { useQueryClient } from "@tanstack/react-query"; -import { Organization } from "@/lib/api"; -import { useOrganizations } from "@/hooks/useOrganizations"; -import { useAuth } from "@/contexts/AuthContext"; +} from 'react'; +import { useQueryClient } from '@tanstack/react-query'; +import { Organization } from '@/lib/api'; +import { useOrganizations } from '@/hooks/useOrganizations'; +import { useAuth } from '@/contexts/AuthContext'; + +const SELECTED_ORG_KEY = 'secuird_selected_org_id'; interface OrgContextType { /** The currently selected organisation (null while loading or no memberships). */ @@ -43,6 +45,13 @@ export function OrgProvider({ children }: { children: ReactNode }) { // Refresh the object in case name/role changed. return organizations.find((o) => o.id === prev.id) ?? prev; } + // Try to restore from localStorage. + const persistedId = localStorage.getItem(SELECTED_ORG_KEY); + if (persistedId) { + const persistedOrg = organizations.find((o) => o.id === persistedId); + if (persistedOrg) return persistedOrg; + } + // Fall back to the first org. return organizations[0]; }); }, [organizations, isAuthenticated]); @@ -50,9 +59,10 @@ export function OrgProvider({ children }: { children: ReactNode }) { const selectOrg = useCallback( (org: Organization) => { setSelectedOrg(org); + localStorage.setItem(SELECTED_ORG_KEY, org.id); // Invalidate all organisation-scoped React Query caches so every page // immediately re-fetches data for the newly selected org. - queryClient.invalidateQueries({ queryKey: ["organizations"] }); + queryClient.invalidateQueries({ queryKey: ['organizations'] }); // Invalidate any queries keyed by the previous org id. The broadest // approach is to remove all non-organisations queries so pages reload. queryClient.invalidateQueries(); @@ -71,6 +81,6 @@ export function OrgProvider({ children }: { children: ReactNode }) { export function useOrg(): OrgContextType { const ctx = useContext(OrgContext); - if (!ctx) throw new Error("useOrg must be used inside "); + if (!ctx) throw new Error('useOrg must be used inside '); return ctx; }