@b3dotfun/sdk 0.0.64 → 0.0.65-test.1
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 +73 -33
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +1 -1
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +1 -5
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +1 -5
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +1 -5
- package/dist/cjs/anyspend/react/components/common/FeeDetailPanel.js +1 -1
- package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.js +2 -2
- package/dist/cjs/anyspend/react/components/common/OrderHistory.d.ts +1 -1
- package/dist/cjs/anyspend/react/components/common/OrderHistory.js +7 -3
- package/dist/cjs/anyspend/react/components/common/PanelOnrampPayment.js +1 -1
- package/dist/cjs/anyspend/react/components/common/PointsDetailPanel.js +1 -1
- package/dist/cjs/anyspend/react/components/common/RecipientSelection.js +1 -1
- package/dist/cjs/anyspend/utils/index.d.ts +0 -1
- package/dist/cjs/anyspend/utils/index.js +0 -1
- package/dist/cjs/global-account/react/components/AccountAssets/AccountAssets.js +38 -2
- package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +139 -33
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +29 -13
- package/dist/cjs/global-account/react/components/Deposit/Deposit.d.ts +1 -0
- package/dist/cjs/global-account/react/components/Deposit/Deposit.js +65 -0
- package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.d.ts +6 -4
- package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.js +113 -279
- package/dist/cjs/global-account/react/components/LinkAccount/LinkNewAccount.d.ts +4 -0
- package/dist/cjs/global-account/react/components/LinkAccount/LinkNewAccount.js +331 -0
- package/dist/cjs/global-account/react/components/ManageAccount/AppsContent.d.ts +6 -0
- package/dist/cjs/global-account/react/components/ManageAccount/AppsContent.js +34 -0
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +2 -2
- package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.d.ts +2 -0
- package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.js +23 -0
- package/dist/cjs/global-account/react/components/ManageAccount/Header.d.ts +3 -0
- package/dist/cjs/global-account/react/components/ManageAccount/Header.js +120 -0
- package/dist/cjs/global-account/react/components/ManageAccount/HomeActions.d.ts +5 -0
- package/dist/cjs/global-account/react/components/ManageAccount/HomeActions.js +43 -0
- package/dist/cjs/global-account/react/components/ManageAccount/HomeContent.d.ts +6 -0
- package/dist/cjs/global-account/react/components/ManageAccount/HomeContent.js +16 -0
- package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +24 -193
- package/dist/cjs/global-account/react/components/ManageAccount/NFTContent.d.ts +2 -0
- package/dist/cjs/global-account/react/components/ManageAccount/NFTContent.js +15 -0
- package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.d.ts +2 -0
- package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.js +44 -0
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsContent.d.ts +7 -0
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsContent.js +50 -0
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsMenuItem.d.ts +9 -0
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsMenuItem.js +8 -0
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsProfileCard.d.ts +2 -0
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsProfileCard.js +38 -0
- package/dist/cjs/global-account/react/components/ManageAccount/TokenContent.d.ts +2 -0
- package/dist/cjs/global-account/react/components/ManageAccount/TokenContent.js +22 -0
- package/dist/cjs/global-account/react/components/ModalHeader/ModalHeader.d.ts +10 -0
- package/dist/cjs/global-account/react/components/ModalHeader/ModalHeader.js +12 -0
- package/dist/cjs/global-account/react/components/Send/Send.d.ts +5 -0
- package/dist/cjs/global-account/react/components/Send/Send.js +187 -0
- package/dist/cjs/global-account/react/components/icons/BellIcon.d.ts +3 -0
- package/dist/cjs/global-account/react/components/icons/BellIcon.js +5 -0
- package/dist/cjs/global-account/react/components/icons/ChevronDownIcon.d.ts +2 -0
- package/dist/cjs/global-account/react/components/icons/ChevronDownIcon.js +7 -0
- package/dist/cjs/global-account/react/components/icons/CopyIcon.d.ts +2 -0
- package/dist/cjs/global-account/react/components/icons/CopyIcon.js +7 -0
- package/dist/cjs/global-account/react/components/icons/LinkIcon.d.ts +3 -0
- package/dist/cjs/global-account/react/components/icons/LinkIcon.js +5 -0
- package/dist/cjs/global-account/react/components/icons/LockIcon.d.ts +3 -0
- package/dist/cjs/global-account/react/components/icons/LockIcon.js +5 -0
- package/dist/cjs/global-account/react/components/icons/WalletIcon.d.ts +2 -0
- package/dist/cjs/global-account/react/components/icons/WalletIcon.js +7 -0
- package/dist/cjs/global-account/react/components/index.d.ts +4 -2
- package/dist/cjs/global-account/react/components/index.js +11 -4
- package/dist/cjs/global-account/react/components/ui/Tabs.js +2 -2
- package/dist/cjs/global-account/react/components/ui/dialog.js +2 -2
- package/dist/cjs/global-account/react/hooks/index.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/index.js +3 -1
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +0 -11
- package/dist/cjs/global-account/react/hooks/useB3BalanceFromAddresses.js +1 -0
- package/dist/cjs/global-account/react/hooks/useGlobalAccount.d.ts +1 -0
- package/dist/cjs/global-account/react/hooks/useGlobalAccount.js +3 -0
- package/dist/cjs/global-account/react/stores/index.d.ts +1 -0
- package/dist/cjs/global-account/react/stores/index.js +3 -1
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +34 -3
- package/dist/cjs/global-account/react/stores/useRecentAddressesStore.d.ts +25 -0
- package/dist/cjs/global-account/react/stores/useRecentAddressesStore.js +36 -0
- package/dist/cjs/global-account/react/utils/profileDisplay.d.ts +2 -0
- package/dist/cjs/global-account/react/utils/profileDisplay.js +2 -2
- package/dist/cjs/shared/constants/chains/supported.d.ts +2 -2
- package/dist/cjs/shared/utils/ipfs.js +1 -1
- package/dist/esm/anyspend/react/components/AnySpend.js +74 -34
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +1 -1
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +2 -6
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +2 -6
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +2 -6
- package/dist/esm/anyspend/react/components/common/FeeDetailPanel.js +1 -1
- package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.js +2 -2
- package/dist/esm/anyspend/react/components/common/OrderHistory.d.ts +1 -1
- package/dist/esm/anyspend/react/components/common/OrderHistory.js +6 -5
- package/dist/esm/anyspend/react/components/common/PanelOnrampPayment.js +1 -1
- package/dist/esm/anyspend/react/components/common/PointsDetailPanel.js +1 -1
- package/dist/esm/anyspend/react/components/common/RecipientSelection.js +1 -1
- package/dist/esm/anyspend/utils/index.d.ts +0 -1
- package/dist/esm/anyspend/utils/index.js +0 -1
- package/dist/esm/global-account/react/components/AccountAssets/AccountAssets.js +38 -2
- package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +140 -34
- package/dist/esm/global-account/react/components/B3DynamicModal.js +30 -14
- package/dist/esm/global-account/react/components/Deposit/Deposit.d.ts +1 -0
- package/dist/esm/global-account/react/components/Deposit/Deposit.js +59 -0
- package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.d.ts +6 -4
- package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.js +113 -280
- package/dist/esm/global-account/react/components/LinkAccount/LinkNewAccount.d.ts +4 -0
- package/dist/esm/global-account/react/components/LinkAccount/LinkNewAccount.js +325 -0
- package/dist/esm/global-account/react/components/ManageAccount/AppsContent.d.ts +6 -0
- package/dist/esm/global-account/react/components/ManageAccount/AppsContent.js +32 -0
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +2 -2
- package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.d.ts +2 -0
- package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.js +21 -0
- package/dist/esm/global-account/react/components/ManageAccount/Header.d.ts +3 -0
- package/dist/esm/global-account/react/components/ManageAccount/Header.js +81 -0
- package/dist/esm/global-account/react/components/ManageAccount/HomeActions.d.ts +5 -0
- package/dist/esm/global-account/react/components/ManageAccount/HomeActions.js +41 -0
- package/dist/esm/global-account/react/components/ManageAccount/HomeContent.d.ts +6 -0
- package/dist/esm/global-account/react/components/ManageAccount/HomeContent.js +10 -0
- package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +26 -195
- package/dist/esm/global-account/react/components/ManageAccount/NFTContent.d.ts +2 -0
- package/dist/esm/global-account/react/components/ManageAccount/NFTContent.js +13 -0
- package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.d.ts +2 -0
- package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.js +42 -0
- package/dist/esm/global-account/react/components/ManageAccount/SettingsContent.d.ts +7 -0
- package/dist/esm/global-account/react/components/ManageAccount/SettingsContent.js +45 -0
- package/dist/esm/global-account/react/components/ManageAccount/SettingsMenuItem.d.ts +9 -0
- package/dist/esm/global-account/react/components/ManageAccount/SettingsMenuItem.js +6 -0
- package/dist/esm/global-account/react/components/ManageAccount/SettingsProfileCard.d.ts +2 -0
- package/dist/esm/global-account/react/components/ManageAccount/SettingsProfileCard.js +36 -0
- package/dist/esm/global-account/react/components/ManageAccount/TokenContent.d.ts +2 -0
- package/dist/esm/global-account/react/components/ManageAccount/TokenContent.js +20 -0
- package/dist/esm/global-account/react/components/ModalHeader/ModalHeader.d.ts +10 -0
- package/dist/esm/global-account/react/components/ModalHeader/ModalHeader.js +10 -0
- package/dist/esm/global-account/react/components/Send/Send.d.ts +5 -0
- package/dist/esm/global-account/react/components/Send/Send.js +181 -0
- package/dist/esm/global-account/react/components/icons/BellIcon.d.ts +3 -0
- package/dist/esm/global-account/react/components/icons/BellIcon.js +3 -0
- package/dist/esm/global-account/react/components/icons/ChevronDownIcon.d.ts +2 -0
- package/dist/esm/global-account/react/components/icons/ChevronDownIcon.js +4 -0
- package/dist/esm/global-account/react/components/icons/CopyIcon.d.ts +2 -0
- package/dist/esm/global-account/react/components/icons/CopyIcon.js +4 -0
- package/dist/esm/global-account/react/components/icons/LinkIcon.d.ts +3 -0
- package/dist/esm/global-account/react/components/icons/LinkIcon.js +3 -0
- package/dist/esm/global-account/react/components/icons/LockIcon.d.ts +3 -0
- package/dist/esm/global-account/react/components/icons/LockIcon.js +3 -0
- package/dist/esm/global-account/react/components/icons/WalletIcon.d.ts +2 -0
- package/dist/esm/global-account/react/components/icons/WalletIcon.js +4 -0
- package/dist/esm/global-account/react/components/index.d.ts +4 -2
- package/dist/esm/global-account/react/components/index.js +7 -2
- package/dist/esm/global-account/react/components/ui/Tabs.js +2 -2
- package/dist/esm/global-account/react/components/ui/dialog.js +2 -2
- package/dist/esm/global-account/react/hooks/index.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/index.js +1 -1
- package/dist/esm/global-account/react/hooks/useAuthentication.js +0 -11
- package/dist/esm/global-account/react/hooks/useB3BalanceFromAddresses.js +1 -0
- package/dist/esm/global-account/react/hooks/useGlobalAccount.d.ts +1 -0
- package/dist/esm/global-account/react/hooks/useGlobalAccount.js +3 -0
- package/dist/esm/global-account/react/stores/index.d.ts +1 -0
- package/dist/esm/global-account/react/stores/index.js +1 -0
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +34 -3
- package/dist/esm/global-account/react/stores/useRecentAddressesStore.d.ts +25 -0
- package/dist/esm/global-account/react/stores/useRecentAddressesStore.js +33 -0
- package/dist/esm/global-account/react/utils/profileDisplay.d.ts +2 -0
- package/dist/esm/global-account/react/utils/profileDisplay.js +2 -2
- package/dist/esm/shared/constants/chains/supported.d.ts +2 -2
- package/dist/esm/shared/utils/ipfs.js +1 -1
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/react/components/common/OrderHistory.d.ts +1 -1
- package/dist/types/anyspend/utils/index.d.ts +0 -1
- package/dist/types/global-account/react/components/Deposit/Deposit.d.ts +1 -0
- package/dist/types/global-account/react/components/LinkAccount/LinkAccount.d.ts +6 -4
- package/dist/types/global-account/react/components/LinkAccount/LinkNewAccount.d.ts +4 -0
- package/dist/types/global-account/react/components/ManageAccount/AppsContent.d.ts +6 -0
- package/dist/types/global-account/react/components/ManageAccount/BottomNavigation.d.ts +2 -0
- package/dist/types/global-account/react/components/ManageAccount/Header.d.ts +3 -0
- package/dist/types/global-account/react/components/ManageAccount/HomeActions.d.ts +5 -0
- package/dist/types/global-account/react/components/ManageAccount/HomeContent.d.ts +6 -0
- package/dist/types/global-account/react/components/ManageAccount/NFTContent.d.ts +2 -0
- package/dist/types/global-account/react/components/ManageAccount/ProfileSection.d.ts +2 -0
- package/dist/types/global-account/react/components/ManageAccount/SettingsContent.d.ts +7 -0
- package/dist/types/global-account/react/components/ManageAccount/SettingsMenuItem.d.ts +9 -0
- package/dist/types/global-account/react/components/ManageAccount/SettingsProfileCard.d.ts +2 -0
- package/dist/types/global-account/react/components/ManageAccount/TokenContent.d.ts +2 -0
- package/dist/types/global-account/react/components/ModalHeader/ModalHeader.d.ts +10 -0
- package/dist/types/global-account/react/components/Send/Send.d.ts +5 -0
- package/dist/types/global-account/react/components/icons/BellIcon.d.ts +3 -0
- package/dist/types/global-account/react/components/icons/ChevronDownIcon.d.ts +2 -0
- package/dist/types/global-account/react/components/icons/CopyIcon.d.ts +2 -0
- package/dist/types/global-account/react/components/icons/LinkIcon.d.ts +3 -0
- package/dist/types/global-account/react/components/icons/LockIcon.d.ts +3 -0
- package/dist/types/global-account/react/components/icons/WalletIcon.d.ts +2 -0
- package/dist/types/global-account/react/components/index.d.ts +4 -2
- package/dist/types/global-account/react/hooks/index.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useGlobalAccount.d.ts +1 -0
- package/dist/types/global-account/react/stores/index.d.ts +1 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +34 -3
- package/dist/types/global-account/react/stores/useRecentAddressesStore.d.ts +25 -0
- package/dist/types/global-account/react/utils/profileDisplay.d.ts +2 -0
- package/dist/types/shared/constants/chains/supported.d.ts +2 -2
- package/package.json +1 -1
- package/src/anyspend/react/components/AnySpend.tsx +225 -167
- package/src/anyspend/react/components/AnySpendCustom.tsx +1 -1
- package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +2 -6
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +2 -6
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +2 -7
- package/src/anyspend/react/components/common/FeeDetailPanel.tsx +1 -1
- package/src/anyspend/react/components/common/FiatPaymentMethod.tsx +2 -2
- package/src/anyspend/react/components/common/OrderHistory.tsx +8 -13
- package/src/anyspend/react/components/common/PanelOnrampPayment.tsx +1 -1
- package/src/anyspend/react/components/common/PointsDetailPanel.tsx +1 -1
- package/src/anyspend/react/components/common/RecipientSelection.tsx +1 -1
- package/src/anyspend/utils/index.ts +0 -1
- package/src/global-account/react/components/AccountAssets/AccountAssets.tsx +115 -25
- package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +303 -126
- package/src/global-account/react/components/B3DynamicModal.tsx +33 -15
- package/src/global-account/react/components/Deposit/Deposit.tsx +211 -0
- package/src/global-account/react/components/LinkAccount/LinkAccount.tsx +332 -433
- package/src/global-account/react/components/LinkAccount/LinkNewAccount.tsx +490 -0
- package/src/global-account/react/components/ManageAccount/AppsContent.tsx +79 -0
- package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +2 -3
- package/src/global-account/react/components/ManageAccount/BottomNavigation.tsx +83 -0
- package/src/global-account/react/components/ManageAccount/Header.tsx +230 -0
- package/src/global-account/react/components/ManageAccount/HomeActions.tsx +118 -0
- package/src/global-account/react/components/ManageAccount/HomeContent.tsx +42 -0
- package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +73 -589
- package/src/global-account/react/components/ManageAccount/NFTContent.tsx +24 -0
- package/src/global-account/react/components/ManageAccount/ProfileSection.tsx +74 -0
- package/src/global-account/react/components/ManageAccount/SettingsContent.tsx +87 -0
- package/src/global-account/react/components/ManageAccount/SettingsMenuItem.tsx +31 -0
- package/src/global-account/react/components/ManageAccount/SettingsProfileCard.tsx +74 -0
- package/src/global-account/react/components/ManageAccount/TokenContent.tsx +41 -0
- package/src/global-account/react/components/ModalHeader/ModalHeader.tsx +50 -0
- package/src/global-account/react/components/Send/Send.tsx +585 -0
- package/src/global-account/react/components/icons/BellIcon.tsx +15 -0
- package/src/global-account/react/components/icons/ChevronDownIcon.tsx +17 -0
- package/src/global-account/react/components/icons/CopyIcon.tsx +22 -0
- package/src/global-account/react/components/icons/LinkIcon.tsx +15 -0
- package/src/global-account/react/components/icons/LockIcon.tsx +15 -0
- package/src/global-account/react/components/icons/WalletIcon.tsx +21 -0
- package/src/global-account/react/components/index.ts +9 -2
- package/src/global-account/react/components/ui/Tabs.tsx +5 -13
- package/src/global-account/react/components/ui/dialog.tsx +32 -14
- package/src/global-account/react/hooks/index.ts +3 -0
- package/src/global-account/react/hooks/useAuthentication.ts +0 -12
- package/src/global-account/react/hooks/useB3BalanceFromAddresses.ts +1 -0
- package/src/global-account/react/hooks/useGlobalAccount.tsx +3 -1
- package/src/global-account/react/stores/index.ts +1 -0
- package/src/global-account/react/stores/useModalStore.ts +39 -2
- package/src/global-account/react/stores/useRecentAddressesStore.ts +55 -0
- package/src/global-account/react/utils/profileDisplay.ts +4 -2
- package/src/shared/utils/ipfs.ts +1 -1
- package/src/styles/index.css +6 -1
- package/dist/cjs/anyspend/utils/accountStore.d.ts +0 -7
- package/dist/cjs/anyspend/utils/accountStore.js +0 -8
- package/dist/esm/anyspend/utils/accountStore.d.ts +0 -7
- package/dist/esm/anyspend/utils/accountStore.js +0 -5
- package/dist/types/anyspend/utils/accountStore.d.ts +0 -7
- package/src/anyspend/utils/accountStore.ts +0 -12
|
@@ -1,138 +1,69 @@
|
|
|
1
1
|
import app from "@b3dotfun/sdk/global-account/app";
|
|
2
|
-
import {
|
|
3
|
-
import { thirdwebB3Mainnet } from "@b3dotfun/sdk/shared/constants/chains/b3Chain";
|
|
2
|
+
import { Button, ManageAccountModalProps, useB3, useModalStore, useQueryB3 } from "@b3dotfun/sdk/global-account/react";
|
|
4
3
|
import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { truncateAddress } from "@b3dotfun/sdk/shared/utils/truncateAddress";
|
|
5
|
+
import { Copy, Loader2, Pencil, UnlinkIcon } from "lucide-react";
|
|
6
|
+
import { useRef, useState } from "react";
|
|
7
7
|
import { toast } from "sonner";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
import { LinkAccountModalProps, useModalStore } from "../../stores/useModalStore";
|
|
8
|
+
import { useProfiles, useUnlinkProfile } from "thirdweb/react";
|
|
9
|
+
|
|
10
|
+
import { Chain } from "thirdweb";
|
|
12
11
|
import { getProfileDisplayInfo } from "../../utils/profileDisplay";
|
|
13
|
-
import { useB3 } from "../B3Provider/useB3";
|
|
14
|
-
import { AppleIcon } from "../icons/AppleIcon";
|
|
15
|
-
import { DiscordIcon } from "../icons/DiscordIcon";
|
|
16
|
-
import { FarcasterIcon } from "../icons/FarcasterIcon";
|
|
17
|
-
import { GoogleIcon } from "../icons/GoogleIcon";
|
|
18
|
-
import { XIcon } from "../icons/XIcon";
|
|
19
|
-
import { Button } from "../ui/button";
|
|
20
|
-
type OTPStrategy = "email" | "phone";
|
|
21
|
-
type SocialStrategy = "google" | "x" | "discord" | "apple" | "farcaster";
|
|
22
|
-
type Strategy = OTPStrategy | SocialStrategy | "wallet";
|
|
23
12
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
icon: React.ReactNode;
|
|
29
|
-
walletType?: WalletId;
|
|
30
|
-
}
|
|
13
|
+
// Helper function to check if a string is a wallet address and format it
|
|
14
|
+
const formatProfileTitle = (title: string): { displayTitle: string; isAddress: boolean } => {
|
|
15
|
+
// Check if title looks like an Ethereum address (0x followed by 40 hex characters)
|
|
16
|
+
const isEthereumAddress = /^0x[a-fA-F0-9]{40}$/.test(title);
|
|
31
17
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{ id: "apple", label: "Apple", enabled: true, icon: <AppleIcon className="size-6" /> },
|
|
39
|
-
{
|
|
40
|
-
id: "farcaster",
|
|
41
|
-
label: "Farcaster",
|
|
42
|
-
enabled: true,
|
|
43
|
-
icon: <FarcasterIcon className="size-6" />,
|
|
44
|
-
},
|
|
45
|
-
];
|
|
18
|
+
if (isEthereumAddress) {
|
|
19
|
+
return {
|
|
20
|
+
displayTitle: truncateAddress(title),
|
|
21
|
+
isAddress: true,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
46
24
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
icon: <WalletIcon className="size-6" />,
|
|
53
|
-
walletType: "com.coinbase.wallet",
|
|
54
|
-
},
|
|
55
|
-
{ id: "wallet", label: "Wallet", enabled: true, icon: <WalletIcon className="size-6" />, walletType: "io.metamask" },
|
|
56
|
-
{
|
|
57
|
-
id: "wallet",
|
|
58
|
-
label: "Wallet",
|
|
59
|
-
enabled: true,
|
|
60
|
-
icon: <WalletIcon className="size-6" />,
|
|
61
|
-
walletType: "me.rainbow",
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
id: "wallet",
|
|
65
|
-
label: "Wallet",
|
|
66
|
-
enabled: true,
|
|
67
|
-
icon: <WalletIcon className="size-6" />,
|
|
68
|
-
walletType: "app.phantom",
|
|
69
|
-
},
|
|
70
|
-
{ id: "wallet", label: "Wallet", enabled: true, icon: <WalletIcon className="size-6" />, walletType: "io.rabby" },
|
|
71
|
-
{
|
|
72
|
-
id: "wallet",
|
|
73
|
-
label: "Wallet",
|
|
74
|
-
enabled: true,
|
|
75
|
-
icon: <WalletIcon className="size-6" />,
|
|
76
|
-
walletType: "walletConnect",
|
|
77
|
-
},
|
|
78
|
-
];
|
|
25
|
+
return {
|
|
26
|
+
displayTitle: title,
|
|
27
|
+
isAddress: false,
|
|
28
|
+
};
|
|
29
|
+
};
|
|
79
30
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
onError,
|
|
83
|
-
onClose,
|
|
84
|
-
chain,
|
|
85
|
-
partnerId,
|
|
86
|
-
className,
|
|
87
|
-
}: LinkAccountModalProps & { className?: string }) {
|
|
88
|
-
const { isLinking, linkingMethod, setLinkingState, navigateBack, setB3ModalContentType } = useModalStore();
|
|
89
|
-
const [selectedMethod, setSelectedMethod] = useState<Strategy | null>(null);
|
|
90
|
-
const [email, setEmail] = useState("");
|
|
91
|
-
const [phone, setPhone] = useState("");
|
|
92
|
-
const [otp, setOtp] = useState("");
|
|
93
|
-
const [otpSent, setOtpSent] = useState(false);
|
|
94
|
-
const [error, setError] = useState<string | null>(null);
|
|
95
|
-
const { data: profilesRaw = [] } = useProfiles({ client });
|
|
31
|
+
import { Referrals, Users } from "@b3dotfun/b3-api";
|
|
32
|
+
import ModalHeader from "../ModalHeader/ModalHeader";
|
|
96
33
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
34
|
+
export const LinkAccount = ({
|
|
35
|
+
partnerId,
|
|
36
|
+
onLogout,
|
|
37
|
+
chain,
|
|
38
|
+
}: {
|
|
39
|
+
partnerId: string;
|
|
40
|
+
onLogout?: () => void;
|
|
41
|
+
chain: Chain;
|
|
42
|
+
}) => {
|
|
43
|
+
const [unlinkingAccountId, setUnlinkingAccountId] = useState<string | null>(null);
|
|
44
|
+
const { data: profilesRaw = [], isLoading: isLoadingProfiles } = useProfiles({ client });
|
|
45
|
+
const { mutate: unlinkProfile, isPending: isUnlinking } = useUnlinkProfile();
|
|
46
|
+
const setB3ModalContentType = useModalStore(state => state.setB3ModalContentType);
|
|
47
|
+
const isLinking = useModalStore(state => state.isLinking);
|
|
48
|
+
const setB3ModalOpen = useModalStore(state => state.setB3ModalOpen);
|
|
49
|
+
const contentType = useModalStore(state => state.contentType);
|
|
50
|
+
const { user, setUser } = useB3();
|
|
51
|
+
const [isUpdatingCode, setIsUpdatingCode] = useState(false);
|
|
52
|
+
const [newReferralCode, setNewReferralCode] = useState("");
|
|
53
|
+
const [isEditingCode, setIsEditingCode] = useState(false);
|
|
54
|
+
const referallCodeRef = useRef<HTMLInputElement>(null);
|
|
55
|
+
const { data: referrals, isLoading: isLoadingReferrals } = useQueryB3(
|
|
56
|
+
"referrals",
|
|
57
|
+
"find",
|
|
58
|
+
{ query: { referrerId: user?.userId } },
|
|
59
|
+
!!user?.userId,
|
|
105
60
|
);
|
|
106
|
-
|
|
107
|
-
const profiles = profilesRaw
|
|
108
|
-
.filter((profile: any) => !["custom_auth_endpoint"].includes(profile.type))
|
|
109
|
-
.map((profile: any) => ({
|
|
110
|
-
...getProfileDisplayInfo(profile),
|
|
111
|
-
originalProfile: profile,
|
|
112
|
-
}));
|
|
113
|
-
|
|
114
|
-
const { account } = useB3();
|
|
115
|
-
const { mutate: linkProfile } = useLinkProfile();
|
|
116
|
-
|
|
117
|
-
const onSuccess = useCallback(async () => {
|
|
118
|
-
await onSuccessCallback?.();
|
|
119
|
-
}, [onSuccessCallback]);
|
|
120
|
-
|
|
121
|
-
// Reset linking state when component unmounts
|
|
122
|
-
useEffect(() => {
|
|
123
|
-
return () => {
|
|
124
|
-
if (isLinking) {
|
|
125
|
-
setLinkingState(false);
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
}, [isLinking, setLinkingState]);
|
|
61
|
+
const showReferralInfo = (contentType as ManageAccountModalProps)?.showReferralInfo ?? false;
|
|
129
62
|
|
|
130
63
|
const mutationOptions = {
|
|
131
64
|
onError: (error: Error) => {
|
|
132
|
-
console.error("Error
|
|
65
|
+
console.error("Error Unlinking account:", error);
|
|
133
66
|
toast.error(error.message);
|
|
134
|
-
setLinkingState(false);
|
|
135
|
-
onError?.(error);
|
|
136
67
|
},
|
|
137
68
|
onSuccess: async (data: any) => {
|
|
138
69
|
console.log("Raw Link Account Data:", data);
|
|
@@ -145,348 +76,316 @@ export function LinkAccount({
|
|
|
145
76
|
},
|
|
146
77
|
};
|
|
147
78
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if (!email) {
|
|
151
|
-
setError("Please enter your email address");
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
155
|
-
setError("Please enter a valid email address");
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
} else if (selectedMethod === "phone") {
|
|
159
|
-
if (!phone) {
|
|
160
|
-
setError("Please enter your phone number");
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
163
|
-
if (!/^\+?[\d\s-]{10,}$/.test(phone)) {
|
|
164
|
-
setError("Please enter a valid phone number");
|
|
165
|
-
return false;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
setError(null);
|
|
169
|
-
return true;
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
const handleSendOTP = async () => {
|
|
173
|
-
if (!validateInput()) return;
|
|
79
|
+
// Fetch referred users
|
|
80
|
+
const currentReferralCode = user?.referralCode || user?.userId || "";
|
|
174
81
|
|
|
82
|
+
const handleCopyCode = async () => {
|
|
175
83
|
try {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (selectedMethod === "email") {
|
|
180
|
-
await preAuthenticate({
|
|
181
|
-
client,
|
|
182
|
-
strategy: "email",
|
|
183
|
-
email,
|
|
184
|
-
ecosystem: {
|
|
185
|
-
id: ecosystemWalletId,
|
|
186
|
-
partnerId: partnerId,
|
|
187
|
-
},
|
|
188
|
-
});
|
|
189
|
-
} else if (selectedMethod === "phone") {
|
|
190
|
-
await preAuthenticate({
|
|
191
|
-
client,
|
|
192
|
-
strategy: "phone",
|
|
193
|
-
phoneNumber: phone,
|
|
194
|
-
ecosystem: {
|
|
195
|
-
id: ecosystemWalletId,
|
|
196
|
-
partnerId: partnerId,
|
|
197
|
-
},
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
setOtpSent(true);
|
|
84
|
+
await navigator.clipboard.writeText(currentReferralCode);
|
|
85
|
+
toast.success("Referral code copied to clipboard!");
|
|
202
86
|
} catch (error) {
|
|
203
|
-
|
|
204
|
-
setError(error instanceof Error ? error.message : "Failed to send OTP");
|
|
205
|
-
onError?.(error as Error);
|
|
206
|
-
setLinkingState(false);
|
|
87
|
+
toast.error("Failed to copy referral code");
|
|
207
88
|
}
|
|
208
89
|
};
|
|
209
90
|
|
|
210
|
-
const
|
|
211
|
-
if (!
|
|
212
|
-
console.error("No OTP entered");
|
|
213
|
-
setError("Please enter the verification code");
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
91
|
+
const handleUpdateReferralCode = async () => {
|
|
92
|
+
if (!newReferralCode) return;
|
|
216
93
|
|
|
94
|
+
setIsUpdatingCode(true);
|
|
217
95
|
try {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
email,
|
|
228
|
-
verificationCode: otp,
|
|
229
|
-
},
|
|
230
|
-
mutationOptions,
|
|
231
|
-
);
|
|
232
|
-
} else if (selectedMethod === "phone") {
|
|
233
|
-
await linkProfile(
|
|
234
|
-
{
|
|
235
|
-
client,
|
|
236
|
-
strategy: "phone",
|
|
237
|
-
phoneNumber: phone,
|
|
238
|
-
verificationCode: otp,
|
|
239
|
-
},
|
|
240
|
-
mutationOptions,
|
|
241
|
-
);
|
|
242
|
-
}
|
|
96
|
+
// @ts-expect-error - setReferralCode is not typed for some reason
|
|
97
|
+
const newUser = await app.service("users").setReferralCode({
|
|
98
|
+
userId: user?.userId,
|
|
99
|
+
referralCode: newReferralCode,
|
|
100
|
+
});
|
|
101
|
+
setUser(newUser as unknown as Users);
|
|
102
|
+
toast.success("Referral code updated successfully!");
|
|
103
|
+
setIsEditingCode(false);
|
|
104
|
+
setNewReferralCode("");
|
|
243
105
|
} catch (error) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
106
|
+
toast.error("Failed to update referral code");
|
|
107
|
+
} finally {
|
|
108
|
+
setIsUpdatingCode(false);
|
|
247
109
|
}
|
|
248
110
|
};
|
|
249
111
|
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
}
|
|
257
|
-
await linkProfile(
|
|
258
|
-
{
|
|
259
|
-
client,
|
|
260
|
-
strategy: "wallet",
|
|
261
|
-
wallet: createWallet(walletType),
|
|
262
|
-
chain: thirdwebB3Mainnet,
|
|
263
|
-
},
|
|
264
|
-
mutationOptions,
|
|
265
|
-
);
|
|
266
|
-
} catch (error) {
|
|
267
|
-
console.error("Error linking account:", error);
|
|
268
|
-
setError(error instanceof Error ? error.message : "Failed to link account");
|
|
269
|
-
onError?.(error as Error);
|
|
270
|
-
}
|
|
271
|
-
};
|
|
112
|
+
const profiles = profilesRaw
|
|
113
|
+
.filter((profile: any) => !["custom_auth_endpoint"].includes(profile.type))
|
|
114
|
+
.map((profile: any) => ({
|
|
115
|
+
...getProfileDisplayInfo(profile),
|
|
116
|
+
originalProfile: profile,
|
|
117
|
+
}));
|
|
272
118
|
|
|
273
|
-
const
|
|
119
|
+
const handleUnlink = async (profile: any) => {
|
|
120
|
+
setUnlinkingAccountId(profile.title);
|
|
274
121
|
try {
|
|
275
|
-
|
|
276
|
-
setLinkingState(true, strategy);
|
|
277
|
-
setError(null);
|
|
278
|
-
|
|
279
|
-
const result = await linkProfile(
|
|
280
|
-
{
|
|
281
|
-
client,
|
|
282
|
-
strategy,
|
|
283
|
-
},
|
|
284
|
-
mutationOptions,
|
|
285
|
-
);
|
|
286
|
-
|
|
287
|
-
console.log("result", result);
|
|
288
|
-
|
|
289
|
-
// Don't close the modal yet, wait for auth to complete
|
|
290
|
-
onSuccess?.();
|
|
122
|
+
unlinkProfile({ client, profileToUnlink: profile.originalProfile }, mutationOptions);
|
|
291
123
|
} catch (error) {
|
|
292
|
-
console.error("Error
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
setLinkingState(false);
|
|
124
|
+
console.error("Error unlinking account:", error);
|
|
125
|
+
} finally {
|
|
126
|
+
setUnlinkingAccountId(null);
|
|
296
127
|
}
|
|
297
128
|
};
|
|
298
129
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}, [isLinking, linkingMethod, selectedMethod, onClose, setLinkingState]);
|
|
317
|
-
|
|
318
|
-
const handleBack = useCallback(() => {
|
|
319
|
-
if (isLinking) return;
|
|
320
|
-
setSelectedMethod(null);
|
|
321
|
-
setEmail("");
|
|
322
|
-
setPhone("");
|
|
323
|
-
setOtp("");
|
|
324
|
-
setOtpSent(false);
|
|
325
|
-
setError(null);
|
|
326
|
-
setLinkingState(false);
|
|
327
|
-
}, [isLinking, setSelectedMethod, setEmail, setPhone, setOtp, setOtpSent, setError, setLinkingState]);
|
|
328
|
-
|
|
329
|
-
const handleFinishedLinking = useCallback(
|
|
330
|
-
(success: boolean) => {
|
|
331
|
-
if (success) {
|
|
332
|
-
onSuccess?.();
|
|
333
|
-
onClose?.();
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
setLinkingState(false);
|
|
337
|
-
navigateBack();
|
|
338
|
-
setB3ModalContentType({
|
|
339
|
-
type: "manageAccount",
|
|
340
|
-
activeTab: "settings",
|
|
341
|
-
setActiveTab: () => {},
|
|
342
|
-
chain,
|
|
343
|
-
partnerId,
|
|
344
|
-
});
|
|
345
|
-
},
|
|
346
|
-
[chain, navigateBack, partnerId, setB3ModalContentType, setLinkingState, onSuccess, onClose],
|
|
347
|
-
);
|
|
348
|
-
|
|
349
|
-
useEffect(() => {
|
|
350
|
-
if (isLinking) {
|
|
351
|
-
handleFinishedLinking(true);
|
|
352
|
-
}
|
|
353
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
354
|
-
}, [profiles.length]);
|
|
355
|
-
|
|
356
|
-
if (!account) {
|
|
357
|
-
return <div className="text-b3-foreground-muted py-8 text-center">Please connect your account first</div>;
|
|
358
|
-
}
|
|
130
|
+
const handleOpenLinkModal = () => {
|
|
131
|
+
setB3ModalOpen(true);
|
|
132
|
+
setB3ModalContentType({
|
|
133
|
+
type: "linkNewAccount",
|
|
134
|
+
partnerId,
|
|
135
|
+
chain,
|
|
136
|
+
onSuccess: async () => {
|
|
137
|
+
// Let the LinkAccount component handle modal closing
|
|
138
|
+
},
|
|
139
|
+
onError: () => {
|
|
140
|
+
// Let the LinkAccount component handle errors
|
|
141
|
+
},
|
|
142
|
+
onClose: () => {
|
|
143
|
+
// Let the LinkAccount component handle closing
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
};
|
|
359
147
|
|
|
360
148
|
return (
|
|
361
|
-
<div className=
|
|
362
|
-
<
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
149
|
+
<div className="linked-accounts-settings">
|
|
150
|
+
<ModalHeader title="Linked Accounts" />
|
|
151
|
+
{/* Linked Accounts Section */}
|
|
152
|
+
<div className="linked-accounts-section space-y-4 p-5">
|
|
153
|
+
{isLoadingProfiles ? (
|
|
154
|
+
<div className="linked-accounts-loading flex justify-center py-8">
|
|
155
|
+
<Loader2 className="text-b3-grey animate-spin" />
|
|
156
|
+
</div>
|
|
157
|
+
) : profiles.length > 0 ? (
|
|
158
|
+
<div className="linked-accounts-list space-y-4">
|
|
159
|
+
{profiles.map(profile => (
|
|
160
|
+
<div
|
|
161
|
+
key={profile.title}
|
|
162
|
+
className="linked-account-item hover:bg-b3-line group flex cursor-pointer items-center justify-between rounded-xl p-4 transition-colors"
|
|
163
|
+
>
|
|
164
|
+
<div className="linked-account-info flex items-center gap-3">
|
|
165
|
+
{profile.imageUrl ? (
|
|
166
|
+
<img
|
|
167
|
+
src={profile.imageUrl}
|
|
168
|
+
alt={profile.title}
|
|
169
|
+
className="linked-account-avatar linked-account-avatar-image size-10 rounded-full"
|
|
170
|
+
/>
|
|
171
|
+
) : (
|
|
172
|
+
<div className="linked-account-avatar linked-account-avatar-placeholder bg-b3-primary-wash flex h-10 w-10 items-center justify-center rounded-full">
|
|
173
|
+
<span className="linked-account-initial text-b3-grey font-neue-montreal-semibold text-sm uppercase">
|
|
174
|
+
{profile.initial}
|
|
175
|
+
</span>
|
|
176
|
+
</div>
|
|
177
|
+
)}
|
|
178
|
+
<div className="linked-account-details">
|
|
179
|
+
<div className="linked-account-title-row flex items-center gap-2">
|
|
180
|
+
{(() => {
|
|
181
|
+
const { displayTitle, isAddress } = formatProfileTitle(profile.title);
|
|
182
|
+
|
|
183
|
+
const handleCopyAddress = async (e: React.MouseEvent) => {
|
|
184
|
+
e.stopPropagation();
|
|
185
|
+
try {
|
|
186
|
+
await navigator.clipboard.writeText(profile.title);
|
|
187
|
+
toast.success("Address copied to clipboard!");
|
|
188
|
+
} catch (error) {
|
|
189
|
+
toast.error("Failed to copy address");
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
return (
|
|
194
|
+
<div className="flex items-center gap-1">
|
|
195
|
+
<span
|
|
196
|
+
className={`linked-account-title text-b3-grey font-neue-montreal-semibold ${
|
|
197
|
+
isAddress
|
|
198
|
+
? "font-mono text-sm" // Use monospace font for addresses
|
|
199
|
+
: "break-words" // Use break-words for emails/names (better than break-all)
|
|
200
|
+
}`}
|
|
201
|
+
title={isAddress ? profile.title : undefined} // Show full address on hover
|
|
202
|
+
>
|
|
203
|
+
{displayTitle}
|
|
204
|
+
</span>
|
|
205
|
+
{isAddress && (
|
|
206
|
+
<button
|
|
207
|
+
onClick={handleCopyAddress}
|
|
208
|
+
className="linked-account-copy-button ml-1 rounded p-1 opacity-0 transition-opacity hover:bg-gray-100 group-hover:opacity-100"
|
|
209
|
+
title="Copy full address"
|
|
210
|
+
>
|
|
211
|
+
<Copy size={12} className="text-gray-500 hover:text-gray-700" />
|
|
212
|
+
</button>
|
|
213
|
+
)}
|
|
214
|
+
</div>
|
|
215
|
+
);
|
|
216
|
+
})()}
|
|
217
|
+
<span className="linked-account-type text-b3-foreground-muted font-neue-montreal-medium bg-b3-primary-wash rounded px-2 py-0.5 text-xs">
|
|
218
|
+
{profile.type.toUpperCase()}
|
|
219
|
+
</span>
|
|
220
|
+
</div>
|
|
221
|
+
<div className="linked-account-subtitle text-b3-foreground-muted font-neue-montreal-medium text-sm">
|
|
222
|
+
{profile.subtitle}
|
|
223
|
+
</div>
|
|
394
224
|
</div>
|
|
395
|
-
<span className="b3-link-account-method-label font-medium">{method.label}</span>
|
|
396
225
|
</div>
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
)}
|
|
419
|
-
</div>
|
|
420
|
-
) : (
|
|
421
|
-
<div className="b3-link-account-form space-y-4">
|
|
422
|
-
{selectedMethod === "email" && (
|
|
423
|
-
<div className="space-y-2">
|
|
424
|
-
<label className="text-b3-grey font-neue-montreal-medium text-sm">Email Address</label>
|
|
425
|
-
<input
|
|
426
|
-
type="email"
|
|
427
|
-
placeholder="Enter your email"
|
|
428
|
-
className="bg-b3-line text-b3-grey font-neue-montreal-medium focus:ring-b3-primary-blue/20 w-full rounded-xl p-4 focus:outline-none focus:ring-2"
|
|
429
|
-
value={email}
|
|
430
|
-
onChange={e => setEmail(e.target.value)}
|
|
431
|
-
disabled={otpSent || (isLinking && linkingMethod === "email")}
|
|
432
|
-
/>
|
|
433
|
-
</div>
|
|
434
|
-
)}
|
|
226
|
+
<Button
|
|
227
|
+
variant="ghost"
|
|
228
|
+
size="icon"
|
|
229
|
+
className="linked-account-unlink-button text-b3-grey hover:text-b3-negative"
|
|
230
|
+
onClick={() => handleUnlink(profile)}
|
|
231
|
+
disabled={unlinkingAccountId === profile.title || isUnlinking}
|
|
232
|
+
>
|
|
233
|
+
{unlinkingAccountId === profile.title || isUnlinking ? (
|
|
234
|
+
<Loader2 className="linked-account-unlink-loading animate-spin" />
|
|
235
|
+
) : (
|
|
236
|
+
<UnlinkIcon size={16} className="linked-account-unlink-icon" />
|
|
237
|
+
)}
|
|
238
|
+
</Button>
|
|
239
|
+
</div>
|
|
240
|
+
))}
|
|
241
|
+
</div>
|
|
242
|
+
) : (
|
|
243
|
+
<div className="linked-accounts-empty text-b3-foreground-muted py-8 text-center">
|
|
244
|
+
No linked accounts found
|
|
245
|
+
</div>
|
|
246
|
+
)}
|
|
435
247
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
248
|
+
{/* Link New Account Button */}
|
|
249
|
+
<Button
|
|
250
|
+
onClick={handleOpenLinkModal}
|
|
251
|
+
disabled={isLinking}
|
|
252
|
+
className="bg-b3-primary-blue hover:bg-b3-primary-blue/90 border-white/12 group relative h-12 w-full rounded-xl border-2 px-[18px] text-base font-semibold text-white shadow-[inset_0px_0px_0px_1px_rgba(10,13,18,0.18),inset_0px_-2px_0px_0px_rgba(10,13,18,0.05)] transition-all"
|
|
253
|
+
>
|
|
254
|
+
<div className="flex items-center justify-center gap-1.5">
|
|
255
|
+
<svg
|
|
256
|
+
width="20"
|
|
257
|
+
height="20"
|
|
258
|
+
viewBox="0 0 20 20"
|
|
259
|
+
fill="none"
|
|
260
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
261
|
+
className="shrink-0"
|
|
262
|
+
>
|
|
263
|
+
<path
|
|
264
|
+
d="M10.0001 13.3333V6.66667M6.66675 10H13.3334M18.3334 10C18.3334 14.6024 14.6025 18.3333 10.0001 18.3333C5.39771 18.3333 1.66675 14.6024 1.66675 10C1.66675 5.39763 5.39771 1.66667 10.0001 1.66667C14.6025 1.66667 18.3334 5.39763 18.3334 10Z"
|
|
265
|
+
stroke="currentColor"
|
|
266
|
+
strokeWidth="1.67"
|
|
267
|
+
strokeLinecap="round"
|
|
268
|
+
strokeLinejoin="round"
|
|
446
269
|
/>
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
{error && <div className="text-b3-negative font-neue-montreal-medium py-2 text-sm">{error}</div>}
|
|
270
|
+
</svg>
|
|
271
|
+
<span>Link new account</span>
|
|
272
|
+
</div>
|
|
273
|
+
</Button>
|
|
274
|
+
</div>
|
|
454
275
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
276
|
+
{showReferralInfo && (
|
|
277
|
+
/* Referral Section */
|
|
278
|
+
<div className="referrals-section space-y-4">
|
|
279
|
+
<h3 className="referrals-title text-b3-grey font-neue-montreal-semibold text-xl">Referrals</h3>
|
|
280
|
+
|
|
281
|
+
{/* Referral Code */}
|
|
282
|
+
<div className="referral-code-container bg-b3-line rounded-xl p-4">
|
|
283
|
+
{isEditingCode && (
|
|
284
|
+
<div className="referral-code-header-editing">
|
|
285
|
+
<div className="referral-code-title text-b3-grey font-neue-montreal-semibold">Your Referral Code</div>
|
|
286
|
+
<div className="referral-code-description text-b3-foreground-muted font-neue-montreal-medium text-sm">
|
|
287
|
+
Share this code with friends to earn rewards
|
|
467
288
|
</div>
|
|
468
|
-
<Button
|
|
469
|
-
className="bg-b3-primary-blue hover:bg-b3-primary-blue/90 font-neue-montreal-semibold h-12 w-full text-white"
|
|
470
|
-
onClick={handleLinkAccount}
|
|
471
|
-
>
|
|
472
|
-
Link Account
|
|
473
|
-
</Button>
|
|
474
289
|
</div>
|
|
475
|
-
)
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
290
|
+
)}
|
|
291
|
+
<div className="referral-code-content flex items-center justify-between">
|
|
292
|
+
{!isEditingCode && (
|
|
293
|
+
<div className="referral-code-header">
|
|
294
|
+
<div className="referral-code-title text-b3-grey font-neue-montreal-semibold">Your Referral Code</div>
|
|
295
|
+
<div className="referral-code-description text-b3-foreground-muted font-neue-montreal-medium text-sm">
|
|
296
|
+
Share this code with friends to earn rewards
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
)}
|
|
300
|
+
<div className="referral-code-actions flex items-center gap-2">
|
|
301
|
+
{isEditingCode ? (
|
|
302
|
+
<div className="referral-code-edit-form flex items-center gap-2">
|
|
303
|
+
<input
|
|
304
|
+
type="text"
|
|
305
|
+
value={newReferralCode}
|
|
306
|
+
onChange={e => setNewReferralCode(e.target.value)}
|
|
307
|
+
className="referral-code-input rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-sm"
|
|
308
|
+
placeholder="Enter new code"
|
|
309
|
+
ref={referallCodeRef}
|
|
310
|
+
/>
|
|
311
|
+
<Button
|
|
312
|
+
size="sm"
|
|
313
|
+
className="referral-code-save-button"
|
|
314
|
+
onClick={handleUpdateReferralCode}
|
|
315
|
+
disabled={isUpdatingCode || !newReferralCode}
|
|
316
|
+
>
|
|
317
|
+
{isUpdatingCode ? (
|
|
318
|
+
<Loader2 className="referral-code-save-loading h-4 w-4 animate-spin" />
|
|
319
|
+
) : (
|
|
320
|
+
"Save"
|
|
321
|
+
)}
|
|
322
|
+
</Button>
|
|
323
|
+
<Button
|
|
324
|
+
size="sm"
|
|
325
|
+
variant="ghost"
|
|
326
|
+
className="referral-code-cancel-button"
|
|
327
|
+
onClick={() => {
|
|
328
|
+
setIsEditingCode(false);
|
|
329
|
+
setNewReferralCode("");
|
|
330
|
+
}}
|
|
331
|
+
>
|
|
332
|
+
Cancel
|
|
333
|
+
</Button>
|
|
334
|
+
</div>
|
|
483
335
|
) : (
|
|
484
|
-
|
|
336
|
+
<>
|
|
337
|
+
<div className="referral-code-display rounded-lg border border-gray-200 bg-white px-3 py-1.5 text-sm">
|
|
338
|
+
{currentReferralCode}
|
|
339
|
+
</div>
|
|
340
|
+
<Button size="icon" variant="ghost" className="referral-code-copy-button" onClick={handleCopyCode}>
|
|
341
|
+
<Copy className="referral-code-copy-icon h-4 w-4" />
|
|
342
|
+
</Button>
|
|
343
|
+
<Button
|
|
344
|
+
size="icon"
|
|
345
|
+
variant="ghost"
|
|
346
|
+
className="referral-code-edit-button"
|
|
347
|
+
onClick={() => {
|
|
348
|
+
setIsEditingCode(true);
|
|
349
|
+
setTimeout(() => {
|
|
350
|
+
referallCodeRef.current?.focus();
|
|
351
|
+
}, 100);
|
|
352
|
+
}}
|
|
353
|
+
>
|
|
354
|
+
<Pencil className="referral-code-edit-icon h-4 w-4" />
|
|
355
|
+
</Button>
|
|
356
|
+
</>
|
|
485
357
|
)}
|
|
486
|
-
</
|
|
487
|
-
|
|
358
|
+
</div>
|
|
359
|
+
</div>
|
|
360
|
+
</div>
|
|
361
|
+
|
|
362
|
+
{/* Referred Users */}
|
|
363
|
+
<div className="referred-users-container bg-b3-line rounded-xl p-4">
|
|
364
|
+
<div className="referred-users-title text-b3-grey font-neue-montreal-semibold mb-4">Referred Users</div>
|
|
365
|
+
{isLoadingReferrals ? (
|
|
366
|
+
<div className="referred-users-loading flex justify-center py-4">
|
|
367
|
+
<Loader2 className="h-6 w-6 animate-spin text-gray-400" />
|
|
368
|
+
</div>
|
|
369
|
+
) : referrals?.data?.length ? (
|
|
370
|
+
<div className="referred-users-list space-y-3">
|
|
371
|
+
{referrals.data.map((referral: Referrals) => (
|
|
372
|
+
<div
|
|
373
|
+
key={String(referral._id)}
|
|
374
|
+
className="referred-user-item flex items-center justify-between rounded-lg bg-white p-3"
|
|
375
|
+
>
|
|
376
|
+
<div className="referred-user-id text-sm font-medium">{referral.referreeId}</div>
|
|
377
|
+
<div className="referred-user-date text-sm text-gray-500">
|
|
378
|
+
{new Date(referral.createdAt).toLocaleDateString()}
|
|
379
|
+
</div>
|
|
380
|
+
</div>
|
|
381
|
+
))}
|
|
382
|
+
</div>
|
|
383
|
+
) : (
|
|
384
|
+
<div className="referred-users-empty py-4 text-center text-gray-500">No referred users yet</div>
|
|
385
|
+
)}
|
|
386
|
+
</div>
|
|
488
387
|
</div>
|
|
489
388
|
)}
|
|
490
389
|
</div>
|
|
491
390
|
);
|
|
492
|
-
}
|
|
391
|
+
};
|