index.tsx raw

   1  import AccountManager from '@/components/AccountManager'
   2  import LoginDialog from '@/components/LoginDialog'
   3  import LogoutDialog from '@/components/LogoutDialog'
   4  import NpubQrCode from '@/components/NpubQrCode'
   5  import PubkeyCopy from '@/components/PubkeyCopy'
   6  import { Button } from '@/components/ui/button'
   7  import { Separator } from '@/components/ui/separator'
   8  import { SimpleUserAvatar } from '@/components/UserAvatar'
   9  import { SimpleUsername } from '@/components/Username'
  10  import PrimaryPageLayout from '@/layouts/PrimaryPageLayout'
  11  import { toBookmarks, toProfile, toRelaySettings, toSettings, toWallet } from '@/lib/link'
  12  import { cn } from '@/lib/utils'
  13  import { useSecondaryPage } from '@/PageManager'
  14  import { useNostr } from '@/providers/NostrProvider'
  15  import { TPageRef } from '@/types'
  16  import {
  17    ArrowDownUp,
  18    Bookmark,
  19    ChevronRight,
  20    LogOut,
  21    Server,
  22    Settings,
  23    UserRound,
  24    Wallet
  25  } from 'lucide-react'
  26  import { forwardRef, HTMLProps, useState } from 'react'
  27  import { useTranslation } from 'react-i18next'
  28  
  29  const MePage = forwardRef<TPageRef>((_, ref) => {
  30    const { t } = useTranslation()
  31    const { push } = useSecondaryPage()
  32    const { pubkey } = useNostr()
  33    const [loginDialogOpen, setLoginDialogOpen] = useState(false)
  34    const [logoutDialogOpen, setLogoutDialogOpen] = useState(false)
  35  
  36    if (!pubkey) {
  37      return (
  38        <PrimaryPageLayout
  39          ref={ref}
  40          pageName="home"
  41          titlebar={<MePageTitlebar />}
  42          hideTitlebarBottomBorder
  43        >
  44          <div className="flex flex-col p-4 gap-4 overflow-auto">
  45            <AccountManager />
  46          </div>
  47        </PrimaryPageLayout>
  48      )
  49    }
  50  
  51    return (
  52      <PrimaryPageLayout
  53        ref={ref}
  54        pageName="home"
  55        titlebar={<MePageTitlebar />}
  56        hideTitlebarBottomBorder
  57      >
  58        <div className="flex gap-4 items-center p-4">
  59          <SimpleUserAvatar userId={pubkey} size="big" />
  60          <div className="space-y-1 flex-1 w-0">
  61            <SimpleUsername
  62              className="text-xl font-semibold text-wrap"
  63              userId={pubkey}
  64              skeletonClassName="h-6 w-32"
  65              showQrCode={false}
  66            />
  67            <div className="flex gap-1 mt-1">
  68              <PubkeyCopy pubkey={pubkey} />
  69              <NpubQrCode pubkey={pubkey} />
  70            </div>
  71          </div>
  72        </div>
  73        <div className="mt-4">
  74          <Item onClick={() => push(toProfile(pubkey))}>
  75            <UserRound />
  76            {t('Profile')}
  77          </Item>
  78          <Item onClick={() => push(toRelaySettings())}>
  79            <Server /> {t('Relays')}
  80          </Item>
  81          <Item onClick={() => push(toBookmarks())}>
  82            <Bookmark /> {t('Bookmarks')}
  83          </Item>
  84          <Item onClick={() => push(toWallet())}>
  85            <Wallet />
  86            {t('Wallet')}
  87          </Item>
  88          <Item onClick={() => setLoginDialogOpen(true)}>
  89            <ArrowDownUp /> {t('Switch account')}
  90          </Item>
  91          <Separator className="bg-background" />
  92          <Item
  93            className="text-destructive focus:text-destructive"
  94            onClick={() => setLogoutDialogOpen(true)}
  95            hideChevron
  96          >
  97            <LogOut />
  98            {t('Logout')}
  99          </Item>
 100        </div>
 101        <LoginDialog open={loginDialogOpen} setOpen={setLoginDialogOpen} />
 102        <LogoutDialog open={logoutDialogOpen} setOpen={setLogoutDialogOpen} />
 103      </PrimaryPageLayout>
 104    )
 105  })
 106  MePage.displayName = 'MePage'
 107  export default MePage
 108  
 109  function MePageTitlebar() {
 110    const { push } = useSecondaryPage()
 111    return (
 112      <div className="flex justify-end items-center">
 113        <Button variant="ghost" size="titlebar-icon" onClick={() => push(toSettings())}>
 114          <Settings />
 115        </Button>
 116      </div>
 117    )
 118  }
 119  
 120  function Item({
 121    children,
 122    className,
 123    hideChevron = false,
 124    ...props
 125  }: HTMLProps<HTMLDivElement> & { hideChevron?: boolean }) {
 126    return (
 127      <div
 128        className={cn(
 129          'flex clickable justify-between items-center px-4 py-2 h-[52px] rounded-lg [&_svg]:size-4 [&_svg]:shrink-0',
 130          className
 131        )}
 132        {...props}
 133      >
 134        <div className="flex items-center gap-4">{children}</div>
 135        {!hideChevron && <ChevronRight />}
 136      </div>
 137    )
 138  }
 139