"use client"; import React, { useEffect, useState, useCallback } from "react"; // REMOVIDO: import ManagerLayout, pois a página já é envolvida pelo layout pai. import Link from "next/link"; import { Button } from "@/components/ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Plus, Eye, Filter, Loader2 } from "lucide-react"; import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; // Assumindo caminhos de importação do seu projeto import { api } from "services/api"; import { usuariosApi } from "@/services/usuariosApi"; import { perfisApi } from "@/services/perfisApi"; import { UserRole } from "@/services/usuariosApi"; interface FlatUser { id: string; user_id: string; full_name?: string; email: string; phone?: string | null; role: string; } interface UserInfoResponse { user: any; profile: any; roles: string[]; permissions: Record; } export default function UsersPage() { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [detailsDialogOpen, setDetailsDialogOpen] = useState(false); const [userDetails, setUserDetails] = useState(null); const [selectedRole, setSelectedRole] = useState(""); // Estado para armazenar papéis disponíveis dinamicamente const [availableRoles, setAvailableRoles] = useState([]); // Função utilitária para capitalizar a primeira letra const capitalize = (s: string) => { if (!s) return s; return s.charAt(0).toUpperCase() + s.slice(1); }; const fetchUsers = useCallback(async () => { setLoading(true); setError(null); try { // 1) Pega papéis e perfis em paralelo para melhor performance const [rolesData, profilesData] = await Promise.all([ usuariosApi.listRoles(), perfisApi.list() ]); const rolesArray: UserRole[] = Array.isArray(rolesData) ? rolesData : []; // 2) Extrair e salvar papéis únicos para o filtro (NOVO) const uniqueRoles = new Set(); rolesArray.forEach(roleItem => { // Usa roleItem.role, se existir if (roleItem.role) { uniqueRoles.add(roleItem.role); } }); // Converter para array, ordenar e atualizar o estado setAvailableRoles(Array.from(uniqueRoles).sort()); const profilesById = new Map(); if (Array.isArray(profilesData)) { for (const p of profilesData) { // A chave do perfil deve ser o user_id, conforme a lógica anterior if (p?.id) profilesById.set(p.id, p); } } // 3) Mapear roles -> flat users const mapped: FlatUser[] = rolesArray.map((roleItem) => { const uid = roleItem.user_id; const profile = profilesById.get(uid); // Determina o role a ser usado. Prioriza roleItem.role, se não, '—' const role = roleItem.role ?? "—"; return { id: uid, user_id: uid, full_name: profile?.full_name ?? "—", email: profile?.email ?? "—", phone: profile?.phone ?? "—", role: role, }; }); setUsers(mapped); } catch (err: any) { console.error("Erro ao buscar usuários:", err); setError("Não foi possível carregar os usuários. Verifique o console."); setUsers([]); setAvailableRoles([]); // Limpa os papéis em caso de erro } finally { setLoading(false); } }, []); useEffect(() => { const init = async () => { // Garante que o interceptor da API seja executado para ler o cookie try { await api.get('/'); } catch (e) { console.warn("API setup (leitura de cookie via interceptor) falhou ou o endpoint raiz não existe:", e); } await fetchUsers(); }; init(); }, [fetchUsers]); const openDetailsDialog = async (flatUser: FlatUser) => { setDetailsDialogOpen(true); setUserDetails(null); try { // O getFullData usa user_id const data = await usuariosApi.getFullData(flatUser.user_id); setUserDetails(data); } catch (err: any) { console.error("Erro ao carregar detalhes:", err); // Fallback details em caso de falha na API setUserDetails({ user: { id: flatUser.user_id, email: flatUser.email }, profile: { full_name: flatUser.full_name, phone: flatUser.phone }, roles: [flatUser.role], permissions: { "read:self": true, "write:profile": false }, }); } }; const filteredUsers = selectedRole && selectedRole !== "all" ? users.filter((u) => u.role === selectedRole) : users; // REMOVIDO: mockUserProfile e mockMenuItems não são mais necessários // pois o ManagerLayout deve ser fornecido pelo arquivo app/manager/layout.tsx return ( // CORRIGIDO: Retornando apenas o conteúdo da página, sem o ManagerLayout
{/* Conteúdo da página */}

Usuários

Gerencie usuários.

{/* Filtros */}
{/* Tabela de Usuários */}
{loading ?
Carregando usuários...
: error ?
{error}
: filteredUsers.length === 0 ?
Nenhum usuário encontrado{selectedRole && selectedRole !== 'all' ? ` para o papel: ${capitalize(selectedRole)}` : '.'}
:
{filteredUsers.map((u) => ( ))}
ID Nome E-mail Telefone Cargo Ações
{u.id} {u.full_name} {u.email} {u.phone} {capitalize(u.role)}
}
{/* Diálogo de Detalhes */} {userDetails?.profile?.full_name || "Detalhes do Usuário"} {!userDetails ?
Buscando dados completos...
:
ID: {userDetails.user.id}
E-mail: {userDetails.user.email}
Nome completo: {userDetails.profile.full_name}
Telefone: {userDetails.profile.phone}
Roles: {userDetails.roles?.map(capitalize).join(", ")}
Permissões:
    {Object.entries(userDetails.permissions || {}).map(([k,v]) =>
  • {k}: {v ? "Sim" : "Não"}
  • )}
}
Fechar
); }