Skip to content

Commit

Permalink
Add a hub page (solana-labs#958)
Browse files Browse the repository at this point in the history
  • Loading branch information
nramadas authored Sep 12, 2022
1 parent bff71ce commit ca59719
Show file tree
Hide file tree
Showing 152 changed files with 9,411 additions and 421 deletions.
2 changes: 2 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ MAINNET_RPC=https://mango.rpcpool.com
DEVNET_RPC=https://mango.devnet.rpcpool.com

DEFAULT_GOVERNANCE_PROGRAM_ID=GTesTBiEWE32WHXXE2S4XbZvA5CrEc4xs6ZgRe895dP

NEXT_PUBLIC_API_ENDPOINT=http://localhost:3001/graphql
221 changes: 221 additions & 0 deletions components/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
import { ThemeProvider } from 'next-themes'
import { WalletIdentityProvider } from '@cardinal/namespaces-components'
import dynamic from 'next/dynamic'
import React, { useEffect } from 'react'
import Head from 'next/head'

import { GatewayProvider } from '@components/Gateway/GatewayProvider'
import { usePrevious } from '@hooks/usePrevious'
import { useVotingPlugins, vsrPluginsPks } from '@hooks/useVotingPlugins'
import ErrorBoundary from '@components/ErrorBoundary'
import handleGovernanceAssetsStore from '@hooks/handleGovernanceAssetsStore'
import handleRouterHistory from '@hooks/handleRouterHistory'
import NavBar from '@components/NavBar'
import PageBodyContainer from '@components/PageBodyContainer'
import tokenService from '@utils/services/token'
import TransactionLoader from '@components/TransactionLoader'
import useDepositStore from 'VoteStakeRegistry/stores/useDepositStore'
import useGovernanceAssets from '@hooks/useGovernanceAssets'
import useHydrateStore from '@hooks/useHydrateStore'
import useMarketStore from 'Strategies/store/marketStore'
import useMembers from '@components/Members/useMembers'
import useRealm from '@hooks/useRealm'
import useTreasuryAccountStore from 'stores/useTreasuryAccountStore'
import useVotePluginsClientStore from 'stores/useVotePluginsClientStore'
import useWallet from '@hooks/useWallet'
import useWalletStore from 'stores/useWalletStore'
import NftVotingCountingModal from '@components/NftVotingCountingModal'
import { getResourcePathPart } from '@tools/core/resources'

const Notifications = dynamic(() => import('../components/Notification'), {
ssr: false,
})

interface Props {
children: React.ReactNode
}

export function App(props: Props) {
useHydrateStore()
useWallet()
handleRouterHistory()
useVotingPlugins()
handleGovernanceAssetsStore()
useMembers()
useEffect(() => {
tokenService.fetchSolanaTokenList()
}, [])
const { loadMarket } = useMarketStore()
const { governedTokenAccounts } = useGovernanceAssets()
const possibleNftsAccounts = governedTokenAccounts.filter(
(x) => x.isSol || x.isNft
)
const { getNfts } = useTreasuryAccountStore()
const { getOwnedDeposits, resetDepositState } = useDepositStore()
const { realm, ownTokenRecord, realmInfo, symbol, config } = useRealm()
const wallet = useWalletStore((s) => s.current)
const connection = useWalletStore((s) => s.connection)
const client = useVotePluginsClientStore((s) => s.state.vsrClient)
const prevStringifyPossibleNftsAccounts = usePrevious(
JSON.stringify(possibleNftsAccounts)
)
const realmName = realmInfo?.displayName ?? realm?.account?.name
const title = realmName ? `${realmName}` : 'Realms'

// Note: ?v==${Date.now()} is added to the url to force favicon refresh.
// Without it browsers would cache the last used and won't change it for different realms
// https://stackoverflow.com/questions/2208933/how-do-i-force-a-favicon-refresh
const faviconUrl =
symbol &&
`/realms/${getResourcePathPart(
symbol as string
)}/favicon.ico?v=${Date.now()}`

useEffect(() => {
if (realm?.pubkey) {
loadMarket(connection, connection.cluster)
}
}, [connection.cluster, realm?.pubkey.toBase58()])
useEffect(() => {
if (
realm &&
config?.account.communityTokenConfig.voterWeightAddin &&
vsrPluginsPks.includes(
config.account.communityTokenConfig.voterWeightAddin.toBase58()
) &&
realm.pubkey &&
wallet?.connected &&
ownTokenRecord &&
client
) {
getOwnedDeposits({
realmPk: realm!.pubkey,
communityMintPk: realm!.account.communityMint,
walletPk: ownTokenRecord!.account!.governingTokenOwner,
client: client!,
connection: connection.current,
})
} else if (!wallet?.connected || !ownTokenRecord) {
resetDepositState()
}
}, [
realm?.pubkey.toBase58(),
ownTokenRecord?.pubkey.toBase58(),
wallet?.connected,
client?.program.programId.toBase58(),
])

useEffect(() => {
if (
prevStringifyPossibleNftsAccounts !==
JSON.stringify(possibleNftsAccounts) &&
realm?.pubkey
) {
getNfts(possibleNftsAccounts, connection)
}
}, [JSON.stringify(possibleNftsAccounts), realm?.pubkey.toBase58()])

return (
<div className="relative bg-bkg-1 text-fgd-1">
<Head>
<meta property="og:title" content={title} key="title" />
<title>{title}</title>
<style>{`
body {
background-color: #17161c;
}
`}</style>
{faviconUrl ? (
<>
<link rel="icon" href={faviconUrl} />
</>
) : (
<>
<link
rel="apple-touch-icon"
sizes="57x57"
href="/favicons/apple-icon-57x57.png"
/>
<link
rel="apple-touch-icon"
sizes="60x60"
href="/favicons/apple-icon-60x60.png"
/>
<link
rel="apple-touch-icon"
sizes="72x72"
href="/favicons/apple-icon-72x72.png"
/>
<link
rel="apple-touch-icon"
sizes="76x76"
href="/favicons/apple-icon-76x76.png"
/>
<link
rel="apple-touch-icon"
sizes="114x114"
href="/favicons/apple-icon-114x114.png"
/>
<link
rel="apple-touch-icon"
sizes="120x120"
href="/favicons/apple-icon-120x120.png"
/>
<link
rel="apple-touch-icon"
sizes="144x144"
href="/favicons/apple-icon-144x144.png"
/>
<link
rel="apple-touch-icon"
sizes="152x152"
href="/favicons/apple-icon-152x152.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/favicons/apple-icon-180x180.png"
/>
<link
rel="icon"
type="image/png"
sizes="192x192"
href="/favicons/android-icon-192x192.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicons/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="96x96"
href="/favicons/favicon-96x96.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicons/favicon-16x16.png"
/>
</>
)}
</Head>
<ErrorBoundary>
<ThemeProvider defaultTheme="Dark">
<WalletIdentityProvider appName={'Realms'}>
<GatewayProvider>
<NavBar />
<Notifications />
<TransactionLoader></TransactionLoader>
<NftVotingCountingModal />
<PageBodyContainer>{props.children}</PageBodyContainer>
</GatewayProvider>
</WalletIdentityProvider>
</ThemeProvider>
</ErrorBoundary>
</div>
)
}
2 changes: 1 addition & 1 deletion components/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const NavBar = () => {
const { fmtUrlWithCluster } = useQueryContext()

return (
<div className="flex flex-col sm:grid sm:grid-cols-12">
<div className="flex flex-col sm:grid sm:grid-cols-12 relative z-20">
<div className="flex items-center justify-between h-20 col-span-12 px-4 xl:col-start-2 xl:col-span-10 md:px-8 xl:px-4">
<Link href={fmtUrlWithCluster('/realms')}>
<div className="flex cursor-pointer sm:items-center min-w-[36px]">
Expand Down
4 changes: 2 additions & 2 deletions components/PageBodyContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ const PageBodyContainer = ({ children }) => {
isNewRealmsWizard ? '' : 'min-h-[calc(100vh_-_80px)] pb-64'
}`}
>
<div className="z-[-1] fixed top-0 left-0 w-[100vw] h-[100vh] bg-bkg-1">
<div className="z-[1] fixed top-0 left-0 w-[100vw] h-[100vh] bg-bkg-1">
<picture>
<source srcSet="/img/bg-desktop.png" media="(min-width: 640px)" />
<img src="/img/bg-mobile.png" />
</picture>
</div>
<div className="col-span-12 px-4 md:px-8 xl:px-4 xl:col-start-2 xl:col-span-10">
<div className="relative z-[2] col-span-12 px-4 md:px-8 xl:px-4 xl:col-start-2 xl:col-span-10">
{children}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion components/treasuryV2/Details/TokenDetails/Activity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function Activity(props: Props) {
const activity = useAccountActivity(props.assets.map((a) => a.address))
const cluster = useWalletStore((s) => s.connection.cluster)

switch (activity.status) {
switch (activity._tag) {
case Status.Failed:
return (
<div className={props.className}>
Expand Down
4 changes: 2 additions & 2 deletions components/treasuryV2/Details/TokenDetails/Investments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function Investments(props: Props) {
})

useEffect(() => {
if (investments.status === Status.Ok) {
if (investments._tag === Status.Ok) {
setShowAvailableInvestments(!investments.data.activeInvestments.length)
}
}, [investments])
Expand All @@ -58,7 +58,7 @@ export default function Investments(props: Props) {
}
}, [connection, props])

switch (investments.status) {
switch (investments._tag) {
case Status.Failed:
return (
<div className={props.className}>
Expand Down
2 changes: 1 addition & 1 deletion components/treasuryV2/Details/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ interface Props {
}

const Details = forwardRef<HTMLDivElement, Props>((props, ref) => {
switch (props.data.status) {
switch (props.data._tag) {
case Status.Failed:
return (
<div className={props.className} ref={ref}>
Expand Down
2 changes: 1 addition & 1 deletion components/treasuryV2/TotalValueTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface Props {
}

export default function TotalValueTitle(props: Props) {
switch (props.data.status) {
switch (props.data._tag) {
case Status.Failed:
return (
<div className={cx(props.className, 'space-y-1')}>
Expand Down
6 changes: 3 additions & 3 deletions components/treasuryV2/WalletList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function WalletList(props: Props) {
const [expanded, setExpanded] = useState<string[]>([])

useEffect(() => {
if (props.data.status === Status.Ok) {
if (props.data._tag === Status.Ok) {
const expanded = props.data.data.wallets[0]
const expandedKey = expanded
? 'address' in expanded
Expand All @@ -41,9 +41,9 @@ export default function WalletList(props: Props) {
}
})
}
}, [props.data.status])
}, [props.data._tag])

switch (props.data.status) {
switch (props.data._tag) {
case Status.Failed:
return (
<div className={cx(props.className, 'h-full')}>
Expand Down
Loading

0 comments on commit ca59719

Please sign in to comment.