@b3dotfun/sdk 0.0.30 → 0.0.31-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/anyspend/react/components/AnySpend.js +1 -1
- package/dist/cjs/anyspend/react/components/AnySpendBuySpin.js +2 -1
- package/dist/cjs/anyspend/react/components/AnySpendStakeB3.js +2 -1
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.d.ts +4 -0
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +6 -1
- package/dist/cjs/anyspend/react/components/common/ChainTokenIcon.d.ts +1 -1
- package/dist/cjs/anyspend/react/components/common/ChainTokenIcon.js +2 -1
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +23 -28
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +2 -2
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +5 -5
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +1 -1
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +4 -1
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +3 -3
- package/dist/cjs/anyspend/react/components/common/PaySection.js +1 -1
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +2 -5
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +5 -0
- package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.js +1 -0
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.d.ts +6 -0
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +94 -0
- package/dist/cjs/global-account/react/components/ManageAccount/ContentTokens.d.ts +14 -0
- package/dist/cjs/global-account/react/components/ManageAccount/ContentTokens.js +272 -0
- package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +9 -51
- package/dist/cjs/global-account/react/components/ManageAccount/TokenBalanceRow.d.ts +10 -0
- package/dist/cjs/global-account/react/components/ManageAccount/TokenBalanceRow.js +8 -0
- package/dist/cjs/global-account/react/components/TokenIcon.d.ts +11 -0
- package/dist/cjs/global-account/react/components/TokenIcon.js +43 -0
- package/dist/cjs/global-account/react/components/ui/accordion.d.ts +7 -0
- package/dist/cjs/global-account/react/components/ui/accordion.js +53 -0
- package/dist/cjs/global-account/react/components/ui/dialog.js +1 -1
- package/dist/cjs/global-account/react/hooks/index.d.ts +2 -0
- package/dist/cjs/global-account/react/hooks/index.js +5 -1
- package/dist/cjs/global-account/react/hooks/useAnalytics.d.ts +7 -0
- package/dist/cjs/global-account/react/hooks/useAnalytics.js +29 -0
- package/dist/cjs/global-account/react/hooks/useB3BalanceFromAddresses.js +2 -1
- package/dist/cjs/global-account/react/hooks/useNativeBalance.js +2 -1
- package/dist/cjs/global-account/react/hooks/useSimBalance.d.ts +24 -0
- package/dist/cjs/global-account/react/hooks/useSimBalance.js +29 -0
- package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +2 -1
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +2 -2
- package/dist/cjs/global-account/react/utils/profileDisplay.js +9 -0
- package/dist/cjs/global-account/utils/analytics.d.ts +16 -0
- package/dist/cjs/global-account/utils/analytics.js +55 -0
- package/dist/cjs/shared/constants/index.d.ts +1 -0
- package/dist/cjs/shared/constants/index.js +2 -1
- package/dist/cjs/shared/generated/chain-networks.json +185 -17
- package/dist/esm/anyspend/react/components/AnySpend.js +1 -1
- package/dist/esm/anyspend/react/components/AnySpendBuySpin.js +2 -1
- package/dist/esm/anyspend/react/components/AnySpendStakeB3.js +2 -1
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.d.ts +4 -0
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +5 -1
- package/dist/esm/anyspend/react/components/common/ChainTokenIcon.d.ts +1 -1
- package/dist/esm/anyspend/react/components/common/ChainTokenIcon.js +2 -1
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +22 -27
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +2 -2
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +5 -5
- package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +1 -1
- package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +4 -1
- package/dist/esm/anyspend/react/components/common/PanelOnramp.js +4 -4
- package/dist/esm/anyspend/react/components/common/PaySection.js +1 -1
- package/dist/esm/global-account/react/components/B3DynamicModal.js +2 -5
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +5 -0
- package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.js +1 -0
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.d.ts +6 -0
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +88 -0
- package/dist/esm/global-account/react/components/ManageAccount/ContentTokens.d.ts +14 -0
- package/dist/esm/global-account/react/components/ManageAccount/ContentTokens.js +266 -0
- package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +12 -51
- package/dist/esm/global-account/react/components/ManageAccount/TokenBalanceRow.d.ts +10 -0
- package/dist/esm/global-account/react/components/ManageAccount/TokenBalanceRow.js +5 -0
- package/dist/esm/global-account/react/components/TokenIcon.d.ts +11 -0
- package/dist/esm/global-account/react/components/TokenIcon.js +37 -0
- package/dist/esm/global-account/react/components/ui/accordion.d.ts +7 -0
- package/dist/esm/global-account/react/components/ui/accordion.js +14 -0
- package/dist/esm/global-account/react/components/ui/dialog.js +1 -1
- package/dist/esm/global-account/react/hooks/index.d.ts +2 -0
- package/dist/esm/global-account/react/hooks/index.js +2 -0
- package/dist/esm/global-account/react/hooks/useAnalytics.d.ts +7 -0
- package/dist/esm/global-account/react/hooks/useAnalytics.js +26 -0
- package/dist/esm/global-account/react/hooks/useB3BalanceFromAddresses.js +2 -1
- package/dist/esm/global-account/react/hooks/useNativeBalance.js +2 -1
- package/dist/esm/global-account/react/hooks/useSimBalance.d.ts +24 -0
- package/dist/esm/global-account/react/hooks/useSimBalance.js +26 -0
- package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +2 -1
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +2 -2
- package/dist/esm/global-account/react/utils/profileDisplay.js +9 -0
- package/dist/esm/global-account/utils/analytics.d.ts +16 -0
- package/dist/esm/global-account/utils/analytics.js +50 -0
- package/dist/esm/shared/constants/index.d.ts +1 -0
- package/dist/esm/shared/constants/index.js +1 -0
- package/dist/esm/shared/generated/chain-networks.json +185 -17
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/react/components/AnyspendDepositHype.d.ts +4 -0
- package/dist/types/anyspend/react/components/common/ChainTokenIcon.d.ts +1 -1
- package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
- package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +4 -1
- package/dist/types/global-account/react/components/ManageAccount/BalanceContent.d.ts +6 -0
- package/dist/types/global-account/react/components/ManageAccount/ContentTokens.d.ts +14 -0
- package/dist/types/global-account/react/components/ManageAccount/TokenBalanceRow.d.ts +10 -0
- package/dist/types/global-account/react/components/TokenIcon.d.ts +11 -0
- package/dist/types/global-account/react/components/ui/accordion.d.ts +7 -0
- package/dist/types/global-account/react/hooks/index.d.ts +2 -0
- package/dist/types/global-account/react/hooks/useAnalytics.d.ts +7 -0
- package/dist/types/global-account/react/hooks/useSimBalance.d.ts +24 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +2 -2
- package/dist/types/global-account/utils/analytics.d.ts +16 -0
- package/dist/types/shared/constants/index.d.ts +1 -0
- package/package.json +10 -18
- package/src/anyspend/react/components/AnySpend.tsx +1 -0
- package/src/anyspend/react/components/AnySpendBuySpin.tsx +2 -1
- package/src/anyspend/react/components/AnySpendStakeB3.tsx +3 -2
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +10 -0
- package/src/anyspend/react/components/AnyspendSignatureMint.tsx +4 -4
- package/src/anyspend/react/components/common/ChainTokenIcon.tsx +8 -2
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +56 -107
- package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +12 -3
- package/src/anyspend/react/components/common/OrderDetails.tsx +5 -5
- package/src/anyspend/react/components/common/OrderTokenAmount.tsx +2 -2
- package/src/anyspend/react/components/common/PanelOnramp.tsx +11 -5
- package/src/anyspend/react/components/common/PaySection.tsx +1 -1
- package/src/global-account/react/components/B3DynamicModal.tsx +8 -7
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +6 -0
- package/src/global-account/react/components/LinkAccount/LinkAccount.tsx +2 -1
- package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +228 -0
- package/src/global-account/react/components/ManageAccount/ContentTokens.tsx +568 -0
- package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +86 -341
- package/src/global-account/react/components/ManageAccount/TokenBalanceRow.tsx +46 -0
- package/src/global-account/react/components/TokenIcon.tsx +87 -0
- package/src/global-account/react/components/ui/accordion.tsx +53 -0
- package/src/global-account/react/components/ui/dialog.tsx +1 -1
- package/src/global-account/react/hooks/index.ts +2 -0
- package/src/global-account/react/hooks/useAccountAssets.ts +1 -0
- package/src/global-account/react/hooks/useAnalytics.tsx +30 -0
- package/src/global-account/react/hooks/useB3BalanceFromAddresses.ts +3 -2
- package/src/global-account/react/hooks/useNativeBalance.tsx +2 -1
- package/src/global-account/react/hooks/useSimBalance.ts +56 -0
- package/src/global-account/react/hooks/useUnifiedChainSwitchAndExecute.ts +3 -1
- package/src/global-account/react/stores/useModalStore.ts +2 -2
- package/src/global-account/react/utils/profileDisplay.ts +9 -0
- package/src/global-account/utils/analytics.ts +64 -0
- package/src/shared/constants/index.ts +2 -0
- package/src/shared/generated/chain-networks.json +185 -17
- package/src/{anyspend/types → types}/window.d.ts +5 -1
- package/dist/cjs/index.d.ts +0 -0
- package/dist/cjs/index.js +0 -2
- package/dist/esm/index.d.ts +0 -0
- package/dist/esm/index.js +0 -2
- package/dist/types/index.d.ts +0 -0
- package/src/index.ts +0 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BalanceContent = BalanceContent;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = require("../../../../global-account/react");
|
|
9
|
+
const BankIcon_1 = require("../../../../global-account/react/components/icons/BankIcon");
|
|
10
|
+
const SignOutIcon_1 = require("../../../../global-account/react/components/icons/SignOutIcon");
|
|
11
|
+
const SwapIcon_1 = require("../../../../global-account/react/components/icons/SwapIcon");
|
|
12
|
+
const utils_1 = require("../../../../shared/utils");
|
|
13
|
+
const lucide_react_1 = require("lucide-react");
|
|
14
|
+
const react_2 = require("react");
|
|
15
|
+
const react_3 = require("thirdweb/react");
|
|
16
|
+
const useFirstEOA_1 = __importDefault(require("../../hooks/useFirstEOA"));
|
|
17
|
+
const TokenIcon_1 = require("../TokenIcon");
|
|
18
|
+
const accordion_1 = require("../ui/accordion");
|
|
19
|
+
const TokenBalanceRow_1 = require("./TokenBalanceRow");
|
|
20
|
+
function centerTruncate(str, length = 4) {
|
|
21
|
+
if (str.length <= length * 2)
|
|
22
|
+
return str;
|
|
23
|
+
return `${str.slice(0, length)}...${str.slice(-length)}`;
|
|
24
|
+
}
|
|
25
|
+
function BalanceContent({ onLogout, partnerId }) {
|
|
26
|
+
const account = (0, react_3.useActiveAccount)();
|
|
27
|
+
const { address: eoaAddress, info: eoaInfo } = (0, useFirstEOA_1.default)();
|
|
28
|
+
const { data: profile } = (0, react_1.useProfile)({
|
|
29
|
+
address: eoaAddress || account?.address,
|
|
30
|
+
fresh: true,
|
|
31
|
+
});
|
|
32
|
+
const { setB3ModalOpen, setB3ModalContentType } = (0, react_1.useModalStore)();
|
|
33
|
+
const { logout } = (0, react_1.useAuthentication)(partnerId);
|
|
34
|
+
const [logoutLoading, setLogoutLoading] = (0, react_2.useState)(false);
|
|
35
|
+
const [openAccordions, setOpenAccordions] = (0, react_2.useState)([]);
|
|
36
|
+
const hasExpandedRef = (0, react_2.useRef)(false);
|
|
37
|
+
console.log("eoaAddress", eoaAddress);
|
|
38
|
+
console.log("account?.address", account?.address);
|
|
39
|
+
// Balance data fetching
|
|
40
|
+
const { data: eoaNativeBalance, isLoading: eoaNativeLoading } = (0, react_1.useNativeBalance)(eoaAddress);
|
|
41
|
+
const { data: eoaB3Balance, isLoading: eoaB3Loading } = (0, react_1.useB3BalanceFromAddresses)(eoaAddress);
|
|
42
|
+
const { data: b3Balance, isLoading: b3Loading } = (0, react_1.useB3BalanceFromAddresses)(account?.address);
|
|
43
|
+
const { data: nativeBalance, isLoading: nativeLoading } = (0, react_1.useNativeBalance)(account?.address);
|
|
44
|
+
// Calculate total USD values for comparison
|
|
45
|
+
const globalAccountTotalUsd = (b3Balance?.balanceUsd || 0) + (nativeBalance?.totalUsd || 0);
|
|
46
|
+
const eoaTotalUsd = (eoaB3Balance?.balanceUsd || 0) + (eoaNativeBalance?.totalUsd || 0);
|
|
47
|
+
// Check if both data sets are ready (not loading and have data)
|
|
48
|
+
const isGlobalDataReady = !b3Loading && !nativeLoading && b3Balance !== undefined && nativeBalance !== undefined;
|
|
49
|
+
const isEoaDataReady = !eoaAddress || (!eoaB3Loading && !eoaNativeLoading && eoaB3Balance !== undefined && eoaNativeBalance !== undefined);
|
|
50
|
+
const isBothDataReady = isGlobalDataReady && isEoaDataReady;
|
|
51
|
+
// Reset expansion flag when component mounts
|
|
52
|
+
(0, react_2.useEffect)(() => {
|
|
53
|
+
hasExpandedRef.current = false;
|
|
54
|
+
setOpenAccordions([]);
|
|
55
|
+
}, []);
|
|
56
|
+
// Auto-expand the appropriate section when data becomes ready
|
|
57
|
+
(0, react_2.useEffect)(() => {
|
|
58
|
+
if (isBothDataReady && !hasExpandedRef.current && eoaAddress && account?.address) {
|
|
59
|
+
hasExpandedRef.current = true;
|
|
60
|
+
// Determine which section to expand based on higher balance
|
|
61
|
+
if (globalAccountTotalUsd === 0 && eoaTotalUsd === 0) {
|
|
62
|
+
// If both have 0 balance, expand global account by default
|
|
63
|
+
setOpenAccordions(["global-account"]);
|
|
64
|
+
}
|
|
65
|
+
else if (globalAccountTotalUsd >= eoaTotalUsd) {
|
|
66
|
+
setOpenAccordions(["global-account"]);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
setOpenAccordions(["eoa-account"]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}, [isBothDataReady, globalAccountTotalUsd, eoaTotalUsd, eoaAddress, account?.address]);
|
|
73
|
+
const onLogoutEnhanced = async () => {
|
|
74
|
+
setLogoutLoading(true);
|
|
75
|
+
await logout();
|
|
76
|
+
onLogout?.();
|
|
77
|
+
setB3ModalOpen(false);
|
|
78
|
+
setLogoutLoading(false);
|
|
79
|
+
};
|
|
80
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-between", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [profile?.avatar ? ((0, jsx_runtime_1.jsx)("img", { src: profile?.avatar, alt: "Profile", className: "size-24 rounded-full" })) : ((0, jsx_runtime_1.jsx)("div", { className: "bg-b3-primary-wash size-24 rounded-full" })), (0, jsx_runtime_1.jsx)("div", { className: "bg-b3-grey border-b3-background absolute -bottom-1 -right-1 flex size-8 items-center justify-center rounded-full border-4", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Pencil, { size: 16, className: "text-b3-background" }) })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-b3-grey text-xl font-semibold", children: profile?.displayName || (0, utils_1.formatUsername)(profile?.name || "") }), (0, jsx_runtime_1.jsxs)("div", { className: "border-b3-line bg-b3-line/20 hover:bg-b3-line/40 flex w-fit items-center gap-2 rounded-full border px-3 py-1 transition-colors", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-mono text-xs", children: centerTruncate(account?.address || "", 6) }), (0, jsx_runtime_1.jsx)(react_1.CopyToClipboard, { text: account?.address || "" })] })] })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [(0, jsx_runtime_1.jsxs)(react_1.Button, { className: "manage-account-deposit bg-b3-primary-wash hover:bg-b3-primary-wash/70 h-[84px] w-full flex-col items-start gap-2 rounded-2xl", onClick: () => {
|
|
81
|
+
setB3ModalOpen(true);
|
|
82
|
+
setB3ModalContentType({
|
|
83
|
+
type: "anySpend",
|
|
84
|
+
defaultActiveTab: "fiat",
|
|
85
|
+
showBackButton: true,
|
|
86
|
+
});
|
|
87
|
+
}, children: [(0, jsx_runtime_1.jsx)(BankIcon_1.BankIcon, { size: 24, className: "text-b3-primary-blue shrink-0" }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: "Deposit" })] }), (0, jsx_runtime_1.jsxs)(react_1.Button, { className: "manage-account-swap bg-b3-primary-wash hover:bg-b3-primary-wash/70 flex h-[84px] w-full flex-col items-start gap-2 rounded-2xl", onClick: () => {
|
|
88
|
+
setB3ModalOpen(true);
|
|
89
|
+
setB3ModalContentType({
|
|
90
|
+
type: "anySpend",
|
|
91
|
+
showBackButton: true,
|
|
92
|
+
});
|
|
93
|
+
}, children: [(0, jsx_runtime_1.jsx)(SwapIcon_1.SwapIcon, { size: 24, className: "text-b3-primary-blue" }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: "Swap" })] })] }), (0, jsx_runtime_1.jsxs)(accordion_1.Accordion, { type: "multiple", value: openAccordions, onValueChange: setOpenAccordions, className: "space-y-2", children: [(0, jsx_runtime_1.jsxs)(accordion_1.AccordionItem, { value: "global-account", className: "border-none", children: [(0, jsx_runtime_1.jsx)(accordion_1.AccordionTrigger, { className: "text-b3-grey font-neue-montreal-semibold py-2 hover:no-underline", children: (0, jsx_runtime_1.jsx)("span", { children: "Balance" }) }), (0, jsx_runtime_1.jsxs)(accordion_1.AccordionContent, { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)(TokenBalanceRow_1.TokenBalanceRow, { icon: (0, jsx_runtime_1.jsx)(TokenIcon_1.B3TokenIcon, { className: "size-10" }), name: "B3", balance: `${b3Balance?.formattedTotal || "0.00"} B3`, usdValue: b3Balance?.balanceUsdFormatted || "0.00", priceChange: b3Balance?.priceChange24h }), (0, jsx_runtime_1.jsx)(TokenBalanceRow_1.TokenBalanceRow, { icon: (0, jsx_runtime_1.jsx)(TokenIcon_1.EthereumTokenIcon, { className: "size-10" }), name: "Ethereum", balance: `${nativeBalance?.formattedTotal || "0.00"} ETH`, usdValue: nativeBalance?.formattedTotalUsd || "0.00", priceChange: nativeBalance?.priceChange24h })] })] }), eoaAddress && ((0, jsx_runtime_1.jsxs)(accordion_1.AccordionItem, { value: "eoa-account", className: "border-none", children: [(0, jsx_runtime_1.jsx)(accordion_1.AccordionTrigger, { className: "text-b3-grey font-neue-montreal-semibold py-2 hover:no-underline", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsxs)("span", { children: ["Connected ", eoaInfo?.data?.name || "Wallet"] }), (0, jsx_runtime_1.jsxs)("div", { className: "border-b3-line bg-b3-line/20 hover:bg-b3-line/40 flex w-fit items-center gap-2 rounded-full border px-3 py-1 transition-colors", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-mono text-xs", children: centerTruncate(eoaAddress, 6) }), (0, jsx_runtime_1.jsx)(react_1.CopyToClipboard, { text: eoaAddress })] })] }) }), (0, jsx_runtime_1.jsxs)(accordion_1.AccordionContent, { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)(TokenBalanceRow_1.TokenBalanceRow, { icon: (0, jsx_runtime_1.jsx)(TokenIcon_1.B3TokenIcon, { className: "size-10" }), name: "B3", balance: `${eoaB3Balance?.formattedTotal || "0.00"} B3`, usdValue: eoaB3Balance?.balanceUsdFormatted || "0.00", priceChange: eoaB3Balance?.priceChange24h }), (0, jsx_runtime_1.jsx)(TokenBalanceRow_1.TokenBalanceRow, { icon: (0, jsx_runtime_1.jsx)(TokenIcon_1.EthereumTokenIcon, { className: "size-10" }), name: "Ethereum", balance: `${eoaNativeBalance?.formattedTotal || "0.00"} ETH`, usdValue: eoaNativeBalance?.formattedTotalUsd || "0.00", priceChange: eoaNativeBalance?.priceChange24h })] })] }))] }), (0, jsx_runtime_1.jsxs)("button", { className: "border-b3-line hover:bg-b3-line relative flex w-full items-center justify-center rounded-2xl border p-4 transition-colors", onClick: onLogoutEnhanced, children: [(0, jsx_runtime_1.jsx)("span", { className: "font-neue-montreal-semibold text-b3-grey", children: "Sign out" }), (0, jsx_runtime_1.jsx)("div", { className: "absolute right-4", children: logoutLoading ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin", size: 16 })) : ((0, jsx_runtime_1.jsx)(SignOutIcon_1.SignOutIcon, { size: 16, className: "text-b3-grey" })) })] })] }));
|
|
94
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface ContentTokensProps {
|
|
2
|
+
activeTab: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* ContentTokens Component
|
|
6
|
+
*
|
|
7
|
+
* Displays user's token balances with ability to send tokens. Features:
|
|
8
|
+
* - Animated transitions between token list and send form
|
|
9
|
+
* - Smart filtering (shows all tokens when ≤5 valuable tokens or no $1+ tokens)
|
|
10
|
+
* - NumericFormat inputs for proper number handling
|
|
11
|
+
* - Focus preservation during transitions (see render functions pattern below)
|
|
12
|
+
*/
|
|
13
|
+
export declare function ContentTokens({ activeTab }: ContentTokensProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ContentTokens = ContentTokens;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const anyspend_1 = require("../../../../anyspend");
|
|
9
|
+
const ChainTokenIcon_1 = require("../../../../anyspend/react/components/common/ChainTokenIcon");
|
|
10
|
+
const react_1 = require("../../../../global-account/react");
|
|
11
|
+
const number_1 = require("../../../../shared/utils/number");
|
|
12
|
+
const lucide_react_1 = require("lucide-react");
|
|
13
|
+
const react_2 = require("react");
|
|
14
|
+
const react_number_format_1 = require("react-number-format");
|
|
15
|
+
const sonner_1 = require("sonner");
|
|
16
|
+
const react_3 = require("thirdweb/react");
|
|
17
|
+
const viem_1 = require("viem");
|
|
18
|
+
const invariant_1 = __importDefault(require("invariant"));
|
|
19
|
+
// Panel view enum for managing navigation between token list and send form
|
|
20
|
+
var TokenPanelView;
|
|
21
|
+
(function (TokenPanelView) {
|
|
22
|
+
TokenPanelView[TokenPanelView["LIST"] = 0] = "LIST";
|
|
23
|
+
TokenPanelView[TokenPanelView["SEND"] = 1] = "SEND";
|
|
24
|
+
})(TokenPanelView || (TokenPanelView = {}));
|
|
25
|
+
/**
|
|
26
|
+
* ContentTokens Component
|
|
27
|
+
*
|
|
28
|
+
* Displays user's token balances with ability to send tokens. Features:
|
|
29
|
+
* - Animated transitions between token list and send form
|
|
30
|
+
* - Smart filtering (shows all tokens when ≤5 valuable tokens or no $1+ tokens)
|
|
31
|
+
* - NumericFormat inputs for proper number handling
|
|
32
|
+
* - Focus preservation during transitions (see render functions pattern below)
|
|
33
|
+
*/
|
|
34
|
+
function ContentTokens({ activeTab }) {
|
|
35
|
+
// === TOKEN FILTERING STATE ===
|
|
36
|
+
const [showAllTokens, setShowAllTokens] = (0, react_2.useState)(false);
|
|
37
|
+
// === NAVIGATION STATE ===
|
|
38
|
+
const [tokenPanelView, setTokenPanelView] = (0, react_2.useState)(TokenPanelView.LIST);
|
|
39
|
+
// === SEND FORM STATE ===
|
|
40
|
+
const [selectedToken, setSelectedToken] = (0, react_2.useState)(null);
|
|
41
|
+
const [recipientAddress, setRecipientAddress] = (0, react_2.useState)("");
|
|
42
|
+
const [sendAmount, setSendAmount] = (0, react_2.useState)("");
|
|
43
|
+
const [isSending, setIsSending] = (0, react_2.useState)(false);
|
|
44
|
+
const [addressError, setAddressError] = (0, react_2.useState)("");
|
|
45
|
+
// === ANIMATION STATE ===
|
|
46
|
+
// CRITICAL: useRef for animation direction prevents component remounting
|
|
47
|
+
// This ensures input focus is preserved during panel transitions
|
|
48
|
+
const animationDirection = (0, react_2.useRef)(null);
|
|
49
|
+
// === DATA FETCHING ===
|
|
50
|
+
const account = (0, react_3.useActiveAccount)();
|
|
51
|
+
const { data: simBalance, refetch: refetchSimBalance, isLoading: isLoadingBalance } = (0, react_1.useSimBalance)(account?.address);
|
|
52
|
+
// === BLOCKCHAIN INTERACTION ===
|
|
53
|
+
const { switchChainAndExecute } = (0, react_1.useUnifiedChainSwitchAndExecute)();
|
|
54
|
+
// === ANALYTICS ===
|
|
55
|
+
const { sendAnalyticsEvent } = (0, react_1.useAnalytics)();
|
|
56
|
+
// === ADDRESS VALIDATION ===
|
|
57
|
+
// Handle recipient address change with real-time validation using viem
|
|
58
|
+
const handleRecipientAddressChange = (value) => {
|
|
59
|
+
setRecipientAddress(value);
|
|
60
|
+
// Only show error if user has typed something and it's invalid
|
|
61
|
+
// Using viem's isAddress for robust EVM address validation
|
|
62
|
+
if (value && !(0, viem_1.isAddress)(value)) {
|
|
63
|
+
setAddressError("Please enter a valid EVM address (0x...)");
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
setAddressError("");
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
// === TAB RESET EFFECT ===
|
|
70
|
+
// Reset all state when user switches away from tokens tab
|
|
71
|
+
(0, react_2.useEffect)(() => {
|
|
72
|
+
if (activeTab !== "tokens") {
|
|
73
|
+
setTokenPanelView(TokenPanelView.LIST);
|
|
74
|
+
setSelectedToken(null);
|
|
75
|
+
setRecipientAddress("");
|
|
76
|
+
setSendAmount("");
|
|
77
|
+
setIsSending(false);
|
|
78
|
+
setAddressError("");
|
|
79
|
+
animationDirection.current = null;
|
|
80
|
+
}
|
|
81
|
+
}, [activeTab]);
|
|
82
|
+
// === HELPER FUNCTION ===
|
|
83
|
+
// Get current version of selected token from fresh balance data
|
|
84
|
+
// 🔧 FIX: Prevents auto-navigation back to token list when balance refreshes
|
|
85
|
+
// The useSimBalance hook refreshes data, creating new token object references
|
|
86
|
+
// This helper ensures we always get the fresh token data instead of stale references
|
|
87
|
+
const getCurrentSelectedToken = () => {
|
|
88
|
+
if (!selectedToken || !simBalance?.balances) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const found = simBalance.balances.find(token => token.chain_id === selectedToken.chain_id && token.address === selectedToken.address);
|
|
92
|
+
return found || null;
|
|
93
|
+
};
|
|
94
|
+
// ==================================================================================
|
|
95
|
+
// === RENDER FUNCTIONS (NOT COMPONENTS!) ===
|
|
96
|
+
// ==================================================================================
|
|
97
|
+
//
|
|
98
|
+
// 🚨 CRITICAL ARCHITECTURE DECISION:
|
|
99
|
+
// These are render functions, NOT component functions with useCallback!
|
|
100
|
+
//
|
|
101
|
+
// WHY THIS WORKS:
|
|
102
|
+
// ✅ Stable wrapper <div> elements with consistent keys
|
|
103
|
+
// ✅ React never sees these as "new components"
|
|
104
|
+
// ✅ Input focus is preserved during transitions
|
|
105
|
+
// ✅ No component remounting issues
|
|
106
|
+
//
|
|
107
|
+
// WHY useCallback DIDN'T WORK:
|
|
108
|
+
// ❌ useCallback(() => <JSX />, [deps]) still creates new component instances
|
|
109
|
+
// ❌ React treats each render as a different component
|
|
110
|
+
// ❌ Causes remounting and focus loss
|
|
111
|
+
//
|
|
112
|
+
// THE PATTERN:
|
|
113
|
+
// Instead of: {[<ComponentA />, <ComponentB />]}
|
|
114
|
+
// We use: {[<div key="a">{renderA()}</div>, <div key="b">{renderB()}</div>]}
|
|
115
|
+
// ==================================================================================
|
|
116
|
+
/**
|
|
117
|
+
* Renders the send token form panel
|
|
118
|
+
* Includes recipient input, amount input with NumericFormat, and percentage buttons
|
|
119
|
+
*/
|
|
120
|
+
const renderSendTokenPanel = () => {
|
|
121
|
+
// Get fresh token data to prevent stale references
|
|
122
|
+
const currentToken = getCurrentSelectedToken();
|
|
123
|
+
// 🔧 SINGLE FALLBACK STRATEGY:
|
|
124
|
+
// Use fresh token data when available, fall back to selectedToken if needed
|
|
125
|
+
// This prevents duplication of "currentToken || selectedToken" throughout the component
|
|
126
|
+
const displayToken = currentToken || selectedToken;
|
|
127
|
+
// Handle percentage button clicks (25%, 50%, 75%, 100%)
|
|
128
|
+
const handlePercentageClick = (percentage) => {
|
|
129
|
+
if (displayToken) {
|
|
130
|
+
const tokenBalance = (BigInt(displayToken.amount) * BigInt(percentage)) / BigInt(100);
|
|
131
|
+
const amount = (0, number_1.formatTokenAmount)(tokenBalance, displayToken.decimals, 30, false);
|
|
132
|
+
setSendAmount(amount);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
// Execute token transfer transaction
|
|
136
|
+
const handleSend = async () => {
|
|
137
|
+
if (!displayToken || !recipientAddress || !sendAmount || parseFloat(sendAmount) <= 0) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
setIsSending(true);
|
|
141
|
+
const amountInWei = (0, viem_1.parseUnits)(sendAmount, displayToken.decimals);
|
|
142
|
+
// Prepare analytics event data
|
|
143
|
+
const analyticsData = {
|
|
144
|
+
amount: sendAmount,
|
|
145
|
+
symbol: displayToken.symbol,
|
|
146
|
+
chain_id: displayToken.chain_id,
|
|
147
|
+
address: displayToken.address,
|
|
148
|
+
};
|
|
149
|
+
try {
|
|
150
|
+
(0, invariant_1.default)((0, viem_1.isAddress)(recipientAddress), "Recipient address is not a valid address");
|
|
151
|
+
const sendTokenData = (0, viem_1.encodeFunctionData)({
|
|
152
|
+
abi: viem_1.erc20Abi,
|
|
153
|
+
functionName: "transfer",
|
|
154
|
+
args: [recipientAddress, amountInWei],
|
|
155
|
+
});
|
|
156
|
+
const tx = await switchChainAndExecute(displayToken.chain_id, {
|
|
157
|
+
to: displayToken.address === "native" ? recipientAddress : displayToken.address,
|
|
158
|
+
data: sendTokenData,
|
|
159
|
+
value: displayToken.address === "native" ? amountInWei : BigInt(0),
|
|
160
|
+
});
|
|
161
|
+
if (tx) {
|
|
162
|
+
// Track successful send
|
|
163
|
+
sendAnalyticsEvent("send_token_button_click", {
|
|
164
|
+
...analyticsData,
|
|
165
|
+
success: true,
|
|
166
|
+
tx: (0, anyspend_1.getExplorerTxUrl)(displayToken.chain_id, tx),
|
|
167
|
+
});
|
|
168
|
+
// Reset form
|
|
169
|
+
setSendAmount("");
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
// Track failed send
|
|
174
|
+
sendAnalyticsEvent("send_token_button_click", {
|
|
175
|
+
...analyticsData,
|
|
176
|
+
success: false,
|
|
177
|
+
reason: error.message || "Unknown error",
|
|
178
|
+
});
|
|
179
|
+
// Error
|
|
180
|
+
sonner_1.toast.error(`Failed to send ${displayToken.symbol}: ${error.message || "Unknown error"}`);
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
// Wait 1 second to make sure the tx is indexed on sim api.
|
|
184
|
+
setTimeout(async () => {
|
|
185
|
+
// Force refetch to bypass cache and get fresh balance data
|
|
186
|
+
await refetchSimBalance();
|
|
187
|
+
}, 1000);
|
|
188
|
+
setIsSending(false);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
// Show loading state only if no token data is available at all
|
|
192
|
+
if (!displayToken) {
|
|
193
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-b3-line/50 mb-4 rounded-full p-4", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "text-b3-foreground-muted h-8 w-8 animate-spin" }) }), (0, jsx_runtime_1.jsx)("h3", { className: "text-b3-grey font-neue-montreal-semibold mb-2", children: "Loading token data..." }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "Please wait while we fetch the latest information" })] }));
|
|
194
|
+
}
|
|
195
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)(react_1.Button, { variant: "ghost", size: "icon", onClick: () => {
|
|
196
|
+
animationDirection.current = "back";
|
|
197
|
+
setTokenPanelView(TokenPanelView.LIST);
|
|
198
|
+
}, className: "hover:bg-b3-line/60", disabled: isSending, children: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowLeft, { className: "h-5 w-5" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex h-8 w-8 items-center justify-center", children: anyspend_1.ALL_CHAINS[displayToken.chain_id]?.logoUrl ? ((0, jsx_runtime_1.jsx)(ChainTokenIcon_1.ChainTokenIcon, { chainUrl: anyspend_1.ALL_CHAINS[displayToken.chain_id].logoUrl, tokenUrl: displayToken.token_metadata?.logo, className: "size-8" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.CircleHelp, { className: "text-b3-react-foreground size-8" })) }), (0, jsx_runtime_1.jsxs)("h2", { className: "text-b3-grey font-neue-montreal-semibold text-lg", children: ["Send ", displayToken.symbol] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Recipient Address" }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-1", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)("input", { type: "text", value: recipientAddress, onChange: e => handleRecipientAddressChange(e.target.value), placeholder: "Enter wallet address (0x...)", className: `border-b3-line bg-b3-background text-b3-grey font-neue-montreal-medium placeholder:text-b3-foreground-muted w-full rounded-xl border px-4 py-3 pr-12 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 ${addressError ? "border-red-500 focus:border-red-500" : "focus:border-b3-primary-blue"}`, disabled: isSending }), (0, jsx_runtime_1.jsx)(react_1.Button, { variant: "ghost", size: "icon", className: "hover:bg-b3-line/60 absolute right-2 top-1/2 h-8 w-8 -translate-y-1/2", disabled: isSending, onClick: () => {
|
|
199
|
+
navigator.clipboard.readText().then(text => {
|
|
200
|
+
handleRecipientAddressChange(text);
|
|
201
|
+
});
|
|
202
|
+
}, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { className: "h-4 w-4" }) })] }), addressError && (0, jsx_runtime_1.jsx)("p", { className: "font-neue-montreal-medium text-xs text-red-500", children: addressError })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [(0, jsx_runtime_1.jsx)("label", { className: "text-b3-grey font-neue-montreal-medium text-sm", children: "Amount" }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-3", children: [(0, jsx_runtime_1.jsx)(react_number_format_1.NumericFormat, { decimalSeparator: ".", allowedDecimalSeparators: [","], thousandSeparator: true, inputMode: "decimal", autoComplete: "off", autoCorrect: "off", type: "text", placeholder: "0.00", minLength: 1, maxLength: 30, spellCheck: "false", className: "border-b3-line bg-b3-background text-b3-grey font-neue-montreal-medium placeholder:text-b3-foreground-muted focus:border-b3-primary-blue w-full rounded-xl border px-4 py-3 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50", pattern: "^[0-9]*[.,]?[0-9]*$", disabled: isSending, value: sendAmount, allowNegative: false, onChange: e => setSendAmount(e.currentTarget.value) }), (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-4 gap-2", children: [25, 50, 75, 100].map(percentage => ((0, jsx_runtime_1.jsxs)(react_1.Button, { variant: "outline", onClick: () => handlePercentageClick(percentage), className: "hover:bg-b3-primary-wash border-b3-line text-b3-grey font-neue-montreal-medium text-sm", disabled: isSending, children: [percentage, "%"] }, percentage))) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: ["Available: ", (0, number_1.formatTokenAmount)(BigInt(displayToken.amount), displayToken.decimals), " ", displayToken.symbol] })] })] }), (0, jsx_runtime_1.jsx)(react_1.Button, { onClick: handleSend, disabled: !recipientAddress ||
|
|
203
|
+
!sendAmount ||
|
|
204
|
+
parseFloat(sendAmount) <= 0 ||
|
|
205
|
+
isSending ||
|
|
206
|
+
!!addressError ||
|
|
207
|
+
!(0, viem_1.isAddress)(recipientAddress), className: "bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold disabled:bg-b3-line disabled:text-b3-foreground-muted w-full rounded-xl py-3 text-white", children: isSending ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), "Sending..."] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Send, { className: "mr-2 h-4 w-4" }), "Send ", displayToken.symbol] })) })] }));
|
|
208
|
+
};
|
|
209
|
+
// Skeleton loading component for token list
|
|
210
|
+
const LoadingIndicator = () => ((0, jsx_runtime_1.jsx)("div", { className: "space-y-4", children: (0, jsx_runtime_1.jsx)("div", { className: "space-y-1", children: [...Array(3)].map((_, index) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between rounded-xl p-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-b3-line h-10 w-10 animate-pulse rounded-full" }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-b3-line mb-1 h-4 w-16 animate-pulse rounded" }), (0, jsx_runtime_1.jsx)("div", { className: "bg-b3-line h-3 w-24 animate-pulse rounded" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-b3-line mb-1 h-4 w-20 animate-pulse rounded" }), (0, jsx_runtime_1.jsx)("div", { className: "bg-b3-line h-3 w-16 animate-pulse rounded" })] })] }, index))) }) }));
|
|
211
|
+
/**
|
|
212
|
+
* Renders the token list panel with smart filtering
|
|
213
|
+
* Features intelligent token display logic to reduce noise while ensuring visibility
|
|
214
|
+
*/
|
|
215
|
+
const renderTokenListPanel = () => {
|
|
216
|
+
// Show loading indicator when balance is loading
|
|
217
|
+
if (isLoadingBalance) {
|
|
218
|
+
return (0, jsx_runtime_1.jsx)(LoadingIndicator, {});
|
|
219
|
+
}
|
|
220
|
+
// Show empty state when no account or no balance data
|
|
221
|
+
if (!account?.address || !simBalance) {
|
|
222
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-b3-line/50 mb-4 rounded-full p-4", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "text-b3-foreground-muted h-8 w-8" }) }), (0, jsx_runtime_1.jsx)("h3", { className: "text-b3-grey font-neue-montreal-semibold mb-2", children: "No wallet connected" }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "Connect your wallet to view token balances" })] }));
|
|
223
|
+
}
|
|
224
|
+
// === SMART FILTERING LOGIC ===
|
|
225
|
+
// Filter tokens with value >= $1 to reduce noise from dust tokens
|
|
226
|
+
const filteredTokens = simBalance?.balances.filter(token => token.value_usd !== undefined && token.value_usd >= 1) || [];
|
|
227
|
+
// 🧠 INTELLIGENT DISPLAY LOGIC:
|
|
228
|
+
// Show all tokens automatically when filtering would be unhelpful:
|
|
229
|
+
// 1. User explicitly requested to show all, OR
|
|
230
|
+
// 2. No tokens with value >= $1 (user has only dust), OR
|
|
231
|
+
// 3. 5 or fewer tokens with value >= $1 (not enough to warrant filtering)
|
|
232
|
+
const shouldShowAllTokens = showAllTokens || filteredTokens.length === 0 || filteredTokens.length <= 5;
|
|
233
|
+
const tokensToShow = shouldShowAllTokens ? simBalance?.balances || [] : filteredTokens;
|
|
234
|
+
const hasHiddenTokens = !shouldShowAllTokens && (simBalance?.balances.length || 0) > filteredTokens.length;
|
|
235
|
+
// Handle token selection and navigate to send form
|
|
236
|
+
const handleTokenClick = (token) => {
|
|
237
|
+
setSelectedToken(token);
|
|
238
|
+
animationDirection.current = "forward"; // Set animation direction BEFORE state change
|
|
239
|
+
setTokenPanelView(TokenPanelView.SEND);
|
|
240
|
+
// Reset form when selecting a new token
|
|
241
|
+
setRecipientAddress("");
|
|
242
|
+
setSendAmount("");
|
|
243
|
+
setIsSending(false);
|
|
244
|
+
setAddressError("");
|
|
245
|
+
};
|
|
246
|
+
// Show empty state when no tokens are available
|
|
247
|
+
if (tokensToShow.length === 0) {
|
|
248
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 text-center", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-b3-line/50 mb-4 rounded-full p-4", children: (0, jsx_runtime_1.jsx)(lucide_react_1.CircleHelp, { className: "text-b3-foreground-muted h-8 w-8" }) }), (0, jsx_runtime_1.jsx)("h3", { className: "text-b3-grey font-neue-montreal-semibold mb-2", children: "No tokens found" }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "No token balances found in your wallet." })] }));
|
|
249
|
+
}
|
|
250
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "space-y-1", children: tokensToShow.map(token => ((0, jsx_runtime_1.jsxs)("div", { className: "hover:bg-b3-line/60 dark:hover:bg-b3-primary-wash/40 group flex cursor-pointer items-center justify-between rounded-xl p-3 transition-all duration-200", onClick: () => handleTokenClick(token), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: anyspend_1.ALL_CHAINS[token.chain_id]?.logoUrl ? ((0, jsx_runtime_1.jsx)(ChainTokenIcon_1.ChainTokenIcon, { chainUrl: anyspend_1.ALL_CHAINS[token.chain_id].logoUrl, tokenUrl: token.token_metadata?.logo, className: "size-10" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.CircleHelp, { className: "text-b3-react-foreground size-10" })) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold transition-colors duration-200 group-hover:font-bold group-hover:text-black", children: token.symbol }) }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm transition-colors duration-200 group-hover:text-gray-700", children: token.name })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-b3-grey font-neue-montreal-semibold transition-colors duration-200 group-hover:font-bold group-hover:text-black", children: (0, number_1.formatTokenAmount)(BigInt(token.amount), token.decimals) }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm transition-colors duration-200 group-hover:text-gray-700", children: (0, number_1.formatDisplayNumber)(token.value_usd, { style: "currency", fractionDigits: 2 }) })] })] }, token.chain_id + "_" + token.address))) }), hasHiddenTokens && !showAllTokens && ((0, jsx_runtime_1.jsx)("div", { className: "flex justify-center", children: (0, jsx_runtime_1.jsx)(react_1.Button, { variant: "ghost", className: "text-b3-primary-blue hover:text-b3-primary-blue/80 font-neue-montreal-semibold text-sm", onClick: () => setShowAllTokens(true), children: "Show more" }) }))] }));
|
|
251
|
+
};
|
|
252
|
+
// === ANIMATION CONFIGURATION ===
|
|
253
|
+
// Memoize variants to prevent re-creation and unwanted re-renders
|
|
254
|
+
const variants = (0, react_2.useMemo)(() => ({
|
|
255
|
+
enter: (direction) => ({
|
|
256
|
+
x: direction === "back" ? -300 : 300, // Back: slide from left, Forward: slide from right
|
|
257
|
+
opacity: 0,
|
|
258
|
+
}),
|
|
259
|
+
center: { x: 0, opacity: 1 }, // Final position: centered and visible
|
|
260
|
+
exit: (direction) => ({
|
|
261
|
+
x: direction === "back" ? 300 : -300, // Back: slide to right, Forward: slide to left
|
|
262
|
+
opacity: 0,
|
|
263
|
+
}),
|
|
264
|
+
}), []);
|
|
265
|
+
// Memoize transition config for consistent spring animation
|
|
266
|
+
const transition = (0, react_2.useMemo)(() => ({
|
|
267
|
+
type: "spring",
|
|
268
|
+
stiffness: 300, // Spring tension
|
|
269
|
+
damping: 30, // Spring damping
|
|
270
|
+
}), []);
|
|
271
|
+
return ((0, jsx_runtime_1.jsx)(react_1.TransitionPanel, { activeIndex: tokenPanelView, className: "min-h-[400px]", custom: animationDirection.current, variants: variants, transition: transition, children: [(0, jsx_runtime_1.jsx)("div", { children: renderTokenListPanel() }, "token-list"), (0, jsx_runtime_1.jsx)("div", { children: renderSendTokenPanel() }, "send-token")] }));
|
|
272
|
+
}
|
|
@@ -1,52 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.ManageAccount = ManageAccount;
|
|
7
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
5
|
const react_1 = require("../../../../global-account/react");
|
|
9
|
-
const BankIcon_1 = require("../../../../global-account/react/components/icons/BankIcon");
|
|
10
6
|
const SignOutIcon_1 = require("../../../../global-account/react/components/icons/SignOutIcon");
|
|
11
|
-
const SwapIcon_1 = require("../../../../global-account/react/components/icons/SwapIcon");
|
|
12
|
-
const utils_1 = require("../../../../shared/utils");
|
|
13
7
|
const formatNumber_1 = require("../../../../shared/utils/formatNumber");
|
|
14
8
|
const thirdweb_1 = require("../../../../shared/utils/thirdweb");
|
|
15
9
|
const lucide_react_1 = require("lucide-react");
|
|
16
10
|
const react_2 = require("react");
|
|
17
11
|
const react_3 = require("thirdweb/react");
|
|
18
12
|
const viem_1 = require("viem");
|
|
19
|
-
const useFirstEOA_1 = __importDefault(require("../../hooks/useFirstEOA"));
|
|
20
13
|
const profileDisplay_1 = require("../../utils/profileDisplay");
|
|
21
14
|
const AccountAssets_1 = require("../AccountAssets/AccountAssets");
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return str;
|
|
25
|
-
return `${str.slice(0, length)}...${str.slice(-length)}`;
|
|
26
|
-
}
|
|
15
|
+
const ContentTokens_1 = require("./ContentTokens");
|
|
16
|
+
const BalanceContent_1 = require("./BalanceContent");
|
|
27
17
|
function ManageAccount({ onLogout, onSwap: _onSwap, onDeposit: _onDeposit, chain, partnerId, }) {
|
|
28
18
|
const [revokingSignerId, setRevokingSignerId] = (0, react_2.useState)(null);
|
|
29
19
|
const account = (0, react_3.useActiveAccount)();
|
|
30
|
-
const { data:
|
|
31
|
-
const { data: b3Balance } = (0, react_1.useB3BalanceFromAddresses)(account?.address);
|
|
32
|
-
const { data: nativeBalance } = (0, react_1.useNativeBalance)(account?.address);
|
|
33
|
-
const { address: eoaAddress } = (0, useFirstEOA_1.default)();
|
|
34
|
-
const { data: profile } = (0, react_1.useProfile)({
|
|
35
|
-
address: eoaAddress || account?.address,
|
|
36
|
-
fresh: true,
|
|
37
|
-
});
|
|
38
|
-
const { data: eoaNativeBalance } = (0, react_1.useNativeBalance)(eoaAddress);
|
|
39
|
-
const { data: eoaB3Balance } = (0, react_1.useB3BalanceFromAddresses)(eoaAddress);
|
|
20
|
+
const { data: nfts, isLoading } = (0, react_1.useAccountAssets)(account?.address);
|
|
40
21
|
const { data: signers, refetch: refetchSigners } = (0, react_1.useGetAllTWSigners)({
|
|
41
22
|
chain,
|
|
42
23
|
accountAddress: account?.address,
|
|
43
24
|
});
|
|
44
|
-
const { setB3ModalOpen,
|
|
45
|
-
const { activeTab = "
|
|
25
|
+
const { setB3ModalOpen, contentType } = (0, react_1.useModalStore)();
|
|
26
|
+
const { activeTab = "overview", setActiveTab } = contentType;
|
|
46
27
|
const { logout } = (0, react_1.useAuthentication)(partnerId);
|
|
47
28
|
const [logoutLoading, setLogoutLoading] = (0, react_2.useState)(false);
|
|
48
|
-
console.log("account", account);
|
|
49
|
-
console.log("eoaAddress", eoaAddress);
|
|
50
29
|
const { removeSessionKey } = (0, react_1.useRemoveSessionKey)({
|
|
51
30
|
chain,
|
|
52
31
|
onSuccess: tx => {
|
|
@@ -70,24 +49,6 @@ function ManageAccount({ onLogout, onSwap: _onSwap, onDeposit: _onDeposit, chain
|
|
|
70
49
|
setB3ModalOpen(false);
|
|
71
50
|
setLogoutLoading(false);
|
|
72
51
|
};
|
|
73
|
-
const BalanceContent = () => {
|
|
74
|
-
const { info: eoaInfo } = (0, useFirstEOA_1.default)();
|
|
75
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-between", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [profile?.avatar ? ((0, jsx_runtime_1.jsx)("img", { src: profile?.avatar, alt: "Profile", className: "size-24 rounded-full" })) : ((0, jsx_runtime_1.jsx)("div", { className: "bg-b3-primary-wash size-24 rounded-full" })), (0, jsx_runtime_1.jsx)("div", { className: "bg-b3-grey border-b3-background absolute -bottom-1 -right-1 flex size-8 items-center justify-center rounded-full border-4", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Pencil, { size: 16, className: "text-b3-background" }) })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h2", { className: "text-b3-grey text-xl font-semibold", children: profile?.displayName || (0, utils_1.formatUsername)(profile?.name || "") }), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted", children: (0, utils_1.formatUsername)(profile?.name || "") })] })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "manage-account-address bg-b3-line flex h-11 items-center gap-2 rounded-full px-4", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: centerTruncate(account?.address || "") }), (0, jsx_runtime_1.jsx)(react_1.CopyToClipboard, { text: account?.address || "" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [(0, jsx_runtime_1.jsxs)(react_1.Button, { className: "manage-account-deposit bg-b3-primary-wash hover:bg-b3-primary-wash/70 h-[84px] w-full flex-col items-start gap-2 rounded-2xl", onClick: () => {
|
|
76
|
-
setB3ModalOpen(true);
|
|
77
|
-
setB3ModalContentType({
|
|
78
|
-
type: "anySpend",
|
|
79
|
-
defaultActiveTab: "fiat",
|
|
80
|
-
showBackButton: true,
|
|
81
|
-
});
|
|
82
|
-
}, children: [(0, jsx_runtime_1.jsx)(BankIcon_1.BankIcon, { size: 24, className: "text-b3-primary-blue shrink-0" }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: "Deposit" })] }), (0, jsx_runtime_1.jsxs)(react_1.Button, { className: "manage-account-swap bg-b3-primary-wash hover:bg-b3-primary-wash/70 flex h-[84px] w-full flex-col items-start gap-2 rounded-2xl", onClick: () => {
|
|
83
|
-
setB3ModalOpen(true);
|
|
84
|
-
setB3ModalContentType({
|
|
85
|
-
type: "anySpend",
|
|
86
|
-
showBackButton: true,
|
|
87
|
-
});
|
|
88
|
-
}, children: [(0, jsx_runtime_1.jsx)(SwapIcon_1.SwapIcon, { size: 24, className: "text-b3-primary-blue" }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: "Swap" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-b3-grey font-neue-montreal-semibold", children: "Balance" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: (0, jsx_runtime_1.jsx)("img", { src: "https://cdn.b3.fun/b3-coin-3d.png", alt: "B3", className: "size-10" }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: "B3" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: [b3Balance?.formattedTotal || "0.00", " B3"] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: ["$", b3Balance?.balanceUsdFormatted || "0.00"] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-1", children: b3Balance?.priceChange24h !== null && b3Balance?.priceChange24h !== undefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Triangle, { className: `size-3 ${b3Balance.priceChange24h >= 0 ? "text-b3-positive fill-b3-positive" : "text-b3-negative fill-b3-negative rotate-180"}` }), (0, jsx_runtime_1.jsxs)("span", { className: `font-neue-montreal-medium text-sm ${b3Balance.priceChange24h >= 0 ? "text-b3-positive" : "text-b3-negative"}`, children: [b3Balance.priceChange24h >= 0 ? "+" : "", b3Balance.priceChange24h.toFixed(2), "%"] })] })) : ((0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "--" })) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: (0, jsx_runtime_1.jsx)("img", { src: "https://cdn.b3.fun/ethereum.svg", alt: "ETH", className: "size-10" }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: "Ethereum" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: [nativeBalance?.formattedTotal || "0.00", " ETH"] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: ["$", nativeBalance?.formattedTotalUsd || "0.00"] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: nativeBalance?.priceChange24h !== null && nativeBalance?.priceChange24h !== undefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Triangle, { className: `size-3 ${nativeBalance.priceChange24h >= 0 ? "text-b3-positive fill-b3-positive" : "text-b3-negative fill-b3-negative rotate-180"}` }), (0, jsx_runtime_1.jsxs)("span", { className: `font-neue-montreal-medium text-sm ${nativeBalance.priceChange24h >= 0 ? "text-b3-positive" : "text-b3-negative"}`, children: [nativeBalance.priceChange24h >= 0 ? "+" : "", nativeBalance.priceChange24h.toFixed(2), "%"] })] })) : ((0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "--" })) })] })] })] }), eoaAddress && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("h3", { className: "text-b3-grey font-neue-montreal-semibold", children: ["Connected ", eoaInfo?.data?.name || "Wallet"] }), (0, jsx_runtime_1.jsxs)("div", { className: "manage-account-address bg-b3-line flex h-11 items-center gap-2 rounded-full px-4", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: centerTruncate(eoaAddress) }), (0, jsx_runtime_1.jsx)(react_1.CopyToClipboard, { text: eoaAddress })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: (0, jsx_runtime_1.jsx)("img", { src: "https://cdn.b3.fun/b3-coin-3d.png", alt: "B3", className: "size-10" }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: "B3" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: [eoaB3Balance?.formattedTotal || "0.00", " B3"] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: ["$", eoaB3Balance?.balanceUsdFormatted || "0.00"] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-1", children: eoaB3Balance?.priceChange24h !== null && eoaB3Balance?.priceChange24h !== undefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Triangle, { className: `size-3 ${eoaB3Balance.priceChange24h >= 0 ? "text-b3-positive fill-b3-positive" : "text-b3-negative fill-b3-negative rotate-180"}` }), (0, jsx_runtime_1.jsxs)("span", { className: `font-neue-montreal-medium text-sm ${eoaB3Balance.priceChange24h >= 0 ? "text-b3-positive" : "text-b3-negative"}`, children: [eoaB3Balance.priceChange24h >= 0 ? "+" : "", eoaB3Balance.priceChange24h.toFixed(2), "%"] })] })) : ((0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "--" })) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: (0, jsx_runtime_1.jsx)("img", { src: "https://cdn.b3.fun/ethereum.svg", alt: "ETH", className: "size-10" }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: "Ethereum" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: [eoaNativeBalance?.formattedTotal || "0.00", " ETH"] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: ["$", eoaNativeBalance?.formattedTotalUsd || "0.00"] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: eoaNativeBalance?.priceChange24h !== null && eoaNativeBalance?.priceChange24h !== undefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Triangle, { className: `size-3 ${eoaNativeBalance.priceChange24h >= 0 ? "text-b3-positive fill-b3-positive" : "text-b3-negative fill-b3-negative rotate-180"}` }), (0, jsx_runtime_1.jsxs)("span", { className: `font-neue-montreal-medium text-sm ${eoaNativeBalance.priceChange24h >= 0 ? "text-b3-positive" : "text-b3-negative"}`, children: [eoaNativeBalance.priceChange24h >= 0 ? "+" : "", eoaNativeBalance.priceChange24h.toFixed(2), "%"] })] })) : ((0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "--" })) })] })] })] })), (0, jsx_runtime_1.jsxs)("div", { className: "border-b3-line flex items-center justify-between rounded-2xl border p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("img", { src: "https://cdn.b3.fun/b3_logo.svg", alt: "B3", className: "h-4" }), (0, jsx_runtime_1.jsx)("h3", { className: "font-neue-montreal-semibold text-b3-grey", children: "Global Account" })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium mt-2 text-sm", children: "Your universal account for all B3-powered apps" })] }), (0, jsx_runtime_1.jsx)("button", { className: "text-b3-grey hover:text-b3-grey/80 hover:bg-b3-line border-b3-line flex size-12 items-center justify-center rounded-full border", onClick: onLogoutEnhanced, children: logoutLoading ? (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin" }) : (0, jsx_runtime_1.jsx)(SignOutIcon_1.SignOutIcon, { size: 16, className: "text-b3-grey" }) })] })] }));
|
|
89
|
-
};
|
|
90
|
-
const AssetsContent = () => ((0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-3 gap-4", children: assets?.nftResponse ? ((0, jsx_runtime_1.jsx)(AccountAssets_1.AccountAssets, { nfts: assets.nftResponse, isLoading: isLoading })) : ((0, jsx_runtime_1.jsx)("div", { className: "col-span-3 py-12 text-center text-gray-500", children: "No NFTs found" })) }));
|
|
91
52
|
const AppsContent = () => ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [signers?.map((signer) => ((0, jsx_runtime_1.jsx)("div", { className: "rounded-xl border border-gray-200 p-4 dark:border-gray-800", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-start justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-start gap-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-gray-100 dark:bg-gray-800", children: (0, jsx_runtime_1.jsx)("span", { className: "text-xs font-medium text-gray-600 dark:text-gray-400", children: "App" }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h3", { className: "font-medium text-gray-900 dark:text-white", children: signer.partner.name }), (0, jsx_runtime_1.jsxs)("div", { className: "mt-2 space-y-1", children: [(0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-gray-500", children: ["Added ", new Date(signer.createdAt).toLocaleDateString()] }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-gray-500", children: ["Expires ", new Date(Number(signer.endTimestamp) * 1000).toLocaleDateString()] }), (0, jsx_runtime_1.jsxs)("p", { className: "text-xs text-gray-500", children: ["Max spend: ", (0, formatNumber_1.formatNumber)(Number((0, viem_1.formatUnits)(signer.nativeTokenLimitPerTransaction, 18))), " ETH"] })] })] })] }), (0, jsx_runtime_1.jsx)(react_1.Button, { variant: "outline", size: "sm", className: "border-red-200 text-red-500 hover:border-red-300 hover:text-red-600", onClick: () => handleRevoke(signer), disabled: revokingSignerId === signer.id, children: revokingSignerId === signer.id ? "Revoking..." : "Revoke" })] }) }, signer.id))), !signers?.length && (0, jsx_runtime_1.jsx)("div", { className: "py-12 text-center text-gray-500", children: "No connected apps" })] }));
|
|
92
53
|
const SettingsContent = () => {
|
|
93
54
|
const [unlinkingAccountId, setUnlinkingAccountId] = (0, react_2.useState)(null);
|
|
@@ -103,10 +64,7 @@ function ManageAccount({ onLogout, onSwap: _onSwap, onDeposit: _onDeposit, chain
|
|
|
103
64
|
const handleUnlink = async (profile) => {
|
|
104
65
|
setUnlinkingAccountId(profile.title);
|
|
105
66
|
try {
|
|
106
|
-
|
|
107
|
-
client: thirdweb_1.client,
|
|
108
|
-
profileToUnlink: profile.originalProfile,
|
|
109
|
-
});
|
|
67
|
+
unlinkProfile({ client: thirdweb_1.client, profileToUnlink: profile.originalProfile });
|
|
110
68
|
}
|
|
111
69
|
catch (error) {
|
|
112
70
|
console.error("Error unlinking account:", error);
|
|
@@ -133,12 +91,12 @@ function ManageAccount({ onLogout, onSwap: _onSwap, onDeposit: _onDeposit, chain
|
|
|
133
91
|
},
|
|
134
92
|
});
|
|
135
93
|
};
|
|
136
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-8", children: [(0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-b3-grey font-neue-montreal-semibold text-xl", children: "Linked Accounts" }), (0, jsx_runtime_1.jsxs)(react_1.Button, { className: "bg-b3-primary-wash hover:bg-b3-primary-wash/70 flex items-center gap-2 rounded-full px-4 py-2", onClick: handleOpenLinkModal, disabled: isLinking, children: [isLinking ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "text-b3-primary-blue animate-spin", size: 16 })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.LinkIcon, { size: 16, className: "text-b3-primary-blue" })), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: isLinking ? "Linking..." : "Link New Account" })] })] }), isLoadingProfiles ? ((0, jsx_runtime_1.jsx)("div", { className: "flex justify-center py-8", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "text-b3-grey animate-spin" }) })) : profiles.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-4", children: profiles.map(profile => ((0, jsx_runtime_1.jsxs)("div", { className: "bg-b3-line flex items-center justify-between rounded-xl p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [profile.imageUrl ? ((0, jsx_runtime_1.jsx)("img", { src: profile.imageUrl, alt: profile.title, className: "size-10 rounded-full" })) : ((0, jsx_runtime_1.jsx)("div", { className: "bg-b3-primary-wash flex h-10 w-10 items-center justify-center rounded-full", children: (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm uppercase", children: profile.initial }) })), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: profile.title }), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-neue-montreal-medium bg-b3-primary-wash rounded px-2 py-0.5 text-xs", children: profile.type.toUpperCase() })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: profile.subtitle })] })] }), (0, jsx_runtime_1.jsx)(react_1.Button, { variant: "ghost", size: "icon", className: "text-b3-grey hover:text-b3-negative", onClick: () => handleUnlink(profile), disabled: unlinkingAccountId === profile.title || isUnlinking, children: unlinkingAccountId === profile.title || isUnlinking ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.UnlinkIcon, { size: 16 })) })] }, profile.title))) })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted py-8 text-center", children: "No linked accounts found" }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-b3-grey font-neue-montreal-semibold text-xl", children: "Account Preferences" }), (0, jsx_runtime_1.jsx)("div", { className: "bg-b3-line rounded-xl p-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: "Dark Mode" }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "Switch between light and dark theme" })] }), (0, jsx_runtime_1.jsx)("div", { className: "bg-b3-primary-wash h-6 w-12 rounded-full" })] }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "border-b3-line flex items-center justify-between rounded-2xl border p-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("img", { src: "https://cdn.b3.fun/b3_logo.svg", alt: "B3", className: "h-4" }), (0, jsx_runtime_1.jsx)("h3", { className: "font-neue-montreal-semibold text-b3-grey", children: "Global Account" })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium mt-2 text-sm", children: "Your universal account for all B3
|
|
94
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-8", children: [(0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-b3-grey font-neue-montreal-semibold text-xl", children: "Linked Accounts" }), (0, jsx_runtime_1.jsxs)(react_1.Button, { className: "bg-b3-primary-wash hover:bg-b3-primary-wash/70 flex items-center gap-2 rounded-full px-4 py-2", onClick: handleOpenLinkModal, disabled: isLinking, children: [isLinking ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "text-b3-primary-blue animate-spin", size: 16 })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.LinkIcon, { size: 16, className: "text-b3-primary-blue" })), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: isLinking ? "Linking..." : "Link New Account" })] })] }), isLoadingProfiles ? ((0, jsx_runtime_1.jsx)("div", { className: "flex justify-center py-8", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "text-b3-grey animate-spin" }) })) : profiles.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-4", children: profiles.map(profile => ((0, jsx_runtime_1.jsxs)("div", { className: "bg-b3-line flex items-center justify-between rounded-xl p-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [profile.imageUrl ? ((0, jsx_runtime_1.jsx)("img", { src: profile.imageUrl, alt: profile.title, className: "size-10 rounded-full" })) : ((0, jsx_runtime_1.jsx)("div", { className: "bg-b3-primary-wash flex h-10 w-10 items-center justify-center rounded-full", children: (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm uppercase", children: profile.initial }) })), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: profile.title }), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-neue-montreal-medium bg-b3-primary-wash rounded px-2 py-0.5 text-xs", children: profile.type.toUpperCase() })] }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: profile.subtitle })] })] }), (0, jsx_runtime_1.jsx)(react_1.Button, { variant: "ghost", size: "icon", className: "text-b3-grey hover:text-b3-negative", onClick: () => handleUnlink(profile), disabled: unlinkingAccountId === profile.title || isUnlinking, children: unlinkingAccountId === profile.title || isUnlinking ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.UnlinkIcon, { size: 16 })) })] }, profile.title))) })) : ((0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted py-8 text-center", children: "No linked accounts found" }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-b3-grey font-neue-montreal-semibold text-xl", children: "Account Preferences" }), (0, jsx_runtime_1.jsx)("div", { className: "bg-b3-line rounded-xl p-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: "Dark Mode" }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "Switch between light and dark theme" })] }), (0, jsx_runtime_1.jsx)("div", { className: "bg-b3-primary-wash h-6 w-12 rounded-full" })] }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "border-b3-line flex items-center justify-between rounded-2xl border p-4", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("img", { src: "https://cdn.b3.fun/b3_logo.svg", alt: "B3", className: "h-4" }), (0, jsx_runtime_1.jsx)("h3", { className: "font-neue-montreal-semibold text-b3-grey", children: "Global Account" })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-b3-foreground-muted font-neue-montreal-medium mt-2 text-sm", children: "Your universal account for all B3 apps" })] }), (0, jsx_runtime_1.jsx)("button", { className: "text-b3-grey hover:text-b3-grey/80 hover:bg-b3-line border-b3-line flex size-12 items-center justify-center rounded-full border", onClick: onLogoutEnhanced, children: logoutLoading ? (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "animate-spin" }) : (0, jsx_runtime_1.jsx)(SignOutIcon_1.SignOutIcon, { size: 16, className: "text-b3-grey" }) })] })] }));
|
|
137
95
|
};
|
|
138
96
|
return ((0, jsx_runtime_1.jsx)("div", { className: "b3-manage-account bg-b3-background flex flex-col rounded-xl", children: (0, jsx_runtime_1.jsx)("div", { className: "flex-1", children: (0, jsx_runtime_1.jsxs)(react_1.TabsPrimitive, { defaultValue: activeTab, onValueChange: value => {
|
|
139
97
|
const tab = value;
|
|
140
|
-
if (["
|
|
98
|
+
if (["overview", "tokens", "nfts", "apps", "settings"].includes(tab)) {
|
|
141
99
|
setActiveTab?.(tab);
|
|
142
100
|
}
|
|
143
|
-
}, children: [(0, jsx_runtime_1.jsxs)(react_1.TabsListPrimitive, { className: "
|
|
101
|
+
}, children: [(0, jsx_runtime_1.jsx)("div", { className: "px-4", children: (0, jsx_runtime_1.jsxs)(react_1.TabsListPrimitive, { className: "grid h-auto grid-cols-2 grid-rows-2 gap-3 rounded-none border-none bg-transparent", children: [(0, jsx_runtime_1.jsxs)(react_1.TabTriggerPrimitive, { value: "overview", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.BarChart3, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "Overview" })] }), (0, jsx_runtime_1.jsxs)(react_1.TabTriggerPrimitive, { value: "tokens", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Coins, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "Tokens" })] }), (0, jsx_runtime_1.jsxs)(react_1.TabTriggerPrimitive, { value: "nfts", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Image, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "NFTs" })] }), (0, jsx_runtime_1.jsxs)(react_1.TabTriggerPrimitive, { value: "settings", className: "data-[state=active]:bg-b3-primary-blue data-[state=active]:hover:bg-b3-primary-blue data-[state=active]:border-b3-primary-blue group flex h-12 w-full items-center justify-center gap-2 rounded-xl border border-gray-200 bg-white p-2 text-center shadow-sm transition-all duration-200 hover:bg-gray-50 hover:shadow-md data-[state=active]:shadow-lg", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Settings, { size: 20, className: "text-b3-primary-blue shrink-0 group-data-[state=active]:text-white" }), (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold text-sm group-data-[state=active]:text-white", children: "Settings" })] })] }) }), (0, jsx_runtime_1.jsx)(react_1.TabsContentPrimitive, { value: "overview", className: "px-4 pb-4 pt-2", children: (0, jsx_runtime_1.jsx)(BalanceContent_1.BalanceContent, { onLogout: onLogout, partnerId: partnerId }) }), (0, jsx_runtime_1.jsx)(react_1.TabsContentPrimitive, { value: "tokens", className: "px-4 pb-4 pt-2", children: (0, jsx_runtime_1.jsx)(ContentTokens_1.ContentTokens, { activeTab: activeTab }) }), (0, jsx_runtime_1.jsx)(react_1.TabsContentPrimitive, { value: "nfts", className: "px-4 pb-4 pt-2", children: (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-3 gap-4", children: nfts?.nftResponse ? ((0, jsx_runtime_1.jsx)(AccountAssets_1.AccountAssets, { nfts: nfts.nftResponse, isLoading: isLoading })) : ((0, jsx_runtime_1.jsx)("div", { className: "col-span-3 py-12 text-center text-gray-500", children: "No NFTs found" })) }) }), (0, jsx_runtime_1.jsx)(react_1.TabsContentPrimitive, { value: "apps", className: "px-4 pb-4 pt-2", children: (0, jsx_runtime_1.jsx)(AppsContent, {}) }), (0, jsx_runtime_1.jsx)(react_1.TabsContentPrimitive, { value: "settings", className: "px-4 pb-4 pt-2", children: (0, jsx_runtime_1.jsx)(SettingsContent, {}) })] }) }) }));
|
|
144
102
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
interface TokenBalanceRowProps {
|
|
3
|
+
icon: ReactNode;
|
|
4
|
+
name: string;
|
|
5
|
+
balance: string;
|
|
6
|
+
usdValue: string;
|
|
7
|
+
priceChange?: number | null;
|
|
8
|
+
}
|
|
9
|
+
export declare function TokenBalanceRow({ icon, name, balance, usdValue, priceChange }: TokenBalanceRowProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TokenBalanceRow = TokenBalanceRow;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const lucide_react_1 = require("lucide-react");
|
|
6
|
+
function TokenBalanceRow({ icon, name, balance, usdValue, priceChange }) {
|
|
7
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex h-10 w-10 items-center justify-center rounded-full", children: icon }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-2", children: (0, jsx_runtime_1.jsx)("span", { className: "text-b3-grey font-neue-montreal-semibold", children: name }) }), (0, jsx_runtime_1.jsx)("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: balance })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-b3-grey font-neue-montreal-semibold", children: ["$", usdValue] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-1", children: priceChange !== null && priceChange !== undefined ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Triangle, { className: `size-3 ${priceChange >= 0 ? "text-b3-positive fill-b3-positive" : "text-b3-negative fill-b3-negative rotate-180"}` }), (0, jsx_runtime_1.jsxs)("span", { className: `font-neue-montreal-medium text-sm ${priceChange >= 0 ? "text-b3-positive" : "text-b3-negative"}`, children: [priceChange >= 0 ? "+" : "", priceChange.toFixed(2), "%"] })] })) : ((0, jsx_runtime_1.jsx)("span", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: "--" })) })] })] }));
|
|
8
|
+
}
|