The InfoJobs DevBoard frontend is a single-page application that combines React 19’s concurrent rendering model with Vite 7’s native ES-module dev server. Page components are lazy-loaded on demand, global state is handled by two lightweight Zustand stores, and all styling is scoped to individual components through CSS Modules. The app connects to the Express backend using theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/mauroperez055/infoJobs/llms.txt
Use this file to discover all available pages before exploring further.
VITE_API_URL environment variable and streams AI-generated job summaries directly into the job detail view.
Source tree
Routing
All routes are declared inApp.jsx. Every page component is imported via React.lazy() so its JavaScript bundle is only downloaded when the route is first visited. A single <Suspense> boundary at the root of the route tree shows a loading indicator while the chunk is fetching.
Route table
| Path | Component | Access |
|---|---|---|
/ | HomePage | Public |
/search | SearchPage | Public |
/jobs/:id | JobDetails | Public |
/profile | ProfilePage | Protected — redirects to /login |
/login | Login | Public |
/register | Register | Public |
* | NotFoundPage | Public (catch-all) |
/profile route is wrapped in <ProtectedRoute redirecTo='/login'>. If the user is not authenticated, ProtectedRoute redirects to /login instead of rendering ProfilePage.
App.jsx
Global state (Zustand)
Zustand is used in two focused stores. Neither store requires a Provider — components import the store hook directly wherever they need it.authStore
Manages authentication state: the current user object, login/logout actions, and the flag that ProtectedRoute reads to decide whether to allow access or redirect.
favoriteStore
Manages the list of saved/favourite job IDs. Components such as JobCard read from and write to this store, allowing users to persist favourites across page navigations within the same session.
Custom hooks
| Hook | Purpose |
|---|---|
useAISummary | Calls GET /ai/summary/:id and exposes the streaming response text and loading state to Details.jsx |
useFilters | Derives and applies active filter state for the search and listing views |
useSearchForm | Manages the controlled search form inputs and triggers navigation to /search |
useRouter | Thin wrapper around React Router’s useNavigate and useLocation |
Styling
Each component co-locates its styles in a CSS Module file (e.g.Header.module.css). Class names are locally scoped by Vite’s CSS Module transform, eliminating the risk of naming collisions between components. Global resets and design tokens live in index.css.
Backend connection
The frontend never hard-codeslocalhost:1234. Instead, Vite exposes the VITE_API_URL environment variable at build time. Set it in a .env file in the frontend/ directory:
fetch calls and the useAISummary hook read from import.meta.env.VITE_API_URL to construct request URLs.