"use client"; import { Loader2, X } from "@/components/icons"; import { useTranslations } from "next-intl"; import type { ParsedMailto } from "@/lib/protocol-handlers/mailto"; import type { ParsedWebcal } from "@/lib/protocol-handlers/webcal"; import type { AccountEntry } from "@/stores/account-store"; import { cn } from "@/lib/utils"; import { Avatar } from "@/components/ui/avatar"; import { useId } from "react"; import { useFocusTrap } from "@/hooks/use-focus-trap"; type ProtocolAccountPickerProps = { accounts: AccountEntry[]; activeAccountId: string | null; isSwitching?: boolean; onSelect: (accountId: string) => void; onCancel: () => void; } & ( | { kind: "mailto"; operation?: ParsedMailto } | { kind: "webcal"; operation?: ParsedWebcal } ); function getHost(value: string): string { try { return new URL(value).hostname; } catch { return value; } } export function ProtocolAccountPicker({ kind, accounts, activeAccountId, isSwitching = false, onSelect, onCancel, operation, }: ProtocolAccountPickerProps) { const t = useTranslations("protocol_handlers"); const tCommon = useTranslations("common"); const details = operation ? kind === "mailto" ? [ { label: t("detail_to"), value: operation.to.join(", ") || "-" }, { label: t("detail_subject"), value: operation.subject || t("detail_no_subject") }, ] : [ { label: t("detail_calendar"), value: operation.suggestedName }, { label: t("detail_source"), value: getHost(operation.subscriptionUrl) }, ] : []; // A modal: the focus starts on the account in use (else the first one), // Tab stays inside, Escape cancels unless a switch is under way, and the // focus goes back to where it was. const titleId = useId(); const panelRef = useFocusTrap({ isActive: true, onEscape: () => { if (!isSwitching) onCancel(); }, restoreFocus: true, initialFocus: () => panelRef.current?.querySelector('[data-active-account="true"]') ?? panelRef.current?.querySelector('[data-account-option]'), }); return (
); }