Skip to main content

Hooks Reference

Complete reference for React hooks provided by @enterpriseaigroup/client.

Store Hooks

useStoreValue

Read a value from the store at a dot-notation path.

import { useStoreValue } from '@enterpriseaigroup/client';

function MyComponent() {
const userName = useStoreValue('user.name');
const theme = useStoreValue('ui.theme');

return <p>Hello, {userName}</p>;
}

Parameters:

  • path: string - Dot-notation path to the value

Returns: The value at the path, or undefined if not found

Notes:

  • Reactive - component re-renders when value changes
  • Type-safe with proper TypeScript generics

useSetStore

Get the setter function for updating store values.

import { useSetStore } from '@enterpriseaigroup/client';

function MyComponent() {
const setStore = useSetStore();

const updateName = () => {
setStore('user.name', 'John', 'MyComponent');
};

return <button onClick={updateName}>Set Name</button>;
}

Returns: (path: string, value: any, caller: string) => void

Parameters:

  • path - Dot-notation path to update
  • value - New value to set
  • caller - Component name (for DevTools debugging)

Notes:

  • Third argument appears in Redux DevTools: set/user.name (MyComponent)
  • Always provide caller for debugging

useGlobalSelector

Create a custom selector for derived state.

import { useGlobalSelector } from '@enterpriseaigroup/client';

function MyComponent() {
// Derived state
const isAdmin = useGlobalSelector(
(state) => state.user?.role === 'admin'
);

// Computed value
const projectCount = useGlobalSelector(
(state) => state.projects?.list?.length ?? 0
);

return <p>Projects: {projectCount}</p>;
}

Parameters:

  • selector: (state: GlobalState) => T - Selector function

Returns: The selected value

Notes:

  • More flexible than useStoreValue
  • Good for derived/computed state
  • Memoize selector if complex

useStoreGetter

Get a non-reactive getter function.

import { useStoreGetter } from '@enterpriseaigroup/client';
import { useCallback } from 'react';

function MyComponent() {
const getMessages = useStoreGetter('chat.messages');

const handleSubmit = useCallback(() => {
// Always returns current value, no stale closure
const messages = getMessages();
console.log('Current messages:', messages.length);
}, [getMessages]);

return <button onClick={handleSubmit}>Submit</button>;
}

Parameters:

  • path: string - Dot-notation path

Returns: () => T - Function that returns current value

Notes:

  • Use in callbacks to avoid stale closures
  • Does NOT trigger re-renders

useResetSlice

Reset a store slice to its initial state.

import { useResetSlice } from '@enterpriseaigroup/client';

function ResetButton() {
const resetProperty = useResetSlice('property');

return (
<button onClick={resetProperty}>
Clear Selection
</button>
);
}

Parameters:

  • sliceName: string - Name of the slice to reset

Returns: () => void - Reset function


useClearPersistedStore

Clear all persisted state from sessionStorage.

import { useClearPersistedStore } from '@enterpriseaigroup/client';

function LogoutButton() {
const clearStore = useClearPersistedStore();

const handleLogout = () => {
clearStore();
// Then redirect to login
};

return <button onClick={handleLogout}>Logout</button>;
}

Returns: () => void - Clear function

Notes:

  • Clears sessionStorage
  • Useful for logout flows

API Hooks

useProvision

Provision a user in a tenant.

import { useProvision } from '@enterpriseaigroup/client';

function ProvisionButton({ tenantId }) {
const { mutateAsync: provision, isPending, error } = useProvision();

const handleProvision = async () => {
try {
await provision(tenantId);
console.log('Provisioned successfully');
} catch (err) {
console.error('Provision failed:', err);
}
};

return (
<button onClick={handleProvision} disabled={isPending}>
{isPending ? 'Provisioning...' : 'Provision Account'}
</button>
);
}

Returns: React Query mutation result


useProjects

CRUD operations for business requests/projects.

import { useProjects } from '@enterpriseaigroup/client';

