import React, { useState, useMemo } from 'react'; import { Users, Plus, Search, Mail, Phone, Shield, Trash2, Crown, X, UserCheck } from 'lucide-react'; import { Button, Card, Badge, Input, StatusCard, getStatusColor } from '../../../../components/ui'; import { PageHeader } from '../../../../components/layout'; import { useTeamMembers, useAddTeamMember, useRemoveTeamMember, useUpdateMemberRole } from '../../../../api/hooks/tenant'; import { useAllUsers } from '../../../../api/hooks/user'; import { useAuthUser } from '../../../../stores/auth.store'; import { useCurrentTenant, useCurrentTenantAccess } from '../../../../stores/tenant.store'; import { useToast } from '../../../../hooks/ui/useToast'; import { TENANT_ROLES } from '../../../../types/roles'; const TeamPage: React.FC = () => { const { addToast } = useToast(); const currentTenant = useCurrentTenant(); const currentTenantAccess = useCurrentTenantAccess(); const tenantId = currentTenant?.id || ''; const { data: teamMembers = [], isLoading } = useTeamMembers(tenantId, false, { enabled: !!tenantId }); // Show all members including inactive const { data: allUsers = [] } = useAllUsers(); // Mutations const addMemberMutation = useAddTeamMember(); const removeMemberMutation = useRemoveTeamMember(); const updateRoleMutation = useUpdateMemberRole(); const [searchTerm, setSearchTerm] = useState(''); const [selectedRole, setSelectedRole] = useState('all'); const [showAddForm, setShowAddForm] = useState(false); const [selectedUserToAdd, setSelectedUserToAdd] = useState(''); const [selectedRoleToAdd, setSelectedRoleToAdd] = useState(TENANT_ROLES.MEMBER); // Enhanced team members that includes owner information const enhancedTeamMembers = useMemo(() => { const members = [...teamMembers]; // If tenant owner is not in the members list, add them if (currentTenant?.owner_id) { const ownerInMembers = members.find(m => m.user_id === currentTenant.owner_id); if (!ownerInMembers) { // Find owner user data const ownerUser = allUsers.find(u => u.id === currentTenant.owner_id); if (ownerUser) { // Add owner as a member members.push({ id: `owner-${currentTenant.owner_id}`, tenant_id: tenantId, user_id: currentTenant.owner_id, role: TENANT_ROLES.OWNER, is_active: true, joined_at: currentTenant.created_at, user_email: ownerUser.email, user_full_name: ownerUser.full_name, user: ownerUser, // Add full user object for compatibility } as any); } } else if (ownerInMembers.role !== TENANT_ROLES.OWNER) { // Update existing member to owner role ownerInMembers.role = TENANT_ROLES.OWNER; } } return members; }, [teamMembers, currentTenant, allUsers, tenantId]); const roles = [ { value: 'all', label: 'Todos los Roles', count: enhancedTeamMembers.length }, { value: TENANT_ROLES.OWNER, label: 'Propietario', count: enhancedTeamMembers.filter(m => m.role === TENANT_ROLES.OWNER).length }, { value: TENANT_ROLES.ADMIN, label: 'Administrador', count: enhancedTeamMembers.filter(m => m.role === TENANT_ROLES.ADMIN).length }, { value: TENANT_ROLES.MEMBER, label: 'Miembro', count: enhancedTeamMembers.filter(m => m.role === TENANT_ROLES.MEMBER).length }, { value: TENANT_ROLES.VIEWER, label: 'Observador', count: enhancedTeamMembers.filter(m => m.role === TENANT_ROLES.VIEWER).length } ]; // Permission checks const isOwner = currentTenantAccess?.role === TENANT_ROLES.OWNER; const canManageTeam = isOwner || currentTenantAccess?.role === TENANT_ROLES.ADMIN; const teamStats = { total: enhancedTeamMembers.length, active: enhancedTeamMembers.filter(m => m.is_active).length, owners: enhancedTeamMembers.filter(m => m.role === TENANT_ROLES.OWNER).length, admins: enhancedTeamMembers.filter(m => m.role === TENANT_ROLES.ADMIN).length, members: enhancedTeamMembers.filter(m => m.role === TENANT_ROLES.MEMBER).length, }; const getRoleLabel = (role: string) => { switch (role) { case TENANT_ROLES.OWNER: return 'Propietario'; case TENANT_ROLES.ADMIN: return 'Administrador'; case TENANT_ROLES.MEMBER: return 'Miembro'; case TENANT_ROLES.VIEWER: return 'Observador'; default: return role; } }; // StatusCard configuration for team members const getMemberStatusConfig = (member: any) => { if (member.role === TENANT_ROLES.OWNER) { return { color: getStatusColor('completed'), // Purple/primary for owner text: getRoleLabel(member.role), icon: Crown, isCritical: false, isHighlight: true }; } if (member.role === TENANT_ROLES.ADMIN) { return { color: getStatusColor('inProgress'), // Blue for admin text: getRoleLabel(member.role), icon: Shield, isCritical: false, isHighlight: false }; } if (member.role === TENANT_ROLES.MEMBER) { return { color: getStatusColor('normal'), // Green for member text: getRoleLabel(member.role), icon: Users, isCritical: false, isHighlight: false }; } // VIEWER or other roles return { color: getStatusColor('pending'), // Yellow for viewer text: getRoleLabel(member.role), icon: Users, isCritical: false, isHighlight: false }; }; const getMemberActions = (member: any) => { const actions = []; // Role change actions (only for non-owners and if user can manage team) if (canManageTeam && member.role !== TENANT_ROLES.OWNER) { if (member.role !== TENANT_ROLES.ADMIN) { actions.push({ label: 'Hacer Admin', icon: Shield, onClick: () => handleUpdateRole(member.user_id, TENANT_ROLES.ADMIN), priority: 'secondary' as const, }); } if (member.role !== TENANT_ROLES.MEMBER) { actions.push({ label: 'Hacer Miembro', icon: Users, onClick: () => handleUpdateRole(member.user_id, TENANT_ROLES.MEMBER), priority: 'secondary' as const, }); } if (member.role !== TENANT_ROLES.VIEWER) { actions.push({ label: 'Hacer Observador', onClick: () => handleUpdateRole(member.user_id, TENANT_ROLES.VIEWER), priority: 'tertiary' as const, }); } } // Remove member action (only for owners) if (isOwner && member.role !== TENANT_ROLES.OWNER) { actions.push({ label: 'Remover', icon: Trash2, onClick: () => { if (confirm('¿Estás seguro de que deseas remover este miembro?')) { handleRemoveMember(member.user_id); } }, priority: 'tertiary' as const, destructive: true, }); } return actions; }; const filteredMembers = enhancedTeamMembers.filter(member => { const matchesRole = selectedRole === 'all' || member.role === selectedRole; const userName = member.user?.full_name || member.user_full_name || ''; const userEmail = member.user?.email || member.user_email || ''; const matchesSearch = userName.toLowerCase().includes(searchTerm.toLowerCase()) || userEmail.toLowerCase().includes(searchTerm.toLowerCase()); return matchesRole && matchesSearch; }); // Available users for adding (exclude current members) const availableUsers = allUsers.filter(u => !enhancedTeamMembers.some(m => m.user_id === u.id) ); // Member action handlers const handleAddMember = async () => { if (!selectedUserToAdd || !selectedRoleToAdd || !tenantId) return; try { await addMemberMutation.mutateAsync({ tenantId, userId: selectedUserToAdd, role: selectedRoleToAdd, }); addToast('Miembro agregado exitosamente', { type: 'success' }); setShowAddForm(false); setSelectedUserToAdd(''); setSelectedRoleToAdd(TENANT_ROLES.MEMBER); } catch (error) { addToast('Error al agregar miembro', { type: 'error' }); } }; const handleRemoveMember = async (memberUserId: string) => { if (!tenantId) return; try { await removeMemberMutation.mutateAsync({ tenantId, memberUserId, }); addToast('Miembro removido exitosamente', { type: 'success' }); } catch (error) { addToast('Error al remover miembro', { type: 'error' }); } }; const handleUpdateRole = async (memberUserId: string, newRole: string) => { if (!tenantId) return; try { await updateRoleMutation.mutateAsync({ tenantId, memberUserId, newRole, }); addToast('Rol actualizado exitosamente', { type: 'success' }); } catch (error) { addToast('Error al actualizar rol', { type: 'error' }); } }; if (isLoading) { return (

Cargando miembros del equipo...

); } return (
0 ? [{ id: 'add-member', label: 'Agregar Miembro', icon: Plus, onClick: () => setShowAddForm(true) }] : undefined } /> {/* Team Stats */}

