// Usuarios Module function Usuarios() { const [users, setUsers] = React.useState([]); const [loading, setLoading] = React.useState(true); const [showModal, setShowModal] = React.useState(false); const [form, setForm] = React.useState({ name: '', email: '', password: '', role: 'usuario', department: '' }); const [creating, setCreating] = React.useState(false); const [showPass, setShowPass] = React.useState(false); const [editTarget, setEditTarget] = React.useState(null); const [editForm, setEditForm] = React.useState({ name: '', role: 'usuario', department: '' }); const [editSaving, setEditSaving] = React.useState(false); const [resetTarget, setResetTarget] = React.useState(null); const [resetForm, setResetForm] = React.useState({ password: '', show: false }); const [resetSaving, setResetSaving] = React.useState(false); const [toast, setToast] = React.useState(null); const showToast = (msg, type = 'success') => { setToast({ msg, type }); setTimeout(() => setToast(null), 3500); }; const fetchUsers = () => { sb.from('app_users').select('*').order('created_at', { ascending: false }).then(({ data }) => { setUsers(data || []); setLoading(false); }); }; React.useEffect(() => { fetchUsers(); }, []); const handleCreate = async () => { if (!form.email.trim() || !form.password.trim()) { showToast('Preencha e-mail e senha.', 'error'); return; } if (form.password.length < 6) { showToast('Senha precisa ter pelo menos 6 caracteres.', 'error'); return; } setCreating(true); const tempClient = supabase.createClient(window.SUPA_URL, window.SUPA_KEY, { auth: { persistSession: false, autoRefreshToken: false }, }); const { data: authData, error: authErr } = await tempClient.auth.signUp({ email: form.email.trim().toLowerCase(), password: form.password, }); if (authErr) { const msg = authErr.message.includes('already') ? 'E-mail já cadastrado.' : 'Erro ao criar usuário: ' + authErr.message; showToast(msg, 'error'); setCreating(false); return; } // Upsert porque o trigger handle_new_auth_user pode ter inserido a linha // primeiro (com role default 'usuario' e department NULL) — aqui sobrescrevemos // com os valores que o admin escolheu na tela. await sb.from('app_users').upsert({ id: authData.user?.id, email: form.email.trim().toLowerCase(), name: form.name.trim() || form.email.split('@')[0], role: form.role, department: form.department || null, }, { onConflict: 'id' }); showToast('Usuário criado com sucesso!'); setForm({ name: '', email: '', password: '', role: 'usuario', department: '' }); setShowModal(false); fetchUsers(); setCreating(false); }; const openEdit = (user) => { setEditTarget(user); setEditForm({ name: user.name || '', role: user.role || 'usuario', department: user.department || '' }); }; const handleEditSave = async () => { if (!editTarget) return; setEditSaving(true); const { error } = await sb.from('app_users').update({ name: editForm.name.trim() || editTarget.email.split('@')[0], role: editForm.role, department: editForm.department || null, }).eq('id', editTarget.id); setEditSaving(false); if (error) { showToast('Erro ao salvar: ' + (error.message || 'tente novamente.'), 'error'); return; } showToast('Usuário atualizado!'); setEditTarget(null); fetchUsers(); }; const openReset = (user) => { setResetTarget(user); setResetForm({ password: '', show: false }); }; const handleSetPassword = async () => { if (!resetTarget) return; if (resetForm.password.length < 6) { showToast('Senha precisa ter pelo menos 6 caracteres.', 'error'); return; } setResetSaving(true); const { error } = await sb.rpc('admin_set_user_password', { p_user_id: resetTarget.id, p_new_password: resetForm.password, }); setResetSaving(false); if (error) { showToast('Erro ao redefinir senha: ' + (error.message || 'tente novamente.'), 'error'); return; } showToast(`Senha de ${resetTarget.name || resetTarget.email} redefinida!`); setResetTarget(null); setResetForm({ password: '', show: false }); }; const handleDelete = async (user) => { if (!window.confirm(`Remover ${user.name || user.email} do sistema?`)) return; await sb.from('app_users').delete().eq('id', user.id); showToast('Usuário removido da lista.'); fetchUsers(); }; const roleLabel = { admin: 'Administrador', usuario: 'Usuário', visualizador: 'Visualizador' }; const roleColor = { admin: 'danger', usuario: 'primary', visualizador: 'default' }; const fmtDate = (iso) => iso ? new Date(iso).toLocaleDateString('pt-BR') : '—'; const inputStyle = { width: '100%', boxSizing: 'border-box', padding: '10px 13px', fontSize: 13, border: `1.5px solid ${DS.colors.border}`, borderRadius: DS.radius.sm, outline: 'none', fontFamily: 'Inter, sans-serif', color: DS.colors.text, background: '#F8FAFC', }; if (loading) { return (
Gerencie quem tem acesso ao sistema