fix(gift): cabinet GiftResult shows claim link for directed gifts + review fixes

Pairs with the backend cabinet-unification. Directed cabinet gifts now stay
PAID/claimable, so the buyer's GiftResult must show the share link for them too.

- GiftResult.tsx: render the share state (and stop polling) for ANY claimable
  paid gift via is_claimable, not just is_code_only.
- api/gift.ts: GiftPurchaseStatus gains is_claimable.
- GiftClaim.tsx: explicit failed/expired state (was falling into the 'almost
  ready' spinner forever).
- PurchaseSuccess.tsx: a paid gift is always claimable — stop polling and show
  the share block on `paid && is_gift` (don't gate on is_claimable, which could
  strand the buyer on a spinner).
- i18n: landing.giftClaim.failedTitle/failedDesc in ru/en/zh/fa.
This commit is contained in:
c0mrade
2026-06-03 14:34:19 +03:00
parent db31d395cd
commit b9521f1aa7
8 changed files with 43 additions and 17 deletions

View File

@@ -142,6 +142,25 @@ export default function GiftClaim() {
);
}
// Payment failed/expired → tell the recipient instead of spinning forever
if (gift.status === 'failed' || gift.status === 'expired') {
return (
<Shell>
<div className="flex flex-col items-center gap-3 py-6 text-center">
<h1 className="text-lg font-semibold text-dark-50">
{t('landing.giftClaim.failedTitle', 'Gift unavailable')}
</h1>
<p className="text-sm text-dark-400">
{t(
'landing.giftClaim.failedDesc',
'The payment for this gift did not go through, so it cannot be activated.',
)}
</p>
</div>
</Shell>
);
}
// Successful web claim → show connection link
if (result) {
return (