/* global React, IconLock, IconMail, IconUser, IconUsers, IconCheck, IconClose, IconPlus */
// Login screen + user management (admin only).
const { useState: _aus } = React;
function Avatar({ name, color, size = 34 }) {
const initials = name.split(" ").map((s) => s[0]).slice(0, 2).join("").toUpperCase();
return (
{initials}
);
}
// ============ Login =============================================
function LoginScreen({ onLogin }) {
const { USERS, CLOSERS } = window.REVOLVR_DATA;
const [email, setEmail] = _aus("");
const [password, setPassword] = _aus("");
const [error, setError] = _aus("");
const [loading, setLoading] = _aus(false);
const submit = (e) => {
e && e.preventDefault();
setLoading(true);
setError("");
const tryLogin = (userList) => {
const u = userList.find((x) => x.email.toLowerCase() === email.trim().toLowerCase());
if (!u || u.password !== password) {
setError("Correo o contraseña incorrectos.");
setLoading(false);
return;
}
if (!u.active) {
setError("Tu usuario está desactivado. Contacta a un administrador.");
setLoading(false);
return;
}
setError("");
setLoading(false);
onLogin(u);
};
// Intentar desde Supabase primero, fallback a data.js
if (window.SUPABASE) {
window.SUPABASE.from("crm_users").select("*")
.then(({ data, error }) => {
if (!error && data && data.length > 0) {
const mapped = data.map((u) => ({ id: u.id, name: u.name, email: u.email, password: u.password, role: u.role, closerId: u.closer_id, active: u.active, lastLogin: u.last_login || "" }));
tryLogin(mapped);
} else {
tryLogin(USERS);
}
});
} else {
tryLogin(USERS);
}
};
return (
CRM · Gestión de llamadas
);
}
// ============ Administración de usuarios (admin) ================
function UsersView({ users, onAddUser, onToggleActive, onDeleteUser, onResetPassword, currentUser }) {
const { CLOSERS } = window.REVOLVR_DATA;
const [modal, setModal] = _aus(false);
const [resetModal, setResetModal] = _aus(null); // usuario a resetear
return (
Usuarios y accesos
{users.length} usuarios · {users.filter((u) => u.active).length} activos
| Usuario |
Correo |
Rol |
Pipeline |
Estado |
Acciones |
{users.map((u) => {
const c = CLOSERS.find((x) => x.id === u.closerId);
return (
{u.name}
Último acceso: {u.lastLogin}
|
{u.email} |
{u.role === "admin" ? "Administrador" : "Closer"}
|
{c ? c.name : "— (todos)"} |
|
{u.id !== currentUser?.id &&
}
|
);
})}
{modal &&
setModal(false)} onSave={(u) => { onAddUser(u); setModal(false); }}/>}
{resetModal && setResetModal(null)} onSave={(id, pwd) => { onResetPassword(id, pwd); setResetModal(null); }}/>}
);
}
function NewUserModal({ onClose, onSave }) {
const { CLOSERS } = window.REVOLVR_DATA;
const [name, setName] = _aus("");
const [email, setEmail] = _aus("");
const [password, setPassword] = _aus("");
const [role, setRole] = _aus("closer");
const [closerId, setCloserId] = _aus("new");
const field = {
width: "100%", padding: "8px 10px", border: "1px solid var(--border)",
borderRadius: "var(--radius-s)", background: "var(--surface)", color: "var(--text)",
fontFamily: "inherit", fontSize: 12.5, marginTop: 4,
};
const lbl = { fontSize: 11, color: "var(--text-3)", fontWeight: 600, textTransform: "uppercase", letterSpacing: ".04em" };
const save = () => {
if (!name.trim() || !email.trim()) return;
onSave({ name: name.trim(), email: email.trim(), password, role, closerId });
};
return (
e.stopPropagation()}>
Nuevo usuario
Crea un acceso para un closer o administrador del equipo.
setName(e.target.value)} style={field} placeholder="Ej. Carla Núñez"/>
setEmail(e.target.value)} style={field} placeholder="carla@revolvr.io"/>
setPassword(e.target.value)} style={field}/>
{role === "closer" &&
}
);
}
function ResetPasswordModal({ user, onClose, onSave }) {
const [pwd, setPwd] = _aus("");
const [confirm, setConfirm] = _aus("");
const [err, setErr] = _aus("");
const field = { width: "100%", padding: "8px 10px", border: "1px solid var(--border)", borderRadius: 7, fontFamily: "inherit", fontSize: 13, background: "var(--bg)", color: "var(--text-1)" };
const save = () => {
if (pwd.length < 6) { setErr("La contraseña debe tener al menos 6 caracteres."); return; }
if (pwd !== confirm) { setErr("Las contraseñas no coinciden."); return; }
onSave(user.id, pwd);
};
return (
e.stopPropagation()}>
Resetear contraseña
Cambiando contraseña de {user.name} ({user.email})
);
}
Object.assign(window, { LoginScreen, UsersView, Avatar });