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.
This commit is contained in:
@@ -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 <OrgProvider>");
|
||||
if (!ctx) throw new Error('useOrg must be used inside <OrgProvider>');
|
||||
return ctx;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user