Tristan Yu commited on
Commit
feb1d93
·
1 Parent(s): 96fdf51

Fix authentication setup - add AuthProvider and auto-visitor authentication

Browse files
Files changed (2) hide show
  1. src/contexts/AuthContext.tsx +45 -13
  2. src/index.tsx +4 -1
src/contexts/AuthContext.tsx CHANGED
@@ -5,7 +5,7 @@ interface User {
5
  id: string;
6
  username: string;
7
  email: string;
8
- role: 'student' | 'instructor' | 'admin';
9
  targetCultures: string[];
10
  nativeLanguage?: string;
11
  }
@@ -53,10 +53,39 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
53
  api.defaults.headers.common['Authorization'] = `Bearer ${token}`;
54
  fetchUser();
55
  } else {
56
- setLoading(false);
 
57
  }
58
  }, []);
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  const fetchUser = async () => {
61
  try {
62
  const response = await api.get('/api/auth/profile');
@@ -65,6 +94,9 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
65
  console.error('Failed to fetch user:', error);
66
  localStorage.removeItem('token');
67
  delete api.defaults.headers.common['Authorization'];
 
 
 
68
  } finally {
69
  setLoading(false);
70
  }
@@ -100,28 +132,28 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
100
  localStorage.removeItem('token');
101
  delete api.defaults.headers.common['Authorization'];
102
  setUser(null);
 
 
103
  };
104
 
105
  const updateProfile = async (data: Partial<User>) => {
106
  try {
107
  const response = await api.put('/api/auth/profile', data);
108
- setUser(response.data.user);
109
  } catch (error: any) {
110
  throw new Error(error.response?.data?.error || 'Profile update failed');
111
  }
112
  };
113
 
114
- const value: AuthContextType = {
115
- user,
116
- loading,
117
- login,
118
- register,
119
- logout,
120
- updateProfile,
121
- };
122
-
123
  return (
124
- <AuthContext.Provider value={value}>
 
 
 
 
 
 
 
125
  {children}
126
  </AuthContext.Provider>
127
  );
 
5
  id: string;
6
  username: string;
7
  email: string;
8
+ role: 'student' | 'instructor' | 'admin' | 'visitor';
9
  targetCultures: string[];
10
  nativeLanguage?: string;
11
  }
 
53
  api.defaults.headers.common['Authorization'] = `Bearer ${token}`;
54
  fetchUser();
55
  } else {
56
+ // Auto-setup visitor authentication
57
+ setupVisitorAuth();
58
  }
59
  }, []);
60
 
61
+ const setupVisitorAuth = async () => {
62
+ try {
63
+ const response = await api.post('/api/auth/login', {
64
+ email: 'visitor@example.com'
65
+ });
66
+ const { token, user } = response.data;
67
+
68
+ localStorage.setItem('token', token);
69
+ api.defaults.headers.common['Authorization'] = `Bearer ${token}`;
70
+ setUser(user);
71
+ } catch (error) {
72
+ console.error('Failed to setup visitor auth:', error);
73
+ // Set a fallback visitor token
74
+ const fallbackToken = `visitor_${Date.now()}`;
75
+ localStorage.setItem('token', fallbackToken);
76
+ api.defaults.headers.common['Authorization'] = `Bearer ${fallbackToken}`;
77
+ setUser({
78
+ id: 'visitor',
79
+ username: 'Visitor',
80
+ email: 'visitor@example.com',
81
+ role: 'visitor',
82
+ targetCultures: []
83
+ });
84
+ } finally {
85
+ setLoading(false);
86
+ }
87
+ };
88
+
89
  const fetchUser = async () => {
90
  try {
91
  const response = await api.get('/api/auth/profile');
 
94
  console.error('Failed to fetch user:', error);
95
  localStorage.removeItem('token');
96
  delete api.defaults.headers.common['Authorization'];
97
+ // Try to setup visitor auth as fallback
98
+ setupVisitorAuth();
99
+ return;
100
  } finally {
101
  setLoading(false);
102
  }
 
132
  localStorage.removeItem('token');
133
  delete api.defaults.headers.common['Authorization'];
134
  setUser(null);
135
+ // Setup visitor auth after logout
136
+ setupVisitorAuth();
137
  };
138
 
139
  const updateProfile = async (data: Partial<User>) => {
140
  try {
141
  const response = await api.put('/api/auth/profile', data);
142
+ setUser(response.data);
143
  } catch (error: any) {
144
  throw new Error(error.response?.data?.error || 'Profile update failed');
145
  }
146
  };
147
 
 
 
 
 
 
 
 
 
 
148
  return (
149
+ <AuthContext.Provider value={{
150
+ user,
151
+ loading,
152
+ login,
153
+ register,
154
+ logout,
155
+ updateProfile
156
+ }}>
157
  {children}
158
  </AuthContext.Provider>
159
  );
src/index.tsx CHANGED
@@ -1,6 +1,7 @@
1
  import React from 'react';
2
  import ReactDOM from 'react-dom/client';
3
  import { BrowserRouter } from 'react-router-dom';
 
4
  import './index.css';
5
  import App from './App';
6
 
@@ -11,7 +12,9 @@ const root = ReactDOM.createRoot(
11
  root.render(
12
  <React.StrictMode>
13
  <BrowserRouter>
14
- <App />
 
 
15
  </BrowserRouter>
16
  </React.StrictMode>
17
  );
 
1
  import React from 'react';
2
  import ReactDOM from 'react-dom/client';
3
  import { BrowserRouter } from 'react-router-dom';
4
+ import { AuthProvider } from './contexts/AuthContext';
5
  import './index.css';
6
  import App from './App';
7
 
 
12
  root.render(
13
  <React.StrictMode>
14
  <BrowserRouter>
15
+ <AuthProvider>
16
+ <App />
17
+ </AuthProvider>
18
  </BrowserRouter>
19
  </React.StrictMode>
20
  );