frontend/context: auth provider + hooks
Pedro Lucas Porcellis porcellis@eletrotupi.com · 6 months ago
5d37e204b398ac39b26f3226aa1500a045d0e2ce Browse filesParents
ab2823cChanged files
1
Additions
+130
Deletions
0
/dev/null → frontend/context/AuthContext.tsx
1 +
import React, { createContext, useContext, useEffect, useState } from 'react';
2 +
import { apiClient, User } from '@/lib/api';
3 +
4 +
interface AuthContextType {
5 +
user: User | null;
6 +
isLoading: boolean;
7 +
isAuthenticated: boolean;
8 +
login: (email: string, password: string) => Promise<void>;
9 +
signup: (userData: {
10 +
first_name: string;
11 +
last_name?: string;
12 +
email: string;
13 +
password: string;
14 +
}) => Promise<void>;
15 +
logout: () => Promise<void>;
16 +
forgotPassword: (email: string) => Promise<{ message: string; token?: string }>;
17 +
resetPassword: (token: string, password: string) => Promise<void>;
18 +
}
19 +
20 +
const AuthContext = createContext<AuthContextType | null>(null);
21 +
22 +
export function useAuth() {
23 +
const context = useContext(AuthContext);
24 +
if (!context) {
25 +
throw new Error('useAuth must be used within an AuthProvider');
26 +
}
27 +
return context;
28 +
}
29 +
30 +
interface AuthProviderProps {
31 +
children: React.ReactNode;
32 +
}
33 +
34 +
export function AuthProvider({ children }: AuthProviderProps) {
35 +
const [user, setUser] = useState<User | null>(null);
36 +
const [isLoading, setIsLoading] = useState(true);
37 +
38 +
const isAuthenticated = !!user;
39 +
40 +
// Check for existing authentication on app start
41 +
useEffect(() => {
42 +
checkAuthState();
43 +
}, []);
44 +
45 +
const checkAuthState = async () => {
46 +
try {
47 +
const { token } = await apiClient.getStoredAuthData();
48 +
49 +
if (token) {
50 +
const verifyResponse = await apiClient.verifyToken();
51 +
if (verifyResponse.valid && verifyResponse.userId && verifyResponse.email) {
52 +
// TODO: Fetch the full user profile
53 +
// For now, we'll create a basic user object
54 +
setUser({
55 +
id: verifyResponse.userId,
56 +
email: verifyResponse.email,
57 +
firstName: '',
58 +
lastName: undefined,
59 +
});
60 +
}
61 +
}
62 +
} catch (error) {
63 +
console.error('Auth check failed:', error);
64 +
// Token is invalid, wipe out any stored data
65 +
await apiClient.logout();
66 +
} finally {
67 +
setIsLoading(false);
68 +
}
69 +
};
70 +
71 +
const login = async (email: string, password: string) => {
72 +
setIsLoading(true);
73 +
try {
74 +
const response = await apiClient.login(email, password);
75 +
setUser(response.user);
76 +
} finally {
77 +
setIsLoading(false);
78 +
}
79 +
};
80 +
81 +
const signup = async (userData: {
82 +
first_name: string;
83 +
last_name?: string;
84 +
email: string;
85 +
password: string;
86 +
}) => {
87 +
setIsLoading(true);
88 +
try {
89 +
const response = await apiClient.signup(userData);
90 +
setUser(response.user);
91 +
} finally {
92 +
setIsLoading(false);
93 +
}
94 +
};
95 +
96 +
const logout = async () => {
97 +
setIsLoading(true);
98 +
try {
99 +
await apiClient.logout();
100 +
setUser(null);
101 +
} finally {
102 +
setIsLoading(false);
103 +
}
104 +
};
105 +
106 +
const forgotPassword = async (email: string) => {
107 +
return apiClient.forgotPassword(email);
108 +
};
109 +
110 +
const resetPassword = async (token: string, password: string) => {
111 +
await apiClient.resetPassword(token, password);
112 +
};
113 +
114 +
const value: AuthContextType = {
115 +
user,
116 +
isLoading,
117 +
isAuthenticated,
118 +
login,
119 +
signup,
120 +
logout,
121 +
forgotPassword,
122 +
resetPassword,
123 +
};
124 +
125 +
return (
126 +
<AuthContext.Provider value={value}>
127 +
{children}
128 +
</AuthContext.Provider>
129 +
);
130 +
}