11/* eslint-disable react-hooks/exhaustive-deps */
2- import {
3- // AccountProvider,
4- // ExtensionProvider,
5- SelectedAccountType ,
6- } from '@polkadot-ui/react'
72import { Sheet , SheetContent , SheetTrigger } from '@/components/ui/sheet'
83import { Button } from '@/components/ui/button'
9- import { RouterType , openInNewTab , resources , routes } from '@/lib/utils'
4+ import { RouterType , openInNewTab , resources , routes , cn } from '@/lib/utils'
105
11- import { PanelLeft , Moon , Sun , NotebookText , BookOpenText } from 'lucide-react'
6+ import {
7+ PanelLeft ,
8+ Moon ,
9+ Sun ,
10+ NotebookText ,
11+ BookOpenText ,
12+ Wallet ,
13+ Check ,
14+ } from 'lucide-react'
1215import { getLinks } from './Resources'
1316import {
1417 // FaCheckCircle,
@@ -17,7 +20,7 @@ import {
1720// import { TbLoaderQuarter } from 'react-icons/tb'
1821import { useTheme } from './components/theme-provider'
1922import { useEffect , useState } from 'react'
20- import { collectiveClient } from './clients'
23+ import { collectiveClient , polkadotClient } from './clients'
2124import {
2225 Dialog ,
2326 DialogContent ,
@@ -35,6 +38,7 @@ import {
3538} from '@radix-ui/react-accordion'
3639import { SiElement } from 'react-icons/si'
3740import { Link } from 'react-router-dom'
41+ import { Badge } from '@/components/ui/badge'
3842
3943// import { Polkicon } from '@polkadot-ui/react'
4044// import {
@@ -45,6 +49,7 @@ import { Link } from 'react-router-dom'
4549// DropdownMenuTrigger,
4650// } from '@/components/ui/dropdown-menu'
4751
52+ import { ConnectionButton } from 'dot-connect/react.js'
4853import { useAccount } from './contexts/AccountContextProvider'
4954
5055interface Props {
@@ -53,12 +58,11 @@ interface Props {
5358}
5459
5560export const Header = ( { lightClientLoaded, setLightClientLoaded } : Props ) => {
56- const { setSelectedAccount } = useAccount ( )
57-
58- const [
59- selAccount ,
60- // setSelAccount
61- ] = useState < SelectedAccountType > ( { } as SelectedAccountType )
61+ const { accounts, selectedAccount, setSelectedAccount } = useAccount ( )
62+ const [ accountDialogOpen , setAccountDialogOpen ] = useState ( false )
63+ const [ latestBlockNumber , setLatestBlockNumber ] = useState < number | null > (
64+ null ,
65+ )
6266
6367 useEffect ( ( ) => {
6468 collectiveClient . finalizedBlock$ . subscribe ( ( finalizedBlock ) => {
@@ -67,12 +71,19 @@ export const Header = ({ lightClientLoaded, setLightClientLoaded }: Props) => {
6771 }
6872 } )
6973 } , [ lightClientLoaded , setLightClientLoaded ] )
70- const { theme, setTheme } = useTheme ( )
7174
72- // TODO Correctly map the account
7375 useEffect ( ( ) => {
74- selAccount ?. address && setSelectedAccount ( selAccount )
75- } , [ selAccount ] )
76+ const subscription = polkadotClient . finalizedBlock$ . subscribe (
77+ ( finalizedBlock ) => {
78+ if ( typeof finalizedBlock . number === 'number' ) {
79+ setLatestBlockNumber ( finalizedBlock . number )
80+ }
81+ } ,
82+ )
83+
84+ return ( ) => subscription . unsubscribe ( )
85+ } , [ ] )
86+ const { theme, setTheme } = useTheme ( )
7687
7788 return (
7889 < header className = "sticky top-5 z-30 flex h-14 items-center gap-4 border-b bg-background px-4 sm:sticky sm:h-auto sm:border-0 sm:bg-transparent sm:px-6" >
@@ -228,7 +239,7 @@ export const Header = ({ lightClientLoaded, setLightClientLoaded }: Props) => {
228239 </ div >
229240 </ SheetContent >
230241 </ Sheet >
231- < div className = "flex w-full justify-between" >
242+ < div className = "flex w-full items-center justify-between" >
232243 < div >
233244 { /* <Menubar>
234245 <MenubarMenu>
@@ -246,70 +257,78 @@ export const Header = ({ lightClientLoaded, setLightClientLoaded }: Props) => {
246257 </MenubarMenu>
247258 </Menubar> */ }
248259 </ div >
249- { /* TODO - ACTIVATE THIS FOR CONNECT BUTTON
250- <div>
251- {!enchancedAccount?.address ? (
252- <Dialog>
253- <DialogTrigger asChild>
254- <Button>Connect</Button>
255- </DialogTrigger>
256- <DialogContent className="sm:max-w-[425px]">
257- <DialogHeader>
258- <DialogTitle className="text-primary font-bold">
259- Connect Wallet
260- </DialogTitle>
261- </DialogHeader>
262- <ExtensionProvider setSelected={setSelAccount}>
263- <AccountProvider
264- selected={selAccount}
265- setSelected={setSelAccount}
266- />
267- </ExtensionProvider>
268- </DialogContent>
269- </Dialog>
270- ) : (
271- <Dialog>
272- <DropdownMenu>
273- <DropdownMenuTrigger asChild>
274- <Button
275- variant="outline"
276- size="icon"
277- className="overflow-hidden rounded-full"
278- >
279- <Polkicon size={36} address={enchancedAccount?.address} />
280- </Button>
281- </DropdownMenuTrigger>
282- <DropdownMenuContent align="end">
283- <DialogTrigger asChild>
284- <DropdownMenuItem className="cursor-pointer">
285- Switch Account
286- </DropdownMenuItem>
287- </DialogTrigger>
288- <DropdownMenuSeparator />
289- <DropdownMenuItem
290- className="cursor-pointer"
291- onClick={() => setSelectedAccount(undefined)}
292- >
293- Logout
294- </DropdownMenuItem>
295- </DropdownMenuContent>
296- </DropdownMenu>
297- <DialogContent className="sm:max-w-[425px]">
298- <DialogHeader>
299- <DialogTitle className="text-primary font-bold">
300- Connect Wallet
301- </DialogTitle>
302- </DialogHeader>
303- <ExtensionProvider setSelected={setSelAccount}>
304- <AccountProvider
305- selected={selAccount}
306- setSelected={setSelAccount}
307- />
308- </ExtensionProvider>
309- </DialogContent>
310- </Dialog>
311- )}
312- </div> */ }
260+ < div className = "flex items-center gap-3" >
261+ < Dialog open = { accountDialogOpen } onOpenChange = { setAccountDialogOpen } >
262+ < DialogTrigger asChild >
263+ < Button variant = "outline" size = "lg" className = "rounded-3xl p-5" >
264+ Manage accounts
265+ </ Button >
266+ </ DialogTrigger >
267+ < DialogContent className = "sm:max-w-[420px]" >
268+ < DialogHeader >
269+ < DialogTitle className = "font-bold text-primary" >
270+ Connected accounts
271+ </ DialogTitle >
272+ < DialogDescription >
273+ Choose which account the dashboard should use.
274+ </ DialogDescription >
275+ </ DialogHeader >
276+ { accounts . length ? (
277+ < div className = "flex flex-col gap-2" >
278+ { accounts . map ( ( account ) => {
279+ const isSelected =
280+ selectedAccount ?. address === account . address
281+ const shortAddress =
282+ account . address . length > 12
283+ ? `${ account . address . slice ( 0 , 6 ) } ...${ account . address . slice ( - 4 ) } `
284+ : account . address
285+
286+ return (
287+ < button
288+ type = "button"
289+ key = { account . address }
290+ onClick = { ( ) => {
291+ setSelectedAccount ( account )
292+ setAccountDialogOpen ( false )
293+ } }
294+ className = { cn (
295+ 'flex w-full items-center justify-between rounded-md border p-3 text-left transition-colors hover:bg-muted' ,
296+ isSelected
297+ ? 'border-primary bg-primary/5'
298+ : 'border-border bg-background' ,
299+ ) }
300+ >
301+ < div className = "flex flex-col" >
302+ < span className = "text-sm font-medium" >
303+ { account . name || 'Wallet account' }
304+ </ span >
305+ < span className = "text-xs text-muted-foreground" >
306+ { shortAddress }
307+ </ span >
308+ </ div >
309+ { isSelected ? (
310+ < Check className = "h-4 w-4 text-primary" />
311+ ) : (
312+ < Wallet className = "h-4 w-4 text-muted-foreground" />
313+ ) }
314+ </ button >
315+ )
316+ } ) }
317+ </ div >
318+ ) : (
319+ < p className = "text-sm text-muted-foreground" >
320+ Connect a wallet to view available accounts.
321+ </ p >
322+ ) }
323+ </ DialogContent >
324+ </ Dialog >
325+ < ConnectionButton />
326+ < Badge variant = "secondary" className = "text-nowrap p-3" >
327+ { latestBlockNumber
328+ ? `#${ latestBlockNumber . toLocaleString ( ) } `
329+ : 'Syncing block...' }
330+ </ Badge >
331+ </ div >
313332 </ div >
314333 </ header >
315334 )
0 commit comments