diff --git a/src/widgets/staking/ui/PositionsPanel.module.css b/src/widgets/staking/ui/PositionsPanel.module.css index fff28f0..c4e595d 100644 --- a/src/widgets/staking/ui/PositionsPanel.module.css +++ b/src/widgets/staking/ui/PositionsPanel.module.css @@ -2,10 +2,44 @@ background: var(--glass-bg); border: 1px solid var(--glass-border); border-radius: 20px; - padding: 24px; + overflow: hidden; +} + +.inner { display: flex; flex-direction: column; gap: 14px; + padding: 24px; +} + +/* Шапка (заголовок + сумма) закреплена, скроллится только список ниже. */ +.body { + display: flex; + flex-direction: column; + gap: 14px; +} + +/* На десктопе (две колонки) высота блока позиций не превышает карточку стейкинга: + .inner вынесен из потока, поэтому высоту строки грида задаёт только левая колонка, + а список позиций при переполнении скроллится внутри. */ +@media (min-width: 1101px) { + .panel { + position: relative; + } + + .inner { + position: absolute; + inset: 0; + } + + .body { + flex: 1; + min-height: 0; + overflow-y: auto; + /* отступ, чтобы контент не уходил под полосу прокрутки */ + padding-right: 4px; + margin-right: -4px; + } } .head { diff --git a/src/widgets/staking/ui/PositionsPanel.tsx b/src/widgets/staking/ui/PositionsPanel.tsx index 709b6a1..27d4fce 100644 --- a/src/widgets/staking/ui/PositionsPanel.tsx +++ b/src/widgets/staking/ui/PositionsPanel.tsx @@ -39,126 +39,130 @@ export function PositionsPanel({ chain, onUnstakeEth, onUnstakeSol, onClaim, uns return (
-
- Мои позиции -
- {truncateDecimals(isError ? '0' : total, 6)} {unit} +
+
+ Мои позиции +
+ {truncateDecimals(isError ? '0' : total, 6)} {unit} +
-
- +
+ - {isLoading && } + {isLoading && } - {isError &&
{getStakingErrorMessage(error)}
} + {isError &&
{getStakingErrorMessage(error)}
} - {!isLoading && !isError && empty && ( -
У вас пока нет активных позиций стейкинга.
- )} - - {!isError && data?.chain === 'ETH' && !empty && ( - <> - {(parseFloat(data.stEthBalanceWeiHuman) || 0) > 0 && ( -
-
-
- - - stETH - - - Активна{data.aprPercent != null ? ` · APR ${data.aprPercent}%` : ''} - -
-
{truncateDecimals(data.stEthBalanceWeiHuman, 8)}
- -
-
+ {!isLoading && !isError && empty && ( +
У вас пока нет активных позиций стейкинга.
)} - {data.withdrawalRequests.length > 0 && ( + {!isError && data?.chain === 'ETH' && !empty && ( <> -
Заявки на вывод
-
- {data.withdrawalRequests.map((r) => { - const ready = r.isFinalized && !r.isClaimed - return ( -
-
- Заявка #{r.requestId} - - {r.isClaimed ? 'Выведено' : ready ? 'Готово к выводу' : 'В очереди'} - -
-
{truncateDecimals(r.amountStEthWeiHuman, 8)} ETH
- {ready ? ( - - ) : r.isClaimed ? null : ( -
Ожидает финализации в Lido
- )} + {(parseFloat(data.stEthBalanceWeiHuman) || 0) > 0 && ( +
+
+
+ + + stETH + + + Активна{data.aprPercent != null ? ` · APR ${data.aprPercent}%` : ''} +
- ) - })} -
+
{truncateDecimals(data.stEthBalanceWeiHuman, 8)}
+ +
+
+ )} + + {data.withdrawalRequests.length > 0 && ( + <> +
Заявки на вывод
+
+ {data.withdrawalRequests.map((r) => { + const ready = r.isFinalized && !r.isClaimed + return ( +
+
+ Заявка #{r.requestId} + + {r.isClaimed ? 'Выведено' : ready ? 'Готово к выводу' : 'В очереди'} + +
+
{truncateDecimals(r.amountStEthWeiHuman, 8)} ETH
+ {ready ? ( + + ) : r.isClaimed ? null : ( +
Ожидает финализации в Lido
+ )} +
+ ) + })} +
+ + )} )} - - )} - {!isError && data?.chain === 'SOL' && !empty && ( -
- {data.positions.map((p) => { - const st = SOL_STATE_META[p.state] - return ( -
-
- - - SOL - - {st.label} -
-
{truncateDecimals(p.lamportsHuman, 8)}
-
- Валидатор: {p.validator} · {p.stakeAccount} -
- {p.state === 'active' && ( - - )} - {p.state === 'inactive' && ( - - )} - {p.state === 'deactivating' &&
Разблокируется через 1–2 эпохи
} - {p.state === 'activating' &&
Активируется…
} -
- ) - })} + {!isError && data?.chain === 'SOL' && !empty && ( +
+ {data.positions.map((p) => { + const st = SOL_STATE_META[p.state] + return ( +
+
+ + + SOL + + {st.label} +
+
{truncateDecimals(p.lamportsHuman, 8)}
+
+ Валидатор: {p.validator} · {p.stakeAccount} +
+ {p.state === 'active' && ( + + )} + {p.state === 'inactive' && ( + + )} + {p.state === 'deactivating' &&
Разблокируется через 1–2 эпохи
} + {p.state === 'activating' &&
Активируется…
} +
+ ) + })} +
+ )}
- )} +
) } diff --git a/src/widgets/staking/ui/StakingWidget.module.css b/src/widgets/staking/ui/StakingWidget.module.css index cc88fb4..437e81b 100644 --- a/src/widgets/staking/ui/StakingWidget.module.css +++ b/src/widgets/staking/ui/StakingWidget.module.css @@ -8,7 +8,9 @@ display: grid; grid-template-columns: 1.5fr 1fr; gap: 20px; - align-items: start; + /* stretch: обе колонки получают высоту строки = высоту карточки стейкинга + (блок позиций вынесен из потока и сам высоту строки не задаёт). */ + align-items: stretch; } @media (max-width: 1100px) {