Total Equipo

{teamStats.total}

Activos

{teamStats.active}

Administradores

{teamStats.admins}

Propietarios

{teamStats.owners}

{/* Filters and Search */}
setSearchTerm(e.target.value)} className="pl-10" />
{roles.map((role) => ( ))}
{/* Team Members List - Responsive grid */}
{filteredMembers.map((member) => ( ))}
{filteredMembers.length === 0 && ( 0 ? [{ label: 'Agregar Primer Miembro', icon: Plus, onClick: () => setShowAddForm(true), priority: 'primary' as const, }] : []} className="col-span-full" /> )} {/* Add Member Modal */} {showAddForm && (

Agregar Miembro al Equipo

{/* User Selection */}
{availableUsers.length === 0 && (

No hay usuarios disponibles para agregar

)}
{/* Role Selection */}
{/* Role Description */}

{selectedRoleToAdd === TENANT_ROLES.ADMIN && 'Los administradores pueden gestionar miembros del equipo y configuraciones.'} {selectedRoleToAdd === TENANT_ROLES.MEMBER && 'Los miembros tienen acceso completo para trabajar con datos y funcionalidades.'} {selectedRoleToAdd === TENANT_ROLES.VIEWER && 'Los observadores solo pueden ver datos, sin realizar cambios.'}

)}
); }; export default TeamPage;