import { useParams } from 'common' import { ArrowRight, Check, ChevronRight, User, X } from 'lucide-react' import Link from 'next/link' import { useMemo } from 'react' import { Badge, cn, HoverCard, HoverCardContent, HoverCardTrigger, ScrollArea, TableCell, TableRow, } from 'ui' import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader' import { isInviteExpired } from '../Organization.utils' import { MemberActions } from './MemberActions' import PartnerIcon from '@/components/ui/PartnerIcon' import { ProfileImage } from '@/components/ui/ProfileImage' import { useOrganizationRolesV2Query } from '@/data/organization-members/organization-roles-query' import { OrganizationMember } from '@/data/organizations/organization-members-query' import { useOrgProjectsInfiniteQuery } from '@/data/projects/org-projects-infinite-query' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' import { useProfile } from '@/lib/profile' interface MemberRowProps { member: OrganizationMember } const MEMBER_ORIGIN_TO_MANAGED_BY = { vercel: 'vercel-marketplace', } as const export const MemberRow = ({ member }: MemberRowProps) => { const { slug } = useParams() const { profile } = useProfile() const { data: selectedOrganization } = useSelectedOrganizationQuery() const { data: roles, isPending: isLoadingRoles } = useOrganizationRolesV2Query({ slug: selectedOrganization?.slug, }) const hasProjectScopedRoles = (roles?.project_scoped_roles ?? []).length > 0 const { data: projectsData } = useOrgProjectsInfiniteQuery({ slug }) const orgProjects = useMemo(() => projectsData?.pages.flatMap((page) => page.projects), [projectsData?.pages]) || [] const isInvitedUser = Boolean(member.invited_id) // Use generic avatar for all team members instead of attempting to fetch from GitHub const profileImageUrl = undefined return (
} />

{member.primary_email}

{member.gotrue_id === profile?.gotrue_id && You} {isInvitedUser && member.invited_at && ( {isInviteExpired(member.invited_at) ? 'Expired' : 'Invited'} )} {member.is_sso_user && SSO} {(member.metadata as any)?.origin && ( )}
{member.mfa_enabled ? ( <> Enabled ) : ( <> Disabled )}
{isLoadingRoles ? ( ) : ( member.role_ids.map((id) => { const orgScopedRole = (roles?.org_scoped_roles ?? []).find((role) => role.id === id) const projectScopedRole = (roles?.project_scoped_roles ?? []).find( (role) => role.id === id ) const role = orgScopedRole || projectScopedRole const roleName = (role?.name ?? '').split('_')[0] const projectsApplied = role?.projects.length === 0 ? (orgProjects?.map((p) => p.name) ?? []) : (role?.projects ?? []) .map(({ ref }) => orgProjects?.find((p) => p.ref === ref)?.name ?? '') .filter((x) => x.length > 0) return (

{roleName}

{hasProjectScopedRoles && ( <> {projectsApplied.length === 1 ? ( {projectsApplied[0]} ) : ( {role?.projects.length === 0 ? 'Organization' : `${projectsApplied.length} project${projectsApplied.length > 1 ? 's' : ''}`}

{roleName} role applies to {projectsApplied.length} project {projectsApplied.length > 1 ? 's' : ''}

5 ? 'h-[130px]' : '')} > {projectsApplied.map((name) => { const ref = orgProjects?.find((p) => p.name === name)?.ref return ( {name} Go to project ) })}
)} )}
) }) )}
) }