From 9f45efc9eb082a291215eb8284f772957c0c3e0d Mon Sep 17 00:00:00 2001 From: rassadin11 Date: Mon, 29 Jun 2026 19:57:36 +0300 Subject: [PATCH] profile refactor --- .../swap-form/ui/SwapConfirmModal.module.css | 30 +++++++++++++++++++ src/widgets/swap-form/ui/SwapConfirmModal.tsx | 21 +++++++++++-- src/widgets/swap-form/ui/SwapForm.tsx | 4 +-- .../swap-form/ui/TrxConfirmModal.module.css | 30 +++++++++++++++++++ src/widgets/swap-form/ui/TrxConfirmModal.tsx | 21 +++++++++++-- 5 files changed, 98 insertions(+), 8 deletions(-) diff --git a/src/widgets/swap-form/ui/SwapConfirmModal.module.css b/src/widgets/swap-form/ui/SwapConfirmModal.module.css index 40095ba..9cf2521 100644 --- a/src/widgets/swap-form/ui/SwapConfirmModal.module.css +++ b/src/widgets/swap-form/ui/SwapConfirmModal.module.css @@ -7,6 +7,11 @@ align-items: center; justify-content: center; z-index: 100; + animation: overlayIn 0.2s ease; +} + +.overlay.closing { + animation: overlayOut 0.2s ease forwards; } .card { @@ -19,6 +24,31 @@ display: flex; flex-direction: column; gap: 24px; + animation: cardIn 0.24s cubic-bezier(0.22, 1, 0.36, 1); +} + +.card.closing { + animation: cardOut 0.2s cubic-bezier(0.55, 0, 1, 0.45) forwards; +} + +@keyframes overlayIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes overlayOut { + from { opacity: 1; } + to { opacity: 0; } +} + +@keyframes cardIn { + from { opacity: 0; transform: translateY(16px) scale(0.96); } + to { opacity: 1; transform: translateY(0) scale(1); } +} + +@keyframes cardOut { + from { opacity: 1; transform: translateY(0) scale(1); } + to { opacity: 0; transform: translateY(16px) scale(0.96); } } .header { diff --git a/src/widgets/swap-form/ui/SwapConfirmModal.tsx b/src/widgets/swap-form/ui/SwapConfirmModal.tsx index d8fd1ab..7f2baa5 100644 --- a/src/widgets/swap-form/ui/SwapConfirmModal.tsx +++ b/src/widgets/swap-form/ui/SwapConfirmModal.tsx @@ -1,3 +1,4 @@ +import { useState } from 'react' import styles from './SwapConfirmModal.module.css' interface SwapData { @@ -22,16 +23,30 @@ interface Props { export function SwapConfirmModal({ data, insufficientBalance, onConfirm, onClose }: Props) { const { details, fees } = data const { currencyIn, currencyOut, totalImpact, rate } = details + const [closing, setClosing] = useState(false) const impactPercent = parseFloat(totalImpact.percent) const rateFormatted = parseFloat(rate).toFixed(4) + // Play the exit animation first, then actually unmount once it ends. + function requestClose() { + setClosing(true) + } + + function handleAnimationEnd() { + if (closing) onClose() + } + return ( -
-
e.stopPropagation()}> +
+
e.stopPropagation()} + onAnimationEnd={handleAnimationEnd} + >
Подтвердить своп - +
diff --git a/src/widgets/swap-form/ui/SwapForm.tsx b/src/widgets/swap-form/ui/SwapForm.tsx index 467bde2..c999736 100644 --- a/src/widgets/swap-form/ui/SwapForm.tsx +++ b/src/widgets/swap-form/ui/SwapForm.tsx @@ -179,7 +179,7 @@ export function SwapForm() { onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['wallet', 'balance', fromNetwork] }) queryClient.invalidateQueries({ queryKey: ['wallet', 'portfolio'] }) - navigate(ROUTES.WALLET) + navigate(`${ROUTES.WALLET}/${fromNetwork.toLowerCase()}`) }, onError: (err) => { setErrorMessage(err instanceof Error ? err.message : 'Не удалось подписать транзакцию') @@ -206,7 +206,7 @@ export function SwapForm() { onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['wallet', 'balance', 'TRX'] }) queryClient.invalidateQueries({ queryKey: ['wallet', 'portfolio'] }) - navigate(ROUTES.WALLET) + navigate(`${ROUTES.WALLET}/${fromNetwork.toLowerCase()}`) }, onError: (err) => { setErrorMessage(err instanceof Error ? err.message : 'Не удалось выполнить свап') diff --git a/src/widgets/swap-form/ui/TrxConfirmModal.module.css b/src/widgets/swap-form/ui/TrxConfirmModal.module.css index 2425856..df72708 100644 --- a/src/widgets/swap-form/ui/TrxConfirmModal.module.css +++ b/src/widgets/swap-form/ui/TrxConfirmModal.module.css @@ -7,6 +7,11 @@ align-items: center; justify-content: center; z-index: 100; + animation: overlayIn 0.2s ease; +} + +.overlay.closing { + animation: overlayOut 0.2s ease forwards; } .card { @@ -19,6 +24,31 @@ display: flex; flex-direction: column; gap: 24px; + animation: cardIn 0.24s cubic-bezier(0.22, 1, 0.36, 1); +} + +.card.closing { + animation: cardOut 0.2s cubic-bezier(0.55, 0, 1, 0.45) forwards; +} + +@keyframes overlayIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes overlayOut { + from { opacity: 1; } + to { opacity: 0; } +} + +@keyframes cardIn { + from { opacity: 0; transform: translateY(16px) scale(0.96); } + to { opacity: 1; transform: translateY(0) scale(1); } +} + +@keyframes cardOut { + from { opacity: 1; transform: translateY(0) scale(1); } + to { opacity: 0; transform: translateY(16px) scale(0.96); } } .header { diff --git a/src/widgets/swap-form/ui/TrxConfirmModal.tsx b/src/widgets/swap-form/ui/TrxConfirmModal.tsx index b3514b3..b499930 100644 --- a/src/widgets/swap-form/ui/TrxConfirmModal.tsx +++ b/src/widgets/swap-form/ui/TrxConfirmModal.tsx @@ -1,3 +1,4 @@ +import { useState } from 'react' import type { TrxSwapQuoteData } from '@features/wallet' import styles from './TrxConfirmModal.module.css' @@ -13,13 +14,27 @@ interface Props { export function TrxConfirmModal({ quote, fromSymbol, toSymbol, amountHuman, insufficientBalance, onConfirm, onClose }: Props) { const { expectedOutFormatted, minOutFormatted, fees } = quote + const [closing, setClosing] = useState(false) + + // Play the exit animation first, then actually unmount once it ends. + function requestClose() { + setClosing(true) + } + + function handleAnimationEnd() { + if (closing) onClose() + } return ( -
-
e.stopPropagation()}> +
+
e.stopPropagation()} + onAnimationEnd={handleAnimationEnd} + >
Подтвердить своп - +