const OVERLAY_ATTRIBUTE = "data-amos-apple-pay-waiting"; const CANCEL_ATTRIBUTE = "data-amos-apple-pay-waiting-cancel"; const TITLE_ID = "amos-apple-pay-waiting-title"; const WAITING_COPY = "Complete your payment in the open Apple Pay window, or close Apple Pay to continue paying another way."; const COMPLETING_COPY = "Completing your payment…"; /** * Create (or return existing) full-viewport waiting UI on the host page while * Apple Pay Code runs in a separate window. Cancel invokes `onCancel`. */ export function showApplePayWaitingOverlay({ onCancel, }: { onCancel: () => void; }): HTMLElement { const existing = document.querySelector( `[${OVERLAY_ATTRIBUTE}]`, ); if (existing) { return existing; } const root = document.createElement("div"); root.setAttribute(OVERLAY_ATTRIBUTE, "true"); root.setAttribute("role", "dialog"); root.setAttribute("aria-modal", "true"); root.setAttribute("aria-labelledby", TITLE_ID); Object.assign(root.style, { position: "fixed", inset: "0", zIndex: "2147483646", display: "flex", alignItems: "center", justifyContent: "center", padding: "24px", boxSizing: "border-box", background: "rgba(0, 0, 0, 0.55)", fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif', } satisfies Partial); const card = document.createElement("div"); Object.assign(card.style, { width: "100%", maxWidth: "360px", borderRadius: "12px", background: "#fff", padding: "28px 24px 20px", boxSizing: "border-box", textAlign: "center", boxShadow: "0 12px 40px rgba(0, 0, 0, 0.25)", } satisfies Partial); const mark = document.createElement("div"); mark.setAttribute("aria-hidden", "true"); Object.assign(mark.style, { display: "inline-flex", alignItems: "center", justifyContent: "center", gap: "6px", marginBottom: "16px", fontSize: "28px", fontWeight: "600", letterSpacing: "-0.02em", color: "#000", lineHeight: "1", } satisfies Partial); mark.innerHTML = `Pay`; const title = document.createElement("p"); title.id = TITLE_ID; Object.assign(title.style, { margin: "0 0 20px", fontSize: "15px", lineHeight: "1.45", color: "#1a1a1a", } satisfies Partial); title.textContent = WAITING_COPY; const cancel = document.createElement("button"); cancel.type = "button"; cancel.setAttribute(CANCEL_ATTRIBUTE, "true"); cancel.textContent = "Cancel payment"; Object.assign(cancel.style, { display: "block", width: "100%", border: "none", borderRadius: "8px", padding: "12px 16px", background: "#2c2c2e", color: "#fff", fontSize: "15px", fontWeight: "500", cursor: "pointer", } satisfies Partial); cancel.addEventListener("click", onCancel); card.append(mark, title, cancel); root.append(card); document.body.append(root); return root; } /** * Sheet already authorized; hide Cancel so the donor cannot double-pay. * No-op if the overlay is not on the page. */ export function setApplePayWaitingOverlayCompleting(): void { const root = document.querySelector(`[${OVERLAY_ATTRIBUTE}]`); if (!root) { return; } const title = root.querySelector(`#${TITLE_ID}`); if (title) { title.textContent = COMPLETING_COPY; } root.querySelector(`[${CANCEL_ATTRIBUTE}]`)?.remove(); } /** Remove the host-page Apple Pay waiting overlay if present. */ export function hideApplePayWaitingOverlay(): void { document.querySelector(`[${OVERLAY_ATTRIBUTE}]`)?.remove(); }