Hooks Reference

All custom React hooks in frontend/kundkort/hooks/.

Source: frontend/kundkort/hooks/*.ts


useAuth

File: hooks/useAuth.ts

Signature:

function useAuth(): UseAuthReturn
 
interface UseAuthReturn {
  token: string | null;
  login: (email: string, password: string) => Promise<void>;
  logout: () => void;
  loading: boolean;
}

Purpose: Authentication state management. Provides JWT token storage, login/logout, and a development bypass.

Behavior:

ModeBehavior
Dev (DEV_MODE = true)Auto-sets 'dev-token' in sessionStorage on mount. No login required.
Prod (DEV_MODE = false)Checks sessionStorage for existing token. If none, returns null and shows login.

Login flow:

  1. POST /api/auth/login with { email, password }
  2. On 401 → throws “Felaktigt e-post eller lösenord”
  3. On other errors → throws “Inloggning misslyckades — försök igen”
  4. On success → stores JWT in sessionStorage, updates state

Logout flow:

  1. Removes token from sessionStorage
  2. Sets token state to null

Storage: sessionStorage key = enrichnode_jwt

Warning

DEV_MODE is hardcoded to true. Must be set to false before production deployment.


useKundkort

File: hooks/useKundkort.ts

Signature:

function useKundkort(orgNr: string | null, token: string | null): UseKundkortReturn
 
interface UseKundkortReturn {
  data: KundkortResponse | null;
  loading: boolean;
  error: string | null;
  statusCode: number | null;
  refetch: () => void;
  enrich: () => Promise<any>;
}

Purpose: Fetches and manages the main company detail data for the kundkort page.

Data fetch:

  • Endpoint: GET /api/kundkort/:orgNr
  • Headers: Authorization: Bearer ${token}
  • Trigger: On mount or when orgNr, token, or tick changes
  • Cancellation: Uses a cancelled flag to ignore stale responses

Error mapping:

HTTP StatusError message (Swedish)
401”Ej autentiserad”
404”Företaget hittades inte”
≥500”Serverfel”
Network failure”Nätverksfel”
Other”Okänt fel”

Refetch:

  • Increments internal tick counter, triggering useEffect re-run
  • Safe to call repeatedly

Enrich:

  • Endpoint: POST /api/kundkort/:orgNr/enrich
  • Body: { bypass_cache: true }
  • On success: increments tick to auto-refetch detail data
  • On failure: sets error state and re-throws

useEcoApi

File: hooks/useEcoApi.ts

Signature:

function useEcoApi(orgNr: string | null, token: string | null): UseEcoApiReturn
 
interface UseEcoApiReturn {
  insights: EcoApiInsights | null;
  gaps: GapsResponse | null;
  financialTrend: any;
  contactDistribution: any;
  loading: boolean;
  error: string | null;
  refetch: () => void;
  enrich: () => Promise<any>;
}

Purpose: Fetches analytics, insights, and gap analysis data in parallel. Complements useKundkort with secondary data.

Parallel fetches:

DataSourceFallback on error
insightsfetchInsights() → ECOAPI financialsnull
gapsfetchGaps() → main API gap analysisnull
financialTrendfetchFinancialTrend() → transformed ECOAPInull
contactDistributionfetchContactDistribution() → main APInull

All four requests fire in parallel via Promise.all. Individual failures are caught (catch(() => null)) — partial data is acceptable.

Refetch: Same tick-based mechanism as useKundkort.

Enrich: Delegates to triggerEcoEnrichment() in ecoApiClient, then calls refetch().


useSearch

File: hooks/useSearch.ts

Signature:

function useSearch(
  query: string,
  token: string | null,
  filters?: SearchFilters
): UseSearchReturn
 
interface UseSearchReturn {
  results: SearchResult[];
  loading: boolean;
}
 
interface SearchFilters {
  sni?: string;
  city?: string;
  legal_form?: string;
  active?: boolean;
}

Purpose: Debounced company search with optional advanced filters.

Debounce: 300ms via setTimeout. Timer is cleared on unmount or query change.

Endpoint selection:

  • Simple search (no filters): GET /api/kundkort/search?q=${query}
  • Advanced search (any filter set): GET /api/kundkort/search/advanced?...

Query parameters:

ParamCondition
qIf query.trim() is non-empty
sniIf filters.sni set
cityIf filters.city set
legal_formIf filters.legal_form set
activeIf filters.active === false (defaults to true)

Early returns:

  • Query < 2 chars AND no filters → empty results, not loading
  • No token → empty results, not loading

Response handling:

  • Expects array response (Array.isArray(data) ? data : [])
  • On any error → empty results

Hook Comparison

HookData sourceParallelDebounceCacheEnrich
useAuthsessionStorage + /api/auth/loginSession
useKundkort/api/kundkort/:orgNrNoNoNoYes (POST)
useEcoApiECOAPI + main API (4 calls)YesNoNoYes (POST)
useSearch/api/kundkort/searchNo300msNo

See also

See also