diff --git a/packages/ui/app/_components/dialogs/manage/DialogWrapper.tsx b/packages/ui/app/_components/dialogs/manage/DialogWrapper.tsx
new file mode 100644
index 000000000..26b8a6e2c
--- /dev/null
+++ b/packages/ui/app/_components/dialogs/manage/DialogWrapper.tsx
@@ -0,0 +1,37 @@
+'use client';
+
+import { Dialog } from '@ui/components/ui/dialog';
+import { useManageDialogContext } from '@ui/context/ManageDialogContext';
+
+import type { ActiveTab } from '.';
+
+const DialogWrapper = ({
+ isOpen,
+ setIsOpen,
+ children,
+ setCurrentActiveTab
+}: {
+ isOpen: boolean;
+ setIsOpen: (open: boolean) => void;
+ children: React.ReactNode;
+ setCurrentActiveTab: (tab: ActiveTab) => void;
+}) => {
+ const { resetTransactionSteps } = useManageDialogContext();
+
+ return (
+
+ );
+};
+
+export default DialogWrapper;
diff --git a/packages/ui/app/_components/dialogs/manage/ManageDialogTabs.tsx b/packages/ui/app/_components/dialogs/manage/ManageDialogTabs.tsx
new file mode 100644
index 000000000..4d64cff8e
--- /dev/null
+++ b/packages/ui/app/_components/dialogs/manage/ManageDialogTabs.tsx
@@ -0,0 +1,248 @@
+'use client';
+import { useMemo } from 'react';
+
+import Image from 'next/image';
+
+import { type Address, formatEther, formatUnits } from 'viem';
+
+import { DialogContent } from '@ui/components/ui/dialog';
+import {
+ Tabs,
+ TabsList,
+ TabsTrigger,
+ TabsContent
+} from '@ui/components/ui/tabs';
+import { useManageDialogContext } from '@ui/context/ManageDialogContext';
+import { useBorrowCapsDataForAsset } from '@ui/hooks/ionic/useBorrowCapsDataForAsset';
+import { useSupplyCapsDataForAsset } from '@ui/hooks/ionic/useSupplyCapsDataForPool';
+import { useUsdPrice } from '@ui/hooks/useAllUsdPrices';
+import { useMaxBorrowAmount } from '@ui/hooks/useMaxBorrowAmount';
+import { useMaxRepayAmount } from '@ui/hooks/useMaxRepayAmount';
+import { useMaxSupplyAmount } from '@ui/hooks/useMaxSupplyAmount';
+import { useMaxWithdrawAmount } from '@ui/hooks/useMaxWithdrawAmount';
+import type { MarketData } from '@ui/types/TokensDataMap';
+
+import BorrowTab from './BorrowTab';
+import RepayTab from './RepayTab';
+import SupplyTab from './SupplyTab';
+import WithdrawTab from './WithdrawTab';
+import AnimateHeight from '../../AnimateHeight';
+
+import type { ActiveTab } from '.';
+
+const ManageDialogTabs = ({
+ selectedMarketData,
+ comptrollerAddress,
+ isBorrowDisabled,
+ currentActiveTab,
+ setCurrentActiveTab,
+ setSwapWidgetOpen,
+ chainId
+}: {
+ selectedMarketData: MarketData;
+ comptrollerAddress: Address;
+ isBorrowDisabled: boolean;
+ currentActiveTab: ActiveTab;
+ setCurrentActiveTab: (tab: ActiveTab) => void;
+ setSwapWidgetOpen: (open: boolean) => void;
+ chainId: number;
+}) => {
+ const { data: usdPrice } = useUsdPrice(chainId.toString());
+ const { data: maxSupplyAmount, isLoading: isLoadingMaxSupply } =
+ useMaxSupplyAmount(selectedMarketData, comptrollerAddress, chainId);
+
+ const { data: maxRepayAmount, isLoading: isLoadingMaxRepayAmount } =
+ useMaxRepayAmount(selectedMarketData, chainId);
+
+ const { data: maxBorrowAmount, isLoading: isLoadingMaxBorrowAmount } =
+ useMaxBorrowAmount(selectedMarketData, comptrollerAddress, chainId);
+
+ const { data: maxWithdrawAmount, isLoading: isLoadingMaxWithdrawAmount } =
+ useMaxWithdrawAmount(selectedMarketData, chainId);
+
+ // Memoize calculations
+ const pricePerSingleAsset = useMemo(
+ () =>
+ parseFloat(formatEther(selectedMarketData.underlyingPrice)) *
+ (usdPrice ?? 0),
+ [selectedMarketData.underlyingPrice, usdPrice]
+ );
+
+ const { data: supplyCap } = useSupplyCapsDataForAsset(
+ comptrollerAddress,
+ selectedMarketData.cToken,
+ chainId
+ );
+
+ const supplyCapAsNumber = useMemo(
+ () =>
+ parseFloat(
+ formatUnits(
+ supplyCap?.supplyCaps ?? 0n,
+ selectedMarketData.underlyingDecimals
+ )
+ ),
+ [supplyCap?.supplyCaps, selectedMarketData.underlyingDecimals]
+ );
+
+ const supplyCapAsFiat = useMemo(
+ () => pricePerSingleAsset * supplyCapAsNumber,
+ [pricePerSingleAsset, supplyCapAsNumber]
+ );
+
+ const totalSupplyAsNumber = useMemo(
+ () =>
+ parseFloat(
+ formatUnits(
+ selectedMarketData.totalSupply,
+ selectedMarketData.underlyingDecimals
+ )
+ ),
+ [selectedMarketData.totalSupply, selectedMarketData.underlyingDecimals]
+ );
+
+ const { data: borrowCap } = useBorrowCapsDataForAsset(
+ selectedMarketData.cToken,
+ chainId
+ );
+
+ const borrowCapAsNumber = useMemo(
+ () =>
+ parseFloat(
+ formatUnits(
+ borrowCap?.totalBorrowCap ?? 0n,
+ selectedMarketData.underlyingDecimals
+ )
+ ),
+ [borrowCap?.totalBorrowCap, selectedMarketData.underlyingDecimals]
+ );
+
+ const borrowCapAsFiat = useMemo(
+ () => pricePerSingleAsset * borrowCapAsNumber,
+ [pricePerSingleAsset, borrowCapAsNumber]
+ );
+
+ const totalBorrowAsNumber = useMemo(
+ () =>
+ parseFloat(
+ formatUnits(
+ selectedMarketData.totalBorrow,
+ selectedMarketData.underlyingDecimals
+ )
+ ),
+ [selectedMarketData.totalBorrow, selectedMarketData.underlyingDecimals]
+ );
+
+ const TabsComponent = () => {
+ const { setActive } = useManageDialogContext();
+
+ const handleTabChange = (value: string) => {
+ const newTab = value as ActiveTab;
+ setCurrentActiveTab(newTab);
+ setActive(newTab);
+ };
+
+ return (
+
+
+
+ Supply
+
+ Borrow
+
+
+ Repay
+
+ Withdraw
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ };
+
+ return (
+
+
+
+
+
+
+
+
+ );
+};
+
+export default ManageDialogTabs;
diff --git a/packages/ui/app/_components/dialogs/manage/SupplyTab.tsx b/packages/ui/app/_components/dialogs/manage/SupplyTab.tsx
index 0aa3bb293..77be2ef14 100644
--- a/packages/ui/app/_components/dialogs/manage/SupplyTab.tsx
+++ b/packages/ui/app/_components/dialogs/manage/SupplyTab.tsx
@@ -42,7 +42,6 @@ const SupplyTab = ({
const {
selectedMarketData,
resetTransactionSteps,
- transactionSteps: supplyTxSteps,
chainId,
comptrollerAddress,
updatedValues,
@@ -52,11 +51,7 @@ const SupplyTab = ({
getStepsForTypes
} = useManageDialogContext();
- const {
- enableCollateral,
- handleCollateralToggle,
- transactionSteps: collateralTxSteps
- } = useCollateralToggle({
+ const { enableCollateral, handleCollateralToggle } = useCollateralToggle({
selectedMarketData,
comptrollerAddress,
onSuccess: refetchUsedQueries
diff --git a/packages/ui/app/_components/dialogs/manage/index.tsx b/packages/ui/app/_components/dialogs/manage/index.tsx
index ab9d5be45..921595429 100644
--- a/packages/ui/app/_components/dialogs/manage/index.tsx
+++ b/packages/ui/app/_components/dialogs/manage/index.tsx
@@ -1,37 +1,17 @@
'use client';
-import { useEffect, useMemo, useState } from 'react';
+import { useState } from 'react';
import dynamic from 'next/dynamic';
-import Image from 'next/image';
-import { type Address, formatEther, formatUnits } from 'viem';
+import { type Address } from 'viem';
import { useChainId } from 'wagmi';
-import { Dialog, DialogContent } from '@ui/components/ui/dialog';
-import {
- Tabs,
- TabsList,
- TabsTrigger,
- TabsContent
-} from '@ui/components/ui/tabs';
-import {
- ManageDialogProvider,
- useManageDialogContext
-} from '@ui/context/ManageDialogContext';
-import { useBorrowCapsDataForAsset } from '@ui/hooks/ionic/useBorrowCapsDataForAsset';
-import { useSupplyCapsDataForAsset } from '@ui/hooks/ionic/useSupplyCapsDataForPool';
-import { useUsdPrice } from '@ui/hooks/useAllUsdPrices';
-import { useMaxBorrowAmount } from '@ui/hooks/useMaxBorrowAmount';
-import { useMaxRepayAmount } from '@ui/hooks/useMaxRepayAmount';
+import { ManageDialogProvider } from '@ui/context/ManageDialogContext';
import { useMaxSupplyAmount } from '@ui/hooks/useMaxSupplyAmount';
-import { useMaxWithdrawAmount } from '@ui/hooks/useMaxWithdrawAmount';
import type { MarketData } from '@ui/types/TokensDataMap';
-import BorrowTab from './BorrowTab';
-import RepayTab from './RepayTab';
-import SupplyTab from './SupplyTab';
-import WithdrawTab from './WithdrawTab';
-import AnimateHeight from '../../AnimateHeight';
+import DialogWrapper from './DialogWrapper';
+import ManageDialogTabs from './ManageDialogTabs';
const SwapWidget = dynamic(() => import('../../markets/SwapWidget'), {
ssr: false
@@ -46,7 +26,7 @@ export enum HFPStatus {
WARNING = 'WARNING'
}
-interface IPopup {
+interface ManageDialogProps {
isOpen: boolean;
setIsOpen: (open: boolean) => void;
comptrollerAddress: Address;
@@ -62,214 +42,37 @@ const ManageDialog = ({
comptrollerAddress,
isBorrowDisabled = false,
activeTab = 'supply'
-}: IPopup) => {
+}: ManageDialogProps) => {
const [swapWidgetOpen, setSwapWidgetOpen] = useState(false);
const chainId = useChainId();
- const { data: usdPrice } = useUsdPrice(chainId.toString());
const [currentActiveTab, setCurrentActiveTab] =
useState(activeTab);
-
- const pricePerSingleAsset = useMemo(
- () =>
- parseFloat(formatEther(selectedMarketData.underlyingPrice)) *
- (usdPrice ?? 0),
- [selectedMarketData, usdPrice]
- );
- const { data: supplyCap } = useSupplyCapsDataForAsset(
+ const { refetch: refetchMaxSupplyAmount } = useMaxSupplyAmount(
+ selectedMarketData,
comptrollerAddress,
- selectedMarketData.cToken,
- chainId
- );
- const supplyCapAsNumber = useMemo(
- () =>
- parseFloat(
- formatUnits(
- supplyCap?.supplyCaps ?? 0n,
- selectedMarketData.underlyingDecimals
- )
- ),
- [supplyCap, selectedMarketData.underlyingDecimals]
- );
- const supplyCapAsFiat = useMemo(
- () => pricePerSingleAsset * supplyCapAsNumber,
- [pricePerSingleAsset, supplyCapAsNumber]
- );
- const totalSupplyAsNumber = useMemo(
- () =>
- parseFloat(
- formatUnits(
- selectedMarketData.totalSupply,
- selectedMarketData.underlyingDecimals
- )
- ),
- [selectedMarketData.totalSupply, selectedMarketData.underlyingDecimals]
- );
- const { data: borrowCap } = useBorrowCapsDataForAsset(
- selectedMarketData.cToken,
chainId
);
- const borrowCapAsNumber = useMemo(
- () =>
- parseFloat(
- formatUnits(
- borrowCap?.totalBorrowCap ?? 0n,
- selectedMarketData.underlyingDecimals
- )
- ),
- [borrowCap, selectedMarketData.underlyingDecimals]
- );
- const borrowCapAsFiat = useMemo(
- () => pricePerSingleAsset * borrowCapAsNumber,
- [pricePerSingleAsset, borrowCapAsNumber]
- );
- const totalBorrowAsNumber = useMemo(
- () =>
- parseFloat(
- formatUnits(
- selectedMarketData.totalBorrow,
- selectedMarketData.underlyingDecimals
- )
- ),
- [selectedMarketData.totalBorrow, selectedMarketData.underlyingDecimals]
- );
-
- const {
- data: maxSupplyAmount,
- isLoading: isLoadingMaxSupply,
- refetch: refetchMaxSupplyAmount
- } = useMaxSupplyAmount(selectedMarketData, comptrollerAddress, chainId);
- const { data: maxRepayAmount, isLoading: isLoadingMaxRepayAmount } =
- useMaxRepayAmount(selectedMarketData, chainId);
- const { data: maxBorrowAmount, isLoading: isLoadingMaxBorrowAmount } =
- useMaxBorrowAmount(selectedMarketData, comptrollerAddress, chainId);
- const { data: maxWithdrawAmount, isLoading: isLoadingMaxWithdrawAmount } =
- useMaxWithdrawAmount(selectedMarketData, chainId);
-
- const TabsWithContext = ({
- isBorrowDisabled
- }: {
- isBorrowDisabled: boolean;
- }) => {
- const { setActive } = useManageDialogContext();
-
- // Handle tab change with persistence
- const handleTabChange = (value: string) => {
- const newTab = value as ActiveTab;
- setCurrentActiveTab(newTab);
- setActive(newTab);
- };
-
- return (
-
-
-
- Supply
-
- Borrow
-
-
- Repay
-
- Withdraw
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- };
return (
setIsOpen(false)}
selectedMarketData={selectedMarketData}
>
-
+
+
setSwapWidgetOpen(false)}
diff --git a/packages/ui/context/ManageDialogContext.tsx b/packages/ui/context/ManageDialogContext.tsx
index ef10a2c22..2ae312213 100644
--- a/packages/ui/context/ManageDialogContext.tsx
+++ b/packages/ui/context/ManageDialogContext.tsx
@@ -12,10 +12,7 @@ import { useQueryClient } from '@tanstack/react-query';
import { type Address, formatUnits } from 'viem';
import { useChainId } from 'wagmi';
-import {
- TransactionStep,
- useTransactionSteps
-} from '@ui/app/_components/dialogs/manage/TransactionStepsHandler';
+import type { TransactionStep } from '@ui/app/_components/dialogs/manage/TransactionStepsHandler';
import { useMultiIonic } from '@ui/context/MultiIonicContext';
import useUpdatedUserAssets from '@ui/hooks/ionic/useUpdatedUserAssets';
import type { MarketData } from '@ui/types/TokensDataMap';
@@ -101,9 +98,8 @@ const ManageDialogContext = createContext(
export const ManageDialogProvider: React.FC<{
selectedMarketData: MarketData;
comptrollerAddress: Address;
- closePopup: () => void;
children: React.ReactNode;
-}> = ({ selectedMarketData, comptrollerAddress, closePopup, children }) => {
+}> = ({ selectedMarketData, comptrollerAddress, children }) => {
const { currentSdk } = useMultiIonic();
const chainId = useChainId();
const [active, setActive] = useState('supply');
@@ -146,24 +142,26 @@ export const ManageDialogProvider: React.FC<{
const queryClient = useQueryClient();
- const refetchUsedQueries = async () => {
- queryClient.invalidateQueries({ queryKey: ['useFusePoolData'] });
- queryClient.invalidateQueries({ queryKey: ['useBorrowMinimum'] });
- queryClient.invalidateQueries({ queryKey: ['useUsdPrice'] });
- queryClient.invalidateQueries({ queryKey: ['useAllUsdPrices'] });
- queryClient.invalidateQueries({ queryKey: ['useTotalSupplyAPYs'] });
- queryClient.invalidateQueries({ queryKey: ['useUpdatedUserAssets'] });
- queryClient.invalidateQueries({ queryKey: ['useMaxSupplyAmount'] });
- queryClient.invalidateQueries({ queryKey: ['useMaxWithdrawAmount'] });
- queryClient.invalidateQueries({ queryKey: ['useMaxBorrowAmount'] });
- queryClient.invalidateQueries({ queryKey: ['useMaxRepayAmount'] });
- queryClient.invalidateQueries({
- queryKey: ['useSupplyCapsDataForPool']
- });
- queryClient.invalidateQueries({
- queryKey: ['useBorrowCapsDataForAsset']
+ const refetchUsedQueries = useCallback(async () => {
+ const queryKeys = [
+ 'useFusePoolData',
+ 'useBorrowMinimum',
+ 'useUsdPrice',
+ 'useAllUsdPrices',
+ 'useTotalSupplyAPYs',
+ 'useUpdatedUserAssets',
+ 'useMaxSupplyAmount',
+ 'useMaxWithdrawAmount',
+ 'useMaxBorrowAmount',
+ 'useMaxRepayAmount',
+ 'useSupplyCapsDataForPool',
+ 'useBorrowCapsDataForAsset'
+ ];
+
+ queryKeys.forEach((key) => {
+ queryClient.invalidateQueries({ queryKey: [key] });
});
- };
+ }, [queryClient]);
const updatedValues = useMemo(() => {
const blocksPerMinute = getBlockTimePerMinuteByChainId(chainId);