Skip to content

Commit a3ae99e

Browse files
author
James Blair
committed
refactor: move IAL 403 redirect into useHouseholdData hook
Moves the 403 + requiredIal detection and redirect logic from DashboardContent into the useHouseholdData hook so all consumers get the behavior automatically. Exposes requiresProofing flag for loading state during redirect.
1 parent 60ead1b commit a3ae99e

3 files changed

Lines changed: 33 additions & 17 deletions

File tree

src/SEBT.Portal.Web/src/features/household/api/useHouseholdData.test.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
1414

1515
import { server } from '@/mocks/server'
1616

17+
vi.mock('next/navigation', () => ({
18+
useRouter: () => ({ push: vi.fn() })
19+
}))
20+
1721
import { useHouseholdData } from './useHouseholdData'
1822

1923
const TEST_HOUSEHOLD_DATA = {

src/SEBT.Portal.Web/src/features/household/api/useHouseholdData.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
'use client'
2+
13
import { useQuery } from '@tanstack/react-query'
4+
import { useRouter } from 'next/navigation'
5+
import { useEffect } from 'react'
26

37
import { ApiError, apiFetch } from '@/api'
48

@@ -15,10 +19,17 @@ async function fetchHouseholdData(): Promise<HouseholdData> {
1519
* Uses real-time fetching (staleTime: 0) to ensure data freshness
1620
* per ticket requirement to mitigate stale household/custody data.
1721
*
18-
* @returns TanStack Query result with household data
22+
* When the API returns 403 with a `requiredIal` extension, the user's IAL is
23+
* below the minimum required by their cases. The hook automatically redirects
24+
* to `/login/id-proofing` and exposes `requiresProofing` so consumers can
25+
* render a loading state during the redirect.
26+
*
27+
* @returns TanStack Query result with household data, plus `requiresProofing` flag
1928
*/
2029
export function useHouseholdData() {
21-
return useQuery({
30+
const router = useRouter()
31+
32+
const query = useQuery({
2233
queryKey: ['householdData'],
2334
queryFn: fetchHouseholdData,
2435
staleTime: 0,
@@ -34,4 +45,19 @@ export function useHouseholdData() {
3445
},
3546
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 10000)
3647
})
48+
49+
// A 403 with requiredIal in the response body means the user's IAL is below
50+
// the minimum required by their cases. Redirect to ID proofing.
51+
const requiresProofing =
52+
query.error instanceof ApiError &&
53+
query.error.status === 403 &&
54+
'requiredIal' in ((query.error.data as Record<string, unknown>) ?? {})
55+
56+
useEffect(() => {
57+
if (requiresProofing) {
58+
router.push('/login/id-proofing')
59+
}
60+
}, [requiresProofing, router])
61+
62+
return { ...query, requiresProofing }
3763
}

src/SEBT.Portal.Web/src/features/household/components/DashboardContent/DashboardContent.tsx

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import { ApiError } from '@/api'
44
import { AnalyticsEvents, useDataLayer } from '@sebt/analytics'
55
import { Alert } from '@sebt/design-system'
6-
import { useRouter } from 'next/navigation'
76
import { useEffect } from 'react'
87
import { useTranslation } from 'react-i18next'
98

@@ -21,22 +20,9 @@ import { UserProfileCard } from '../UserProfileCard'
2120
// TODO: Add to CSV: "S2 - Portal Dashboard - Error Heading" and "S2 - Portal Dashboard - Error Description"
2221
export function DashboardContent() {
2322
const { t } = useTranslation('dashboard')
24-
const router = useRouter()
25-
const { data, isLoading, isError, error } = useHouseholdData()
23+
const { data, isLoading, isError, error, requiresProofing } = useHouseholdData()
2624
const { setPageData, setUserData, trackEvent } = useDataLayer()
2725

28-
// A 403 with requiredIal in the response body means the user's IAL is below
29-
// the minimum required by their cases. Redirect to ID proofing.
30-
const requiresProofing =
31-
error instanceof ApiError &&
32-
error.status === 403 &&
33-
'requiredIal' in ((error.data as Record<string, unknown>) ?? {})
34-
useEffect(() => {
35-
if (requiresProofing) {
36-
router.push('/login/id-proofing')
37-
}
38-
}, [requiresProofing, router])
39-
4026
useEffect(() => {
4127
if (isLoading) return
4228
if (isError) {

0 commit comments

Comments
 (0)