// Gift Detail bottom-sheet — Portals-style. function AttrRow({ label, name, rarity, isLast }) { return ( <>
{label}
{name || '—'} {rarity != null && ( {rarity}% )}
{!isLast &&
} ); } function HeroIconBtn({ children, onClick }) { return ( ); } function GiftDetailSheet({ listing, balance, inCart, onClose, onBuy, onAddToCart }) { if (!listing) return null; const g = GIFT_KINDS[listing.kind]; // Покупка идёт с внутреннего баланса кошелька — гейтим по нему. const canAfford = balance >= listing.rub; // Открыт СВОЙ купленный подарок из «Мои» (есть order_id) → режим просмотра, // без кнопок покупки/корзины (нельзя «купить» подарок, который уже твой). const owned = listing.order_id != null; const [realAttrs, setRealAttrs] = React.useState(null); React.useEffect(() => { // У реальных листингов атрибуты уже в listing.attrs (с бэка) — fragment-фетч // не нужен (и блокируется CORS). Пробуем только для мок-листингов с номером. if (listing._raw || listing.num == null) return; let cancel = false; fetch(`https://nft.fragment.com/gift/${listing.kind}-${listing.num}.json`) .then(r => r.ok ? r.json() : null) .then(d => { if (cancel || !d?.attributes) return; const get = (t) => d.attributes.find(a => a.trait_type === t)?.value; setRealAttrs({ model: get('Model'), backdrop: get('Backdrop'), symbol: get('Symbol'), }); }) .catch(() => {}); return () => { cancel = true; }; }, [listing.kind, listing.num]); const attrs = { model: { name: realAttrs?.model ?? listing.attrs.model.name, rarity: listing.attrs.model.rarity }, backdrop: { name: realAttrs?.backdrop ?? listing.attrs.backdrop.name, rarity: listing.attrs.backdrop.rarity }, symbol: { name: realAttrs?.symbol ?? listing.attrs.symbol.name, rarity: listing.attrs.symbol.rarity }, }; return ( {/* Hero card — the gift's Lottie fills the card; its own backdrop colors it. */}
{/* Lottie fills the card */}
{/* Title overlay at bottom */}
{listing.name}
{listing.num != null && (
#{listing.num.toLocaleString('ru-RU')}
)}
{/* Attribute table */}
{/* View-only для своего подарка; иначе — покупка. */} {owned ? ( {close => ( )} ) : ( <> {/* Buy button — pill with title + price stacked, like Portals */}
{onAddToCart && ( )}
{!canAfford && (
Пополните баланс ещё на{' '} {fmtRub(listing.rub - balance)} {' '}в разделе Кошелёк
)} )}
); } window.GiftDetailSheet = GiftDetailSheet;