{stage === 'confirm' &&
Забрать {gift.name}?
Укажи Telegram-получателя — подарок появится на его профиле в течение
пары минут. Можно указать свой @username.
@
setUsername(e.target.value.replace(/^@/, ''))}
style={{ flex: 1, background: 'transparent', border: 0, outline: 0, color: 'var(--text)', fontSize: 16, fontWeight: 600, lineHeight: 1, padding: 0, marginLeft: -2 }}/>
{err && (
{err}
)}
{close => (
)}
}
{stage === 'progress' &&
Передаём в Telegram…
Подключаемся к API Portals
}
{stage === 'done' &&
Готово! 🎉
{gift.name}{gift.num != null ? ` #${gift.num}` : ''} уже летит к{' '}
@{uname} — придёт в течение пары минут
{close => (
)}
}
,
target
);
}
function MyGiftsScreen({ onStartSend, onGiftClick, gifts, onChanged }) {
const held = gifts || []; // реальные held-подарки из /me/gifts (проброс из app.jsx)
const [selected, setSelected] = React.useState(null);
const [withdrawing, setWithdrawing] = React.useState(null);
const [myFilter, setMyFilter] = React.useState('vault');
const [page, setPage] = React.useState(1);
// «Выведенные» — реальный /me/gifts?released=1; рефетч, когда меняется held
// (после вывода/отправки подарок переезжает из хранилища в выведенные).
const _rel = (window.DataSource && window.DataSource.useReleasedGifts)
? window.DataSource.useReleasedGifts('rel-' + held.length)
: { data: null };
const releasedItems = (_rel.data && _rel.data.items) || [];
const items = myFilter === 'withdrawn' ? releasedItems : held;
React.useEffect(() => { setPage(1); }, [myFilter]);
const PAGE_SIZE = 6;
const totalPages = Math.max(1, Math.ceil(items.length / PAGE_SIZE));
const safePage = Math.min(page, totalPages);
const pageItems = items.slice((safePage - 1) * PAGE_SIZE, safePage * PAGE_SIZE);
const totalRub = items.reduce((s, i) => s + i.rub, 0);
const totalTon = items.reduce((s, i) => s + i.ton, 0);
return (
<>
Коллекция
{items.length}
подарков
Стоимость
{fmtRub(totalRub)}
{[
['vault', 'В хранилище'],
['withdrawn', 'Выведенные']].
map(([k, l]) => {
const on = (myFilter || 'vault') === k;
return (
);
})}
{pageItems.map((g) => {
return (
{ if (myFilter === 'vault') setSelected(g); }}
style={{ display: 'flex', flexDirection: 'column', gap: 8,
cursor: myFilter === 'vault' ? 'pointer' : 'default',
opacity: myFilter === 'withdrawn' ? 0.75 : 1 }}>
);
})}
{totalPages > 1 &&
{safePage}
/
{totalPages}
}
Всего {items.length} {items.length === 1 ? 'подарок' : items.length < 5 ? 'подарка' : 'подарков'}
{selected && !withdrawing &&