Skip to content

Commit

Permalink
feat: redirect users to login when endpoint throws a 4XX status (#99)
Browse files Browse the repository at this point in the history
* feat: redirect users to login when endpoint throws a 4XX status

* adding a error map of messages. Fix for home to sign in if endpoint is returning 4XX

* fix: home page to route to sign in page

* add login page if loader is 400

* Edits to message being sent to login page is controlled in a map instead of hard coded

* removed status from testing and added a state to have the latest datacall

* changing hardcoded error messages for userTable to dynamic error messages
  • Loading branch information
ATNoblis authored Nov 22, 2024
1 parent a8cf3ff commit b4077c8
Show file tree
Hide file tree
Showing 9 changed files with 352 additions and 140 deletions.
2 changes: 1 addition & 1 deletion src/components/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const ErrorBoundary: React.FC = (): JSX.Element => {
const title = useErrorTitle(error)
const message = useErrorMessage(error)

console.error(error)
// console.error(error)

return (
<Container sx={{ m: 3 }}>
Expand Down
9 changes: 9 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,12 @@ export const COPYRIGHT_LABEL = `Copyright © ${new Date()

// * Configuration Constants
export const DEFAULT_ALERT_TIMEOUT = 3000

export const ERROR_MESSAGES = {
login: 'Please log in to continue.',
expired: 'Your session has expired. Please log in again.',
notSaved:
'Your changes were not saved. Your session may have expired. Please log in again.',
error:
'An error occurred. Please log in and try again. If the error persists, please contact support.',
}
3 changes: 3 additions & 0 deletions src/router/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ export enum RouteIds {
APPLICATIONS = 'applications',
DATA = 'data',
USERS = 'users',
SIGNIN = 'signin',
}

export enum RouteNames {
DASHBOARD = 'Dashboard',
LOGIN = 'Login',
LOGOUT = 'Logout',
SIGNIN = 'Sign In',
}

export enum Routes {
Expand All @@ -29,4 +31,5 @@ export enum Routes {
AUTH = `/${RouteIds.AUTH}/*`,
AUTH_LOGIN = `/${RouteIds.AUTH}/${RouteIds.LOGIN}`,
AUTH_LOGOUT = `/${RouteIds.AUTH}/${RouteIds.LOGOUT}`,
SIGNIN = `/${RouteIds.SIGNIN}`,
}
7 changes: 7 additions & 0 deletions src/router/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Title from '@/views/Title/Title'
import ErrorBoundary from '@/components/ErrorBoundary'
import HomePageContainer from '@/views/Home/Home'
import UserTable from '@/views/UserTable/UserTable'
import LoginPage from '@/views/LoginPage/LoginPage'
/**
* The hash router for the application that defines routes
* and specifies the loaders for routes with dynamic data.
Expand All @@ -36,6 +37,12 @@ const router = createHashRouter([
element: <UserTable />,
errorElement: <ErrorBoundary />,
},
{
path: Routes.SIGNIN,
id: RouteIds.SIGNIN,
element: <LoginPage />,
errorElement: <ErrorBoundary />,
},
],
errorElement: <ErrorBoundary />,
},
Expand Down
58 changes: 38 additions & 20 deletions src/views/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,64 @@ import FismaTable from '../FismaTable/FismaTable'
import StatisticsBlocks from '../StatisticBlocks/StatisticsBlocks'
import { useState, useEffect } from 'react'
import axiosInstance from '@/axiosConfig'
import { useNavigate } from 'react-router-dom'
import { Routes } from '@/router/constants'
import { ERROR_MESSAGES } from '@/constants'
import { FismaSystemType } from '@/types'
import CircularProgress from '@mui/material/CircularProgress'
import { Box } from '@mui/material'

/**
* Component that renders the contents of the Home view.
* @returns {JSX.Element} Component that renders the home contents.
*/

export default function HomePageContainer() {
const [loading, setLoading] = useState<boolean>(true)
const navigate = useNavigate()
const [fismaSystems, setFismaSystems] = useState<FismaSystemType[]>([])
const [scoreMap, setScoreMap] = useState<Record<number, number>>({})
useEffect(() => {
async function fetchFismaSystems() {
try {
const fismaSystems = await axiosInstance.get('/fismasystems')
if (fismaSystems.status !== 200) {
setLoading(true)
if (
fismaSystems.status !== 200 &&
fismaSystems.status.toString()[0] === '4'
) {
navigate(Routes.SIGNIN, {
replace: true,
state: {
message: ERROR_MESSAGES.expired,
},
})
return
}
setFismaSystems(fismaSystems.data.data)
setLoading(false)
} catch (error) {
console.log(error)
navigate(Routes.SIGNIN, {
replace: true,
state: {
message: ERROR_MESSAGES.login,
},
})
}
}
fetchFismaSystems()
}, [])
}, [navigate])

useEffect(() => {
async function fetchScores() {
try {
const scores = await axiosInstance.get('/scores/aggregate')
if (scores.status !== 200 && scores.status.toString()[0] === '4') {
navigate(Routes.SIGNIN, {
replace: true,
state: {
message: ERROR_MESSAGES.expired,
},
})
return
}
const scoresMap: Record<number, number> = {}
for (const obj of scores.data.data) {
let score = 0
Expand All @@ -47,24 +71,18 @@ export default function HomePageContainer() {
setScoreMap(scoresMap)
setLoading(false)
} catch (error) {
console.log(error)
navigate(Routes.SIGNIN, {
replace: true,
state: {
message: ERROR_MESSAGES.expired,
},
})
}
}
fetchScores()
}, [])
}, [navigate])
if (loading) {
return (
<Box
flex={1}
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<CircularProgress size={100} />
</Box>
)
return <div>Loading...</div>
}
return (
<>
Expand Down
32 changes: 32 additions & 0 deletions src/views/LoginPage/LoginPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Box, Typography } from '@mui/material'
import { Button as CmsButton } from '@cmsgov/design-system'
import { useLocation } from 'react-router-dom'

export default function LoginPage() {
const location = useLocation()
const message = location.state?.message || ''
return (
<Box
flex={1}
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '50vh',
}}
>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Typography variant="h4" sx={{ mb: 2 }}>
{message}
</Typography>
<CmsButton href="/login">Login</CmsButton>
</Box>
</Box>
)
}
Loading

0 comments on commit b4077c8

Please sign in to comment.