@b3dotfun/sdk 0.0.65-test.5 → 0.0.66-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 +69 -97
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +23 -10
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +45 -14
- package/dist/cjs/anyspend/react/components/AnySpendDepositUpside.d.ts +11 -0
- package/dist/cjs/anyspend/react/components/AnySpendDepositUpside.js +41 -0
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.d.ts +1 -1
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +14 -251
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.d.ts +6 -0
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +3 -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 +3 -7
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +2 -10
- 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/react/components/index.d.ts +1 -0
- package/dist/cjs/anyspend/react/components/index.js +4 -1
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +5 -1
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +16 -10
- package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +7 -5
- package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +13 -9
- package/dist/cjs/anyspend/react/hooks/useCryptoPaymentMethodState.d.ts +42 -0
- package/dist/cjs/anyspend/react/hooks/useCryptoPaymentMethodState.js +51 -0
- package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/cjs/global-account/react/components/AccountAssets/AccountAssets.js +2 -38
- package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +0 -1
- package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +35 -251
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +15 -23
- package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.d.ts +4 -6
- package/dist/cjs/global-account/react/components/LinkAccount/LinkAccount.js +279 -113
- package/dist/cjs/global-account/react/components/ManageAccount/BalanceContent.js +5 -6
- package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +193 -24
- package/dist/cjs/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/cjs/global-account/react/components/ProfileEditor/ProfileEditor.js +141 -0
- package/dist/cjs/global-account/react/components/SignInWithB3/SignIn.js +1 -3
- package/dist/cjs/global-account/react/components/index.d.ts +4 -5
- package/dist/cjs/global-account/react/components/index.js +9 -14
- 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/components/ui/drawer.js +1 -1
- package/dist/cjs/global-account/react/hooks/index.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/index.js +1 -3
- package/dist/cjs/global-account/react/hooks/useAccountWallet.d.ts +0 -1
- package/dist/cjs/global-account/react/hooks/useAccountWallet.js +0 -18
- package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/cjs/global-account/react/hooks/useB3BalanceFromAddresses.js +0 -1
- package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +6 -14
- package/dist/cjs/global-account/react/hooks/useUserQuery.d.ts +2 -2
- package/dist/cjs/global-account/react/stores/index.d.ts +0 -1
- package/dist/cjs/global-account/react/stores/index.js +1 -3
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +26 -31
- package/dist/cjs/global-account/react/utils/profileDisplay.d.ts +0 -2
- package/dist/cjs/global-account/react/utils/profileDisplay.js +2 -2
- package/dist/cjs/shared/constants/chains/supported.d.ts +3 -3
- package/dist/cjs/shared/utils/ipfs.js +3 -10
- package/dist/esm/anyspend/react/components/AnySpend.js +70 -98
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +23 -10
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.d.ts +3 -1
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +45 -14
- package/dist/esm/anyspend/react/components/AnySpendDepositUpside.d.ts +11 -0
- package/dist/esm/anyspend/react/components/AnySpendDepositUpside.js +38 -0
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.d.ts +1 -1
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +15 -249
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.d.ts +6 -0
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +3 -5
- 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 +5 -6
- package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +2 -10
- 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/react/components/index.d.ts +1 -0
- package/dist/esm/anyspend/react/components/index.js +1 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +5 -1
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +16 -10
- package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +7 -5
- package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +13 -9
- package/dist/esm/anyspend/react/hooks/useCryptoPaymentMethodState.d.ts +42 -0
- package/dist/esm/anyspend/react/hooks/useCryptoPaymentMethodState.js +48 -0
- package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/esm/global-account/react/components/AccountAssets/AccountAssets.js +2 -38
- package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +0 -1
- package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +38 -254
- package/dist/esm/global-account/react/components/B3DynamicModal.js +15 -23
- package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.d.ts +4 -6
- package/dist/esm/global-account/react/components/LinkAccount/LinkAccount.js +280 -113
- package/dist/esm/global-account/react/components/ManageAccount/BalanceContent.js +5 -6
- package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +195 -26
- package/dist/esm/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/esm/global-account/react/components/ProfileEditor/ProfileEditor.js +135 -0
- package/dist/esm/global-account/react/components/SignInWithB3/SignIn.js +2 -4
- package/dist/esm/global-account/react/components/index.d.ts +4 -5
- package/dist/esm/global-account/react/components/index.js +5 -9
- 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/components/ui/drawer.js +1 -1
- 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/useAccountWallet.d.ts +0 -1
- package/dist/esm/global-account/react/hooks/useAccountWallet.js +0 -17
- package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/esm/global-account/react/hooks/useB3BalanceFromAddresses.js +0 -1
- package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +6 -14
- package/dist/esm/global-account/react/hooks/useUserQuery.d.ts +2 -2
- package/dist/esm/global-account/react/stores/index.d.ts +0 -1
- package/dist/esm/global-account/react/stores/index.js +0 -1
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +26 -31
- package/dist/esm/global-account/react/utils/profileDisplay.d.ts +0 -2
- package/dist/esm/global-account/react/utils/profileDisplay.js +2 -2
- package/dist/esm/shared/constants/chains/supported.d.ts +3 -3
- package/dist/esm/shared/utils/ipfs.js +3 -10
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/react/components/AnySpendCustomExactIn.d.ts +3 -1
- package/dist/types/anyspend/react/components/AnySpendDepositUpside.d.ts +11 -0
- package/dist/types/anyspend/react/components/AnyspendDepositHype.d.ts +1 -1
- package/dist/types/anyspend/react/components/common/CryptoPaymentMethod.d.ts +6 -0
- package/dist/types/anyspend/react/components/common/OrderHistory.d.ts +1 -1
- package/dist/types/anyspend/react/components/index.d.ts +1 -0
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +5 -1
- package/dist/types/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +7 -5
- package/dist/types/anyspend/react/hooks/useCryptoPaymentMethodState.d.ts +42 -0
- package/dist/types/anyspend/react/hooks/useSigMint.d.ts +1 -1
- package/dist/types/global-account/react/components/AvatarEditor/AvatarEditor.d.ts +0 -1
- package/dist/types/global-account/react/components/LinkAccount/LinkAccount.d.ts +4 -6
- package/dist/types/global-account/react/components/ProfileEditor/ProfileEditor.d.ts +6 -0
- package/dist/types/global-account/react/components/index.d.ts +4 -5
- package/dist/types/global-account/react/hooks/index.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useAccountWallet.d.ts +0 -1
- package/dist/types/global-account/react/hooks/useAuthentication.d.ts +2 -2
- package/dist/types/global-account/react/hooks/useUserQuery.d.ts +2 -2
- package/dist/types/global-account/react/stores/index.d.ts +0 -1
- package/dist/types/global-account/react/stores/useModalStore.d.ts +26 -31
- package/dist/types/global-account/react/utils/profileDisplay.d.ts +0 -2
- package/dist/types/shared/constants/chains/supported.d.ts +3 -3
- package/package.json +1 -2
- package/src/anyspend/react/components/AnySpend.tsx +218 -256
- package/src/anyspend/react/components/AnySpendCustom.tsx +31 -16
- package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +56 -13
- package/src/anyspend/react/components/AnySpendDepositUpside.tsx +81 -0
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +36 -524
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +14 -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 +13 -8
- package/src/anyspend/react/components/common/OrderTokenAmount.tsx +2 -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/react/components/index.ts +1 -0
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +24 -12
- package/src/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.ts +20 -12
- package/src/anyspend/react/hooks/useCryptoPaymentMethodState.ts +71 -0
- package/src/global-account/react/components/AccountAssets/AccountAssets.tsx +25 -115
- package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +128 -477
- package/src/global-account/react/components/B3DynamicModal.tsx +17 -28
- package/src/global-account/react/components/LinkAccount/LinkAccount.tsx +433 -332
- package/src/global-account/react/components/ManageAccount/BalanceContent.tsx +10 -6
- package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +589 -73
- package/src/global-account/react/components/ProfileEditor/ProfileEditor.tsx +265 -0
- package/src/global-account/react/components/SignInWithB3/SignIn.tsx +7 -11
- package/src/global-account/react/components/index.ts +5 -11
- package/src/global-account/react/components/ui/Tabs.tsx +13 -5
- package/src/global-account/react/components/ui/dialog.tsx +14 -32
- package/src/global-account/react/components/ui/drawer.tsx +1 -1
- package/src/global-account/react/hooks/index.ts +0 -3
- package/src/global-account/react/hooks/useAccountWallet.tsx +0 -26
- package/src/global-account/react/hooks/useB3BalanceFromAddresses.ts +0 -1
- package/src/global-account/react/hooks/useUnifiedChainSwitchAndExecute.ts +6 -12
- package/src/global-account/react/stores/index.ts +0 -1
- package/src/global-account/react/stores/useModalStore.ts +28 -35
- package/src/global-account/react/utils/profileDisplay.ts +2 -4
- package/src/shared/utils/ipfs.ts +3 -10
- package/src/styles/index.css +9 -6
- package/dist/cjs/global-account/react/components/Deposit/Deposit.d.ts +0 -1
- package/dist/cjs/global-account/react/components/Deposit/Deposit.js +0 -65
- package/dist/cjs/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.d.ts +0 -39
- package/dist/cjs/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.js +0 -37
- package/dist/cjs/global-account/react/components/LinkAccount/LinkNewAccount.d.ts +0 -4
- package/dist/cjs/global-account/react/components/LinkAccount/LinkNewAccount.js +0 -331
- package/dist/cjs/global-account/react/components/ManageAccount/AppsContent.d.ts +0 -6
- package/dist/cjs/global-account/react/components/ManageAccount/AppsContent.js +0 -34
- package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.d.ts +0 -2
- package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.js +0 -23
- package/dist/cjs/global-account/react/components/ManageAccount/Header.d.ts +0 -3
- package/dist/cjs/global-account/react/components/ManageAccount/Header.js +0 -120
- package/dist/cjs/global-account/react/components/ManageAccount/HomeActions.d.ts +0 -5
- package/dist/cjs/global-account/react/components/ManageAccount/HomeActions.js +0 -43
- package/dist/cjs/global-account/react/components/ManageAccount/HomeContent.d.ts +0 -6
- package/dist/cjs/global-account/react/components/ManageAccount/HomeContent.js +0 -16
- package/dist/cjs/global-account/react/components/ManageAccount/NFTContent.d.ts +0 -2
- package/dist/cjs/global-account/react/components/ManageAccount/NFTContent.js +0 -15
- package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.d.ts +0 -2
- package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.js +0 -47
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsContent.d.ts +0 -7
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsContent.js +0 -50
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsMenuItem.d.ts +0 -9
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsMenuItem.js +0 -8
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsProfileCard.d.ts +0 -2
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsProfileCard.js +0 -106
- package/dist/cjs/global-account/react/components/ManageAccount/TokenContent.d.ts +0 -2
- package/dist/cjs/global-account/react/components/ManageAccount/TokenContent.js +0 -22
- package/dist/cjs/global-account/react/components/ModalHeader/ModalHeader.d.ts +0 -11
- package/dist/cjs/global-account/react/components/ModalHeader/ModalHeader.js +0 -12
- package/dist/cjs/global-account/react/components/Send/Send.d.ts +0 -5
- package/dist/cjs/global-account/react/components/Send/Send.js +0 -187
- package/dist/cjs/global-account/react/components/icons/BellIcon.d.ts +0 -3
- package/dist/cjs/global-account/react/components/icons/BellIcon.js +0 -5
- package/dist/cjs/global-account/react/components/icons/ChevronDownIcon.d.ts +0 -2
- package/dist/cjs/global-account/react/components/icons/ChevronDownIcon.js +0 -7
- package/dist/cjs/global-account/react/components/icons/CopyIcon.d.ts +0 -2
- package/dist/cjs/global-account/react/components/icons/CopyIcon.js +0 -7
- package/dist/cjs/global-account/react/components/icons/LinkIcon.d.ts +0 -3
- package/dist/cjs/global-account/react/components/icons/LinkIcon.js +0 -5
- package/dist/cjs/global-account/react/components/icons/LockIcon.d.ts +0 -3
- package/dist/cjs/global-account/react/components/icons/LockIcon.js +0 -5
- package/dist/cjs/global-account/react/components/icons/WalletIcon.d.ts +0 -2
- package/dist/cjs/global-account/react/components/icons/WalletIcon.js +0 -7
- package/dist/cjs/global-account/react/stores/useRecentAddressesStore.d.ts +0 -25
- package/dist/cjs/global-account/react/stores/useRecentAddressesStore.js +0 -36
- package/dist/esm/global-account/react/components/Deposit/Deposit.d.ts +0 -1
- package/dist/esm/global-account/react/components/Deposit/Deposit.js +0 -59
- package/dist/esm/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.d.ts +0 -39
- package/dist/esm/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.js +0 -34
- package/dist/esm/global-account/react/components/LinkAccount/LinkNewAccount.d.ts +0 -4
- package/dist/esm/global-account/react/components/LinkAccount/LinkNewAccount.js +0 -325
- package/dist/esm/global-account/react/components/ManageAccount/AppsContent.d.ts +0 -6
- package/dist/esm/global-account/react/components/ManageAccount/AppsContent.js +0 -32
- package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.d.ts +0 -2
- package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.js +0 -21
- package/dist/esm/global-account/react/components/ManageAccount/Header.d.ts +0 -3
- package/dist/esm/global-account/react/components/ManageAccount/Header.js +0 -81
- package/dist/esm/global-account/react/components/ManageAccount/HomeActions.d.ts +0 -5
- package/dist/esm/global-account/react/components/ManageAccount/HomeActions.js +0 -41
- package/dist/esm/global-account/react/components/ManageAccount/HomeContent.d.ts +0 -6
- package/dist/esm/global-account/react/components/ManageAccount/HomeContent.js +0 -10
- package/dist/esm/global-account/react/components/ManageAccount/NFTContent.d.ts +0 -2
- package/dist/esm/global-account/react/components/ManageAccount/NFTContent.js +0 -13
- package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.d.ts +0 -2
- package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.js +0 -45
- package/dist/esm/global-account/react/components/ManageAccount/SettingsContent.d.ts +0 -7
- package/dist/esm/global-account/react/components/ManageAccount/SettingsContent.js +0 -45
- package/dist/esm/global-account/react/components/ManageAccount/SettingsMenuItem.d.ts +0 -9
- package/dist/esm/global-account/react/components/ManageAccount/SettingsMenuItem.js +0 -6
- package/dist/esm/global-account/react/components/ManageAccount/SettingsProfileCard.d.ts +0 -2
- package/dist/esm/global-account/react/components/ManageAccount/SettingsProfileCard.js +0 -101
- package/dist/esm/global-account/react/components/ManageAccount/TokenContent.d.ts +0 -2
- package/dist/esm/global-account/react/components/ManageAccount/TokenContent.js +0 -20
- package/dist/esm/global-account/react/components/ModalHeader/ModalHeader.d.ts +0 -11
- package/dist/esm/global-account/react/components/ModalHeader/ModalHeader.js +0 -10
- package/dist/esm/global-account/react/components/Send/Send.d.ts +0 -5
- package/dist/esm/global-account/react/components/Send/Send.js +0 -181
- package/dist/esm/global-account/react/components/icons/BellIcon.d.ts +0 -3
- package/dist/esm/global-account/react/components/icons/BellIcon.js +0 -3
- package/dist/esm/global-account/react/components/icons/ChevronDownIcon.d.ts +0 -2
- package/dist/esm/global-account/react/components/icons/ChevronDownIcon.js +0 -4
- package/dist/esm/global-account/react/components/icons/CopyIcon.d.ts +0 -2
- package/dist/esm/global-account/react/components/icons/CopyIcon.js +0 -4
- package/dist/esm/global-account/react/components/icons/LinkIcon.d.ts +0 -3
- package/dist/esm/global-account/react/components/icons/LinkIcon.js +0 -3
- package/dist/esm/global-account/react/components/icons/LockIcon.d.ts +0 -3
- package/dist/esm/global-account/react/components/icons/LockIcon.js +0 -3
- package/dist/esm/global-account/react/components/icons/WalletIcon.d.ts +0 -2
- package/dist/esm/global-account/react/components/icons/WalletIcon.js +0 -4
- package/dist/esm/global-account/react/stores/useRecentAddressesStore.d.ts +0 -25
- package/dist/esm/global-account/react/stores/useRecentAddressesStore.js +0 -33
- package/dist/types/global-account/react/components/Deposit/Deposit.d.ts +0 -1
- package/dist/types/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.d.ts +0 -39
- package/dist/types/global-account/react/components/LinkAccount/LinkNewAccount.d.ts +0 -4
- package/dist/types/global-account/react/components/ManageAccount/AppsContent.d.ts +0 -6
- package/dist/types/global-account/react/components/ManageAccount/BottomNavigation.d.ts +0 -2
- package/dist/types/global-account/react/components/ManageAccount/Header.d.ts +0 -3
- package/dist/types/global-account/react/components/ManageAccount/HomeActions.d.ts +0 -5
- package/dist/types/global-account/react/components/ManageAccount/HomeContent.d.ts +0 -6
- package/dist/types/global-account/react/components/ManageAccount/NFTContent.d.ts +0 -2
- package/dist/types/global-account/react/components/ManageAccount/ProfileSection.d.ts +0 -2
- package/dist/types/global-account/react/components/ManageAccount/SettingsContent.d.ts +0 -7
- package/dist/types/global-account/react/components/ManageAccount/SettingsMenuItem.d.ts +0 -9
- package/dist/types/global-account/react/components/ManageAccount/SettingsProfileCard.d.ts +0 -2
- package/dist/types/global-account/react/components/ManageAccount/TokenContent.d.ts +0 -2
- package/dist/types/global-account/react/components/ModalHeader/ModalHeader.d.ts +0 -11
- package/dist/types/global-account/react/components/Send/Send.d.ts +0 -5
- package/dist/types/global-account/react/components/icons/BellIcon.d.ts +0 -3
- package/dist/types/global-account/react/components/icons/ChevronDownIcon.d.ts +0 -2
- package/dist/types/global-account/react/components/icons/CopyIcon.d.ts +0 -2
- package/dist/types/global-account/react/components/icons/LinkIcon.d.ts +0 -3
- package/dist/types/global-account/react/components/icons/LockIcon.d.ts +0 -3
- package/dist/types/global-account/react/components/icons/WalletIcon.d.ts +0 -2
- package/dist/types/global-account/react/stores/useRecentAddressesStore.d.ts +0 -25
- package/src/global-account/react/components/Deposit/Deposit.tsx +0 -211
- package/src/global-account/react/components/IPFSMediaRenderer/IPFSMediaRenderer.tsx +0 -84
- package/src/global-account/react/components/LinkAccount/LinkNewAccount.tsx +0 -490
- package/src/global-account/react/components/ManageAccount/AppsContent.tsx +0 -79
- package/src/global-account/react/components/ManageAccount/BottomNavigation.tsx +0 -83
- package/src/global-account/react/components/ManageAccount/Header.tsx +0 -230
- package/src/global-account/react/components/ManageAccount/HomeActions.tsx +0 -118
- package/src/global-account/react/components/ManageAccount/HomeContent.tsx +0 -42
- package/src/global-account/react/components/ManageAccount/NFTContent.tsx +0 -24
- package/src/global-account/react/components/ManageAccount/ProfileSection.tsx +0 -79
- package/src/global-account/react/components/ManageAccount/SettingsContent.tsx +0 -87
- package/src/global-account/react/components/ManageAccount/SettingsMenuItem.tsx +0 -31
- package/src/global-account/react/components/ManageAccount/SettingsProfileCard.tsx +0 -182
- package/src/global-account/react/components/ManageAccount/TokenContent.tsx +0 -41
- package/src/global-account/react/components/ModalHeader/ModalHeader.tsx +0 -61
- package/src/global-account/react/components/Send/Send.tsx +0 -585
- package/src/global-account/react/components/icons/BellIcon.tsx +0 -15
- package/src/global-account/react/components/icons/ChevronDownIcon.tsx +0 -17
- package/src/global-account/react/components/icons/CopyIcon.tsx +0 -22
- package/src/global-account/react/components/icons/LinkIcon.tsx +0 -15
- package/src/global-account/react/components/icons/LockIcon.tsx +0 -15
- package/src/global-account/react/components/icons/WalletIcon.tsx +0 -21
- package/src/global-account/react/stores/useRecentAddressesStore.ts +0 -55
|
@@ -1,59 +1,30 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import app from "@b3dotfun/sdk/global-account/app";
|
|
4
|
-
import { Button,
|
|
5
|
-
import { validateImageUrl } from "@b3dotfun/sdk/global-account/react/utils/profileDisplay";
|
|
4
|
+
import { Button, useB3, useProfile } from "@b3dotfun/sdk/global-account/react";
|
|
6
5
|
import { cn } from "@b3dotfun/sdk/shared/utils/cn";
|
|
7
6
|
import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
|
|
8
7
|
import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
|
|
9
|
-
import { Loader2, Upload, X } from "lucide-react";
|
|
10
|
-
import {
|
|
11
|
-
import type { Area } from "react-easy-crop";
|
|
12
|
-
import Cropper from "react-easy-crop";
|
|
13
|
-
import "react-easy-crop/react-easy-crop.css";
|
|
8
|
+
import { Check, Loader2, Upload, X } from "lucide-react";
|
|
9
|
+
import { useRef, useState } from "react";
|
|
14
10
|
import { toast } from "sonner";
|
|
15
11
|
import { useActiveAccount } from "thirdweb/react";
|
|
16
12
|
import { upload } from "thirdweb/storage";
|
|
17
|
-
import { useProfileSettings } from "../../hooks/useProfile";
|
|
18
|
-
import { useModalStore } from "../../stores";
|
|
19
|
-
import ModalHeader from "../ModalHeader/ModalHeader";
|
|
20
13
|
|
|
21
14
|
const debug = debugB3React("AvatarEditor");
|
|
22
15
|
|
|
23
|
-
// Helper function to create an image element from a URL
|
|
24
|
-
const createImage = (url: string): Promise<HTMLImageElement> =>
|
|
25
|
-
new Promise((resolve, reject) => {
|
|
26
|
-
const image = new Image();
|
|
27
|
-
image.addEventListener("load", () => resolve(image));
|
|
28
|
-
image.addEventListener("error", error => reject(error));
|
|
29
|
-
image.setAttribute("crossOrigin", "anonymous");
|
|
30
|
-
image.src = url;
|
|
31
|
-
});
|
|
32
|
-
|
|
33
16
|
interface AvatarEditorProps {
|
|
34
17
|
onSetAvatar?: () => void;
|
|
35
18
|
className?: string;
|
|
36
19
|
}
|
|
37
20
|
|
|
38
|
-
type ViewStep = "select" | "upload";
|
|
39
|
-
|
|
40
21
|
export function AvatarEditor({ onSetAvatar, className }: AvatarEditorProps) {
|
|
41
|
-
const [viewStep, setViewStep] = useState<ViewStep>("select");
|
|
42
|
-
const [selectedAvatar, setSelectedAvatar] = useState<string | null>(null);
|
|
43
|
-
const [selectedProfileType, setSelectedProfileType] = useState<string | null>(null); // Track which profile was selected
|
|
44
|
-
const [hoveredProfile, setHoveredProfile] = useState<string | null>(null);
|
|
45
22
|
const [selectedFile, setSelectedFile] = useState<File | null>(null);
|
|
46
23
|
const [previewUrl, setPreviewUrl] = useState<string | null>(null);
|
|
24
|
+
const [isUploading, setIsUploading] = useState(false);
|
|
47
25
|
const [isSaving, setIsSaving] = useState(false);
|
|
48
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
49
|
-
const [crop, setCrop] = useState({ x: 0, y: 0 });
|
|
50
|
-
const [zoom, setZoom] = useState(1);
|
|
51
|
-
const [croppedAreaPixels, setCroppedAreaPixels] = useState<Area | null>(null);
|
|
52
26
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
53
|
-
const { setUser
|
|
54
|
-
const setB3ModalContentType = useModalStore(state => state.setB3ModalContentType);
|
|
55
|
-
const contentType = useModalStore(state => state.contentType);
|
|
56
|
-
const { setPreference } = useProfileSettings();
|
|
27
|
+
const { setUser } = useB3();
|
|
57
28
|
|
|
58
29
|
const account = useActiveAccount();
|
|
59
30
|
const { data: profile, refetch: refreshProfile } = useProfile({
|
|
@@ -61,52 +32,9 @@ export function AvatarEditor({ onSetAvatar, className }: AvatarEditorProps) {
|
|
|
61
32
|
fresh: true,
|
|
62
33
|
});
|
|
63
34
|
|
|
64
|
-
//
|
|
65
|
-
const rawCurrentAvatar = user?.avatar || profile?.avatar;
|
|
66
|
-
const currentAvatar = validateImageUrl(rawCurrentAvatar);
|
|
67
|
-
const safePreviewUrl = validateImageUrl(previewUrl);
|
|
68
|
-
|
|
69
|
-
const onCropComplete = useCallback((_croppedArea: Area, croppedAreaPixels: Area) => {
|
|
70
|
-
setCroppedAreaPixels(croppedAreaPixels);
|
|
71
|
-
}, []);
|
|
72
|
-
|
|
73
|
-
const createCroppedImage = async (imageSrc: string, pixelCrop: Area): Promise<Blob> => {
|
|
74
|
-
const image = await createImage(imageSrc);
|
|
75
|
-
const canvas = document.createElement("canvas");
|
|
76
|
-
const ctx = canvas.getContext("2d");
|
|
77
|
-
|
|
78
|
-
if (!ctx) {
|
|
79
|
-
throw new Error("Failed to get canvas context");
|
|
80
|
-
}
|
|
35
|
+
// Thirdweb upload function
|
|
81
36
|
|
|
82
|
-
|
|
83
|
-
canvas.width = pixelCrop.width;
|
|
84
|
-
canvas.height = pixelCrop.height;
|
|
85
|
-
|
|
86
|
-
// Draw the cropped image
|
|
87
|
-
ctx.drawImage(
|
|
88
|
-
image,
|
|
89
|
-
pixelCrop.x,
|
|
90
|
-
pixelCrop.y,
|
|
91
|
-
pixelCrop.width,
|
|
92
|
-
pixelCrop.height,
|
|
93
|
-
0,
|
|
94
|
-
0,
|
|
95
|
-
pixelCrop.width,
|
|
96
|
-
pixelCrop.height,
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
// Return as blob
|
|
100
|
-
return new Promise((resolve, reject) => {
|
|
101
|
-
canvas.toBlob(blob => {
|
|
102
|
-
if (!blob) {
|
|
103
|
-
reject(new Error("Canvas is empty"));
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
resolve(blob);
|
|
107
|
-
}, "image/jpeg");
|
|
108
|
-
});
|
|
109
|
-
};
|
|
37
|
+
const hasAvatar = profile?.avatar;
|
|
110
38
|
|
|
111
39
|
const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
112
40
|
const file = event.target.files?.[0];
|
|
@@ -124,19 +52,14 @@ export function AvatarEditor({ onSetAvatar, className }: AvatarEditorProps) {
|
|
|
124
52
|
}
|
|
125
53
|
|
|
126
54
|
setSelectedFile(file);
|
|
127
|
-
// Clear profile type selection when uploading a new file
|
|
128
|
-
setSelectedProfileType(null);
|
|
129
55
|
|
|
130
56
|
// Create preview URL
|
|
131
57
|
const url = URL.createObjectURL(file);
|
|
132
58
|
setPreviewUrl(url);
|
|
133
|
-
setSelectedAvatar(url);
|
|
134
59
|
}
|
|
135
60
|
};
|
|
136
61
|
|
|
137
|
-
const
|
|
138
|
-
setSelectedAvatar(currentAvatar || null);
|
|
139
|
-
setSelectedProfileType(null);
|
|
62
|
+
const handleRemoveFile = () => {
|
|
140
63
|
setSelectedFile(null);
|
|
141
64
|
if (previewUrl) {
|
|
142
65
|
URL.revokeObjectURL(previewUrl);
|
|
@@ -145,438 +68,166 @@ export function AvatarEditor({ onSetAvatar, className }: AvatarEditorProps) {
|
|
|
145
68
|
if (fileInputRef.current) {
|
|
146
69
|
fileInputRef.current.value = "";
|
|
147
70
|
}
|
|
148
|
-
// Reset crop state
|
|
149
|
-
setCrop({ x: 0, y: 0 });
|
|
150
|
-
setZoom(1);
|
|
151
|
-
setCroppedAreaPixels(null);
|
|
152
71
|
};
|
|
153
72
|
|
|
154
|
-
const
|
|
155
|
-
if (!
|
|
156
|
-
toast.error("
|
|
73
|
+
const handleUpload = async () => {
|
|
74
|
+
if (!selectedFile) {
|
|
75
|
+
toast.error("Please select an image first");
|
|
157
76
|
return;
|
|
158
77
|
}
|
|
159
78
|
|
|
160
|
-
|
|
79
|
+
setIsUploading(true);
|
|
161
80
|
try {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// If user uploaded a new file and cropped it
|
|
165
|
-
if (selectedFile && previewUrl && croppedAreaPixels) {
|
|
166
|
-
try {
|
|
167
|
-
const croppedBlob = await createCroppedImage(previewUrl, croppedAreaPixels);
|
|
168
|
-
const extension = selectedFile.name.split(".").pop() || "jpg";
|
|
169
|
-
fileToUpload = new File([croppedBlob], `avatar-cropped.${extension}`, { type: "image/jpeg" });
|
|
170
|
-
} catch (error) {
|
|
171
|
-
debug("Error cropping image:", error);
|
|
172
|
-
toast.error("Failed to crop image. Please try again.");
|
|
173
|
-
setIsSaving(false);
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
} else if (selectedFile) {
|
|
177
|
-
// Fallback if no crop was made
|
|
178
|
-
fileToUpload = selectedFile;
|
|
179
|
-
} else if (selectedProfileType && selectedAvatar) {
|
|
180
|
-
// User selected from existing profile avatars
|
|
181
|
-
// Fetch the image from the URL and convert to blob
|
|
182
|
-
debug("Fetching image from social profile:", selectedAvatar);
|
|
183
|
-
|
|
184
|
-
try {
|
|
185
|
-
const response = await fetch(selectedAvatar);
|
|
186
|
-
if (!response.ok) {
|
|
187
|
-
throw new Error("Failed to fetch image");
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const blob = await response.blob();
|
|
191
|
-
debug("Fetched blob with type:", blob.type);
|
|
81
|
+
debug("Starting upload to IPFS", selectedFile);
|
|
192
82
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
"image/png": "png",
|
|
199
|
-
"image/gif": "gif",
|
|
200
|
-
"image/webp": "webp",
|
|
201
|
-
"image/svg+xml": "svg",
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
const extension = blob.type ? mimeToExtension[blob.type.toLowerCase()] || "jpg" : "jpg";
|
|
205
|
-
const mimeType = blob.type || `image/${extension}`;
|
|
206
|
-
|
|
207
|
-
fileToUpload = new File([blob], `avatar-${selectedProfileType}.${extension}`, { type: mimeType });
|
|
208
|
-
|
|
209
|
-
debug("Successfully converted social profile image to file with extension:", extension);
|
|
210
|
-
} catch (fetchError) {
|
|
211
|
-
debug("Error fetching social profile image:", fetchError);
|
|
212
|
-
toast.error("Failed to fetch profile image. Please try uploading manually.");
|
|
213
|
-
setIsSaving(false);
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Upload to IPFS if we have a file
|
|
219
|
-
if (fileToUpload) {
|
|
220
|
-
debug("Starting upload to IPFS", fileToUpload);
|
|
221
|
-
|
|
222
|
-
// Upload to IPFS using Thirdweb
|
|
223
|
-
const ipfsUrl = await upload({
|
|
224
|
-
client,
|
|
225
|
-
files: [fileToUpload],
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
debug("Upload successful", ipfsUrl);
|
|
229
|
-
|
|
230
|
-
// Save avatar URL using profiles service
|
|
231
|
-
const user = await app.service("users").setAvatar(
|
|
232
|
-
{
|
|
233
|
-
avatar: ipfsUrl,
|
|
234
|
-
},
|
|
235
|
-
// @ts-expect-error - our typed client is expecting context even though it's set elsewhere
|
|
236
|
-
{},
|
|
237
|
-
);
|
|
238
|
-
// update user
|
|
239
|
-
// @ts-expect-error this resolved fine, look into why expect-error needed
|
|
240
|
-
setUser(user);
|
|
83
|
+
// Upload to IPFS using Thirdweb
|
|
84
|
+
const ipfsUrl = await upload({
|
|
85
|
+
client,
|
|
86
|
+
files: [selectedFile],
|
|
87
|
+
});
|
|
241
88
|
|
|
242
|
-
|
|
243
|
-
|
|
89
|
+
debug("Upload successful", ipfsUrl);
|
|
90
|
+
|
|
91
|
+
// Save avatar URL using profiles service
|
|
92
|
+
setIsSaving(true);
|
|
93
|
+
const user = await app.service("users").setAvatar(
|
|
94
|
+
{
|
|
95
|
+
avatar: ipfsUrl,
|
|
96
|
+
},
|
|
97
|
+
// @ts-expect-error - our typed client is expecting context even though it's set elsewhere
|
|
98
|
+
{},
|
|
99
|
+
);
|
|
100
|
+
// update user
|
|
101
|
+
// @ts-expect-error this resolved fine, look into why expect-error needed
|
|
102
|
+
setUser(user);
|
|
244
103
|
|
|
245
104
|
// Refresh profile to get updated avatar
|
|
246
105
|
await refreshProfile();
|
|
247
106
|
|
|
107
|
+
toast.success(
|
|
108
|
+
hasAvatar ? "Nice look! Your avatar has been updated!" : "Looks great! Your avatar has been saved!",
|
|
109
|
+
);
|
|
110
|
+
|
|
248
111
|
onSetAvatar?.();
|
|
112
|
+
|
|
113
|
+
// Clean up
|
|
114
|
+
handleRemoveFile();
|
|
249
115
|
} catch (error) {
|
|
250
|
-
debug("Error
|
|
251
|
-
toast.error("Failed to
|
|
116
|
+
debug("Error uploading avatar:", error);
|
|
117
|
+
toast.error("Failed to upload avatar. Please try again.");
|
|
252
118
|
} finally {
|
|
119
|
+
setIsUploading(false);
|
|
253
120
|
setIsSaving(false);
|
|
254
121
|
}
|
|
255
122
|
};
|
|
256
123
|
|
|
257
|
-
const
|
|
258
|
-
if (viewStep === "upload") {
|
|
259
|
-
setViewStep("select");
|
|
260
|
-
handleRemovePreview();
|
|
261
|
-
} else {
|
|
262
|
-
setB3ModalContentType({
|
|
263
|
-
type: "manageAccount",
|
|
264
|
-
chain: (contentType as any)?.chain,
|
|
265
|
-
partnerId: partnerId,
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
const handleProfileAvatarSelect = (avatarUrl: string, profileType: string) => {
|
|
271
|
-
setSelectedAvatar(avatarUrl);
|
|
272
|
-
setSelectedProfileType(profileType);
|
|
273
|
-
// Clear any selected file since we're selecting from profile
|
|
274
|
-
setSelectedFile(null);
|
|
275
|
-
if (previewUrl) {
|
|
276
|
-
URL.revokeObjectURL(previewUrl);
|
|
277
|
-
setPreviewUrl(null);
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
const handleUploadImageClick = () => {
|
|
282
|
-
setViewStep("upload");
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
const handleOpenFilePicker = () => {
|
|
124
|
+
const handleFileInputClick = () => {
|
|
286
125
|
fileInputRef.current?.click();
|
|
287
126
|
};
|
|
288
127
|
|
|
289
|
-
const
|
|
290
|
-
e.preventDefault();
|
|
291
|
-
e.stopPropagation();
|
|
292
|
-
setIsDragging(true);
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {
|
|
296
|
-
e.preventDefault();
|
|
297
|
-
e.stopPropagation();
|
|
298
|
-
setIsDragging(false);
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
|
|
302
|
-
e.preventDefault();
|
|
303
|
-
e.stopPropagation();
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
|
|
307
|
-
e.preventDefault();
|
|
308
|
-
e.stopPropagation();
|
|
309
|
-
setIsDragging(false);
|
|
310
|
-
|
|
311
|
-
const file = e.dataTransfer.files?.[0];
|
|
312
|
-
if (file) {
|
|
313
|
-
// Validate file type
|
|
314
|
-
if (!file.type.startsWith("image/")) {
|
|
315
|
-
toast.error("Please select an image file");
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Validate file size (max 5MB)
|
|
320
|
-
if (file.size > 5 * 1024 * 1024) {
|
|
321
|
-
toast.error("File size must be less than 5MB");
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
setSelectedFile(file);
|
|
326
|
-
// Clear profile type selection when uploading a new file
|
|
327
|
-
setSelectedProfileType(null);
|
|
328
|
-
|
|
329
|
-
// Create preview URL
|
|
330
|
-
const url = URL.createObjectURL(file);
|
|
331
|
-
setPreviewUrl(url);
|
|
332
|
-
setSelectedAvatar(url);
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
const handleLinkMoreAccount = () => {
|
|
337
|
-
setB3ModalContentType({
|
|
338
|
-
type: "linkAccount",
|
|
339
|
-
chain: (contentType as any)?.chain,
|
|
340
|
-
partnerId: partnerId,
|
|
341
|
-
});
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
const isLoading = isSaving;
|
|
345
|
-
|
|
346
|
-
// Get profile avatars with validated URLs
|
|
347
|
-
const profileAvatars =
|
|
348
|
-
profile?.profiles
|
|
349
|
-
?.filter(p => p.avatar)
|
|
350
|
-
.map(p => {
|
|
351
|
-
const rawAvatarUrl = p?.avatar || "";
|
|
352
|
-
const validatedUrl = validateImageUrl(rawAvatarUrl);
|
|
353
|
-
return {
|
|
354
|
-
type: p.type,
|
|
355
|
-
avatar: validatedUrl,
|
|
356
|
-
name: p.name || p.type,
|
|
357
|
-
};
|
|
358
|
-
})
|
|
359
|
-
.filter(p => p.avatar !== null) || []; // Filter out profiles with invalid avatars
|
|
128
|
+
const isLoading = isUploading || isSaving;
|
|
360
129
|
|
|
361
130
|
return (
|
|
362
|
-
<div className={cn("flex
|
|
363
|
-
|
|
364
|
-
|
|
131
|
+
<div className={cn("flex flex-col items-center justify-center space-y-6 p-8", className)}>
|
|
132
|
+
<div className="space-y-2 text-center">
|
|
133
|
+
<h2 className="font-neue-montreal-semibold text-b3-grey text-2xl">
|
|
134
|
+
{hasAvatar ? "Update Your Avatar" : "Set Your Avatar"}
|
|
135
|
+
</h2>
|
|
136
|
+
<p className="text-b3-foreground-muted font-neue-montreal-medium">
|
|
137
|
+
Upload an image to personalize your profile
|
|
138
|
+
</p>
|
|
139
|
+
</div>
|
|
365
140
|
|
|
366
|
-
{/*
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
{
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
141
|
+
{/* Current Avatar Display */}
|
|
142
|
+
{hasAvatar && !previewUrl && (
|
|
143
|
+
<div className="relative">
|
|
144
|
+
<div className="border-b3-primary-blue h-32 w-32 overflow-hidden rounded-full border-4">
|
|
145
|
+
<img src={profile.avatar} alt="Current avatar" className="h-full w-full object-cover" />
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
)}
|
|
149
|
+
|
|
150
|
+
{/* File Upload Area */}
|
|
151
|
+
<div className="w-full max-w-md">
|
|
152
|
+
{!selectedFile ? (
|
|
153
|
+
<div
|
|
154
|
+
onClick={handleFileInputClick}
|
|
155
|
+
className="border-b3-line hover:border-b3-primary-blue hover:bg-b3-primary-wash/20 cursor-pointer rounded-xl border-2 border-dashed p-8 text-center transition-colors"
|
|
156
|
+
>
|
|
157
|
+
<Upload className="text-b3-grey mx-auto mb-4 h-12 w-12" />
|
|
158
|
+
<p className="text-b3-grey font-neue-montreal-semibold mb-2">Click to select an image</p>
|
|
159
|
+
<p className="text-b3-foreground-muted font-neue-montreal-medium text-sm">PNG, JPG, or GIF up to 5MB</p>
|
|
160
|
+
</div>
|
|
161
|
+
) : (
|
|
162
|
+
<div className="space-y-4">
|
|
163
|
+
{/* Preview */}
|
|
164
|
+
<div className="relative">
|
|
165
|
+
<div className="border-b3-primary-blue mx-auto h-32 w-32 overflow-hidden rounded-full border-4">
|
|
166
|
+
{previewUrl ? (
|
|
167
|
+
<img src={previewUrl} alt="Preview" className="h-full w-full object-cover" />
|
|
379
168
|
) : (
|
|
380
|
-
<div className="bg-b3-primary-wash h-full w-full"
|
|
169
|
+
<div className="bg-b3-primary-wash flex h-full w-full items-center justify-center rounded-full">
|
|
170
|
+
<p className="text-b3-grey font-neue-montreal-semibold text-sm">No file selected</p>
|
|
171
|
+
</div>
|
|
381
172
|
)}
|
|
382
173
|
</div>
|
|
383
|
-
{(selectedAvatar !== currentAvatar || selectedFile) && (
|
|
384
|
-
<button
|
|
385
|
-
onClick={handleRemovePreview}
|
|
386
|
-
className="absolute -right-1 -top-1 flex h-8 w-8 items-center justify-center rounded-full bg-[#51525c] text-white transition-colors hover:bg-[#71717a]"
|
|
387
|
-
>
|
|
388
|
-
<X className="h-4 w-4" />
|
|
389
|
-
</button>
|
|
390
|
-
)}
|
|
391
|
-
</div>
|
|
392
|
-
|
|
393
|
-
{/* Upload Image Button */}
|
|
394
|
-
<button
|
|
395
|
-
onClick={handleUploadImageClick}
|
|
396
|
-
className="font-inter mb-6 flex w-full items-center justify-center gap-2 rounded-xl border border-[#e4e4e7] bg-white px-4 py-3 text-sm font-semibold text-[#18181b] shadow-sm transition-colors hover:bg-[#f4f4f5]"
|
|
397
|
-
>
|
|
398
|
-
<Upload className="h-4 w-4" />
|
|
399
|
-
Upload image
|
|
400
|
-
</button>
|
|
401
|
-
|
|
402
|
-
{/* Select Profile Image Section */}
|
|
403
|
-
<div className="w-full">
|
|
404
|
-
<h3 className="mb-2 text-base font-semibold text-[#18181b]">Select your profile image</h3>
|
|
405
|
-
<p className="mb-4 text-sm font-semibold text-[#475467]">
|
|
406
|
-
Pick an avatar from your linked profiles, ENS or upload a new one.
|
|
407
|
-
</p>
|
|
408
|
-
|
|
409
|
-
{/* Profile Avatars */}
|
|
410
|
-
<div className="mb-4 flex gap-3">
|
|
411
|
-
{profileAvatars.map((profileAvatar, index) => {
|
|
412
|
-
// Skip if avatar is null (should not happen due to filter, but TypeScript doesn't know that)
|
|
413
|
-
if (!profileAvatar.avatar) return null;
|
|
414
|
-
|
|
415
|
-
return (
|
|
416
|
-
<div
|
|
417
|
-
key={index}
|
|
418
|
-
className="relative"
|
|
419
|
-
onMouseEnter={() => setHoveredProfile(profileAvatar.type)}
|
|
420
|
-
onMouseLeave={() => setHoveredProfile(null)}
|
|
421
|
-
>
|
|
422
|
-
<button
|
|
423
|
-
onClick={() => handleProfileAvatarSelect(profileAvatar.avatar || "", profileAvatar.type || "")}
|
|
424
|
-
className={cn(
|
|
425
|
-
"h-16 w-16 overflow-hidden rounded-full border-2 transition-all",
|
|
426
|
-
selectedProfileType === profileAvatar.type
|
|
427
|
-
? "border-[#3368ef] ring-2 ring-[#3368ef]/20"
|
|
428
|
-
: "border-transparent hover:border-[#e4e4e7]",
|
|
429
|
-
)}
|
|
430
|
-
>
|
|
431
|
-
<img
|
|
432
|
-
src={profileAvatar.avatar}
|
|
433
|
-
alt={`${profileAvatar.type} avatar`}
|
|
434
|
-
className="h-full w-full object-cover"
|
|
435
|
-
/>
|
|
436
|
-
</button>
|
|
437
|
-
|
|
438
|
-
{/* Tooltip */}
|
|
439
|
-
{hoveredProfile === profileAvatar.type && (
|
|
440
|
-
<div className="absolute -top-10 left-1/2 -translate-x-1/2 whitespace-nowrap rounded-md bg-[#18181b] px-3 py-1.5 text-xs text-white">
|
|
441
|
-
{profileAvatar.name}
|
|
442
|
-
</div>
|
|
443
|
-
)}
|
|
444
|
-
</div>
|
|
445
|
-
);
|
|
446
|
-
})}
|
|
447
|
-
</div>
|
|
448
|
-
|
|
449
|
-
{/* Link More Account */}
|
|
450
174
|
<button
|
|
451
|
-
onClick={
|
|
452
|
-
className="
|
|
175
|
+
onClick={handleRemoveFile}
|
|
176
|
+
className="bg-b3-negative absolute -right-2 -top-2 flex h-8 w-8 items-center justify-center rounded-full text-white transition-colors hover:bg-red-600"
|
|
177
|
+
disabled={isLoading}
|
|
453
178
|
>
|
|
454
|
-
<
|
|
455
|
-
width="16"
|
|
456
|
-
height="16"
|
|
457
|
-
viewBox="0 0 16 16"
|
|
458
|
-
fill="none"
|
|
459
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
460
|
-
className="h-4 w-4"
|
|
461
|
-
>
|
|
462
|
-
<path
|
|
463
|
-
d="M8.75 2.75C8.75 2.33579 8.41421 2 8 2C7.58579 2 7.25 2.33579 7.25 2.75V7.25H2.75C2.33579 7.25 2 7.58579 2 8C2 8.41421 2.33579 8.75 2.75 8.75H7.25V13.25C7.25 13.6642 7.58579 14 8 14C8.41421 14 8.75 13.6642 8.75 13.25V8.75H13.25C13.6642 8.75 14 8.41421 14 8C14 7.58579 13.6642 7.25 13.25 7.25H8.75V2.75Z"
|
|
464
|
-
fill="currentColor"
|
|
465
|
-
/>
|
|
466
|
-
</svg>
|
|
467
|
-
Link more account
|
|
179
|
+
<X size={16} />
|
|
468
180
|
</button>
|
|
469
181
|
</div>
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
onDragOver={handleDragOver}
|
|
480
|
-
onDrop={handleDrop}
|
|
481
|
-
className={cn(
|
|
482
|
-
"mb-6 flex w-full cursor-pointer flex-col items-center justify-center rounded-xl border-2 border-dashed p-16 transition-colors",
|
|
483
|
-
isDragging
|
|
484
|
-
? "border-[#3368ef] bg-[#f0f5ff]"
|
|
485
|
-
: "border-[#e4e4e7] hover:border-[#3368ef] hover:bg-[#f0f5ff]",
|
|
486
|
-
)}
|
|
487
|
-
>
|
|
488
|
-
<p className="font-inter mb-1 text-sm">
|
|
489
|
-
<span className="font-semibold text-[#3368ef]">Click to upload</span>
|
|
490
|
-
<span className="text-[#71717a]"> or drag and drop</span>
|
|
491
|
-
</p>
|
|
492
|
-
<p className="text-xs text-[#71717a]">PNG, JPG or GIF (up to 5MB)</p>
|
|
493
|
-
</div>
|
|
494
|
-
) : (
|
|
495
|
-
<div className="mb-6 w-full">
|
|
496
|
-
<div className="relative aspect-square w-full overflow-hidden rounded-xl bg-[#f4f4f5]">
|
|
497
|
-
{safePreviewUrl ? (
|
|
498
|
-
<>
|
|
499
|
-
<Cropper
|
|
500
|
-
image={safePreviewUrl}
|
|
501
|
-
crop={crop}
|
|
502
|
-
zoom={zoom}
|
|
503
|
-
aspect={1}
|
|
504
|
-
onCropChange={setCrop}
|
|
505
|
-
onCropComplete={onCropComplete}
|
|
506
|
-
onZoomChange={setZoom}
|
|
507
|
-
cropShape="rect"
|
|
508
|
-
showGrid={false}
|
|
509
|
-
style={{
|
|
510
|
-
containerStyle: {
|
|
511
|
-
width: "100%",
|
|
512
|
-
height: "100%",
|
|
513
|
-
backgroundColor: "#f4f4f5",
|
|
514
|
-
},
|
|
515
|
-
cropAreaStyle: {
|
|
516
|
-
border: "2px solid #3368ef",
|
|
517
|
-
borderRadius: "0px",
|
|
518
|
-
},
|
|
519
|
-
}}
|
|
520
|
-
/>
|
|
521
|
-
<button
|
|
522
|
-
onClick={handleRemovePreview}
|
|
523
|
-
className="absolute right-4 top-4 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-[#51525c] text-white transition-colors hover:bg-[#71717a]"
|
|
524
|
-
>
|
|
525
|
-
<X className="h-4 w-4" />
|
|
526
|
-
</button>
|
|
527
|
-
</>
|
|
528
|
-
) : (
|
|
529
|
-
<div className="bg-b3-primary-wash h-full w-full" />
|
|
530
|
-
)}
|
|
531
|
-
</div>
|
|
532
|
-
{safePreviewUrl && (
|
|
533
|
-
<div className="mt-4 flex items-center gap-3">
|
|
534
|
-
<label className="flex-shrink-0 text-sm font-semibold text-[#475467]">Zoom</label>
|
|
535
|
-
<input
|
|
536
|
-
type="range"
|
|
537
|
-
min={1}
|
|
538
|
-
max={3}
|
|
539
|
-
step={0.1}
|
|
540
|
-
value={zoom}
|
|
541
|
-
onChange={e => setZoom(Number(e.target.value))}
|
|
542
|
-
className="flex-1 accent-[#3368ef]"
|
|
543
|
-
/>
|
|
544
|
-
</div>
|
|
545
|
-
)}
|
|
546
|
-
</div>
|
|
547
|
-
)}
|
|
548
|
-
</>
|
|
182
|
+
|
|
183
|
+
{/* File Info */}
|
|
184
|
+
<div className="space-y-1 text-center">
|
|
185
|
+
<p className="text-b3-grey font-neue-montreal-semibold text-sm">{selectedFile.name}</p>
|
|
186
|
+
<p className="text-b3-foreground-muted font-neue-montreal-medium text-xs">
|
|
187
|
+
{(selectedFile.size / 1024 / 1024).toFixed(2)} MB
|
|
188
|
+
</p>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
549
191
|
)}
|
|
550
192
|
|
|
551
193
|
{/* Hidden file input */}
|
|
552
194
|
<input ref={fileInputRef} type="file" accept="image/*" onChange={handleFileSelect} className="hidden" />
|
|
553
195
|
</div>
|
|
554
196
|
|
|
555
|
-
{/*
|
|
556
|
-
<div className="
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
197
|
+
{/* Action Buttons */}
|
|
198
|
+
<div className="flex w-full max-w-md gap-3">
|
|
199
|
+
{selectedFile && (
|
|
200
|
+
<Button
|
|
201
|
+
onClick={handleUpload}
|
|
202
|
+
disabled={isLoading}
|
|
203
|
+
className="bg-b3-primary-blue hover:bg-b3-primary-blue/90 flex-1 text-white"
|
|
204
|
+
>
|
|
205
|
+
{isLoading ? (
|
|
206
|
+
<>
|
|
207
|
+
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
208
|
+
{isUploading ? "Uploading..." : "Saving..."}
|
|
209
|
+
</>
|
|
210
|
+
) : (
|
|
211
|
+
<>
|
|
212
|
+
<Check className="mr-2 h-4 w-4" />
|
|
213
|
+
{hasAvatar ? "Update Avatar" : "Set Avatar"}
|
|
214
|
+
</>
|
|
215
|
+
)}
|
|
216
|
+
</Button>
|
|
217
|
+
)}
|
|
218
|
+
|
|
219
|
+
<Button variant="outline" onClick={handleFileInputClick} disabled={isLoading} className="flex-1">
|
|
220
|
+
<Upload className="mr-2 h-4 w-4" />
|
|
221
|
+
{selectedFile ? "Change Image" : "Select Image"}
|
|
578
222
|
</Button>
|
|
579
223
|
</div>
|
|
224
|
+
|
|
225
|
+
{/* Help Text */}
|
|
226
|
+
<div className="text-b3-foreground-muted font-neue-montreal-medium max-w-md text-center text-xs">
|
|
227
|
+
<p>
|
|
228
|
+
Your avatar will be uploaded to IPFS and stored securely. Make sure you have the rights to use this image.
|
|
229
|
+
</p>
|
|
230
|
+
</div>
|
|
580
231
|
</div>
|
|
581
232
|
);
|
|
582
233
|
}
|