import { useEffect, useRef, useLayoutEffect, useState } from "react"; import { createPortal } from "react-dom"; import { useTranslation } from "react-i18next"; /** * Всплывающее окно с текстом вознаграждения (rewardText). * Открывается под/рядом с кнопкой-якорем, закрывается по клику мимо или Esc. */ export default function RewardPopup({ text, anchorRef, onClose }) { const { t } = useTranslation(); const ref = useRef(null); const [coords, setCoords] = useState(null); useLayoutEffect(() => { if (!anchorRef?.current || !ref.current) return; const anchorRect = anchorRef.current.getBoundingClientRect(); const popupRect = ref.current.getBoundingClientRect(); const gap = 8; const margin = 10; // Всплываем слева сверху от кнопки (как календарь): низ попапа — у верха якоря, // правая грань попапа выравнивается по правой грани кнопки. let top = anchorRect.top + window.scrollY - popupRect.height - gap; const minTop = window.scrollY + margin; if (top < minTop) top = minTop; let left = anchorRect.right + window.scrollX - popupRect.width; const minLeft = window.scrollX + margin; if (left < minLeft) left = minLeft; setCoords({ top, left }); }, [anchorRef]); useEffect(() => { const onDown = (e) => { const inAnchor = anchorRef?.current?.contains(e.target); const inPopup = ref.current?.contains(e.target); if (!inAnchor && !inPopup) onClose(); }; const onKey = (e) => { if (e.key === "Escape") onClose(); }; document.addEventListener("mousedown", onDown); document.addEventListener("keydown", onKey); return () => { document.removeEventListener("mousedown", onDown); document.removeEventListener("keydown", onKey); }; }, [onClose, anchorRef]); return createPortal(
💛 {t("postCard.reward")}
{text}
, document.body ); }