The PitchPro frontend implements JWT-based authentication entirely on the client side. AnDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/JuanSerna14/Final-lenguaje-Avanzado/llms.txt
Use this file to discover all available pages before exploring further.
AuthProvider React context wraps the application, holding the current user object and exposing login, register, and logout methods. Access tokens are stored in sessionStorage, automatically attached to every outgoing Axios request by a request interceptor, and validated on startup so that page refreshes within the same browser session don’t force a re-login.
AuthProvider
src/auth/context/jwt/auth-provider.tsx is a React context provider that manages the full authentication lifecycle. On mount it reads any existing token from sessionStorage, validates it, and fetches the current user profile before rendering child routes.
Initialization flow:
- Read
sessionStorage.getItem('accessToken'). - If a token exists, call
isValidToken(accessToken)— this decodes the JWT and checks thatexp > Date.now() / 1000. - If valid, call
GET /api/auth/meto load the user object. - Dispatch
INITIALwith the user (ornullon failure) and setloading: false.
useAuthContext() hook:
Authentication Methods
login(email, password)
Posts credentials to the backend, stores both tokens, and updates the context user.
PATH_AFTER_LOGIN (/dashboard), or to the returnTo query param if the guard set one.
register(email, password, firstName, lastName)
Creates a new account. The payload combines firstName and lastName into a single nombre field.
logout()
Sends the refresh token to the backend to invalidate the server-side session, then clears both tokens from sessionStorage.
finally block, even if the backend call fails.
Token Storage
Both tokens are stored in the browser’ssessionStorage (not localStorage). This means tokens are scoped to the current tab and are cleared automatically when the tab or browser window is closed.
| Key | Storage | Contents |
|---|---|---|
accessToken | sessionStorage | Short-lived JWT sent as Authorization: Bearer on every request |
refreshToken | sessionStorage | Longer-lived token sent only to POST /api/auth/logout |
setSession helper in src/auth/context/jwt/utils.ts handles both the sessionStorage write and the Axios default header in one call. It also schedules an expiry timer:
src/auth/context/jwt/utils.ts
Axios Interceptor
src/utils/axios.ts registers a request interceptor that reads the access token from sessionStorage and injects it as a Bearer header on every outgoing request:
src/utils/axios.ts
axiosInstance — including all canchasApi and reservasApi methods. You never need to manually set the Authorization header in individual API calls.
A response interceptor normalises error payloads:
Route Guards
Two guard components protect routes based on authentication state:AuthGuard
src/auth/guard/auth-guard.tsx — wraps protected routes. While loading is true it shows a SplashScreen. Once loading finishes, if the user is not authenticated it redirects to /auth/jwt/login, preserving the original path as a returnTo query param:
AuthGuard via src/routes/sections/dashboard.tsx:
src/routes/sections/dashboard.tsx
GuestGuard
src/auth/guard/guest-guard.tsx — wraps public routes (login and register pages). If a user is already authenticated it immediately redirects them to returnTo (or /dashboard by default), preventing logged-in users from seeing the auth forms:
Login and Register Views
Both auth views live insrc/sections/auth/jwt/:
-
JwtLoginView— React Hook Form with Yup validation (emailrequired + valid format,passwordrequired). On submit it callslogin(email, password)fromuseAuthContext()and navigates toPATH_AFTER_LOGIN(/dashboard) or thereturnToparam. -
JwtRegisterView— React Hook Form collectingfirstName,lastName,email, andpassword. All fields are required; email must be a valid address. On submit it callsregister()fromuseAuthContext().
Alert with the server error message if the request fails, and reset the form fields after an error so the user can retry.
Troubleshooting
401 Unauthorized on every API call
401 Unauthorized on every API call
Token not persisting across browser tabs or restarts
Token not persisting across browser tabs or restarts
This is expected behaviour. PitchPro intentionally uses
sessionStorage rather than localStorage. Each browser tab gets its own isolated session storage, and all tokens are cleared when the tab closes. To share a session across tabs you would need to migrate to localStorage — keep in mind the security trade-offs of doing so.Register succeeds but dashboard shows 401 immediately after
Register succeeds but dashboard shows 401 immediately after
The
POST /api/auth/register endpoint creates the account but does not return an accessToken. After register() resolves, no token is written to sessionStorage, so any subsequent authenticated request fails with 401. You must navigate to the login page and sign in with the newly created credentials to receive a token.Backend Authentication
JWT signing, refresh token rotation, and the /api/auth/* endpoints on the Express side.
Auth API Reference
Request/response shapes for login, register, logout, and /api/auth/me.
Dashboard
Courts table, reservations list, stat cards, and CRUD dialogs.
Frontend Setup
Installation, environment variables, and available npm scripts.