From edd51e61d323437e1b450a73faa1734b36ca1433 Mon Sep 17 00:00:00 2001 From: jessikitty Date: Tue, 27 Jan 2026 22:21:39 +1100 Subject: [PATCH] Add auth context for user state management --- frontend/src/contexts/AuthContext.tsx | 77 +++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 frontend/src/contexts/AuthContext.tsx diff --git a/frontend/src/contexts/AuthContext.tsx b/frontend/src/contexts/AuthContext.tsx new file mode 100644 index 0000000..262a4d1 --- /dev/null +++ b/frontend/src/contexts/AuthContext.tsx @@ -0,0 +1,77 @@ +import React, { createContext, useContext, useState, useEffect } from 'react'; +import { authService, User } from '../api/auth'; + +interface AuthContextType { + user: User | null; + token: string | null; + login: (username: string, password: string) => Promise; + logout: () => void; + isLoading: boolean; +} + +const AuthContext = createContext(undefined); + +export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const [user, setUser] = useState(null); + const [token, setToken] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + // Check for existing token on mount + const storedToken = localStorage.getItem('token'); + const storedUser = localStorage.getItem('user'); + + if (storedToken && storedUser) { + setToken(storedToken); + setUser(JSON.parse(storedUser)); + + // Verify token is still valid + authService.getCurrentUser() + .then(user => { + setUser(user); + localStorage.setItem('user', JSON.stringify(user)); + }) + .catch(() => { + // Token invalid, clear storage + localStorage.removeItem('token'); + localStorage.removeItem('user'); + setToken(null); + setUser(null); + }) + .finally(() => setIsLoading(false)); + } else { + setIsLoading(false); + } + }, []); + + const login = async (username: string, password: string) => { + const response = await authService.login({ username, password }); + const userData = await authService.getCurrentUser(); + + localStorage.setItem('token', response.access_token); + localStorage.setItem('user', JSON.stringify(userData)); + + setToken(response.access_token); + setUser(userData); + }; + + const logout = () => { + authService.logout(); + setToken(null); + setUser(null); + }; + + return ( + + {children} + + ); +}; + +export const useAuth = () => { + const context = useContext(AuthContext); + if (context === undefined) { + throw new Error('useAuth must be used within an AuthProvider'); + } + return context; +};