mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
Merge PR #478: stagger-анимация скрывала контент, пришедший из API после mount
framer-motion stagger раздаёт детям команду показаться один раз при монтировании
родителя; дети, смонтированные позже (когда resolve-ится react-query), оставались
в initial (opacity:0) — пустые страницы после F5/прямого захода.
- ConnectedAccounts, SavedCards: key={isLoading?...} перемонтирует контейнер
после загрузки → stagger проигрывается со всеми детьми;
- Balance (2), Profile, Support: явные initial/animate на условных staggerItem —
элемент самоанимируется при mount, вне оркестрации родителя;
- Wheel: исправлены несуществующие варианты hidden/show → initial/animate
(stagger истории спинов молча не работал).
Валидация на смердженном дереве: tsc, biome lint/format, build — чисто.
Правки #477 и #478 в общих файлах (ConnectedAccounts/Profile) сосуществуют.
This commit is contained in:
@@ -308,9 +308,11 @@ export default function Balance() {
|
|||||||
</Card>
|
</Card>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* Payment Methods */}
|
{/* Payment Methods — self-animated: mounts after its query resolves, when
|
||||||
|
the parent stagger orchestration has already finished and would leave
|
||||||
|
it stuck at opacity 0 */}
|
||||||
{paymentMethods && paymentMethods.length > 0 && (
|
{paymentMethods && paymentMethods.length > 0 && (
|
||||||
<motion.div variants={staggerItem}>
|
<motion.div variants={staggerItem} initial="initial" animate="animate">
|
||||||
<Card>
|
<Card>
|
||||||
<h2 className="mb-4 text-lg font-semibold text-dark-100">
|
<h2 className="mb-4 text-lg font-semibold text-dark-100">
|
||||||
{t('balance.topUpBalance')}
|
{t('balance.topUpBalance')}
|
||||||
@@ -474,9 +476,10 @@ export default function Balance() {
|
|||||||
</Card>
|
</Card>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* Saved Cards Navigation */}
|
{/* Saved Cards Navigation — self-animated: mounts after its query resolves
|
||||||
|
(see Payment Methods above) */}
|
||||||
{savedCardsData?.recurrent_enabled && (
|
{savedCardsData?.recurrent_enabled && (
|
||||||
<motion.div variants={staggerItem}>
|
<motion.div variants={staggerItem} initial="initial" animate="animate">
|
||||||
<Card interactive onClick={() => navigate('/balance/saved-cards')}>
|
<Card interactive onClick={() => navigate('/balance/saved-cards')}>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
|
|||||||
@@ -640,7 +640,11 @@ export default function ConnectedAccounts() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
// key: remount the container when loading resolves — stagger orchestration
|
||||||
|
// runs once on mount, so provider cards arriving from the API later would
|
||||||
|
// otherwise stay stuck at their initial variant (opacity 0) after a hard refresh
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key={isLoading ? 'loading' : 'ready'}
|
||||||
className="space-y-6"
|
className="space-y-6"
|
||||||
variants={staggerContainer}
|
variants={staggerContainer}
|
||||||
initial="initial"
|
initial="initial"
|
||||||
|
|||||||
@@ -325,9 +325,11 @@ export default function Profile() {
|
|||||||
</Card>
|
</Card>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* Referral Link Widget */}
|
{/* Referral Link Widget — self-animated: mounts after the referral queries
|
||||||
|
resolve, when the parent stagger orchestration has already finished and
|
||||||
|
would leave it stuck at opacity 0 */}
|
||||||
{referralTerms?.is_enabled && referralLink && (
|
{referralTerms?.is_enabled && referralLink && (
|
||||||
<motion.div variants={staggerItem}>
|
<motion.div variants={staggerItem} initial="initial" animate="animate">
|
||||||
<Card>
|
<Card>
|
||||||
<div className="mb-4 flex items-center justify-between">
|
<div className="mb-4 flex items-center justify-between">
|
||||||
<h2 className="text-lg font-semibold text-dark-100">{t('referral.yourLink')}</h2>
|
<h2 className="text-lg font-semibold text-dark-100">{t('referral.yourLink')}</h2>
|
||||||
|
|||||||
@@ -73,7 +73,11 @@ export default function SavedCards() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
// key: remount the container when loading resolves — stagger orchestration
|
||||||
|
// runs once on mount, so cards arriving from the API later would otherwise
|
||||||
|
// stay stuck at their initial variant (opacity 0) after a hard refresh
|
||||||
<motion.div
|
<motion.div
|
||||||
|
key={isLoading ? 'loading' : 'ready'}
|
||||||
className="space-y-6"
|
className="space-y-6"
|
||||||
variants={staggerContainer}
|
variants={staggerContainer}
|
||||||
initial="initial"
|
initial="initial"
|
||||||
|
|||||||
@@ -348,9 +348,11 @@ export default function Support() {
|
|||||||
</Button>
|
</Button>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* Contact support card for "both" mode */}
|
{/* Contact support card for "both" mode — self-animated: mounts after the
|
||||||
|
config query resolves, when the parent stagger orchestration has already
|
||||||
|
finished and would leave it stuck at opacity 0 */}
|
||||||
{supportConfig?.support_type === 'both' && supportConfig.support_username && (
|
{supportConfig?.support_type === 'both' && supportConfig.support_username && (
|
||||||
<motion.div variants={staggerItem}>
|
<motion.div variants={staggerItem} initial="initial" animate="animate">
|
||||||
<Card className="flex items-center justify-between">
|
<Card className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className="flex h-10 w-10 items-center justify-center rounded-xl bg-dark-800">
|
<div className="flex h-10 w-10 items-center justify-center rounded-xl bg-dark-800">
|
||||||
|
|||||||
@@ -774,10 +774,13 @@ export default function Wheel() {
|
|||||||
>
|
>
|
||||||
<div className="border-t border-dark-700/30 px-4 pb-4 pt-2">
|
<div className="border-t border-dark-700/30 px-4 pb-4 pt-2">
|
||||||
{history && history.items.length > 0 ? (
|
{history && history.items.length > 0 ? (
|
||||||
|
// "hidden"/"show" don't exist in staggerContainer/staggerItem
|
||||||
|
// (their keys are initial/animate/exit), so the stagger here
|
||||||
|
// was silently a no-op
|
||||||
<motion.div
|
<motion.div
|
||||||
variants={staggerContainer}
|
variants={staggerContainer}
|
||||||
initial="hidden"
|
initial="initial"
|
||||||
animate="show"
|
animate="animate"
|
||||||
className="space-y-2"
|
className="space-y-2"
|
||||||
>
|
>
|
||||||
{history.items.map((item: SpinHistoryItem) => (
|
{history.items.map((item: SpinHistoryItem) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user