-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathAccount.tsx
113 lines (103 loc) · 3.03 KB
/
Account.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { GroupRounded, WalletRounded } from '@mui/icons-material'
import { useRouter } from 'next/router'
import { ComponentType, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import {
AccountTab,
AccountTabId,
ButtonLinkProps,
LoadingDataWithError,
SuspenseLoaderProps,
WalletProfileHeaderProps,
} from '@dao-dao/types'
import { getAccountPath } from '@dao-dao/utils'
import {
CopyableAddress,
ErrorPage,
Loader,
TabBar,
WalletProfileHeader,
} from '../components'
export type AccountProps = {
address: string
hexPublicKey: LoadingDataWithError<string | undefined>
AccountDaos: ComponentType
AccountWallet: ComponentType
SuspenseLoader: ComponentType<SuspenseLoaderProps>
ButtonLink: ComponentType<ButtonLinkProps>
} & Pick<WalletProfileHeaderProps, 'profile'>
export const Account = ({
address,
hexPublicKey,
AccountDaos,
AccountWallet,
SuspenseLoader,
ButtonLink,
...headerProps
}: AccountProps) => {
const { t } = useTranslation()
const router = useRouter()
const tabs: AccountTab[] = [
{
id: AccountTabId.Daos,
label: t('title.daos'),
Icon: GroupRounded,
Component: AccountDaos,
},
{
id: AccountTabId.Wallet,
label: t('title.wallet'),
Icon: WalletRounded,
Component: AccountWallet,
},
]
// Pre-fetch tabs.
useEffect(() => {
tabs.forEach(({ id }) => {
router.prefetch(getAccountPath(address, id))
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router, address])
const _tab = router.query.tab
const tabPath = _tab && Array.isArray(_tab) ? _tab[0] : undefined
const selectedTabId =
// If tabPath is not a valid tab, default to first tab. This ensures that
// the default `/account/:address` page will render the first tab, and also
// that an invalid tab was not passed.
tabPath && tabs.some(({ id }) => id === tabPath)
? (tabPath as AccountTabId)
: tabs[0].id
const selectedTab = tabs.find(({ id }) => id === selectedTabId)
return (
<div className="flex min-h-full flex-col items-stretch gap-6">
{!hexPublicKey.loading && (hexPublicKey.errored || !hexPublicKey.data) ? (
<ErrorPage title={t('error.couldntFindWallet')}>
<ButtonLink href="/" variant="secondary">
{t('button.returnHome')}
</ButtonLink>
</ErrorPage>
) : (
<>
<WalletProfileHeader editable={false} {...headerProps}>
<CopyableAddress address={address} />
</WalletProfileHeader>
<TabBar
onSelect={(tab) =>
router.replace(getAccountPath(address, tab), undefined, {
shallow: true,
})
}
selectedTabId={selectedTabId}
tabs={tabs}
/>
{/* Don't render a tab unless it is visible. */}
{selectedTab && (
<SuspenseLoader fallback={<Loader />}>
<selectedTab.Component />
</SuspenseLoader>
)}
</>
)}
</div>
)
}