"use client" import { useTranslations } from "next-intl" import React, { useEffect, useState } from "react" import { GeneralAccount, useAccountBalance, useAccountState, useConnectModal, useCsbDetailModal, useDisconnectModal, useIsOpSignEnabled, useOpSignSettingsModal, useSelectCharactersModal, useUpgradeEmailAccountModal, useWalletMintNewCharacterModal, } from "@crossbell/connect-kit" import { useNotifications, useShowNotificationModal, } from "@crossbell/notification" import { useRefCallback } from "@crossbell/util-hooks" import { BellIcon, FaceFrownIcon, FaceSmileIcon, PlusCircleIcon, } from "@heroicons/react/24/outline" import { BellAlertIcon } from "@heroicons/react/24/solid" import { Avatar } from "~/components/ui/Avatar" import { Button, type Variant, type VariantColor } from "~/components/ui/Button" import { Menu } from "~/components/ui/Menu" import { SITE_URL } from "~/lib/env" import { getSiteLink } from "~/lib/helpers" import { cn } from "~/lib/utils" type HeaderLinkType = { icon?: React.ReactNode label: string | JSX.Element } & ( | { href: string } | { onClick: React.MouseEventHandler } ) export const ConnectButton = ({ left, variant, variantColor, size = "sm", hideNotification, mobileSimplification, hideName, }: { left?: boolean variant?: Variant variantColor?: VariantColor size?: "base" | "sm" hideNotification?: boolean mobileSimplification?: boolean hideName?: boolean }) => { let avatarSize let sizeDecrease switch (size) { case "base": avatarSize = 40 sizeDecrease = "sm" break default: avatarSize = 30 sizeDecrease = "xs" } const [ssrReady, account] = useAccountState(({ ssrReady, computed }) => [ ssrReady, computed.account, ]) const isOpSignEnabled = useIsOpSignEnabled({ characterId: account?.characterId, }) const { show: openConnectModal } = useConnectModal() const { show: disconnect } = useDisconnectModal() const { balance } = useAccountBalance() const [copyLabelDisplay, copyLabel] = useCopyLabel(account) const csbDetailModal = useCsbDetailModal() const opSignSettingsModal = useOpSignSettingsModal() const upgradeAccountModal = useUpgradeEmailAccountModal() const selectCharactersModal = useSelectCharactersModal() const walletMintNewCharacterModal = useWalletMintNewCharacterModal() const showNotificationModal = useShowNotificationModal() const { isAllRead } = useNotifications() const [InsufficientBalance, setInsufficientBalance] = useState(false) const t = useTranslations() useEffect(() => { if (balance) { if ( BigInt(balance.value.toString()) > BigInt("1" + "0".repeat(balance.decimals - 2)) ) { setInsufficientBalance(false) } else { setInsufficientBalance(true) } } }, [balance]) const dropdownLinks: HeaderLinkType[] = [ account?.character ? { icon: "i-mingcute-home-1-line", label: t("My xLog") || "", href: getSiteLink({ subdomain: account?.character?.handle || "", }), } : { icon: "i-mingcute-home-1-line", label: t("My xLog") || "", onClick: () => walletMintNewCharacterModal.show(), }, { icon: "i-mingcute-grid-line", label: t("Dashboard") || "", href: `${SITE_URL}/dashboard`, }, { icon: "i-mingcute-copy-2-line", label: t(copyLabelDisplay) || "", onClick: (e) => { e.preventDefault() copyLabel() }, }, ...(account?.type === "wallet" ? [ { icon: "i-mingcute-seal-line", label: ( <> {t("Operator Sign")} ( {isOpSignEnabled ? ( ) : ( )} ) ), onClick: () => { if (account?.characterId) { opSignSettingsModal.show({ characterId: account?.characterId, }) } }, }, { icon: "i-mingcute-currency-euro-line", label: ( {balance?.formatted.replace(/\.(\d{5})\d*$/, ".$1") || "0.00000"}{" "} CSB ), onClick: csbDetailModal.show, }, { icon: "i-mingcute-repeat-line", label: t("Switch Characters") || "", onClick: selectCharactersModal.show, }, ] : [ { icon: "i-mingcute-vip-2-line", label: t("Upgrade to Wallet") || "", onClick: upgradeAccountModal.show, }, ]), { icon: "i-mingcute-exit-line", label: t("Disconnect") || "", onClick: disconnect, }, ] const addDropdownLinks: HeaderLinkType[] = [ { icon: "i-mingcute-news-line", label: t("New Post") || "", href: `${SITE_URL}/dashboard/${account?.character?.handle}/editor?type=post`, }, { icon: "i-mingcute-file-line", label: t("New Page") || "", href: `${SITE_URL}/dashboard/${account?.character?.handle}/editor?type=page`, }, { icon: "i-mingcute-ins-line", label: t("New Short") || "", href: `${SITE_URL}/dashboard/${account?.character?.handle}/editor?type=short`, }, { icon: "i-mingcute-cloud-line", label: t("New Portfolio") || "", href: `${SITE_URL}/dashboard/${account?.character?.handle}/editor?type=portfolio`, }, ] return (
{(() => { if (!account) { return ( ) } return (
{!hideNotification && ( <> {isAllRead ? ( ) : ( )}
) })()}
) } function useCopyLabel(account: GeneralAccount | null) { const [isShowCopied, setIsShowCopied] = useState(false) const copyLabel = useRefCallback(() => { const value = (account?.type === "email" ? account.email : account?.address) || "" navigator.clipboard.writeText(value) setIsShowCopied(true) setTimeout(() => setIsShowCopied(false), 1000) }) return [ isShowCopied ? "Copied!" : getAccountDisplayName(account), copyLabel, ] as const } function getAccountDisplayName(account: GeneralAccount | null) { const value = (account?.type === "email" ? account.email : account?.address) || "" return value.slice(0, 5) + "..." + value.slice(-4) }