mango-v4-ui/components/TopBar.tsx

316 lines
12 KiB
TypeScript
Raw Normal View History

import { useCallback, useEffect, useState } from 'react'
2022-11-19 10:33:12 -08:00
import {
ArrowRightIcon,
CheckCircleIcon,
ChevronRightIcon,
Cog8ToothIcon,
DocumentDuplicateIcon,
2022-11-19 10:33:12 -08:00
ExclamationTriangleIcon,
EyeIcon,
2022-11-19 10:33:12 -08:00
} from '@heroicons/react/20/solid'
2022-11-15 20:12:51 -08:00
import { useWallet } from '@solana/wallet-adapter-react'
import { useTranslation } from 'next-i18next'
import WalletIcon from './icons/WalletIcon'
import ConnectedMenu from './wallet/ConnectedMenu'
import ConnectWalletButton from './wallet/ConnectWalletButton'
import CreateAccountModal from './modals/CreateAccountModal'
2023-08-06 22:57:02 -07:00
// import SolanaTps from './SolanaTps'
2022-11-18 09:09:39 -08:00
import useMangoAccount from 'hooks/useMangoAccount'
2022-11-19 10:33:12 -08:00
import useOnlineStatus from 'hooks/useOnlineStatus'
2022-12-15 20:04:26 -08:00
import { abbreviateAddress } from 'utils/formatting'
import DepositWithdrawModal from './modals/DepositWithdrawModal'
import AccountsButton from './AccountsButton'
import useUnownedAccount from 'hooks/useUnownedAccount'
import NotificationsButton from './notifications/NotificationsButton'
import Tooltip from './shared/Tooltip'
import { copyToClipboard } from 'utils'
2023-06-06 22:00:59 -07:00
import mangoStore from '@store/mangoStore'
import UserSetupModal from './modals/UserSetupModal'
import { IS_ONBOARDED_KEY } from 'utils/constants'
import useLocalStorageState from 'hooks/useLocalStorageState'
import SettingsModal from './modals/SettingsModal'
import DepositWithdrawIcon from './icons/DepositWithdrawIcon'
2023-10-22 19:02:40 -07:00
import { useAccountPointsAndRank, useCurrentSeason } from 'hooks/useRewards'
import SheenLoader from './shared/SheenLoader'
import Link from 'next/link'
2023-09-27 20:59:14 -07:00
import { useIsWhiteListed } from 'hooks/useIsWhiteListed'
2023-10-17 18:28:28 -07:00
import FormatNumericValue from './shared/FormatNumericValue'
import { useRouter } from 'next/router'
2023-10-20 08:11:19 -07:00
import TopBarStore from '@store/topBarStore'
2023-10-22 19:02:40 -07:00
import MedalIcon from './icons/MedalIcon'
export const TOPBAR_ICON_BUTTON_CLASSES =
2023-10-17 04:28:43 -07:00
'relative flex h-16 w-10 sm:w-16 items-center justify-center sm:border-l sm:border-th-bkg-3 focus-visible:bg-th-bkg-3 md:hover:bg-th-bkg-2'
2023-07-21 07:28:26 -07:00
const set = mangoStore.getState().set
const TopBar = () => {
const { t } = useTranslation('common')
2023-08-01 14:38:08 -07:00
const { mangoAccount, mangoAccountAddress } = useMangoAccount()
const { connected, wallet } = useWallet()
const { data: seasonData } = useCurrentSeason()
const {
2023-10-22 19:02:40 -07:00
data: accountPointsAndRank,
isInitialLoading: loadingAccountPointsAndRank,
refetch: refetchPoints,
} = useAccountPointsAndRank(mangoAccountAddress, seasonData?.season_id)
2023-09-27 20:59:14 -07:00
const { data: isWhiteListed } = useIsWhiteListed()
const router = useRouter()
2023-06-06 22:00:59 -07:00
const themeData = mangoStore((s) => s.themeData)
const [action, setAction] = useState<'deposit' | 'withdraw'>('deposit')
const [copied, setCopied] = useState('')
const [showDepositWithdrawModal, setShowDepositWithdrawModal] =
useState(false)
const [showCreateAccountModal, setShowCreateAccountModal] = useState(false)
2023-10-20 08:11:19 -07:00
const { showSettingsModal, setShowSettingsModal } = TopBarStore()
2022-11-19 10:33:12 -08:00
const isOnline = useOnlineStatus()
const { isUnownedAccount } = useUnownedAccount()
2023-07-21 07:28:26 -07:00
const showUserSetup = mangoStore((s) => s.showUserSetup)
const [, setIsOnboarded] = useLocalStorageState(IS_ONBOARDED_KEY)
2022-11-11 03:24:24 -08:00
const handleCloseSetup = useCallback(() => {
2023-07-21 07:28:26 -07:00
set((s) => {
s.showUserSetup = false
})
2022-11-11 03:24:24 -08:00
setIsOnboarded(true)
2023-07-21 07:28:26 -07:00
}, [setIsOnboarded])
2022-11-11 03:24:24 -08:00
const handleShowSetup = useCallback(() => {
2023-07-21 07:28:26 -07:00
set((s) => {
s.showUserSetup = true
})
}, [])
const handleDepositWithdrawModal = (action: 'deposit' | 'withdraw') => {
if (!connected || mangoAccount) {
setAction(action)
setShowDepositWithdrawModal(true)
} else {
setShowCreateAccountModal(true)
}
}
const handleCopy = (text: string) => {
copyToClipboard(text)
setCopied(text)
}
useEffect(() => {
setTimeout(() => setCopied(''), 2000)
}, [copied])
useEffect(() => {
if (router.pathname === '/rewards') {
2023-10-22 19:02:40 -07:00
refetchPoints()
}
}, [router])
return (
2023-05-14 21:30:00 -07:00
<div
2023-08-09 20:31:47 -07:00
className={`flex h-16 items-center justify-between border-b border-th-bkg-3 bg-th-bkg-1 bg-contain`}
2023-06-06 22:00:59 -07:00
style={{ backgroundImage: `url(${themeData.topTilePath})` }}
2023-05-14 21:30:00 -07:00
>
2023-05-29 22:30:34 -07:00
<div className="flex w-full items-center justify-between md:space-x-4">
2022-10-25 02:42:51 -07:00
<span className="mb-0 flex items-center">
<div className="flex h-[63px] w-16 items-center justify-center bg-th-bkg-1 md:hidden">
2023-11-01 17:55:30 -07:00
<Link href="/" shallow={true}>
<img
className="h-8 w-8 flex-shrink-0"
src={themeData.logoPath}
alt="logo"
/>
</Link>
</div>
{!connected ? (
mangoAccount ? (
2023-06-06 05:52:33 -07:00
<span className="hidden items-center md:flex md:pl-6">
<EyeIcon className="h-5 w-5 text-th-fgd-3" />
<span className="ml-2">
{t('unowned-helper', {
accountPk: '',
})}
</span>
:
<Tooltip
content={
<>
<p>{t('account')}</p>
<button
className="mb-2 flex items-center"
onClick={() =>
handleCopy(mangoAccount.publicKey.toString())
}
>
<p className="mr-1.5 font-mono text-th-fgd-1">
{abbreviateAddress(mangoAccount.publicKey)}
</p>
{copied === mangoAccount.publicKey.toString() ? (
<CheckCircleIcon className="h-4 w-4 flex-shrink-0 text-th-success" />
) : (
<DocumentDuplicateIcon className="h-4 w-4 flex-shrink-0" />
)}
</button>
<p>{t('wallet')}</p>
<button
className="flex items-center"
onClick={() =>
handleCopy(mangoAccount.owner.toString())
}
>
<p className="mr-1.5 font-mono text-th-fgd-1">
{abbreviateAddress(mangoAccount.owner)}
</p>
{copied === mangoAccount.owner.toString() ? (
<CheckCircleIcon className="h-4 w-4 flex-shrink-0 text-th-success" />
) : (
<DocumentDuplicateIcon className="h-4 w-4 flex-shrink-0" />
)}
</button>
</>
}
>
<span className="tooltip-underline ml-1 font-bold text-th-fgd-1">
{mangoAccount.name
? mangoAccount.name
: abbreviateAddress(mangoAccount.publicKey)}
</span>
</Tooltip>
</span>
) : (
2023-06-06 05:52:33 -07:00
<span className="hidden items-center md:flex md:pl-6">
<WalletIcon className="h-5 w-5 text-th-fgd-3" />
<span className="ml-2">{t('connect-helper')}</span>
<ArrowRightIcon className="sideways-bounce ml-2 h-5 w-5 text-th-fgd-1" />
</span>
)
2023-09-27 20:59:14 -07:00
) : isWhiteListed ? (
<Link href="/rewards" shallow={true}>
2023-10-24 20:02:36 -07:00
<div className="flex h-16 items-center justify-between border-x border-th-bkg-3 bg-th-bkg-1 px-4 md:border-l-0">
2023-10-22 19:02:40 -07:00
{accountPointsAndRank?.rank ? (
<div
className={`relative hidden h-6 w-6 flex-shrink-0 items-center justify-center rounded-full sm:flex ${
accountPointsAndRank.rank < 4 ? '' : 'bg-th-bkg-3'
} mr-2`}
>
<p
className={`relative z-10 text-xs font-bold ${
accountPointsAndRank.rank < 4
? 'text-th-bkg-1'
: 'text-th-fgd-1'
}`}
>
{accountPointsAndRank.rank}
</p>
{accountPointsAndRank.rank < 4 ? (
<MedalIcon
className="absolute"
rank={accountPointsAndRank.rank}
/>
) : null}
</div>
) : loadingAccountPointsAndRank ? (
<SheenLoader className="mr-2 hidden sm:block">
<div className="h-6 w-6 bg-th-bkg-2" />
</SheenLoader>
) : null}
<div>
<span className="whitespace-nowrap font-bold text-th-fgd-2">
Points
</span>
2023-10-22 19:02:40 -07:00
{!loadingAccountPointsAndRank ? (
<p className="bg-gradient-to-br from-yellow-400 to-red-400 bg-clip-text font-display text-base text-transparent">
2023-10-22 19:02:40 -07:00
{accountPointsAndRank?.total_points ? (
<FormatNumericValue
value={accountPointsAndRank.total_points}
decimals={0}
/>
2023-10-17 18:28:28 -07:00
) : wallet?.adapter.publicKey ? (
0
) : (
''
)}
</p>
) : (
<SheenLoader className="mt-1.5">
<div className="h-[18px] w-12 rounded-sm bg-th-bkg-3" />
</SheenLoader>
)}
</div>
2023-10-17 04:28:43 -07:00
<ChevronRightIcon className="ml-2 hidden h-6 w-6 text-th-fgd-4 lg:block" />
</div>
</Link>
2023-09-27 20:59:14 -07:00
) : null}
</span>
2022-11-19 10:33:12 -08:00
{!isOnline ? (
<div className="absolute left-1/2 top-3 z-10 flex h-10 w-max -translate-x-1/2 items-center rounded-full bg-th-down px-4 py-2 md:top-8">
2023-05-29 22:30:34 -07:00
<ExclamationTriangleIcon className="h-5 w-5 flex-shrink-0 text-th-fgd-1" />
2022-12-16 03:26:42 -08:00
<p className="ml-2 text-th-fgd-1">
Your connection appears to be offline
</p>
2022-11-19 10:33:12 -08:00
</div>
) : null}
2022-12-16 03:26:42 -08:00
<div className="flex items-center">
2023-10-17 04:28:43 -07:00
{isUnownedAccount || !connected ? null : (
2023-10-05 16:49:46 -07:00
<div className="h-[63px] bg-th-bkg-1">
<button
onClick={() => handleDepositWithdrawModal('deposit')}
className={TOPBAR_ICON_BUTTON_CLASSES}
>
<DepositWithdrawIcon className="h-6 w-6" />
</button>
</div>
2022-12-21 03:07:17 -08:00
)}
<div className="h-[63px] bg-th-bkg-1">
<button
className={TOPBAR_ICON_BUTTON_CLASSES}
onClick={() => setShowSettingsModal(true)}
>
<Cog8ToothIcon className="h-5 w-5" />
<span className="sr-only">Settings</span>
</button>
</div>
2022-12-16 03:26:42 -08:00
{connected ? (
<div className="flex h-[63px] items-center bg-th-bkg-1">
2023-08-01 14:38:08 -07:00
{mangoAccountAddress && <NotificationsButton />}
<AccountsButton />
2023-10-17 04:28:43 -07:00
<div className="pl-2 sm:pl-0">
<ConnectedMenu />
</div>
2022-12-16 03:26:42 -08:00
</div>
) : (
2023-10-17 04:28:43 -07:00
<div className="pl-2 sm:pl-0">
<ConnectWalletButton handleShowSetup={handleShowSetup} />
</div>
2022-12-16 03:26:42 -08:00
)}
</div>
</div>
{showDepositWithdrawModal ? (
<DepositWithdrawModal
action={action}
isOpen={showDepositWithdrawModal}
onClose={() => setShowDepositWithdrawModal(false)}
/>
) : null}
2022-12-20 17:14:35 -08:00
{showUserSetup ? (
<UserSetupModal isOpen={showUserSetup} onClose={handleCloseSetup} />
) : null}
{showCreateAccountModal ? (
<CreateAccountModal
isOpen={showCreateAccountModal}
onClose={() => setShowCreateAccountModal(false)}
/>
) : null}
{showSettingsModal ? (
<SettingsModal
isOpen={showSettingsModal}
onClose={() => setShowSettingsModal(false)}
/>
) : null}
2023-05-14 21:30:00 -07:00
</div>
)
}
export default TopBar