eletrotupi / tcc/ frontend/context/AuthContext.tsx74ae5f1274f034c64cdb19c5573e5c370571e697
4.1 KB | 172 lines Raw
1
import React, { createContext, useContext, useEffect, useState } from 'react';
2
import { apiClient, User } from '@/lib/api';
3
import { queryClient, storage } from '@/lib/queryClient';
4

5
interface AuthProviderProps {
6
  children: React.ReactNode;
7
}
8

9
interface AuthContextType {
10
  user: User | null;
11
  isLoading: boolean;
12
  isAuthenticated: boolean;
13
  updateAuthUser: (user: User) => void;
14
  login: (email: string, password: string) => Promise<void>;
15
  signup: (userData: {
16
    firstName: string;
17
    lastName?: string;
18
    email: string;
19
    password: string;
20
  }) => Promise<void>;
21
  logout: () => Promise<void>;
22
  forgotPassword: (email: string) => Promise<{ message: string; token?: string }>;
23
  resetPassword: (token: string, password: string) => Promise<void>;
24
  activate: (code: string) => Promise<void>;
25
  requestActivateCode: () => Promise<void>;
26
}
27

28
export function sanitizeUser(data: any): User {
29
  return {
30
    id: data.id,
31
    email: data.email,
32
    firstName: data.firstName,
33
    lastName: data.lastName,
34
    updatedAt: data.updatedAt,
35
    avatarKey: data.avatarKey,
36
    avatarURL: data.avatarURL,
37
    active: data.active
38
  };
39
}
40

41
const AuthContext = createContext<AuthContextType | null>(null);
42

43
export function useAuth() {
44
  const context = useContext(AuthContext);
45
  if (!context) {
46
    throw new Error('useAuth must be used within an AuthProvider');
47
  }
48

49
  return context;
50
}
51

52
export const AuthProvider = ({ children }: AuthProviderProps) => {
53
  const [user, setUser] = useState<User | null>(null);
54
  const [isLoading, setIsLoading] = useState(true);
55
  const isAuthenticated = !!user;
56

57
  // Check for existing authentication on app start
58
  useEffect(() => {
59
    checkAuthState();
60
  }, []);
61

62
  const checkAuthState = async () => {
63
    try {
64
      const { token } = await apiClient.getStoredAuthData();
65

66
      if (token) {
67
        const verifyResponse = await apiClient.verifyToken();
68
        if (verifyResponse.valid && verifyResponse.userId && verifyResponse.email) {
69
          // TODO: Fetch the full user profile
70
          // For now, we'll create a basic user object
71
          setUser({
72
            id: verifyResponse.userId,
73
            email: verifyResponse.email,
74
            ...verifyResponse.user
75
          });
76
        }
77
      }
78
    } catch (error) {
79
      console.error('Auth check failed:', error);
80
      // Token is invalid, wipe out any stored data
81
      await apiClient.logout();
82
    } finally {
83
      setIsLoading(false);
84
    }
85
  };
86

87
  const login = async (email: string, password: string) => {
88
    setIsLoading(true);
89

90
    try {
91
      const response = await apiClient.login(email, password);
92
      setUser(response.user);
93
    } finally {
94
      setIsLoading(false);
95
    }
96
  };
97

98
  const signup = async (userData: {
99
    firstName: string;
100
    lastName?: string;
101
    email: string;
102
    password: string;
103
  }) => {
104
    setIsLoading(true);
105
    try {
106
      const response = await apiClient.signup(userData);
107
      setUser(response.user);
108
    } finally {
109
      setIsLoading(false);
110
    }
111
  };
112

113
  const logout = async () => {
114
    setIsLoading(true);
115
    try {
116
      await apiClient.logout();
117

118
      setUser(null);
119
      // Clear both the in-memory cache and the persisted MMKV cache
120
      queryClient.clear();
121
      storage.clearAll();
122
    } finally {
123
      setIsLoading(false);
124
    }
125
  };
126

127
  const forgotPassword = async (email: string) => {
128
    return apiClient.forgotPassword(email);
129
  };
130

131
  const resetPassword = async (token: string, password: string) => {
132
    await apiClient.resetPassword(token, password);
133
  };
134

135
  const activate = async (code: number) => {
136
    const response = await apiClient.activate(code);
137

138
    if (response.user) {
139
      setUser(response.user)
140
    }
141

142
    return response
143
  }
144

145
  const requestActivateCode = async() => {
146
    await apiClient.requestActivateCode();
147
  }
148

149
  const updateAuthUser = (user) => {
150
    setUser(user);
151
  }
152

153
  const value: AuthContextType = {
154
    user,
155
    isLoading,
156
    isAuthenticated,
157
    login,
158
    signup,
159
    logout,
160
    forgotPassword,
161
    resetPassword,
162
    updateAuthUser,
163
    activate,
164
    requestActivateCode
165
  };
166

167
  return (
168
    <AuthContext.Provider value={value}>
169
      {children}
170
    </AuthContext.Provider>
171
  );
172
}