import { LOCAL_STORAGE_KEYS } from 'common' import { Check, ChevronDown } from 'lucide-react' import { useMemo, useState, type ReactNode } from 'react' import { cn, Collapsible, CollapsibleContent, CollapsibleTrigger } from 'ui' import { CreateOrganizationCard, OrganizationCard, } from '@/components/interfaces/Organization/OrganizationCard' import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage' import type { Organization } from '@/types' const VISIBLE_ORGANIZATIONS_LIMIT = 3 const CONNECT_DISCLOSURE_TRIGGER_CLASSNAME = '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' export const OrganizationSelector = ({ organizations, selectedSlug, disabled = false, description, createLabel, createHrefParams, onSelect, getOrganizationDescription, }: { organizations: Organization[] selectedSlug?: string | null disabled?: boolean description?: ReactNode createLabel?: string createHrefParams?: { [key: string]: string } onSelect: (slug: string) => void getOrganizationDescription?: (organization: Organization) => ReactNode }) => { const [showMore, setShowMore] = useState(false) const [lastVisitedOrganization] = useLocalStorageQuery( LOCAL_STORAGE_KEYS.LAST_VISITED_ORGANIZATION, '' ) 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 return ( Organization {description && {description}} {visibleOrganizations.map((organization) => ( onSelect(organization.slug)} description={ getOrganizationDescription?.(organization) ?? getPlanDescription(organization) } /> ))} {!!createLabel && !!createHrefParams && ( )} {hasOverflow && ( {showMore ? 'Show fewer' : `Show ${overflowOrganizations.length} more`} {overflowOrganizations.map((organization) => ( onSelect(organization.slug)} description={ getOrganizationDescription?.(organization) ?? getPlanDescription(organization) } /> ))} )} ) } 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}