@@ -16,6 +16,11 @@ import Clients from '../../pages/Clients';
16
16
import Settings from '../../pages/Settings' ;
17
17
import Help from '../../pages/Help' ;
18
18
19
+ import React , { useContext , useEffect } from 'react' ;
20
+ import { AppContext } from './AppContext' ;
21
+ import { useZipCaseApi } from '../../hooks' ;
22
+ import { useNavigate , useLocation } from 'react-router-dom' ;
23
+
19
24
// Create theme for Amplify UI components
20
25
const amplifyTheme = {
21
26
tokens : {
@@ -130,30 +135,72 @@ const components = {
130
135
} ,
131
136
} ;
132
137
138
+ // Onboarding logic: check for portal credentials on login, set firstTimeUser, and redirect if needed
133
139
const App : React . FC = ( ) => {
134
140
return (
135
141
< ThemeProvider theme = { { ...defaultTheme , ...amplifyTheme } } >
136
142
< Authenticator hideSignUp = { true } components = { components } >
137
143
< QueryClientProvider client = { queryClient } >
138
- < AppContextProvider >
139
- < BrowserRouter >
140
- < Routes >
141
- < Route path = "/" element = { < Navigate to = "/search/case" /> } />
142
- < Route element = { < Shell /> } >
143
- < Route path = "/search" element = { < Navigate to = "/search/case" /> } />
144
- < Route path = "/search/case" element = { < Search type = "case" /> } />
145
- < Route path = "/search/name" element = { < Search type = "name" /> } />
146
- < Route path = "/clients" element = { < Clients /> } />
147
- < Route path = "/settings" element = { < Settings /> } />
148
- < Route path = "/help" element = { < Help /> } />
149
- </ Route >
150
- </ Routes >
151
- </ BrowserRouter >
152
- </ AppContextProvider >
144
+ < BrowserRouter >
145
+ < AppContextProvider >
146
+ < OnboardingRouter />
147
+ </ AppContextProvider >
148
+ </ BrowserRouter >
153
149
</ QueryClientProvider >
154
150
</ Authenticator >
155
151
</ ThemeProvider >
156
152
) ;
157
153
} ;
158
154
155
+ const OnboardingRouter : React . FC = ( ) => {
156
+ const { dispatch } = useContext ( AppContext ) ;
157
+ const getPortalCredentials = useZipCaseApi ( client => client . credentials . get ( ) ) . callApi ;
158
+ const [ checked , setChecked ] = React . useState ( false ) ;
159
+ const navigate = useNavigate ( ) ;
160
+ const location = useLocation ( ) ;
161
+
162
+ useEffect ( ( ) => {
163
+ // Check onboarding on first mount and on login (when location or credentials change)
164
+ let cancelled = false ;
165
+ ( async ( ) => {
166
+ try {
167
+ const resp = await getPortalCredentials ( ) ;
168
+ const isFirstTime = ! resp . success || ! resp . data || ! resp . data . username ;
169
+ dispatch ( { type : 'SET_FIRST_TIME_USER' , payload : isFirstTime } ) ;
170
+ if ( isFirstTime && location . pathname . startsWith ( '/search' ) ) {
171
+ navigate ( '/settings' , { replace : true } ) ;
172
+ }
173
+ } catch {
174
+ dispatch ( { type : 'SET_FIRST_TIME_USER' , payload : true } ) ;
175
+ if ( location . pathname . startsWith ( '/search' ) ) {
176
+ navigate ( '/settings' , { replace : true } ) ;
177
+ }
178
+ } finally {
179
+ if ( ! cancelled ) setChecked ( true ) ;
180
+ }
181
+ } ) ( ) ;
182
+ return ( ) => {
183
+ cancelled = true ;
184
+ } ;
185
+ // Run on mount and when location changes (to catch initial login)
186
+ } , [ location . pathname , dispatch , getPortalCredentials , navigate ] ) ;
187
+
188
+ // Wait until onboarding check is done before rendering routes
189
+ if ( ! checked ) return null ;
190
+
191
+ return (
192
+ < Routes >
193
+ < Route path = "/" element = { < Navigate to = "/search/case" /> } />
194
+ < Route element = { < Shell /> } >
195
+ < Route path = "/search" element = { < Navigate to = "/search/case" /> } />
196
+ < Route path = "/search/case" element = { < Search type = "case" /> } />
197
+ < Route path = "/search/name" element = { < Search type = "name" /> } />
198
+ < Route path = "/clients" element = { < Clients /> } />
199
+ < Route path = "/settings" element = { < Settings /> } />
200
+ < Route path = "/help" element = { < Help /> } />
201
+ </ Route >
202
+ </ Routes >
203
+ ) ;
204
+ } ;
205
+
159
206
export default App ;
0 commit comments