import { useEffect, useLayoutEffect, useRef, useState } from 'react' import { createPortal } from 'react-dom' import { Building2, ExternalLink, Globe, MoreHorizontal, Trash2, UserRound, } from 'lucide-react' import { fitFixedPopover } from '../utils/fitFixedPopover' import styles from './BusinessActionsOverflowMenu.module.css' type PopoverPosition = { top: number left: number } interface DomainLinksOverflowMenuProps { host: string onRemove: () => void } function apexHost(host: string) { return host.trim().replace(/^www\./i, '') } function siteProtocol(host: string) { return /\.local$/i.test(host) ? 'http:' : 'https:' } function siteUrl(host: string) { return `${siteProtocol(host)}//${host}` } function openHost(host: string) { window.open(siteUrl(host), '_blank', 'noopener,noreferrer') } export function DomainLinksOverflowMenu({ host, onRemove }: DomainLinksOverflowMenuProps) { const [open, setOpen] = useState(false) const [popoverPos, setPopoverPos] = useState(null) const wrapRef = useRef(null) const popoverRef = useRef(null) const triggerRef = useRef(null) const apex = apexHost(host) const websiteHost = apex const businessHost = `business.${apex}` const customerHost = `customer.${apex}` function updatePopoverPosition() { const rect = triggerRef.current?.getBoundingClientRect() if (!rect) return const size = popoverRef.current ? { width: popoverRef.current.offsetWidth, height: popoverRef.current.offsetHeight } : { width: 220, height: 220 } setPopoverPos(fitFixedPopover(rect, size, 'end')) } function toggleOpen() { if (open) { setOpen(false) return } updatePopoverPosition() setOpen(true) } useLayoutEffect(() => { if (!open) return updatePopoverPosition() }, [open]) useEffect(() => { if (!open) return function handleClickOutside(e: MouseEvent) { const target = e.target as Node if (wrapRef.current?.contains(target)) return if (popoverRef.current?.contains(target)) return setOpen(false) } function handleEscape(e: KeyboardEvent) { if (e.key === 'Escape') setOpen(false) } function handleReposition() { updatePopoverPosition() } document.addEventListener('mousedown', handleClickOutside) document.addEventListener('keydown', handleEscape) window.addEventListener('resize', handleReposition) window.addEventListener('scroll', handleReposition, true) return () => { document.removeEventListener('mousedown', handleClickOutside) document.removeEventListener('keydown', handleEscape) window.removeEventListener('resize', handleReposition) window.removeEventListener('scroll', handleReposition, true) } }, [open]) const items = [ { key: 'website', label: 'Open website', detail: websiteHost, icon: Globe, onClick: () => openHost(websiteHost), }, { key: 'business', label: 'Business dashboard', detail: businessHost, icon: Building2, onClick: () => openHost(businessHost), }, { key: 'customer', label: 'Customer dashboard', detail: customerHost, icon: UserRound, onClick: () => openHost(customerHost), }, ] as const return (
{open && popoverPos && createPortal(
{items.map(({ key, label, detail, icon: Icon, onClick }) => ( ))}
, document.body, )}
) }