gilded / client /src /context /AuthContext.jsx
OmegaOne
Upload 41 files
0a8fe79 verified
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
const AuthContext = createContext(null);
export function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const [token, setToken] = useState(localStorage.getItem('gilded-token'));
const [loading, setLoading] = useState(true);
useEffect(() => {
if (!token) {
setLoading(false);
return;
}
fetch('/api/auth/me', {
headers: { Authorization: `Bearer ${token}` },
})
.then((res) => {
if (!res.ok) throw new Error('Invalid token');
return res.json();
})
.then((data) => {
setUser(data.user || data);
})
.catch(() => {
localStorage.removeItem('gilded-token');
setToken(null);
setUser(null);
})
.finally(() => setLoading(false));
}, [token]);
const login = useCallback(async (email, password) => {
const res = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.message || 'Login failed');
}
const data = await res.json();
localStorage.setItem('gilded-token', data.token);
setToken(data.token);
setUser(data.user);
return data;
}, []);
const register = useCallback(async (username, email, password) => {
const res = await fetch('/api/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, email, password }),
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.message || 'Registration failed');
}
const data = await res.json();
localStorage.setItem('gilded-token', data.token);
setToken(data.token);
setUser(data.user);
return data;
}, []);
const logout = useCallback(() => {
localStorage.removeItem('gilded-token');
setToken(null);
setUser(null);
}, []);
const updateUser = useCallback((data) => {
setUser((prev) => (prev ? { ...prev, ...data } : data));
}, []);
return (
<AuthContext.Provider value={{ user, token, loading, login, register, logout, updateUser }}>
{children}
</AuthContext.Provider>
);
}
export function useAuth() {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error('useAuth must be used within AuthProvider');
return ctx;
}