restaurante / src /context /AuthContext.jsx
Antigravity AI
Fix blank screen and empty menu with robust fallbacks and error handling
1a3d3dd
import React, { createContext, useContext, useEffect, useState } from 'react';
import { auth, db } from '../firebase/config';
import { onAuthStateChanged, signInWithEmailAndPassword, signOut } from 'firebase/auth';
import { ref, get } from 'firebase/database';
export const AuthContext = createContext();
export const useAuth = () => {
return useContext(AuthContext);
};
export const AuthProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(null);
const [userRole, setUserRole] = useState(null);
const [loading, setLoading] = useState(true);
const login = async (email, password) => {
// Manejo de cuentas Demo para facilitar el acceso
const isDemoAdmin = email === 'admin@rest-os.com' && password === 'admin-password123';
const isDemoWaiter = (email === 'mesero@rest-os.com' && password === 'mesero-password123') || (email === 'mesero@rest-os.com' && password === 'waiter-password123');
if (isDemoAdmin || isDemoWaiter) {
const { signInWithEmailAndPassword, createUserWithEmailAndPassword } = await import('firebase/auth');
try {
// Intentar login real para obtener token de Firebase
const res = await signInWithEmailAndPassword(auth, email, password);
return res.user;
} catch (error) {
if (error.code === 'auth/user-not-found' || error.code === 'auth/invalid-credential' || error.code === 'auth/invalid-email') {
try {
// Si no existe, crear el usuario en Firebase automáticamente
const res = await createUserWithEmailAndPassword(auth, email, password);
// Registrar rol en DB para que el sistema lo reconozca
const { set, ref: dbRef } = await import('firebase/database');
await set(dbRef(db, `users/${res.user.uid}`), {
name: isDemoAdmin ? 'Admin Demo' : 'Mesero Demo',
email: email,
role: isDemoAdmin ? 'admin' : 'mesero'
});
return res.user;
} catch (createError) {
console.error("Error creando usuario demo en Firebase", createError);
// Fallback a objeto mock si falla la creación (ej. reglas de seguridad de Auth)
const mockUser = { uid: isDemoAdmin ? 'demo-admin-uid' : 'demo-mesero-uid', email, isDemo: true };
setCurrentUser(mockUser);
setUserRole(isDemoAdmin ? 'admin' : 'mesero');
return mockUser;
}
}
throw error;
}
}
return signInWithEmailAndPassword(auth, email, password);
};
const logout = () => {
return signOut(auth);
};
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, async (user) => {
try {
if (user) {
setCurrentUser(user);
// Si es un usuario demo, asignar rol directamente sin consultar DB (evita permission_denied)
if (user.email === 'admin@rest-os.com') {
setUserRole('admin');
} else if (user.email === 'mesero@rest-os.com') {
setUserRole('mesero');
} else {
// Obtener rol del usuario desde DB para usuarios reales
const userRef = ref(db, `users/${user.uid}`);
const snapshot = await get(userRef);
if (snapshot.exists()) {
setUserRole(snapshot.val().role);
} else {
setUserRole('comensal');
}
}
} else {
setCurrentUser(null);
setUserRole(null);
}
} catch (error) {
console.error("Error al obtener el rol del usuario", error);
// Fallback en caso de error
if (user && user.email === 'admin@rest-os.com') setUserRole('admin');
else setUserRole('comensal');
} finally {
setLoading(false);
}
});
return unsubscribe;
}, []);
const value = {
currentUser,
userRole,
login,
logout
};
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
};