eletrotupi / tcc/ commit / 5d37e20

frontend/context: auth provider + hooks

Pedro Lucas Porcellis porcellis@eletrotupi.com · 6 months ago 5d37e204b398ac39b26f3226aa1500a045d0e2ce Browse files
Parents ab2823c
Changed 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 +
}