import { ChevronDown } from 'lucide-react' import { useMemo, useState, type ReactNode } from 'react' import { cn, Collapsible, CollapsibleContent, CollapsibleTrigger, SuccessCheck } from 'ui' import { CreateOrganizationCard, OrganizationCard, } from '@/components/interfaces/Organization/OrganizationCard' import { useLastVisitedOrganization } from '@/hooks/misc/useLastVisitedOrganization' import type { Organization } from '@/types' const VISIBLE_ORGANIZATIONS_LIMIT = 3 const CONNECT_DISCLOSURE_TRIGGER_CLASSNAME = cn( 'mx-auto flex h-7 cursor-pointer items-center justify-center gap-1.5 rounded-md px-2', 'text-xs text-foreground-lighter transition-colors', 'hover:bg-surface-200 hover:text-foreground', '[&[data-state=open]>svg]:-rotate-180!' ) export const OrganizationSelector = ({ organizations, unavailableOrganizations = [], selectedSlug, disabled = false, description, createLabel, createHrefParams, onCreate, onSelect, getOrganizationDescription, getUnavailableOrganizationDescription, unavailableReason, }: { organizations: Organization[] unavailableOrganizations?: Organization[] selectedSlug?: string | null disabled?: boolean description?: ReactNode createLabel?: string createHrefParams?: { [key: string]: string } onCreate?: () => void onSelect: (slug: string) => void getOrganizationDescription?: (organization: Organization) => ReactNode getUnavailableOrganizationDescription?: (organization: Organization) => ReactNode unavailableReason?: ReactNode }) => { const [showMore, setShowMore] = useState(false) const { lastVisitedOrganization } = useLastVisitedOrganization() const { visibleOrganizations, overflowOrganizations } = useMemo(() => { const lastVisitedOrg = organizations.find(({ slug }) => slug === lastVisitedOrganization) const selectedIndex = organizations.findIndex(({ slug }) => slug === selectedSlug) const selectedInOverflow = selectedIndex >= VISIBLE_ORGANIZATIONS_LIMIT if (!!lastVisitedOrg) { const withoutLastVisited = organizations.filter( ({ slug }) => slug !== lastVisitedOrganization ) return { visibleOrganizations: [ lastVisitedOrg, ...withoutLastVisited.slice(0, VISIBLE_ORGANIZATIONS_LIMIT - 1), ], overflowOrganizations: withoutLastVisited.slice(VISIBLE_ORGANIZATIONS_LIMIT - 1), } } if (!selectedInOverflow || !selectedSlug) { return { visibleOrganizations: organizations.slice(0, VISIBLE_ORGANIZATIONS_LIMIT), overflowOrganizations: organizations.slice(VISIBLE_ORGANIZATIONS_LIMIT), } } const selected = organizations[selectedIndex] const withoutSelected = organizations.filter(({ slug }) => slug !== selectedSlug) return { visibleOrganizations: [ ...withoutSelected.slice(0, VISIBLE_ORGANIZATIONS_LIMIT - 1), selected, ], overflowOrganizations: withoutSelected.slice(VISIBLE_ORGANIZATIONS_LIMIT - 1), } }, [lastVisitedOrganization, organizations, selectedSlug]) const hasOverflow = overflowOrganizations.length > 0 const hasUnavailableOrganizations = unavailableOrganizations.length > 0 return ( Organization {description && {description}} {visibleOrganizations.map((organization) => ( onSelect(organization.slug)} description={ getOrganizationDescription?.(organization) ?? getPlanDescription(organization) } /> ))} {!!createLabel && (!!createHrefParams || !!onCreate) && ( )} {hasOverflow && ( {showMore ? 'Show fewer' : `Show ${overflowOrganizations.length} more`} {overflowOrganizations.map((organization) => ( onSelect(organization.slug)} description={ getOrganizationDescription?.(organization) ?? getPlanDescription(organization) } /> ))} )} {hasUnavailableOrganizations && ( Organizations that can't be linked {unavailableOrganizations.map((organization) => ( ))} {unavailableReason && ( {unavailableReason} )} )} ) } const getPlanDescription = (organization: Organization) => `${organization.plan.name} Plan` const ConnectOrganizationButton = ({ organization, selected, disabled, onClick, description, }: { organization: Organization selected?: boolean disabled?: boolean onClick?: () => void description?: ReactNode }) => ( {selected && ( )} )
Organization
{description}
{unavailableReason}