chore: estructura inicial del MVP
Backend (Express + MariaDB) y frontend (React + Vite, identidad Fluent/Windows) con el nucleo funcional: seguridad, organizacion, proyectos, actividades, subtareas, dependencias, dashboard, calendario, gantt, comentarios, adjuntos, notificaciones in-app y catalogos. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
import { createContext, useContext, useEffect, useMemo, useState, useCallback } from 'react';
|
||||
import { api, setUnauthorizedHandler } from '../services/api.js';
|
||||
|
||||
const AuthContext = createContext(null);
|
||||
|
||||
export function AuthProvider({ children }) {
|
||||
const [user, setUser] = useState(null);
|
||||
const [ready, setReady] = useState(false);
|
||||
|
||||
const logout = useCallback(() => {
|
||||
api.setToken(null);
|
||||
setUser(null);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setUnauthorizedHandler(() => logout());
|
||||
}, [logout]);
|
||||
|
||||
useEffect(() => {
|
||||
const token = localStorage.getItem('plc_token');
|
||||
if (!token) { setReady(true); return; }
|
||||
api.get('/auth/me')
|
||||
.then((me) => setUser(me))
|
||||
.catch(() => logout())
|
||||
.finally(() => setReady(true));
|
||||
}, [logout]);
|
||||
|
||||
const login = useCallback(async (email, password) => {
|
||||
const result = await api.post('/auth/login', { email, password });
|
||||
api.setToken(result.token);
|
||||
setUser(result.user);
|
||||
return result.user;
|
||||
}, []);
|
||||
|
||||
const value = useMemo(() => ({ user, ready, login, logout }), [user, ready, login, logout]);
|
||||
|
||||
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
||||
}
|
||||
|
||||
export function useAuth() {
|
||||
const ctx = useContext(AuthContext);
|
||||
if (!ctx) throw new Error('useAuth debe usarse dentro de AuthProvider');
|
||||
return ctx;
|
||||
}
|
||||
Reference in New Issue
Block a user