function ProjectsList({ tenantId, workflowId, userOid, userEmail }) {
const {
projects,
currentProject,
isLoading,
error,
fetchProjects,
createProject,
selectProject,
saveProject,
deleteProject,
} = useProjects({ tenantId, workflowId, userOid, userEmail });

if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;

return (
<ul>
{projects.map((project) => (
<li
key={project.id}
onClick={() => selectProject(project.id)}
>
{project.name}
</li>
))}
</ul>
);
}

Parameters:

  • tenantId: string - Tenant identifier
  • workflowId: string - Workflow identifier
  • userOid: string - User object ID
  • userEmail: string - User email

Returns:

  • projects: Project[] - List of projects
  • currentProject: Project | null - Selected project
  • isLoading: boolean - Loading state
  • error: Error | null - Error state
  • fetchProjects: () => void - Refresh projects
  • createProject: (data) => Promise - Create new project
  • selectProject: (id) => void - Select a project
  • saveProject: (data) => Promise - Update current project
  • deleteProject: (id) => Promise - Delete a project

useUserProfile

Fetch the current user's profile.

import { useUserProfile } from '@enterpriseaigroup/client';

function UserInfo() {
const { data: profile, isLoading, error } = useUserProfile();

if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error loading profile</div>;

return (
<div>
<p>Name: {profile.displayName}</p>
<p>Email: {profile.email}</p>
</div>
);
}

Returns: React Query result with user profile


useStageTransition

Navigate between workflow stages.

import { useStageTransition } from '@enterpriseaigroup/client';

function StageNavigation() {
const {
currentStage,
goToStage,
canGoToStage,
nextStage,
previousStage,
} = useStageTransition();

return (
<div>
<p>Current: {currentStage}</p>
<button onClick={previousStage}>Back</button>
<button
onClick={() => goToStage('planning')}
disabled={!canGoToStage('planning')}
>
Go to Planning
</button>
<button onClick={nextStage}>Next</button>
</div>
);
}

Returns:

  • currentStage: string - Current stage name
  • goToStage: (stage) => void - Navigate to specific stage
  • canGoToStage: (stage) => boolean - Check if stage is accessible
  • nextStage: () => void - Go to next stage
  • previousStage: () => void - Go to previous stage

useAddressLookup

Address autocomplete with debouncing.

import { useAddressLookup } from '@enterpriseaigroup/client';

function AddressSearch({ tenantId }) {
const {
suggestions,
status,
search,
select,
clear,
} = useAddressLookup(
'/api/eai/public/v3/nsw/address-lookup',
3, // minimum characters
tenantId
);

return (
<div>
<input
type="text"
onChange={(e) => search(e.target.value)}
placeholder="Search address..."
/>
{status === 'loading' && <span>Loading...</span>}
<ul>
{suggestions.map((suggestion) => (
<li
key={suggestion.id}
onClick={() => select(suggestion)}
>
{suggestion.address}
</li>
))}
</ul>
</div>
);
}

Parameters:

  • endpoint: string - API endpoint for address lookup
  • minChars: number - Minimum characters before searching
  • tenantId: string - Tenant identifier

Returns:

  • suggestions: Address[] - Search results
  • status: 'idle' | 'loading' | 'success' | 'error' - Current status
  • search: (query) => void - Trigger search
  • select: (address) => void - Select an address
  • clear: () => void - Clear suggestions

Configuration Hooks

useConfig

Access the current tenant configuration.

import { useConfig } from '@enterpriseaigroup/client';

function ConfigInfo() {
const config = useConfig();

return (
<div>
<p>Tenant: {config.tenantId}</p>
<p>Name: {config.displayName}</p>
</div>
);
}

Returns: EAIConfig - Current tenant configuration


useRuntimeConfig

Access runtime configuration from the server.

import { useRuntimeConfig } from '@enterpriseaigroup/client';

function MapComponent() {
const { mapboxToken, tenants } = useRuntimeConfig();

return <Map token={mapboxToken} />;
}

Returns: RuntimeConfig - Server-provided configuration